所以这是我的问题:
我在DocuShare服务器上发生某个事件时会调用一些代码。我在自己的eventlistener中听这个事件。到目前为止一切顺利,这没有问题。
此侦听器将调用其他单独开发的代码并驻留在自己的jar文件中。
目前我们总是不得不关闭整个系统来部署其中一个罐子的新版本,以便可以使用它。
所以现在我正在尝试创建一个将jarfile(不在类路径上)复制到另一个临时位置(因此没有jarlock)的系统,将jarfile加载到自己的不同类加载器中并执行它。这样我就可以在开发新版本时简单地覆盖原始的jar文件。然后,代码将查看是否对jar文件进行了修改,如果是这种情况,则执行相同的步骤。
我已经在一个更简单的设置(一个被调用的servlet)中成功完成了这个,所以我知道“热部署”jar的方法。
然而,在这种情况下,代码工作正常,直到我开始使用单独的类加载器。 我可以找到jar文件并检查差异并相应地加载jar文件但是当我尝试访问该类时,我不再在System.out或System.err中获得任何输出。 jar中的代码没有正确执行,但我看不出原因。
额外信息:代码正在自己的线程中执行
发生什么事情概述:
代码示例(在Runnable.run()方法中):
URLClassLoader hotCL = new URLClassLoader(((URLClassLoader) systemCL).getURLs()); //new URLclassloader with URLs from system CL
//the following approach for putting the class on the classpath comes from another SO question from somebody else
Method m = cl.getClass().getDeclaredMethod("addURL", new Class[]{URL.class});
m.setAccessible(true);
m.invoke(cl, jar.toURI().toURL());
String cp = System.getProperty("java.class.path");
if (cp != null) {
cp += File.pathSeparatorChar + jar.getCanonicalPath();
} else {
cp = jar.toURI().getPath();
}
Logger.log(">>>>>>>> instantiating impl"); //this is printed in the System.out
Class<?> clsService = hotCL.loadClass(strService); //strService is the class inside the separate jar
Object instance = clsService.newInstance();
Logger.log(">>>>>>>>>>>> class: " + clsService.getClass().toString()); //this is not printed in the System.out, neither is any log-statement after this or any error
//after this a method of the class instance is called but the code doesn't do anything. Possibly an error but there's no error/stacktrace
有没有关于ClassLoaders的东西?我只是不明白为什么我没有看到任何错误或代码被执行。
答案 0 :(得分:1)
您的类加载器在尝试加载从动态类引用的JDK类时可能会挂起,因为它需要一个能够加载JDK类的父类加载器。您可以从当前上下文借用功能性父级,即:
new URLClassLoader(urls, this.getClass().getClassLoader())
如果在重新加载已经实例化的类后遇到问题,请查看this thread。