简体   繁体   English

Tomcat 7 / Java 8 ClassNotFoundException

[英]Tomcat 7 / Java 8 ClassNotFoundException

I have a testing Ubuntu server running tomcat7 and oracle jdk 8, I am trying to load a few jar files that will be needed for a variety of future programs. 我有一个运行tomcat7和oracle jdk 8的测试Ubuntu服务器,我正在尝试加载一些jar文件,这些文件将在将来的各种程序中使用。 Both web and jvm programs. Web和jvm程序。 I realized that there is a problem when I did a test run of a jar that will be running as a server background process, but when it runs I get the following error: 我意识到当我对将作为服务器后台进程运行的jar进行测试运行时出现问题,但是当它运行时出现以下错误:

Exception in thread "main" java.lang.NoClassDefFoundError: edu/illinois/sql/sqlConnection
    at server.edu.illinois.xmlConverter.convertXML.run(Converter.java:27)
    at server.edu.illinois.xmlConverter.Converter.main(Converter.java:13)
Caused by: java.lang.ClassNotFoundException: edu.illinois.sql.sqlConnection
    at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 2 more

I have added my jars with my classes to /shared/lib and catalina.properties knows to look there and there are symbolic links in $JAVA_HOME/jre/lib. 我已经将带有我的类的jar添加到/ shared / lib中,并且catalina.properties知道要在此处查找,并且$ JAVA_HOME / jre / lib中有符号链接。 Does anyone have any advice as to why my custom classes from my jars on the server are not being loaded properly? 对于为什么我的服务器上的jar中的自定义类无法正确加载,是否有人有任何建议? Also the jar that I ran to generate the error runs great in eclipse. 而且,我运行以生成错误的jar在Eclipse中运行得很好。

This is a different question than ClassNotFoundException/NoClassDefFoundError in my Java web application because I believe my jars are in the correct locations and I am trying to figure out what I have done wrong that is causing these classes not to load. 这是与Java Web应用程序中的ClassNotFoundException / NoClassDefFoundError不同的问题因为我认为我的jar放在正确的位置,并且我试图找出我做错了什么导致这些类无法加载。

Do not modify your JVM installation, it's not worth it. 不要修改JVM安装,这是不值得的。 There are well-known ways to bundle JARs with your program: 有一些将JAR与程序捆绑在一起的方法:

  • for standalone programs as executable JARs, see this answer 对于独立程序作为可执行JAR,请参见此答案
  • for web applications, place them in WEB-INF/lib . 对于Web应用程序,请将它们放在WEB-INF/lib Maven will even do it for you. Maven甚至会为您做。

Yes, the same JAR will be duplicated. 是的,相同的JAR将被复制。 No, it really is OK. 不,真的可以。 Yes, there is some overhead. 是的,有一些开销。 Yes, the benefits vs a modified JVM are really worth it (cue myself wasting ~5 hours trying to find why suddenly my development machine did not find my classes after java got auto-updated...). 是的,与经过修改的JVM相比,这样做的好处确实是值得的(提示自己浪费了大约5个小时来尝试查找为什么Java自动更新后,我的开发机器突然找不到我的类的原因……)。

I might not have explained this well enough I still new to java and am self taught. 我可能还没有对Java进行足够好的解释,我仍然是Java的新手,而且自学成才。 I did however figure out my answer. 但是我确实弄清楚了答案。 Tassos and Thorbjørn make good point that I will keep in mind, particularly not messing with /jre/lib or /jre/lib/etx . 我将牢记Tassos和Thorbjørn的观点,尤其是不要弄乱/jre/lib/jre/lib/etx However since I do not want to bundle the external jars in with the runnable jar, I have found my solution that will work for me as I am both running the server and creating the jars. 但是,由于我不想将外部jar与可运行的jar捆绑在一起,因此我发现我的解决方案对我来说是行得通的,因为我同时在运行服务器和创建jar。

I am going to add create a custom MANIFEST.MF which will contain a Class-path: statement pointing to the directory where I am putting the common jars. 我将添加创建一个自定义MANIFEST.MF ,其中将包含一个Class-path:语句,该语句指向放置普通jar的目录。

For example: 例如:

Manifest-Version: 1.0
Main-Class: server.edu.illinois.Main
Class-Path: /shared/lib/guava-17.0.jar /shared/lib/jcifs-1.3.17.jar /shared/lib/mysql-connector-java-3.1.14-bin.jar

This way I can include the external jars I need only once and update anything I need to in Eclipse when I update the manifest's jar. 这样,我可以只包含一次的外部jar,并在更新清单的jar时更新在Eclipse中需要的所有内容。 I can still leave tomcat to pickup those jars in that library when it does the common classload. 当它执行常见的类加载时,我仍然可以离开tomcat在该库中提取那些jar。 When I get back to my dev machine tomorrow I am going to pull the symbolic links out of /jre/lib/ext . 明天当我回到开发机时,我将从/jre/lib/ext拉出符号链接。

Overall, my jars were not being loaded properly to begin with because they were not actually in the path that the class loader was looking at. 总体而言,我的jar最初没有正确加载,因为它们实际上不在类加载器正在查看的路径中。 To solve this problem without adding overhead and since these will be one off programs, adding directories to the common class loader for catalina and the jar paths to the manifest of my stand alone programs. 为了解决此问题而又不增加开销,并且由于这些都是一次性程序,因此将目录添加到catalina的公共类加载器中,并将jar路径添加到我的独立程序的清单中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM