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;
  }
Example #3
0
  /**
   * 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);
        }
      }
    }
  }
Example #5
0
  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();
      }
    }
  }