Search in sources :

Example 41 with CtClass

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

the class EnhancerProxyCreater method buildProxyCallbackClass.

/**
 * Creates a Cglib Callback which is a subclass of DetachableBeanHolder
 *
 * @param cglibPackage
 *            Cglib Package name
 * @param cp
 * @return Class of the Enhancer Proxy callback
 * @throws CannotCompileException
 * @throws NotFoundException
 */
private Class<?> buildProxyCallbackClass(String cglibPackage, ClassPool cp) throws CannotCompileException, NotFoundException {
    String proxyPackage = cglibPackage + "proxy.";
    CtClass ct = cp.makeClass("HotswapSpringCallback" + getClassSuffix(cglibPackage));
    ct.setSuperclass(cp.get(DetachableBeanHolder.class.getName()));
    ct.addInterface(cp.get(proxyPackage + "MethodInterceptor"));
    String rawBody = // 
    "	public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, {0}MethodProxy proxy) throws Throwable {" + // 
    "		if(method != null && method.getName().equals(\"finalize\") && method.getParameterTypes().length == 0)" + // 
    "			return null;" + // 
    "		return proxy.invoke(getBean(), args);" + "	}";
    String body = rawBody.replaceAll("\\{0\\}", proxyPackage);
    CtMethod m = CtNewMethod.make(body, ct);
    ct.addMethod(m);
    return ct.toClass(loader, pd);
}
Also used : CtClass(org.hotswap.agent.javassist.CtClass) CtMethod(org.hotswap.agent.javassist.CtMethod)

Example 42 with CtClass

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

the class ComponentScanWithWildcardsTest method copyClassFile.

public static File copyClassFile(Class<?> clazz, String newName) throws Exception {
    String directoryName = clazz.getClassLoader().getResource("").getPath();
    ClassPool classPool = new ClassPool();
    classPool.appendClassPath(new LoaderClassPath(clazz.getClassLoader()));
    CtClass ctClass = classPool.getAndRename(clazz.getName(), newName);
    ctClass.writeFile(directoryName);
    File file = new File(directoryName + File.separatorChar + newName.replace('.', File.separatorChar) + ".class");
    assertTrue(file.exists());
    return file;
}
Also used : CtClass(org.hotswap.agent.javassist.CtClass) ClassPool(org.hotswap.agent.javassist.ClassPool) LoaderClassPath(org.hotswap.agent.javassist.LoaderClassPath) File(java.io.File)

Example 43 with CtClass

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

the class CtClassJavaProxyGenerator method generateClassFile.

/**
 * Generate a class file for the proxy class. This method drives the class file generation process.
 */
private byte[] generateClassFile() {
    /*
		 * ============================================================ Step 1: Assemble ProxyMethod objects for all
		 * methods to generate proxy dispatching code for.
		 */
    /*
		 * Record that proxy methods are needed for the hashCode, equals, and toString methods of java.lang.Object. This
		 * is done before the methods from the proxy interfaces so that the methods from java.lang.Object take
		 * precedence over duplicate methods in the proxy interfaces.
		 */
    addProxyMethod(f.hashCodeMethod, f.oclp);
    addProxyMethod(f.equalsMethod, f.oclp);
    addProxyMethod(f.toStringMethod, f.oclp);
    Collection<CtClass> iWithSuper = new HashSet<>();
    addInterfacesWithSuperInterfaces(iWithSuper, interfaces);
    /*
		 * Now record all of the methods from the proxy interfaces, giving earlier interfaces precedence over later ones
		 * with duplicate methods.
		 */
    for (CtClass intf : iWithSuper) {
        for (CtMethod m : intf.getDeclaredMethods()) {
            addProxyMethod(m, intf);
        }
    }
    /*
		 * For each set of proxy methods with the same signature, verify that the methods' return types are compatible.
		 */
    for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
        checkReturnTypes(sigmethods);
    }
    /*
		 * ============================================================ Step 2: Assemble FieldInfo and MethodInfo
		 * structs for all of fields and methods in the class we are generating.
		 */
    try {
        methods.add(generateConstructor());
        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
            for (ProxyMethod pm : sigmethods) {
                // add static field for method's Method object
                fields.add(new FieldInfo(pm.methodFieldName, "Ljava/lang/reflect/Method;", ACC_PRIVATE | ACC_STATIC));
            }
        }
        fields.add(new FieldInfo(initFieldName, "Z", ACC_PRIVATE | ACC_STATIC));
        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
            for (ProxyMethod pm : sigmethods) {
                // generate code for proxy method and add it
                methods.add(pm.generateMethod());
            }
        }
        methods.add(generateStaticInitializer());
        methods.add(generateStaticInitializerCaller());
    } catch (IOException e) {
        throw new InternalError("unexpected I/O Exception");
    }
    if (methods.size() > 65535) {
        throw new IllegalArgumentException("method limit exceeded");
    }
    if (fields.size() > 65535) {
        throw new IllegalArgumentException("field limit exceeded");
    }
    /*
		 * ============================================================ Step 3: Write the final class file.
		 */
    /*
		 * Make sure that constant pool indexes are reserved for the following items before starting to write the final
		 * class file.
		 */
    cp.getClass(dotToSlash(className));
    cp.getClass(superclassName);
    for (CtClass intf : interfaces) {
        cp.getClass(dotToSlash(intf.getName()));
    }
    /*
		 * Disallow new constant pool additions beyond this point, since we are about to write the final constant pool
		 * table.
		 */
    cp.setReadOnly();
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    DataOutputStream dout = new DataOutputStream(bout);
    try {
        /*
			 * Write all the items of the "ClassFile" structure. See JVMS section 4.1.
			 */
        // u4 magic;
        dout.writeInt(0xCAFEBABE);
        // u2 minor_version;
        dout.writeShort(CLASSFILE_MINOR_VERSION);
        // u2 major_version;
        dout.writeShort(CLASSFILE_MAJOR_VERSION);
        // (write constant pool)
        cp.write(dout);
        // u2 access_flags;
        dout.writeShort(accessFlags);
        // u2 this_class;
        dout.writeShort(cp.getClass(dotToSlash(className)));
        // u2 super_class;
        dout.writeShort(cp.getClass(superclassName));
        // u2 interfaces_count;
        dout.writeShort(interfaces.length);
        // u2 interfaces[interfaces_count];
        for (CtClass intf : interfaces) {
            dout.writeShort(cp.getClass(dotToSlash(intf.getName())));
        }
        // u2 fields_count;
        dout.writeShort(fields.size());
        // field_info fields[fields_count];
        for (FieldInfo f : fields) {
            f.write(dout);
        }
        // u2 methods_count;
        dout.writeShort(methods.size());
        // method_info methods[methods_count];
        for (MethodInfo m : methods) {
            m.write(dout);
        }
        // u2 attributes_count;
        // (no ClassFile attributes for proxy classes)
        dout.writeShort(0);
    } catch (IOException e) {
        throw new InternalError("unexpected I/O Exception");
    }
    return bout.toByteArray();
}
Also used : DataOutputStream(java.io.DataOutputStream) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) CtClass(org.hotswap.agent.javassist.CtClass) CtMethod(org.hotswap.agent.javassist.CtMethod) HashSet(java.util.HashSet)

Example 44 with CtClass

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

the class WebappLoaderTransformer method patchStandardRoot.

/**
 * Resource lookup for Tomcat 8x.
 *
 * Before the resource is handled by Tomcat, try to get extraResource handled by the plugin.
 */
@OnClassLoadEvent(classNameRegexp = "org.apache.catalina.webresources.StandardRoot")
public static void patchStandardRoot(ClassPool classPool, CtClass ctClass) throws NotFoundException, CannotCompileException, ClassNotFoundException {
    CtClass ctFileResource = classPool.get("org.apache.catalina.webresources.FileResource");
    CtConstructor ctFileResourceConstructor = ctFileResource.getConstructors()[0];
    CtClass[] constructorTypes = ctFileResourceConstructor.getParameterTypes();
    String constrParams;
    if (constructorTypes.length == 4)
        constrParams = "this, path, file, false";
    else if (constructorTypes.length == 5)
        constrParams = "this, path, file, false, null";
    else {
        LOGGER.warning("org.apache.catalina.webresources.FileResource unknown constructor. Tomcat plugin will not work properly.");
        return;
    }
    try {
        ctClass.getDeclaredMethod("getResourceInternal", new CtClass[] { classPool.get(String.class.getName()), CtPrimitiveType.booleanType }).insertBefore("java.io.File file = " + TomcatPlugin.class.getName() + ".getExtraResourceFile(this, path);" + "if (file != null) return new org.apache.catalina.webresources.FileResource(" + constrParams + ");");
    } catch (NotFoundException e) {
        LOGGER.warning("org.apache.catalina.webresources.StandardRoot does not contain getResourceInternal method. Tomcat plugin will not work properly.");
        return;
    }
    // if getResources() should contain extraClasspath, expand the original returned array and prepend extraClasspath result
    try {
        ctClass.getDeclaredMethod("getResources", new CtClass[] { classPool.get(String.class.getName()), CtPrimitiveType.booleanType }).insertAfter("java.io.File file = " + TomcatPlugin.class.getName() + ".getExtraResourceFile(this, path);" + "if (file != null) {" + "org.apache.catalina.WebResource[] ret = new org.apache.catalina.WebResource[$_.length + 1];" + "ret[0] = new org.apache.catalina.webresources.FileResource(" + constrParams + ");" + "java.lang.System.arraycopy($_, 0, ret, 1, $_.length);" + "return ret;" + "} else {return $_;}");
    } catch (NotFoundException e) {
        LOGGER.warning("org.apache.catalina.webresources.StandardRoot does not contain getResourceInternal method. Tomcat plugin will not work properly.");
        return;
    }
}
Also used : CtClass(org.hotswap.agent.javassist.CtClass) NotFoundException(org.hotswap.agent.javassist.NotFoundException) CtConstructor(org.hotswap.agent.javassist.CtConstructor) OnClassLoadEvent(org.hotswap.agent.annotation.OnClassLoadEvent)

Example 45 with CtClass

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

the class PluginCache method scanPlugins.

public Set<CtClass> scanPlugins(ClassLoader classLoader) throws IOException {
    if (!pluginDefs.containsKey(classLoader)) {
        synchronized (pluginDefs) {
            if (!pluginDefs.containsKey(classLoader)) {
                final Set<CtClass> plugins = new HashSet<CtClass>();
                final ClassPool classPool = ClassPool.getDefault();
                scanner.scan(getClass().getClassLoader(), PLUGIN_PATH, new ScannerVisitor() {

                    @Override
                    public void visit(InputStream file) throws IOException {
                        plugins.add(classPool.makeClass(file));
                    }
                });
            }
        }
    }
    return pluginDefs.get(classLoader);
}
Also used : CtClass(org.hotswap.agent.javassist.CtClass) InputStream(java.io.InputStream) ClassPool(org.hotswap.agent.javassist.ClassPool) IOException(java.io.IOException)

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