package org.hotswap.agent.plugin.deltaspike.proxy; import java.security.ProtectionDomain; import java.util.HashMap; import java.util.Map; import org.apache.deltaspike.proxy.impl.AsmProxyClassGenerator; import org.hotswap.agent.config.PluginManager; import org.hotswap.agent.logging.AgentLogger; import org.hotswap.agent.util.ReflectionHelper; /** * Delegates proxy loading to AsmProxyClassGenerator or PluginManager.getInstance().hotswap * @author Vladimir Dvorak */ public class ProxyClassLoadingDelegate { private static AgentLogger LOGGER = AgentLogger.getLogger(ProxyClassLoadingDelegate.class); private static final ThreadLocal<Boolean> MAGIC_IN_PROGRESS = new ThreadLocal<Boolean>() { @Override protected Boolean initialValue() { return false; } }; public static final void beginProxyRegeneration() { MAGIC_IN_PROGRESS.set(true); } public static final void endProxyRegeneration() { MAGIC_IN_PROGRESS.remove(); } // Deltaspike 1.7 public static Class<?> tryToLoadClassForName(String proxyClassName, Class<?> targetClass, ClassLoader classLoader) { if (MAGIC_IN_PROGRESS.get()) { return null; } return (Class<?>) ReflectionHelper.invoke(null, org.apache.deltaspike.core.util.ClassUtils.class, "tryToLoadClassForName", new Class[] { String.class, Class.class, ClassLoader.class }, proxyClassName, targetClass, classLoader); } // Deltaspike 1.5 public static Class<?> tryToLoadClassForName(String proxyClassName, Class<?> targetClass) { if (MAGIC_IN_PROGRESS.get()) { return null; } return org.apache.deltaspike.core.util.ClassUtils.tryToLoadClassForName(proxyClassName, targetClass); } public static Class<?> loadClass(ClassLoader loader, String className, byte[] bytes, ProtectionDomain protectionDomain) { if (MAGIC_IN_PROGRESS.get()) { try { final Class<?> originalProxyClass = loader.loadClass(className); try { Map<Class<?>, byte[]> reloadMap = new HashMap<Class<?>, byte[]>(); reloadMap.put(originalProxyClass, bytes); PluginManager.getInstance().hotswap(reloadMap); return originalProxyClass; } catch (Exception e) { throw new RuntimeException(e); } } catch (ClassNotFoundException e) { //it has not actually been loaded yet } } try { return (Class<?>) ReflectionHelper.invoke(null, AsmProxyClassGenerator.class, "loadClass", new Class[]{ClassLoader.class, String.class, byte[].class, ProtectionDomain.class}, loader, className, bytes, protectionDomain); } catch (Exception e) { LOGGER.error("loadClass() exception {}", e.getMessage()); } return null; } }