运行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”。

解:-

  1. 右键单击项目,选择“导出”。
  2. 选择Java Folder并在其中选择Runnable JAR File而不是JAR文件。
  3. 选择正确的选项,然后在Library Handling部分中选择第3个选项,即(将所需的库复制到生成的JAR旁边的子文件夹中)。
  4. 单击“完成”,将在指定位置创建JAR以及包含清单文件中提到的JARS的文件夹。
  5. 打开终端,给你的jar正确的路径并使用这个命令java -jar abc.jar运行它

    现在将发生的事情是类加载器将在引用的JARS的正确文件夹中查找,因为现在它们存在于包含应用程序JAR的同一文件夹中。现在没有抛出“java.lang.NoClassDefFoundError”exception。

这对我有用……希望它也适合你!