Search in sources :

Example 26 with CtClass

use of org.hotswap.agent.javassist.CtClass in project HotswapAgent by HotswapProjects.

the class HotswapperPlugin method watchReload.

/**
 * For each changed class create a reload command.
 */
@OnClassFileEvent(classNameRegexp = ".*", events = { FileEvent.MODIFY, FileEvent.CREATE })
public void watchReload(CtClass ctClass, ClassLoader appClassLoader, URL url) throws IOException, CannotCompileException {
    if (!ClassLoaderHelper.isClassLoaded(appClassLoader, ctClass.getName())) {
        LOGGER.trace("Class {} not loaded yet, no need for autoHotswap, skipped URL {}", ctClass.getName(), url);
        return;
    }
    LOGGER.debug("Class {} will be reloaded from URL {}", ctClass.getName(), url);
    // search for a class to reload
    Class clazz;
    try {
        clazz = appClassLoader.loadClass(ctClass.getName());
    } catch (ClassNotFoundException e) {
        LOGGER.warning("Hotswapper tries to reload class {}, which is not known to application classLoader {}.", ctClass.getName(), appClassLoader);
        return;
    }
    synchronized (reloadMap) {
        reloadMap.put(clazz, ctClass.toBytecode());
    }
    scheduler.scheduleCommand(hotswapCommand, 100, Scheduler.DuplicateSheduleBehaviour.SKIP);
}
Also used : CtClass(org.hotswap.agent.javassist.CtClass) OnClassFileEvent(org.hotswap.agent.annotation.OnClassFileEvent)

Example 27 with CtClass

use of org.hotswap.agent.javassist.CtClass in project HotswapAgent by HotswapProjects.

the class AnonymousClassInfo method getMethodSignature.

private void getMethodSignature(StringBuilder methodsSignature, CtMethod m) throws NotFoundException {
    methodsSignature.append(m.getReturnType().getName());
    methodsSignature.append(" ");
    methodsSignature.append(m.getName());
    methodsSignature.append("(");
    for (CtClass paramType : m.getParameterTypes()) methodsSignature.append(paramType.getName());
    methodsSignature.append(")");
    methodsSignature.append(";");
}
Also used : CtClass(org.hotswap.agent.javassist.CtClass)

Example 28 with CtClass

use of org.hotswap.agent.javassist.CtClass in project HotswapAgent by HotswapProjects.

the class ClassInitPlugin method patch.

@OnClassLoadEvent(classNameRegexp = ".*", events = LoadEvent.REDEFINE)
public static void patch(final CtClass ctClass, final ClassLoader classLoader, final Class<?> originalClass) throws IOException, CannotCompileException, NotFoundException {
    if (isSyntheticClass(originalClass)) {
        return;
    }
    final String className = ctClass.getName();
    try {
        CtMethod origMethod = ctClass.getDeclaredMethod(HOTSWAP_AGENT_CLINIT_METHOD);
        ctClass.removeMethod(origMethod);
    } catch (org.hotswap.agent.javassist.NotFoundException ex) {
    // swallow
    }
    CtConstructor clinit = ctClass.getClassInitializer();
    if (clinit != null) {
        LOGGER.debug("Adding __ha_clinit to class: {}", className);
        CtConstructor haClinit = new CtConstructor(clinit, ctClass, null);
        haClinit.getMethodInfo().setName(HOTSWAP_AGENT_CLINIT_METHOD);
        haClinit.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
        ctClass.addConstructor(haClinit);
        final boolean[] reinitializeStatics = new boolean[] { false };
        haClinit.instrument(new ExprEditor() {

            public void edit(FieldAccess f) throws CannotCompileException {
                try {
                    if (f.isStatic() && f.isWriter()) {
                        Field originalField = null;
                        try {
                            originalField = originalClass.getDeclaredField(f.getFieldName());
                        } catch (NoSuchFieldException e) {
                            LOGGER.debug("New field will be initialized {}", f.getFieldName());
                            reinitializeStatics[0] = true;
                        }
                        if (originalField != null) {
                            // ENUM$VALUES is last in enumeration
                            if (originalClass.isEnum() && "ENUM$VALUES".equals(f.getFieldName())) {
                                if (reinitializeStatics[0]) {
                                    LOGGER.debug("New field will be initialized {}", f.getFieldName());
                                } else {
                                    reinitializeStatics[0] = checkOldEnumValues(ctClass, originalClass);
                                }
                            } else {
                                LOGGER.debug("Skipping old field {}", f.getFieldName());
                                f.replace("{}");
                            }
                        }
                    }
                } catch (Exception e) {
                    LOGGER.error("Patching __ha_clinit method failed.", e);
                }
            }
        });
        if (reinitializeStatics[0]) {
            PluginManager.getInstance().getScheduler().scheduleCommand(new Command() {

                @Override
                public void executeCommand() {
                    try {
                        Class<?> clazz = classLoader.loadClass(className);
                        Method m = clazz.getDeclaredMethod(HOTSWAP_AGENT_CLINIT_METHOD, new Class[] {});
                        if (m != null) {
                            m.invoke(null, new Object[] {});
                        }
                    } catch (Exception e) {
                        LOGGER.error("Error initializing redefined class {}", e, className);
                    } finally {
                        reloadFlag = false;
                    }
                }
            }, // Hack : init should be done after dependant class redefinition. Since the class can
            150);
        // be proxied by syntetic proxy, the class init must be scheduled after proxy redefinition.
        // Currently proxy redefinition (in ProxyPlugin) is scheduled with 100ms delay, therefore
        // the class init must be scheduled after it.
        } else {
            reloadFlag = false;
        }
    }
}
Also used : CannotCompileException(org.hotswap.agent.javassist.CannotCompileException) CtMethod(org.hotswap.agent.javassist.CtMethod) Method(java.lang.reflect.Method) CannotCompileException(org.hotswap.agent.javassist.CannotCompileException) IOException(java.io.IOException) NotFoundException(org.hotswap.agent.javassist.NotFoundException) CtConstructor(org.hotswap.agent.javassist.CtConstructor) Field(java.lang.reflect.Field) CtField(org.hotswap.agent.javassist.CtField) Command(org.hotswap.agent.command.Command) NotFoundException(org.hotswap.agent.javassist.NotFoundException) ExprEditor(org.hotswap.agent.javassist.expr.ExprEditor) CtClass(org.hotswap.agent.javassist.CtClass) FieldAccess(org.hotswap.agent.javassist.expr.FieldAccess) CtMethod(org.hotswap.agent.javassist.CtMethod) OnClassLoadEvent(org.hotswap.agent.annotation.OnClassLoadEvent)

Example 29 with CtClass

use of org.hotswap.agent.javassist.CtClass in project HotswapAgent by HotswapProjects.

the class HotSwapper method swapClasses.

/**
 * Swap class definition from another class file.
 * <p/>
 * This is mainly useful for unit testing - declare multiple version of a class and then
 * hotswap definition and do the tests.
 *
 * @param original original class currently in use
 * @param swap     fully qualified class name of class to swap
 * @throws Exception swap exception
 */
public static void swapClasses(Class original, String swap) throws Exception {
    // need to recreate classpool on each swap to avoid stale class definition
    ClassPool classPool = new ClassPool();
    classPool.appendClassPath(new LoaderClassPath(original.getClassLoader()));
    CtClass ctClass = classPool.getAndRename(swap, original.getName());
    reload(original, ctClass.toBytecode());
}
Also used : CtClass(org.hotswap.agent.javassist.CtClass) ClassPool(org.hotswap.agent.javassist.ClassPool) LoaderClassPath(org.hotswap.agent.javassist.LoaderClassPath)

Example 30 with CtClass

use of org.hotswap.agent.javassist.CtClass in project HotswapAgent by HotswapProjects.

the class HotSwapper method newClass.

public static Class newClass(String className, String directory, ClassLoader cl) {
    try {
        ClassPool classPool = new ClassPool();
        classPool.appendClassPath(new LoaderClassPath(cl));
        CtClass makeClass = classPool.makeClass(className);
        makeClass.writeFile(directory);
        return makeClass.toClass();
    } catch (Throwable ex) {
        Logger.getLogger(HotSwapper.class.getName()).log(Level.SEVERE, null, ex);
        throw new RuntimeException(ex);
    }
}
Also used : CtClass(org.hotswap.agent.javassist.CtClass) ClassPool(org.hotswap.agent.javassist.ClassPool) LoaderClassPath(org.hotswap.agent.javassist.LoaderClassPath)

Aggregations

CtClass (org.hotswap.agent.javassist.CtClass)69 NotFoundException (org.hotswap.agent.javassist.NotFoundException)20 CtMethod (org.hotswap.agent.javassist.CtMethod)18 ClassPool (org.hotswap.agent.javassist.ClassPool)14 OnClassLoadEvent (org.hotswap.agent.annotation.OnClassLoadEvent)13 CannotCompileException (org.hotswap.agent.javassist.CannotCompileException)8 CtConstructor (org.hotswap.agent.javassist.CtConstructor)8 CtField (org.hotswap.agent.javassist.CtField)8 HashMap (java.util.HashMap)6 LoaderClassPath (org.hotswap.agent.javassist.LoaderClassPath)6 IOException (java.io.IOException)5 ArrayList (java.util.ArrayList)5 Map (java.util.Map)5 Test (org.junit.Test)5 Iterator (java.util.Iterator)4 ExprEditor (org.hotswap.agent.javassist.expr.ExprEditor)4 Method (java.lang.reflect.Method)3 IdentityHashMap (java.util.IdentityHashMap)3 BadBytecode (org.hotswap.agent.javassist.bytecode.BadBytecode)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2