【发布时间】:2015-09-24 19:19:32
【问题描述】:
我正在处理一个需要从文件系统动态加载类的项目,我用谷歌搜索发现我需要使用自定义ClassLoader。我已经实现了自己的类加载器,当我在控制台上运行它时工作正常,当我尝试在服务器上部署应用程序时出现问题,它导致ClassNotFoundException。
问题是我试图加载的类包含一些对另一个类的引用,该类已经由应用程序加载,但它试图从同一位置加载引用。
public class HandlerClassLoader extends ClassLoader {
static Logger log = Logger.getLogger(HandlerClassLoader.class.getName());
URLClassLoader ucl;
private ProcessDefinition processDefinition = null;
boolean flag = false;
public URL[] loadJars() throws MalformedURLException {
PropertiesFiles propFiles = new PropertiesFiles();
File f = new File(propFiles.getValue("jarslocation"));
log.debug("Loading JARS files from " + f.getAbsolutePath());
List<URL> urls = new ArrayList<URL>();
String filesName[] = f.list();
for (String jars : filesName)
if (jars.endsWith("jar")) {
urls.add(new URL("file:///"
+ propFiles.getValue("jarslocation") + "/" + jars));
}
URL[] array = urls.toArray(new URL[urls.size()]);
return array;
}
public HandlerClassLoader() {
super(Thread.currentThread().getContextClassLoader());
log.debug("Called to the " + this.getClass().getName()
+ " No Parameter Constructor");
try {
ucl = new URLClassLoader(loadJars());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
public HandlerClassLoader(ClassLoader parent,
ProcessDefinition processDefinition) {
super(parent);
log.debug("Called to the " + this.getClass().getName()
+ " Parameterized Constructor");
try {
ucl = new URLClassLoader(loadJars());
} catch (MalformedURLException e) {
e.printStackTrace();
}
this.processDefinition = processDefinition;
}
public Class<?> findClass(String className) throws ClassNotFoundException {
log.debug("findClass method of " + this.getClass().getName()
+ " is called with className : " + className);
return ucl.loadClass(className);
}
我认为委托原则不起作用,或者该服务器可能必须具有不同的类加载器实现。
【问题讨论】:
-
你真的实现了自己的类加载器吗?很可能你可以使用
URLClassLoader来加载你的类,它会正确地委托给父类。 -
@Kayaman 是的,我使用 URLClassLoader 实现了自己的类加载器,并且在构造函数中传递了父类加载器
-
@Kayaman 我已经提供了我的类加载器
-
您的 ClassLoader 实现并没有真正添加任何有用的东西。为什么不直接使用
URLClassLoader?
标签: java classloader