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.");
}
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);
}
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);
}
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;
}
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();
}
Aggregations