使用不同的类加载器时没有看到任何输出

时间:2013-06-21 14:13:45

标签: java thread-safety classloader output

所以这是我的问题:

我在DocuShare服务器上发生某个事件时会调用一些代码。我在自己的eventlistener中听这个事件。到目前为止一切顺利,这没有问题。

此侦听器将调用其他单独开发的代码并驻留在自己的jar文件中。

目前我们总是不得不关闭整个系统来部署其中一个罐子的新版本,以便可以使用它。

所以现在我正在尝试创建一个将jarfile(不在类路径上)复制到另一个临时位置(因此没有jarlock)的系统,将jarfile加载到自己的不同类加载器中并执行它。这样我就可以在开发新版本时简单地覆盖原始的jar文件。然后,代码将查看是否对jar文件进行了修改,如果是这种情况,则执行相同的步骤。

我已经在一个更简单的设置(一个被调用的servlet)中成功完成了这个,所以我知道“热部署”jar的方法。

然而,在这种情况下,代码工作正常,直到我开始使用单独的类加载器。 我可以找到jar文件并检查差异并相应地加载jar文件但是当我尝试访问该类时,我不再在System.out或System.err中获得任何输出。 jar中的代码没有正确执行,但我看不出原因。

额外信息:代码正在自己的线程中执行

发生什么事情概述:

  1. DocuShare发送活动
  2. 我的听众拿起活动
  3. 监听器(实现java.util.concurrent.Executor)启动一个新的Thread(Runnable impl)
  4. Runnable impl创建一个新的类加载器,然后检查文件夹中是否有新版本的jar文件,如果是,它会将其复制到另一个目录,如果没有,则使用现有版本,将其加载到类路径中新的类加载器并执行它
  5. 从我使用新的ClassLoader加载一个类的那一刻起,我看不到System.out / System.err中打印过任何行。
  6. 代码示例(在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的东西?我只是不明白为什么我没有看到任何错误或代码被执行。

1 个答案:

答案 0 :(得分:1)

您的类加载器在尝试加载从动态类引用的JDK类时可能会挂起,因为它需要一个能够加载JDK类的父类加载器。您可以从当前上下文借用功能性父级,即:

new URLClassLoader(urls, this.getClass().getClassLoader())

如果在重新加载已经实例化的类后遇到问题,请查看this thread