private static Class<?> reloadProxyByteCode(ClassLoader classLoader, String proxyName, byte[] proxyBytes) { try { final Class<?> originalProxyClass = classLoader.loadClass(proxyName); try { Map<Class<?>, byte[]> reloadMap = new HashMap<Class<?>, byte[]>(); reloadMap.put(originalProxyClass, proxyBytes); // TODO : is this standard way how to reload class? PluginManager.getInstance().hotswap(reloadMap); return originalProxyClass; } catch (Exception e) { throw new RuntimeException(e); } } catch (ClassNotFoundException e) { //it has not actually been loaded yet } return null; } }
public static void close(ClassLoader classLoader) { Map<String, ClassLoader> registerMap = extraRepositories.remove(classLoader); if (registerMap != null) { for (ClassLoader loader : registerMap.values()) { PluginManager.getInstance().getWatcher().closeClassLoader(loader); } } }
public TomcatSetup(ClassLoader originalClassLoader) { System.err.println("PluginManagerInstance = " + PluginManager.getInstance()); PluginManagerInvoker.callInitializePlugin(TomcatPlugin.class, originalClassLoader); //PluginManagerInvoker.callPluginMethod(TomcatPlugin.class, originalClassLoader, "init" URL[] extraClassPath = (URL[]) PluginManagerInvoker.callPluginMethod(TomcatPlugin.class, originalClassLoader, "getExtraClassPath", new Class[] {}, new Object[] {}); System.err.println("extraClassPath = " + Arrays.toString(extraClassPath)); LOGGER.debug("extraClassPath = {}", extraClassPath); if (extraClassPath.length > 0) { LOGGER.debug("Registering extraClasspath {} to classloader {}", extraClassPath, originalClassLoader); for (URL url : extraClassPath) { // classLoader.addRepository(classesPath + "/", classRepository); try { File classRepository = new File(url.toURI()); Method m = originalClassLoader.getClass().getDeclaredMethod("addRepository", String.class, File.class); m.setAccessible(true); m.invoke(originalClassLoader, classRepository.getAbsolutePath() + "/", classRepository); } catch (Exception e) { throw new Error(e); } } } }
public void executeSingleCommand() { try { Class<?> clazz = classLoader.loadClass(className); Map<String, String> signatureMap = ProxyClassSignatureHelper.getNonSyntheticSignatureMap(clazz); if (!signatureMap.equals(signatureMapOrig)) { byte[] generateProxyClass = ProxyGenerator.generateProxyClass(className, clazz.getInterfaces()); Map<Class<?>, byte[]> reloadMap = new HashMap<Class<?>, byte[]>(); reloadMap.put(clazz, generateProxyClass); PluginManager.getInstance().hotswap(reloadMap); LOGGER.reload("Class '{}' has been reloaded.", className); } } catch (ClassNotFoundException e) { LOGGER.error("Error redefining java proxy {}", e, className); } }
Map<Class<?>, byte[]> reloadMap = new HashMap<Class<?>, byte[]>(); reloadMap.put(originalProxyClass, bytes); PluginManager.getInstance().hotswap(reloadMap); return originalProxyClass; } catch (Exception e) {
public static Class<?> toClass(ClassFile ct, ClassLoader loader, ProtectionDomain domain) { if (MAGIC_IN_PROGRESS.get()) { try { final Class<?> originalProxyClass = loader.loadClass(ct.getName()); try { ByteArrayDataOutputStream out = new ByteArrayDataOutputStream(); ct.write(out); Map<Class<?>, byte[]> reloadMap = new HashMap<Class<?>, byte[]>(); reloadMap.put(originalProxyClass, out.getBytes()); // TODO : is this standard way how to reload class? PluginManager.getInstance().hotswap(reloadMap); return originalProxyClass; } catch (Exception e) { throw new RuntimeException(e); } } catch (ClassNotFoundException e) { //it has not actually been loaded yet return ClassFileUtils.toClass(ct, loader, domain); } } return ClassFileUtils.toClass(ct, loader, domain); }
watchResourcesClassLoader.initWatchResources(new URL[]{newRepositories[i]}, PluginManager.getInstance().getWatcher()); } else { watchResourcesClassLoader.initExtraPath(new URL[]{newRepositories[i]});
@OnClassLoadEvent(classNameRegexp = "com.sun.proxy.\\$Proxy.*", events = LoadEvent.REDEFINE, skipSynthetic = false) public static void transformJavaProxy(final Class<?> classBeingRedefined, final ClassLoader classLoader) { /* * Proxy can't be redefined directly in this method (and return new proxy class bytes), since the classLoader contains * OLD definition of proxie's interface. Therefore proxy is defined in deferred command (after some delay) * after proxied interface is redefined in DCEVM. */ Object proxyCache = ReflectionHelper.getNoException(null, java.lang.reflect.Proxy.class, "proxyCache"); if (proxyCache != null) { try { ReflectionHelper.invoke(proxyCache, proxyCache.getClass().getSuperclass(), "removeAll", new Class[] { ClassLoader.class }, classLoader); } catch (IllegalArgumentException e) { LOGGER.error("Reflection proxy cache flush failed. {}", e.getMessage()); } } if (!ClassLoaderHelper.isClassLoderStarted(classLoader)) { return; } final String className = classBeingRedefined.getName(); if (proxyRedefiningMap.contains(className)) { proxyRedefiningMap.remove(className); return; } proxyRedefiningMap.add(className); final Map<String, String> signatureMapOrig = ProxyClassSignatureHelper.getNonSyntheticSignatureMap(classBeingRedefined); reloadFlag = true; // TODO: can be single command if scheduler guarantees the keeping execution order in the order of redefinition PluginManager.getInstance().getScheduler().scheduleCommand(new ReloadJavaProxyCommand(classLoader, className, signatureMapOrig), 50); }
public WatcherTomcatWebappClassLoader(ClassLoader originalClassLoader) { super(originalClassLoader); PluginManagerInvoker.callInitializePlugin(TomcatPlugin.class, originalClassLoader); //PluginManagerInvoker.callPluginMethod(TomcatPlugin.class, originalClassLoader, "init" URL[] extraClassPath = (URL[]) PluginManagerInvoker.callPluginMethod(TomcatPlugin.class, originalClassLoader, "getExtraClassPath", new Class[] {}, new Object[] {}); LOGGER.debug("extraClassPath = {}", extraClassPath); if (extraClassPath.length > 0) { LOGGER.debug("Registering extraClasspath {} to classloader {}", extraClassPath, originalClassLoader); initExtraPath(extraClassPath); } URL[] watchResources = (URL[]) PluginManagerInvoker.callPluginMethod(TomcatPlugin.class, originalClassLoader, "getWatchResources", new Class[] {}, new Object[] {}); System.err.println("watchResources = " + Arrays.toString(watchResources)); LOGGER.debug("watchResources = {}", watchResources); if (watchResources.length > 0) { LOGGER.debug("Registering watchResources {} to classloader {}", extraClassPath, originalClassLoader); initWatchResources(watchResources, PluginManager.getInstance().getWatcher()); } } }
if (watchResources.length > 0) { if (majorVersion >= 7) watchResourcesClassLoader.initWatchResources(watchResources, PluginManager.getInstance().getWatcher()); else addRepositoriesAtStart(appClassLoader, watchResources, true);
protected void bindHotSwapClassesRedefinitionWatcher() { try { ClassLoader classLoader = getClassloaderToUseToBindHotSwapClassesRedefinitionWatcher(); PluginRegistry pluginRegistry = PluginManager.getInstance().getPluginRegistry(); pluginRegistry.scanPlugins(classLoader, HotSwapClassesRedefinitionsWatcherDefault.class.getPackage().getName()); pluginRegistry.initializePlugin(HotSwapClassesRedefinitionsWatcherDefault.class.getName(), classLoader); HotSwapClassesRedefinitionsWatcherDefault plugin = pluginRegistry.getPlugin(HotSwapClassesRedefinitionsWatcherDefault.class, classLoader); bind(HotSwapClassesRedefinitionsWatcherDefault.class).toInstance(plugin); } catch (Exception ex) { throw SpincastStatics.runtimize(ex); } }