jar类上的java ClassNotFoundException,我可以从中成功加载其他类
背景:
我正试图在Java类中启动一个嵌入式Tomcat服务器,它是通过JRuby从Ruby脚本启动的。这意味着我使用的所有jar都需要从ruby脚本加载
在ruby脚本中,我有:
require 'java'
load 'servlet-api-2.5.jar'
...
com.mycompany.RunWebApplicationTomcat.main(nil)
//com.mycompany.RunWebApplicationJetty.main(nil) //Commented out for Tomcat Test
Java类如下:
public class RunWebApplicationTomcat {
public static void main(String[] args) throws Exception {
try {
Class.forName("javax.servlet.http.HttpServlet");
} catch(ClassNotFoundException e) {
System.err.println(e.getMessage());
}
DispatcherServlet dispatcherServlet = new DispatcherServlet();
....
}
}
问题:
当我运行脚本时,我在类上没有得到异常。对于name测试,我在javax上得到了一个ClassNotFoundException。servlet。http。尝试DispatcherServlet初始化时的HttpServlet。(DispatcherServlet是SpringServlet,但我尝试了其他servlet实现,并遇到了相同的异常)
为什么我对servlet api有99.9%的把握。jar位于类路径中:
奇怪的是,我已经成功地使用相同的模式创建了一个嵌入式Jetty服务器。该服务器不需要HttpServlet类。但是,它确实使用了HttpServletRequest/Response类,它们位于同一个ServletAPI中。罐子,它工作得很好
问题:
1.有人知道如何在jar中找不到加载到类路径中的特定类吗
2.是否有某种java安全机制可以防止类被实例化?(JRuby可执行文件是一个自定义的、专有的黑盒,因此我不确定其中会发生什么)
3.是否有任何其他我可能会执行的测试可以揭示问题
Stacktrace
Caused by: java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet
... 38 more
Caused by: java.lang.ClassNotFoundException: javax.servlet.http.HttpServlet
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
# 1 楼答案
一个
ClassNotFoundException
可以由许多因素引起,包括以下因素:有问题的班级不在那里
类在那里,但它所依赖的其他类/接口/注释/枚举不在那里
您的类依赖于以前在类初始化中失败的其他类
证据似乎与所有这些相矛盾。(根据javadoc,
Class.forName(String)
触发类初始化。)然而,堆栈跟踪将提供更多的证据在这里,类加载器会发生什么棘手的事情;i、 e.DispatcherServlet类以前是使用与
forName
正在使用的“当前”类加载程序不同的类加载程序加载的您还应该考虑^ { CD3>}在您的示例代码中没有测试的不同的^ ^ {CD5>}(或^ {CD6>})的可能性。
# 2 楼答案
Tomcat提供了自己版本的ServletAPI。罐子版本差异可能导致缺少类
从Tomcat 7.0 Docs: