运行java -jar时的java.lang.ClassNotFoundException
我正在使用ant来构建我的build.xml
文件,它编译好了,但是当通过“ java -jar my_jar.jar
”运行生成的jar时获得运行时java.lang.NoClassDefFoundError
。 这似乎很多,但相关问题的解决方案都没有对我有用。
我的javac
类路径只包含“ /usr/local/lib/libthrift.jar
”,主.java
文件导入了一堆thrift包,如org.apache.thrift.transport.TTransportException
。
当我尝试通过以下方式运行程序时:
java -jar MyClass.jar
,我收到错误:
Exception in thread "main" **java.lang.NoClassDefFoundError**: org/apache/thrift/transport/TTransportException Caused by: java.lang.ClassNotFoundException: org.apache.thrift.transport.TTransportException at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) Could not find the main class: **MyClass**. Program will exit.
以下是我到目前为止尝试过的不起作用的事情:
-
在命令行上添加一个标志,如“java
-cp /usr/local/lib/libthrift.jar
-jar my_jar.jar
”,结果与上面的错误相同 -
在我的jar的
manifest>
标签中添加<attribute name="Class-Path" value="./:/usr/local/lib/libthrift.jar"/>
,结果与上面的错误相同 -
将
-Xbootclasspath/a:/usr/local/lib/libthrift.jar:./
到java命令行。 它解决了第一个错误,但出现了不同的错误:线程“main”中的exceptionjava.lang.NoClassDefFoundError:org / apache / log4j / Logger atg.apache.thrift.transport.TServerSocket。(TServerSocket.java:36)位于MyClass的MyClass.start(未知来源) .main(未知来源)
编辑:
如果我注释掉实例化缺少的类但保留导入的代码,代码执行正常。
编辑:
我将我的java类移动到服务器并使用manifest属性中的服务器引用MainClass,但这并没有修复任何问题。
Could not find the main class: MyClass
该错误似乎与您的MANIFEST
有关:
- 可能没有完整的类路径
Class-Path
:请参阅此HowTo
有jar子的最佳解决方案是尝试将所需的jar子包含在清单声明中。
Manifest-Version: 1.0 Class-Path: customer_client.jar mailer_client.jar signon_client.jar
- 或者可能没有充分定义’my_jar.jar’中的MainClass。
看到这个HowTo :
需要指定
的完整路径(包),而不仅仅是MainClass
。
如果您的主类在默认包( 未命名的包 )中,我不确定它是否可以被加载器引用(请参阅此SO问题 )
因此,将JarRunner
移动到一个包中,并在
元素中正确声明它。
您需要在清单文件中指定类路径中所需的所有其他jar,然后才能执行java -jar my-test.jar,这里是我的一个清单文件的副本。 通过清单中的所有这些条目,我可以指定java -jar db_field_cleaner.jar
并将所有其他jar内联到类路径中:
Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven Built-By: James B Build-Jdk: 1.6.0_01 Package: com.blah.dbfieldcleaner Specification-Title: db_field_cleaner Specification-Version: 2.5.7-SNAPSHOT Implementation-Title: db_field_cleaner Implementation-Version: 2.5.7-SNAPSHOT Implementation-Vendor-Id: com.blah.dbfieldcleaner Implementation-Vendor: Main-Class: com.blah.dbfieldcleaner.main.Main mode: development url: ..\..\db_field_cleaner\target\site Class-Path: log4j-1.2.14.jar cygna_commons-2.5.7-SNAPSHOT.jar mail-1.4 .jar activation-1.1.jar jdic-0.9.5.jar jdic_native-0.9.5.jar jdic_plu s-0.2.2.jar jdic_plus_native-0.2.2.jar jtds-1.2.2.jar xstream-1.3.1.j ar xpp3_min-1.1.4c.jar commons-net-2.0.jar text_processing-2.5.7-SNAP SHOT.jar
或者,使用Maven,它可以更好地加载这种东西!
您自己给出了答案:-)将所有jar添加到运行时类路径中。如前所述* .jar解决了一个问题,但记录器无法找到,因此将log4j.jar添加到路径中。 基本上这个想法是添加运行到classpath所需的所有jar。
可以在此处找到java
的命令行选项。
-jar
和-cp/-classpath
选项是互斥的。 -jar
选项需要使用清单,并且应在此文件中列出依赖关系的相对路径。 但实质上,清单是一种可选机制 – 您可以在引导时从外部指定所需信息。 如果清单导致您出现问题,请不要使用清单。
我会测试你是否已使用如下命令找到所有依赖项:
java -cp /usr/local/lib/libthrift.jar:my_jar.jar MyClass
请注意,即使运行时可能需要的所有类都不存在,编译器也可能成功编译您的类。 如果存在类的直接依赖性,则编译将成功。 创建二进制文件不需要依赖项的依赖项,编译器也不会不必要地检查它们。
有关org/apache/log4j/Logger
的消息表明您对log4j缺少依赖性。 有必要将此库添加到类路径中。 检查Thrift库的文档以确定其依赖性。
清单文件中的类路径引用是相对引用。 只是为了调试,您可能希望将所有jar复制到与my_jar.jar相同的位置并再次尝试。
参考: http : //www.rgagnon.com/javadetails/java-0587.html
您可以尝试将jar添加到服务器的域中。 我遇到了类似的问题,当我在glassfish上运行时,这对我有用。 我会得到那些未找到的例外。 Eclipse认识到它并且编译得很好,但是当在服务器上运行时它无法找到该文件。 尝试将其添加到服务器安装到的任何lib目录中。
这是正在发生的问题,
如果JAR文件是从“C:\ java \ apps \ appli.jar”加载的,并且您的清单文件具有Class-Path:引用“lib / other.jar”,则类加载器将查看“C:\ java” \ apps \ lib \“for”other.jar“。 它不会查看JAR文件条目“lib / other.jar”。
解:-
- 右键单击项目,选择“导出”。
- 选择Java Folder并在其中选择Runnable JAR File而不是JAR文件。
- 选择正确的选项,然后在Library Handling部分中选择第3个选项,即(将所需的库复制到生成的JAR旁边的子文件夹中)。
- 单击“完成”,将在指定位置创建JAR以及包含清单文件中提到的JARS的文件夹。
-
打开终端,给你的jar正确的路径并使用这个命令java -jar abc.jar运行它
现在将发生的事情是类加载器将在引用的JARS的正确文件夹中查找,因为现在它们存在于包含应用程序JAR的同一文件夹中。现在没有抛出“java.lang.NoClassDefFoundError”exception。
这对我有用……希望它也适合你!