Search in sources :

Example 31 with CtMethod

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

the class SeamPlugin method seamServletCallInitialized.

@OnClassLoadEvent(classNameRegexp = "org.jboss.seam.init.Initialization")
public static void seamServletCallInitialized(CtClass ctClass) throws NotFoundException, CannotCompileException {
    CtMethod init = ctClass.getDeclaredMethod("init");
    init.insertBefore("{" + PluginManagerInvoker.buildInitializePlugin(SeamPlugin.class) + "}");
    LOGGER.debug("org.jboss.seam.init.Initialization enhanced with plugin initialization.");
}
Also used : CtMethod(org.hotswap.agent.javassist.CtMethod) OnClassLoadEvent(org.hotswap.agent.annotation.OnClassLoadEvent)

Example 32 with CtMethod

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

the class EnhancerProxyCreater method buildProxyCreaterClass.

/**
 * Builds a class that has a single public static method create(Object beanFactry, Object bean, Class[] classes,
 * Object[] params). The method of the created class returns a Cglib Enhancer created proxy of the parameter bean.
 * The proxy has single callback, whish is a subclass of DetachableBeanHolder. Classname prefix for created proxies
 * will be HOTSWAPAGENT_
 *
 * @param cglibPackage
 *            Cglib Package name
 * @param callback
 *            Callback class used for Enhancer
 * @param namingPolicy
 *            NamingPolicy class used for Enhancer
 * @param cp
 * @return Class that creates proxies via method "public static Object create(Object beanFactry, Object bean,
 *         Class[] classes, Object[] params)"
 * @throws CannotCompileException
 */
private Class<?> buildProxyCreaterClass(String cglibPackage, Class<?> callback, Class<?> namingPolicy, ClassPool cp) throws CannotCompileException {
    CtClass ct = cp.makeClass("HotswapAgentSpringBeanProxy" + getClassSuffix(cglibPackage));
    String proxy = cglibPackage + "proxy.";
    String core = cglibPackage + "core.";
    String rawBody = "public static Object create(Object beanFactry, Object bean, Class[] classes, Object[] params) {" + // 
    "{2} handler = new {2}(bean, beanFactry, classes, params);" + // 
    "		{0}Enhancer e = new {0}Enhancer();" + // 
    "		e.setUseCache(true);" + // 
    "		Class[] proxyInterfaces = new Class[bean.getClass().getInterfaces().length];" + // 
    "		Class[] classInterfaces = bean.getClass().getInterfaces();" + // 
    "		for (int i = 0; i < classInterfaces.length; i++) {" + // 
    "			proxyInterfaces[i] = classInterfaces[i];" + // 
    "		}" + // 
    "		e.setInterfaces(proxyInterfaces);" + // 
    "		e.setSuperclass(bean.getClass().getSuperclass());" + // 
    "		e.setCallback(handler);" + // 
    "		e.setCallbackType({2}.class);" + // 
    "		e.setNamingPolicy(new {3}());" + // 
    "		return e.create();" + "	}";
    String body = rawBody.replaceAll("\\{0\\}", proxy).replaceAll("\\{1\\}", core).replaceAll("\\{2\\}", callback.getName()).replaceAll("\\{3\\}", namingPolicy.getName());
    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 33 with CtMethod

use of org.hotswap.agent.javassist.CtMethod 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 34 with CtMethod

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

the class GeneratorParametersTransformer method transform.

/**
 * Adds bytecode generation call parameter recording
 *
 * @param cc
 * @return
 * @throws Exception
 */
public static CtClass transform(CtClass cc) throws Exception {
    if (isGeneratorStrategy(cc)) {
        for (CtMethod method : cc.getDeclaredMethods()) {
            if (!Modifier.isAbstract(method.getModifiers()) && method.getName().equals("generate") && method.getMethodInfo().getDescriptor().endsWith(";)[B")) {
                cc.defrost();
                method.insertAfter("org.hotswap.agent.plugin.proxy.hscglib.GeneratorParametersRecorder.register($0, $1, $_);");
            }
        }
    }
    return cc;
}
Also used : CtMethod(org.hotswap.agent.javassist.CtMethod)

Example 35 with CtMethod

use of org.hotswap.agent.javassist.CtMethod 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)

Aggregations

CtMethod (org.hotswap.agent.javassist.CtMethod)48 OnClassLoadEvent (org.hotswap.agent.annotation.OnClassLoadEvent)29 CtClass (org.hotswap.agent.javassist.CtClass)18 NotFoundException (org.hotswap.agent.javassist.NotFoundException)15 CtField (org.hotswap.agent.javassist.CtField)13 CannotCompileException (org.hotswap.agent.javassist.CannotCompileException)11 CtConstructor (org.hotswap.agent.javassist.CtConstructor)6 ExprEditor (org.hotswap.agent.javassist.expr.ExprEditor)6 MethodCall (org.hotswap.agent.javassist.expr.MethodCall)4 IOException (java.io.IOException)2 Method (java.lang.reflect.Method)2 Set (java.util.Set)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 DataOutputStream (java.io.DataOutputStream)1 Field (java.lang.reflect.Field)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 Command (org.hotswap.agent.command.Command)1 PluginManager (org.hotswap.agent.config.PluginManager)1 FieldAccess (org.hotswap.agent.javassist.expr.FieldAccess)1