2015-08-20 9 views
1

У меня есть приложение, запущенное в контейнере причала, где пользовательский загрузчик классов загружает классы из/SHARED/< jar files> .. Теперь я хочу, чтобы любой из этих загруженных классов использовал другие классы (WEB-INF/libs) из приложений, работающих в другом контейнере причала во время выполнения. На данный момент я получаю исключение класса, которое не найдено.Как загрузить класс java из одного веб-контейнера в другой?

Веб-контейнер 1:

Jar местоположение:/CI/Shared/< банки> Для загрузки выше банков, у нас есть класс клиента загрузчик под названием SharedJarsClassLoader ..

Web Container 2:

App_1/WEB-INF/LIBS App_2/WEB-INF/ЛИЭС

Мое требование к опорам для классов в/CI/Shared/< банок> в контейнер 1 т o загруженные классы из app1 & app2 jars из WEB-INF/libs.

Итак, теперь, когда приложение запускается, класс show show не найден. Приложение не может загружать классы из App_1/WEB-INF/libs & App_2/WEB-INF/libs.

Это иерархия Загрузчик класс ..

[email protected]           (Extensions class loader) 
    [email protected]          (System class loader) 
    [email protected]              (Jetty class loader) 
     [email protected]cbd  (Shared jars class loader) 
     [email protected]          (Webapp class loader) 
     [email protected]           (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

Чтобы сделать это, ваш пользовательский загрузчик классов (CCL) должен быть дочерним элементом загрузчика классов веб-приложений. Причина в том, что classloader только когда-либо спрашивает, что это родитель для отсутствующих классов. В вашем случае это наоборот. Это означает:

  • Код приложения обращается к пользовательскому классу через CCL. Это работает, поскольку CCL является родителем загрузчика классов вашего приложения.
  • Пользовательский класс теперь пытается открыть другой класс приложения. Он спрашивает CCL, о котором не знает. Затем CCL спрашивает родителей, которые также не имеют понятия - doom.

Если вы перевернете это вверх ногами, пользовательские классы смогут получить доступ к коду приложения. Теперь у вас возникнет проблема с доступом к пользовательским классам. Чтобы решить эту проблему, вы должны передать ссылку CCL вокруг и вручную загружать типы через API загрузчика классов, используя CCL, и создать экземпляр типа, который вам нужен. Вы не можете заставить Java «автоматически» открывать эти классы.