我有一个使用多个应用程序运行的大型设备。我有多个Jetty容器,每个容器都部署了多个应用程序。现在,我在部署应用程序时面临一个简单的类未找到警告。
这是我的分析:
这是堆栈跟踪..
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]
关于如何解决此问题的任何输入..我正在使用Maven来构建应用程序..我怀疑这是becoz,因为两个库都位于不同的位置,spring类(存在于jettyContainer1中)无法从App_3加载ClassAInContainer3。所以我们可以添加一些依赖项或类加载器配置..
任何输入都将非常感谢..提前感谢.. :))
答案 0 :(得分:0)
如果" spring框架类"那么例外是有意义的。由Jetty类加载器加载,ClassAInContainer3
加载WebAppClassLoader
(通常是这样,如果它在WEB-INF / lib或WEB-INF / webapp类中)。
我在调试中启动了一个Jetty服务器并执行了以下命令(在Eclipse的Display视图中),同时在Web控制器内的一个breack点被阻塞(即我执行WebAppClassLoader
加载的代码):
this.getClass().getClassLoader()
org.eclipse.jetty.webapp.WebAppClassLoader) WebAppClassLoader=653648989@26f5e45d
如果我尝试爬上类加载器层次结构,我会得到Jetty的服务器类加载器:
this.getClass().getClassLoader().getParent()
(org.codehaus.plexus.classworlds.realm.ClassRealm) ClassRealm[plugin>org.eclipse.jetty:jetty-maven-plugin:9.3.2.v20150730, parent: sun.misc.Launcher$AppClassLoader@58644d46]
这是根类加载器,超出这一点我不能去,事实上:
this.getClass().getClassLoader().getParent().getParent()
null
现在,如果我在loadClass
加载的类的代码中调用AppClassLoader
(通常在服务器启动时),它将首先使用自己的类加载器(也就是说,AppClassLoader
本身)然后,如果找不到类,那么父类加载器(因为servlet容器将使用"父最后一个"加载策略,但请注意,我之前说过,除AppClassLoader
之外没有其他类加载器。
但AppClassLoader无法访问ClassAInContainer3
是完全可行的,因为它不在其已知的类路径中。事实上,如果我尝试使用AppClassLoader
加载我的Web控制器实例(WEB-INF / classes中包含的类)会发生什么:
this.getClass().getClassLoader().getParent().loadClass("org.test.showcase.HomeController")
Evaluation failed. Reason(s):
An exception occurred: java.lang.ClassNotFoundException
我怀疑你的情况正是如此。