📄 pluginclassloader.java
字号:
/**
* $RCSfile$
* $Revision: 2993 $
* $Date: 2005-10-24 18:11:33 -0300 (Mon, 24 Oct 2005) $
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.container;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.XMPPServer;
import java.io.File;
import java.io.FilenameFilter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
* ClassLoader for plugins. It searches the plugin directory for classes
* and JAR files, then constructs a class loader for the resources found.
* Resources are loaded as follows:<ul>
* <p/>
* <li>Any JAR files in the <tt>lib</tt> will be added to the classpath.
* <li>Any files in the classes directory will be added to the classpath.
* </ul>
*
* @author Derek DeMoro
*/
public class PluginClassLoader {
private URLClassLoader classLoader;
private final List<URL> list = new ArrayList<URL>();
/**
* Constructs a plugin loader for the given plugin directory.
*
* @throws SecurityException if the created class loader violates
* existing security constraints.
*/
public PluginClassLoader() throws SecurityException {
}
/**
* Adds a directory to the class loader. The {@link #initialize()} method should be called
* after adding the directory to make the change take effect.
*
* @param directory the directory.
* @param developmentMode true if the plugin is running in development mode. This
* resolves classloader conflicts between the deployed plugin
* and development classes.
*/
public void addDirectory(File directory, boolean developmentMode) {
try {
// Add classes directory to classpath.
File classesDir = new File(directory, "classes");
if (classesDir.exists()) {
list.add(classesDir.toURL());
}
// Add i18n directory to classpath.
File databaseDir = new File(directory, "database");
if(databaseDir.exists()){
list.add(databaseDir.toURL());
}
// Add i18n directory to classpath.
File i18nDir = new File(directory, "i18n");
if(i18nDir.exists()){
list.add(i18nDir.toURL());
}
// Add lib directory to classpath.
File libDir = new File(directory, "lib");
File[] jars = libDir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".jar") || name.endsWith(".zip");
}
});
if (jars != null) {
for (int i = 0; i < jars.length; i++) {
if (jars[i] != null && jars[i].isFile()) {
if (developmentMode) {
// Do not add plugin-pluginName.jar to classpath.
if (!jars[i].getName().equals("plugin-" + directory.getName() + ".jar")) {
list.add(jars[i].toURL());
}
}
else {
list.add(jars[i].toURL());
}
}
}
}
}
catch (MalformedURLException mue) {
Log.error(mue);
}
}
public Collection<URL> getURLS() {
return list;
}
/**
* Adds a URL to the class loader. The {@link #initialize()} method should be called
* after adding the URL to make the change take effect.
*
* @param url the url.
*/
public void addURL(URL url) {
list.add(url);
}
/**
* Initializes the class loader with all configured classpath URLs. This method
* can be called multiple times if the list of URLs changes.
*/
public void initialize() {
Iterator urls = list.iterator();
URL[] urlArray = new URL[list.size()];
for (int i = 0; urls.hasNext(); i++) {
urlArray[i] = (URL)urls.next();
}
// If the classloader is to be used by a child plugin, we should
// never use the ContextClassLoader, but only reuse the plugin classloader itself.
if (classLoader != null) {
classLoader = new URLClassLoader(urlArray, classLoader);
}
else {
classLoader = new URLClassLoader(urlArray, findParentClassLoader());
}
}
/**
* Load a class using this plugin class loader.
*
* @param name the fully qualified name of the class to load.
* @return The module object loaded
* @throws ClassNotFoundException if the class could not be loaded by this class loader.
* @throws IllegalAccessException if the class constructor was private or protected.
* @throws InstantiationException if the class could not be instantiated (initialization error).
* @throws SecurityException if the custom class loader not allowed.
*/
public Class loadClass(String name) throws ClassNotFoundException, IllegalAccessException,
InstantiationException, SecurityException {
return classLoader.loadClass(name);
}
/**
* Destroys this class loader.
*/
public void destroy() {
classLoader = null;
}
/**
* Locates the best parent class loader based on context.
*
* @return the best parent classloader to use.
*/
private ClassLoader findParentClassLoader() {
ClassLoader parent = XMPPServer.class.getClassLoader();
if (parent == null) {
parent = this.getClass().getClassLoader();
}
if (parent == null) {
parent = ClassLoader.getSystemClassLoader();
}
return parent;
}
/**
* Returns the URLClassloader used.
*
* @return the URLClassLoader used.
*/
public ClassLoader getClassLoader() {
return classLoader;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -