private void logPluginDetails(final PluginWrapper plugin) { assert plugin != null; log.debug("Loaded plugin: {} ({})", plugin.getShortName(), plugin.getVersion()); // Some details are not valid until the createPluginWrapper() has returned... like bundled // status log.debug( " State: active={}, enabled={}, pinned={}, downgradable={}", new Object[] { plugin.isActive(), plugin.isEnabled(), plugin.isPinned(), plugin.isDowngradable() }); // Spit out some debug/trace details about the classpath PluginClassLoader cl = (PluginClassLoader) plugin.classLoader; URL[] classpath = cl.getURLs(); if (classpath.length > 1) { log.debug(" Classpath:"); int i = 0; boolean trace = log.isTraceEnabled(); for (URL url : classpath) { // skip the classes/ dir its always there if (i++ == 0) { continue; } // for trace still log as debug, but flip on the full URL log.debug(" {}", trace ? url.toString() : basename(url.getFile())); } } // Spit out some debug information about the plugin dependencies List<Dependency> dependencies = plugin.getDependencies(); if (dependencies != null && !dependencies.isEmpty()) { log.debug(" Dependencies:"); for (Dependency dependency : dependencies) { log.debug(" {}", dependency); } } dependencies = plugin.getOptionalDependencies(); if (dependencies != null && !dependencies.isEmpty()) { log.debug(" Optional dependencies:"); for (Dependency dependency : plugin.getOptionalDependencies()) { log.debug(" {}", dependency); } } }
public Class<?> getClassByName(final String name) { Class<?> cachedClass = classes.get(name); if (cachedClass != null) { return cachedClass; } else { for (String current : loaders.keySet()) { PluginClassLoader loader = loaders.get(current); try { cachedClass = loader.findClass(name, false); } catch (ClassNotFoundException cnfe) { } if (cachedClass != null) { return cachedClass; } } } return null; }
/** * Returns the classpath to use for the JSPC Compiler. * * @param plugin the plugin the jspc will handle. * @return the classpath needed to compile a single jsp in a plugin. */ private static String getClasspathForPlugin(Plugin plugin) { final StringBuilder classpath = new StringBuilder(); File pluginDirectory = pluginManager.getPluginDirectory(plugin); PluginDevEnvironment pluginEnv = pluginManager.getDevEnvironment(plugin); PluginClassLoader pluginClassloader = pluginManager.getPluginClassloader(plugin); for (URL url : pluginClassloader.getURLs()) { File file = new File(url.getFile()); classpath.append(file.getAbsolutePath()).append(";"); } // Load all jars from lib File libDirectory = new File(pluginDirectory, "lib"); File[] libs = libDirectory.listFiles(); final int no = libs != null ? libs.length : 0; for (int i = 0; i < no; i++) { File libFile = libs[i]; classpath.append(libFile.getAbsolutePath()).append(';'); } File openfireRoot = pluginDirectory.getParentFile().getParentFile().getParentFile(); File openfireLib = new File(openfireRoot, "target//lib"); classpath.append(openfireLib.getAbsolutePath()).append("//servlet.jar;"); classpath.append(openfireLib.getAbsolutePath()).append("//openfire.jar;"); classpath.append(openfireLib.getAbsolutePath()).append("//jasper-compiler.jar;"); classpath.append(openfireLib.getAbsolutePath()).append("//jasper-runtime.jar;"); if (pluginEnv.getClassesDir() != null) { classpath.append(pluginEnv.getClassesDir().getAbsolutePath()).append(";"); } return classpath.toString(); }
public void disablePlugin(Plugin plugin) { if (!(plugin instanceof JavaPlugin)) { throw new IllegalArgumentException("Plugin is not associated with this PluginLoader"); } if (plugin.isEnabled()) { JavaPlugin jPlugin = (JavaPlugin) plugin; ClassLoader cloader = jPlugin.getClassLoader(); try { jPlugin.setEnabled(false); } catch (Throwable ex) { server .getLogger() .log( Level.SEVERE, "Error occurred while disabling " + plugin.getDescription().getFullName() + " (Is it up to date?): " + ex.getMessage(), ex); } server.getPluginManager().callEvent(new PluginDisableEvent(plugin)); loaders.remove(jPlugin.getDescription().getName()); if (cloader instanceof PluginClassLoader) { PluginClassLoader loader = (PluginClassLoader) cloader; Set<String> names = loader.getClasses(); for (String name : names) { removeClass(name); } } } }
protected List<PluginInfo<T>> scan( LogSource logger, String hosterpath, final List<? extends LazyPlugin<T>> pluginCache, final AtomicLong lastFolderModification) throws Exception { DirectoryStream<Path> stream = null; final ArrayList<PluginInfo<T>> ret = new ArrayList<PluginInfo<T>>(); final long timeStamp = System.currentTimeMillis(); try { long lastModified = lastFolderModification != null ? lastFolderModification.get() : -1; final Path folder = Application.getRootByClass(jd.SecondLevelLaunch.class, hosterpath).toPath(); final long lastFolderModified = Files.readAttributes(folder, BasicFileAttributes.class).lastModifiedTime().toMillis(); if (lastModified > 0 && lastFolderModified == lastModified && pluginCache != null && pluginCache.size() > 0) { for (final LazyPlugin<T> lazyPlugin : pluginCache) { final PluginInfo<T> pluginInfo = new PluginInfo<T>(lazyPlugin.getLazyPluginClass(), null); pluginInfo.setLazyPlugin(lazyPlugin); ret.add(pluginInfo); } return ret; } PluginClassLoaderChild cl = null; MessageDigest md = null; final String pkg = hosterpath.replace("/", "."); final byte[] mdCache = new byte[32767]; final HashMap<String, List<LazyPlugin<T>>> lazyPluginClassMap; if (pluginCache != null && pluginCache.size() > 0) { lazyPluginClassMap = new HashMap<String, List<LazyPlugin<T>>>(); for (final LazyPlugin<T> lazyPlugin : pluginCache) { List<LazyPlugin<T>> list = lazyPluginClassMap.get(lazyPlugin.getLazyPluginClass().getClassName()); if (list == null) { list = new ArrayList<LazyPlugin<T>>(); lazyPluginClassMap.put(lazyPlugin.getLazyPluginClass().getClassName(), list); } list.add(lazyPlugin); } } else { lazyPluginClassMap = null; } if (lastFolderModification != null) { lastFolderModification.set(lastFolderModified); } stream = Files.newDirectoryStream(folder, "*.class"); for (final Path path : stream) { try { final String pathFileName = path.getFileName().toString(); final String className = pathFileName.substring(0, pathFileName.length() - 6); if (className.indexOf("$") < 0 && !PluginController.IGNORELIST.contains(className)) { byte[] sha256 = null; final BasicFileAttributes pathAttr = Files.readAttributes(path, BasicFileAttributes.class); if (lazyPluginClassMap != null) { final List<LazyPlugin<T>> lazyPlugins = lazyPluginClassMap.get(className); if (lazyPlugins != null && lazyPlugins.size() > 0) { final LazyPluginClass lazyPluginClass = lazyPlugins.get(0).getLazyPluginClass(); if (lazyPluginClass != null && (lazyPluginClass.getLastModified() == pathAttr.lastModifiedTime().toMillis() || ((md = MessageDigest.getInstance("SHA-256")) != null && (sha256 = PluginController.getFileHashBytes(path.toFile(), md, mdCache)) != null && Arrays.equals(sha256, lazyPluginClass.getSha256())))) { for (final LazyPlugin<T> lazyPlugin : lazyPlugins) { // logger.finer("Cached: " + className + "|" + lazyPlugin.getDisplayName() + "|" // + // lazyPluginClass.getRevision()); final PluginInfo<T> pluginInfo = new PluginInfo<T>(lazyPluginClass, null); pluginInfo.setLazyPlugin(lazyPlugin); ret.add(pluginInfo); } continue; } } } Class<T> pluginClass = null; long[] infos = null; try { if (cl == null) { cl = PluginClassLoader.getInstance().getChild(); } if (md == null) { md = MessageDigest.getInstance("SHA-256"); } pluginClass = (Class<T>) cl.loadClass(pkg + "." + className); if (!Modifier.isAbstract(pluginClass.getModifiers()) && Plugin.class.isAssignableFrom(pluginClass)) { infos = getPluginController().getInfos(pluginClass); if (infos == null) { continue; } } else { continue; } } catch (final Throwable e) { logger.finer("Failed: " + className); logger.log(e); continue; } if (sha256 == null) { sha256 = PluginController.getFileHashBytes(path.toFile(), md, mdCache); } // final LazyPluginClass lazyPluginClass = new LazyPluginClass( className, sha256, pathAttr.lastModifiedTime().toMillis(), (int) infos[0], infos[1]); final PluginInfo<T> pluginInfo = new PluginInfo<T>(lazyPluginClass, pluginClass); // logger.finer("Scaned: " + className + "|" + lazyPluginClass.getRevision()); ret.add(pluginInfo); } } catch (Throwable e) { logger.finer("Failed: " + path); logger.log(e); } } return ret; } finally { logger.info( "@PluginController(NIO): scan took " + (System.currentTimeMillis() - timeStamp) + "ms for " + ret.size()); if (stream != null) { stream.close(); } } }