package org.hotswap.agent.plugin.glassfish; import org.hotswap.agent.annotation.OnClassLoadEvent; import org.hotswap.agent.annotation.Plugin; 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; /** * GlassFish Plugin * - set boot delegation for hotswapagent's classes in felix class loader * * @author Vladimir Dvorak */ @Plugin(name = "GlassFish", description = "GlassFish - glassfish server.", testedVersions = {""}, expectedVersions = {""}, supportClass={WebappClassLoaderTransformer.class} ) public class GlassFishPlugin { protected static AgentLogger LOGGER = AgentLogger.getLogger(GlassFishPlugin.class); private static String FRAMEWORK_BOOTDELEGATION = "org.osgi.framework.bootdelegation"; private static final String BOOTDELEGATION_PACKAGES = "org.hotswap.agent, " + "org.hotswap.agent.*"; @OnClassLoadEvent(classNameRegexp = "org.apache.felix.framework.Felix") public static void transformFelix(ClassPool classPool, CtClass ctClass) throws NotFoundException, CannotCompileException { CtClass[] constructorParams = new CtClass[] { classPool.get("java.util.Map") }; CtConstructor declaredConstructor = ctClass.getDeclaredConstructor(constructorParams); declaredConstructor.insertBefore( "{" + "if ($1 == null) { " + "$1 = new java.util.HashMap();" + "}" + "String __bootDeleg = (String) $1.get(\"" + FRAMEWORK_BOOTDELEGATION + "\");" + "if (__bootDeleg == null) {" + "__bootDeleg = \"\";" + "}" + "if (__bootDeleg.indexOf(\"org.hotswap.agent\") == -1) {" + "__bootDeleg = __bootDeleg.trim();" + "if (!__bootDeleg.isEmpty()) {" + "__bootDeleg = __bootDeleg + \", \";" + "}" + "__bootDeleg = __bootDeleg + \"" + BOOTDELEGATION_PACKAGES + "\";" + "$1.put(\"" + FRAMEWORK_BOOTDELEGATION + "\", __bootDeleg);" + "}" + "}" ); // declaredConstructor.insertAfter(PluginManagerInvoker.buildInitializePlugin(GlassFishPlugin.class)); LOGGER.debug("Class 'org.apache.felix.framework.Felix' patched in classLoader {}."); } @OnClassLoadEvent(classNameRegexp = "org.apache.felix.framework.BundleWiringImpl") public static void transformBundleClassLoader(ClassPool classPool, CtClass ctClass) throws NotFoundException, CannotCompileException { // String initializePlugin = PluginManagerInvoker.buildInitializePlugin(GlassFishPlugin.class); // // for (CtConstructor constructor : ctClass.getDeclaredConstructors()) { // constructor.insertAfter(initializePlugin); // } // /* CtMethod getClassLoaderInternalCopy = CtMethod.make("public ClassLoader __getClassLoaderInternal(){return null;}", ctClass); getClassLoaderInternalCopy.setBody(ctClass.getDeclaredMethod("getClassLoaderInternal"), null); ctClass.addMethod(getClassLoaderInternalCopy); CtMethod getClassLoaderInternal = ctClass.getDeclaredMethod("getClassLoaderInternal"); getClassLoaderInternal.setBody( "{ " + "boolean wasClassLoader = (m_classLoader == null); " + "ClassLoader ret = __getClassLoaderInternal();" + "if (!wasClassLoader && ret != null) {" + PluginManagerInvoker.buildInitializePlugin(GlassFishPlugin.class, "ret") + "}" + "return ret;" + "}" ); LOGGER.debug("org.apache.felix.framework.BundleWiringImpl resource bundles registration."); */ } }