use of org.hotswap.agent.javassist.CtClass in project HotswapAgent by HotswapProjects.
the class EnhancerProxyCreater method buildNamingPolicyClass.
/**
* Creates a NamingPolicy for usage in buildProxyCreaterClass. Eventually a instance of this class will be used as
* an argument for an Enhancer instances setNamingPolicy method. Classname prefix for proxies will be HOTSWAPAGENT_
*
* @param cglibPackage
* Cglib Package name
* @param cp
* @return DefaultNamingPolicy sublass
* @throws CannotCompileException
* @throws NotFoundException
*/
private Class<?> buildNamingPolicyClass(String cglibPackage, ClassPool cp) throws CannotCompileException, NotFoundException {
CtClass ct = cp.makeClass("HotswapAgentSpringNamingPolicy" + getClassSuffix(cglibPackage));
String core = cglibPackage + "core.";
String originalNamingPolicy = core + "SpringNamingPolicy";
if (cp.find(originalNamingPolicy) == null)
originalNamingPolicy = core + "DefaultNamingPolicy";
ct.setSuperclass(cp.get(originalNamingPolicy));
String rawBody = //
" public String getClassName(String prefix, String source, Object key, {0}Predicate names) {" + //
" return super.getClassName(prefix + \"$HOTSWAPAGENT_\", source, key, names);" + " }";
String body = rawBody.replaceAll("\\{0\\}", core);
CtMethod m = CtNewMethod.make(body, ct);
ct.addMethod(m);
return ct.toClass(loader, pd);
}
use of org.hotswap.agent.javassist.CtClass in project HotswapAgent by HotswapProjects.
the class CdiContextsTransformer method transformOwbContexts.
@OnClassLoadEvent(classNameRegexp = "(org.apache.webbeans.context.AbstractContext)|" + "(org.apache.myfaces.flow.cdi.FlowScopedContextImpl)|" + "(org.apache.myfaces.cdi.view.ViewScopeContextImpl)")
public static void transformOwbContexts(CtClass clazz, ClassPool classPool, ClassLoader cl) throws NotFoundException, CannotCompileException {
CtClass superClass = clazz.getSuperclass();
while (superClass != null) {
if ("org.apache.webbeans.context.AbstractContext".equals(superClass.getName())) {
return;
}
superClass = superClass.getSuperclass();
}
LOGGER.debug("Adding interface {} to {}.", OwbHotswapContext.class.getName(), clazz.getName());
clazz.addInterface(classPool.get(OwbHotswapContext.class.getName()));
CtField toReloadFld = CtField.make("public transient java.util.Set $$ha$toReloadOwb = null;", clazz);
clazz.addField(toReloadFld);
CtField reloadingFld = CtField.make("public transient boolean $$ha$reloadingOwb = false;", clazz);
clazz.addField(reloadingFld);
CtMethod addBeanToReload = CtMethod.make("public void $$ha$addBeanToReloadOwb(javax.enterprise.context.spi.Contextual bean){" + "if ($$ha$toReloadOwb == null)" + "$$ha$toReloadOwb = new java.util.HashSet();" + "$$ha$toReloadOwb.add(bean);" + "}", clazz);
clazz.addMethod(addBeanToReload);
CtMethod getBeansToReload = CtMethod.make("public java.util.Set $$ha$getBeansToReloadOwb(){return $$ha$toReloadOwb;}", clazz);
clazz.addMethod(getBeansToReload);
CtMethod reload = CtMethod.make("public void $$ha$reloadOwb() {" + ContextualReloadHelper.class.getName() + ".reload(this);}", clazz);
clazz.addMethod(reload);
CtMethod isActive = clazz.getDeclaredMethod("isActive");
isActive.insertAfter("if($_ && !$$ha$reloadingOwb ) { " + "$$ha$reloadingOwb = true;" + "$$ha$reloadOwb();" + "$$ha$reloadingOwb = false;" + "}" + "return $_;");
// addDestroyMethod(clazz, classPool);
LOGGER.debug("Class '{}' patched with hot-swapping support", clazz.getName());
}
use of org.hotswap.agent.javassist.CtClass in project HotswapAgent by HotswapProjects.
the class ProxyFactoryTransformer method patchProxyFactory.
/**
* 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, $$); }");
}
});
}
use of org.hotswap.agent.javassist.CtClass in project HotswapAgent by HotswapProjects.
the class AbstractProxyBytecodeTransformer method transform.
public byte[] transform(byte[] byteCode) throws Exception {
CtClass cc = classPool.makeClass(new ByteArrayInputStream(byteCode), false);
try {
String initFieldName = INIT_FIELD_PREFIX + generateRandomString();
addStaticInitStateField(cc, initFieldName);
String initCode = getInitCall(cc, initFieldName);
addInitCallToMethods(cc, initFieldName, initCode);
return cc.toBytecode();
} finally {
cc.detach();
}
}
use of org.hotswap.agent.javassist.CtClass in project HotswapAgent by HotswapProjects.
the class CtClassJavaProxyGenerator method addProxyMethod.
/**
* Add another method to be proxied, either by creating a new ProxyMethod object or augmenting an old one for a
* duplicate method.
*
* "fromClass" indicates the proxy interface that the method was found through, which may be different from (a
* subinterface of) the method's "declaring class". Note that the first Method object passed for a given name and
* descriptor identifies the Method object (and thus the declaring class) that will be passed to the invocation
* handler's "invoke" method for a given set of duplicate methods.
*/
private void addProxyMethod(CtMethod m, CtClass fromClass) {
String name = m.getName();
CtClass[] parameterTypes;
CtClass returnType;
CtClass[] exceptionTypes;
try {
parameterTypes = m.getParameterTypes();
returnType = m.getReturnType();
exceptionTypes = m.getExceptionTypes();
} catch (NotFoundException e) {
throw new RuntimeException(e);
}
String sig = name + getParameterDescriptors(parameterTypes);
List<ProxyMethod> sigmethods = proxyMethods.get(sig);
if (sigmethods != null) {
for (ProxyMethod pm : sigmethods) {
if (returnType == pm.returnType || returnType.getName().equals(pm.returnType.getName())) {
/*
* Found a match: reduce exception types to the greatest set of exceptions that can thrown
* compatibly with the throws clauses of both overridden methods.
*/
List<CtClass> legalExceptions = new ArrayList<>();
collectCompatibleTypes(exceptionTypes, pm.exceptionTypes, legalExceptions);
collectCompatibleTypes(pm.exceptionTypes, exceptionTypes, legalExceptions);
pm.exceptionTypes = new CtClass[legalExceptions.size()];
pm.exceptionTypes = legalExceptions.toArray(pm.exceptionTypes);
return;
}
}
} else {
sigmethods = new ArrayList<>(3);
proxyMethods.put(sig, sigmethods);
}
sigmethods.add(new ProxyMethod(name, parameterTypes, returnType, exceptionTypes, fromClass));
}
Aggregations