package org.hotswap.agent.plugin.owb;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.hotswap.agent.annotation.OnClassLoadEvent;
import org.hotswap.agent.javassist.CannotCompileException;
import org.hotswap.agent.javassist.ClassPool;
import org.hotswap.agent.javassist.CtClass;
import org.hotswap.agent.javassist.CtMethod;
import org.hotswap.agent.javassist.NotFoundException;
import org.hotswap.agent.javassist.expr.ExprEditor;
import org.hotswap.agent.javassist.expr.MethodCall;
/**
* Hook into AbstractProxyFactory constructors to register proxy factory into OwbPlugin. If OwbPlugin is not initialized in proxy factory
* classLoader (ModuleClassLoader) then the proxy factory is not registered - it happens most likely in case of system beans proxy factories.
*
* @author Vladimir Dvorak
*/
public class ProxyFactoryTransformer {
/**
* Patch AbstractProxyFactory class.
* - add factory registration into constructor
* - changes call classLoader.loadClass(...) in getProxyClass() to ProxyClassLoadingDelegate.loadClass(classLoader, ...)
* - changes call ClassFileUtils.toClass() in createProxyClass() to ProxyClassLoadingDelegate.loadClass(...)
*
* @param ctClass the ProxyFactory class
* @param classPool the class pool
* @throws NotFoundException the not found exception
* @throws CannotCompileException the cannot compile exception
*/
@OnClassLoadEvent(classNameRegexp = "org.apache.webbeans.proxy.AbstractProxyFactory")
public static void patchProxyFactory(CtClass ctClass, ClassPool classPool) throws NotFoundException, CannotCompileException {
CtMethod getProxyClassMethod = ctClass.getDeclaredMethod("getUnusedProxyClassName");
getProxyClassMethod.instrument(
new ExprEditor() {
public void edit(MethodCall m) throws CannotCompileException {
if (m.getClassName().equals(Class.class.getName()) && m.getMethodName().equals("forName"))
m.replace("{ $_ = org.hotswap.agent.plugin.owb.command.ProxyClassLoadingDelegate.forName($$); }");
}
});
CtMethod createProxyClassMethod = ctClass.getDeclaredMethod("createProxyClass", new CtClass[] {
classPool.get(ClassLoader.class.getName()),
classPool.get(String.class.getName()),
classPool.get(Class.class.getName()),
classPool.get(Method.class.getName() + "[]"),
classPool.get(Method.class.getName() + "[]"),
classPool.get(Constructor.class.getName())
}
);
createProxyClassMethod.instrument(
new ExprEditor() {
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("defineAndLoadClass"))
m.replace("{ $_ = org.hotswap.agent.plugin.owb.command.ProxyClassLoadingDelegate.defineAndLoadClass(this, $$); }");
}
});
}
}