如何将java类从一个Web容器加载到另一个Web容器?

时间:2015-08-20 07:26:24

标签: java maven jetty containers classloader

我有一个在jetty容器中运行的应用程序,其中自定义类加载器将从/ SHARED /< jar文件> ..现在我希望这些加载的类中的任何一个在运行时从另一个jetty容器中运行的应用程序中使用另一个类(WEB-INF / libs)。截至目前,我找到了一个没有发现异常的课程。

Web容器1:

Jar位置:/ ci / Shared /<罐子> 要加载上面的jar,我们有一个名为SharedJarsClassLoader的客户类加载器..

Web容器2:

APP_1 / WEB-INF /库 APP_2 / WEB-INF /库

我的要求是支持/ ci / Shared /<中的类。罐子>从容器1到app1&amp ;;的加载类来自WEB-INF / libs的app2罐..

现在,当应用程序启动时,它会显示未找到类的异常。应用程序无法从App_1 / WEB-INF / libs& APP_2 / WEB-INF /库。

这是类加载器层次结构..

sun.misc.Launcher$ExtClassLoader@4921a90                                         (Extensions class loader)
  sun.misc.Launcher$AppClassLoader@3da997a                                       (System class loader)
    startJarLoader@68758d51                                                      (Jetty class loader)
      com.test.jetty_ext.NewWebAppProvider$SharedJarsClassLoader@374d1cbd        (Shared jars class loader)
        WebAppClassLoader=settings@2fee2019                                      (Webapp class loader)
        WebAppClassLoader=taskt@6a57cf0b                                         (2nd Webapp class loader)

这是堆栈跟踪..

Caused by: java.lang.ClassNotFoundException: com.test.ClassAInContainer3
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366) ~[na:1.7.0_55]
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355) ~[na:1.7.0_55]
    at java.security.AccessController.doPrivileged(Native Method) ~[na:1.7.0_55]
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354) ~[na:1.7.0_55]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425) ~[na:1.7.0_55]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ~[na:1.7.0_55]
    at org.springframework.util.ClassUtils.forName(ClassUtils.java:258) ~[spring-core.jar:3.2.0.RELEASE]
    at org.springframework.amqp.support.converter.DefaultJavaTypeMapper.getClassIdType(DefaultJavaTypeMapper.java:82) ~[spring-amqp.jar:na]
    ... 16 common frames omitted
2015-08-19 05:38:16.123 UTC,WARN ,App1-web,messaging,com.test.Rabbit,null,SimpleAsyncTaskExecutor-1,Caught an exception while handling a rabbitmq message, Publisher/Consumer should have handled this.
org.springframework.amqp.support.converter.MessageConversionException: failed to resolve class name. Class not found [com.test.ClassAInContainer3]
    at org.springframework.amqp.support.converter.DefaultJavaTypeMapper.getClassIdType(DefaultJavaTypeMapper.java:85) ~[spring-amqp.jar:na]
    at org.springframework.amqp.support.converter.DefaultJavaTypeMapper.toJavaType(DefaultJavaTypeMapper.java:53) ~[spring-amqp.jar:na]
    at org.springframework.amqp.support.converter.JsonMessageConverter.fromMessage(JsonMessageConverter.java:117) ~[spring-amqp.jar:na]

有关如何解决此问题的任何意见?

1 个答案:

答案 0 :(得分:1)

为了能够做到这一点,您的自定义类加载器(CCL)必须是Web应用程序类加载器的子级。原因是类加载器只会询问它的父类是否缺少类。在你的情况下,它是相反的方式。这意味着:

  • 应用代码通过CCL访问自定义类。这是有效的,因为CCL是应用程序类加载器的父级。
  • 自定义类现在尝试发现另一个应用类。它问CCL不知道的是。然后CCL要求父母也不知道 - >灭亡。

如果您颠倒过来,自定义类将能够访问应用程序代码。现在,您将无法访问自定义类。为了解决这个问题,您必须传递CCL引用并使用CCL通过类加载器API手动加载类型并实例化您需要的类型。你不能让Java“自动”发现这个类。