package org.hotswap.agent.plugin.weld; 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.CtConstructor; import org.hotswap.agent.javassist.NotFoundException; import org.hotswap.agent.logging.AgentLogger; import org.hotswap.agent.util.PluginManagerInvoker; /** * Hook into WeldBeanDeploymentArchive or BeanDeploymentArchiveImpl(WildFly) constructors to initialize WeldPlugin * * @author Vladimir Dvorak */ public class BeanDeploymentArchiveTransformer { private static AgentLogger LOGGER = AgentLogger.getLogger(BeanDeploymentArchiveTransformer.class); /** * Basic WeldBeanDeploymentArchive transformation. * * @param clazz * @param classPool * @throws NotFoundException * @throws CannotCompileException */ @OnClassLoadEvent(classNameRegexp = "org.jboss.weld.environment.deployment.WeldBeanDeploymentArchive") public static void transform(CtClass clazz, ClassPool classPool) throws NotFoundException, CannotCompileException { CtClass[] constructorParams = new CtClass[] { classPool.get("java.lang.String"), classPool.get("java.util.Collection"), classPool.get("org.jboss.weld.bootstrap.spi.BeansXml"), classPool.get("java.util.Set") }; StringBuilder src = new StringBuilder("{"); src.append(PluginManagerInvoker.buildInitializePlugin(WeldPlugin.class)); src.append(PluginManagerInvoker.buildCallPluginMethod(WeldPlugin.class, "init")); src.append("org.hotswap.agent.plugin.weld.command.BeanDeploymentArchiveAgent.registerArchive(getClass().getClassLoader(), this, null);"); src.append("}"); CtConstructor declaredConstructor = clazz.getDeclaredConstructor(constructorParams); declaredConstructor.insertAfter(src.toString()); LOGGER.debug("Class '{}' patched with BDA registration.", clazz.getName()); } /** * JbossAS (Wildfly) BeanDeploymentArchiveImpl transformation. * * @param clazz * @param classPool * @throws NotFoundException * @throws CannotCompileException */ @OnClassLoadEvent(classNameRegexp = "org.jboss.as.weld.deployment.BeanDeploymentArchiveImpl") public static void transformJbossBda(CtClass clazz, ClassPool classPool) throws NotFoundException, CannotCompileException { StringBuilder src = new StringBuilder("{"); src.append("if (beansXml!=null && beanArchiveType!=null && (\"EXPLICIT\".equals(beanArchiveType.toString()) || \"IMPLICIT\".equals(beanArchiveType.toString()))){"); src.append(PluginManagerInvoker.buildInitializePlugin(WeldPlugin.class, "module.getClassLoader()")); src.append(PluginManagerInvoker.buildCallPluginMethod("module.getClassLoader()", WeldPlugin.class, "initInJBossAS")); src.append(" Class agC = Class.forName(\"org.hotswap.agent.plugin.weld.command.BeanDeploymentArchiveAgent\", true, module.getClassLoader());"); src.append(" java.lang.reflect.Method agM = agC.getDeclaredMethod(\"registerArchive\", new Class[] {java.lang.ClassLoader.class, org.jboss.weld.bootstrap.spi.BeanDeploymentArchive.class, java.lang.String.class});"); src.append(" agM.invoke(null, new Object[] { module.getClassLoader(),this, beanArchiveType.toString()});"); src.append("}}"); for (CtConstructor constructor : clazz.getDeclaredConstructors()) { constructor.insertAfter(src.toString()); } LOGGER.debug("Class 'org.jboss.as.weld.deployment.BeanDeploymentArchiveImpl' patched with BDA registration."); } /** * GlassFish BeanDeploymentArchiveImpl transformation. * * @param clazz * @param classPool * @throws NotFoundException * @throws CannotCompileException */ @OnClassLoadEvent(classNameRegexp = "org.glassfish.weld.BeanDeploymentArchiveImpl") public static void transformGlassFishBda(CtClass clazz, ClassPool classPool) throws NotFoundException, CannotCompileException { StringBuilder src = new StringBuilder("{"); src.append(PluginManagerInvoker.buildInitializePlugin(WeldPlugin.class, "this.moduleClassLoaderForBDA")); src.append(PluginManagerInvoker.buildCallPluginMethod("this.moduleClassLoaderForBDA", WeldPlugin.class, "initInGlassFish")); src.append(" Class agC = Class.forName(\"org.hotswap.agent.plugin.weld.command.BeanDeploymentArchiveAgent\", true, this.moduleClassLoaderForBDA);"); src.append(" java.lang.reflect.Method agM = agC.getDeclaredMethod(\"registerArchive\", new Class[] {java.lang.ClassLoader.class, org.jboss.weld.bootstrap.spi.BeanDeploymentArchive.class, java.lang.String.class});"); src.append(" agM.invoke(null, new Object[] { this.moduleClassLoaderForBDA, this, null});"); src.append("}"); for (CtConstructor constructor : clazz.getDeclaredConstructors()) { constructor.insertAfter(src.toString()); } LOGGER.debug("Class 'org.jboss.as.weld.deployment.BeanDeploymentArchiveImpl' patched with BDA registration."); } }