简体   繁体   English

运行java -jar时的java.lang.ClassNotFoundException

[英]java.lang.ClassNotFoundException when running java -jar

I'm using ant to build my build.xml file, it compiles ok, but then getting a runtime java.lang.NoClassDefFoundError when running the resulting jar via " java -jar my_jar.jar ". 我正在使用ant来构建我的build.xml文件,它编译好了,但是当通过“ java -jar my_jar.jar ”运行生成的jar时获得运行时java.lang.NoClassDefFoundError It seems like this comes up a lot but none of the related questions' solutions worked for me. 这似乎出现了很多,但没有相关问题的解决方案对我有用。

My classpath for javac contains only " /usr/local/lib/libthrift.jar " and the main .java file imports a bunch of thrift packages such as org.apache.thrift.transport.TTransportException . 我的javac类路径只包含“ /usr/local/lib/libthrift.jar ”,主.java文件导入了一堆thrift包,如org.apache.thrift.transport.TTransportException

When I try running the program via: 当我尝试通过以下方式运行程序时:

java -jar MyClass.jar

, I get the error: ,我收到错误:

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.

Here are the things I've tried so far that don't work: 这是迄今为止我尝试过的不起作用的东西:

  • adding a flag on the command line like "java -cp /usr/local/lib/libthrift.jar -jar my_jar.jar ", the result is the same error as above 在命令行上添加一个标志,如“java -cp /usr/local/lib/libthrift.jar -jar my_jar.jar ”,结果与上面的错误相同

  • adding <attribute name="Class-Path" value="./:/usr/local/lib/libthrift.jar"/> inside my jar's manifest> tag, the result is the same error as above 在我的jar的manifest>标签中添加<attribute name="Class-Path" value="./:/usr/local/lib/libthrift.jar"/> ,结果与上面的错误相同

  • adding -Xbootclasspath/a:/usr/local/lib/libthrift.jar:./ to the java command line. -Xbootclasspath/a:/usr/local/lib/libthrift.jar:./到java命令行。 it solves the first error but a different error comes up: 它解决了第一个错误,但出现了不同的错误:

    Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger at org.apache.thrift.transport.TServerSocket.<clinit>(TServerSocket.java:36) at MyClass.start(Unknown Source) at MyClass.main(Unknown Source) 线程“main”中的异常java.lang.NoClassDefFoundError:org / apache / log4j / Logger atg.apache.thrift.transport.TServerSocket。<clinit>(TServerSocket.java:36)位于MyClass的MyClass.start(未知来源) .main(未知来源)

EDIT: 编辑:

If I comment out the code that instantiates the missing classes but leave the imports, the code executes fine. 如果我注释掉实例化缺少的类但保留导入的代码,代码执行正常。

EDIT: 编辑:

I moved my java classes to a server and referenced the MainClass with the server in the manifest attribute, but that didn't fix anything. 我将我的java类移动到服务器并使用manifest属性中的服务器引用MainClass,但这并没有修复任何问题。

Could not find the main class: MyClass

The error seems actually related to your MANIFEST which: 该错误似乎与您的MANIFEST有关:

  • may not have a complete classpath Class-Path : see this HowTo 可能没有完整的类路径Class-Path :请参阅此HowTo

The best solution when you have a jar is to try to include the required jars into the manifest declaration. 有罐子的最佳解决方案是尝试将所需的罐子包含在清单声明中。

Manifest-Version: 1.0 
Class-Path:  
 customer_client.jar  
 mailer_client.jar  
 signon_client.jar 
  • or may not define adequately the MainClass within your 'my_jar.jar'. 或者可能没有充分定义'my_jar.jar'中的MainClass。

See this HowTo : 这个HowTo

<target name="jar" depends="compile">
     <delete file="hello.jar"/>
     <delete file="MANIFEST.MF"/>
     <manifest file="MANIFEST.MF">
        <attribute name="Built-By" value="${user.name}"/>
        <attribute name="Main-Class" value="howto.Hello"/>
    </manifest>

      <jar destfile="hello.jar"
           basedir="."
           includes="**/*.class"
           manifest="MANIFEST.MF"
           />
  </target>

the <attribute name="Main-Class" value="howto.Hello"/> needs to specify the full path (packages) of the MainClass , not just MainClass . 所述<attribute name="Main-Class" value="howto.Hello"/>需要指定的全路径(包) MainClass ,不只是MainClass

If your main class is in the default package (the unnamed package ), I am not sure it can be referenced by the loader (see this SO question ) 如果您的主类在默认包( 未命名的包 )中,我不确定它是否可以由加载器引用(请参阅此SO问题
So move your JarRunner into a package, and declare it appropriately in the <attribute name="Main-Class" value="myPackage.JarRunner"/> element. 因此,将JarRunner移动到一个包中,并在<attribute name="Main-Class" value="myPackage.JarRunner"/>元素中正确声明它。

You need to specify all the other jars that are required in your classpath in the manifest file before you can execute java -jar my-test.jar, here is a copy of one of my manifest files. 您需要在清单文件中指定类路径中所需的所有其他jar,然后才能执行java -jar my-test.jar,这里是我的一个清单文件的副本。 With all these entries in the manifest I can specify java -jar db_field_cleaner.jar and all the other jars are inlined into the classpath : 通过清单中的所有这些条目,我可以指定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

Alternatively, use Maven, it's loads better at this kind of stuff! 或者,使用Maven,它可以更好地加载这种东西!

You had given answer yourself :-) add all the jars to your runtime classpath.As you said earlier *.jar solved one problem but loggers are not able to find out, so add log4j.jar to the path. 您自己给出了答案:-)将所有jar添加到运行时类路径中。如前所述* .jar解决了一个问题,但记录器无法找到,因此将log4j.jar添加到路径中。 Basically the idea is add all the jars required for running in to classpath. 基本上,这个想法是添加运行到classpath所需的所有jar。

This is the problem that is occurring, 这是正在发生的问题,

if the JAR file was loaded from "C:\\java\\apps\\appli.jar", and your manifest file has the Class-Path: reference "lib/other.jar", the class loader will look in "C:\\java\\apps\\lib\\" for "other.jar". 如果JAR文件是从“C:\\ java \\ apps \\ appli.jar”加载的,并且您的清单文件具有Class-Path:引用“lib / other.jar”,则类加载器将查看“C:\\ java” \\ apps \\ lib \\“for”other.jar“。 It won't look at the JAR file entry "lib/other.jar". 它不会查看JAR文件条目“lib / other.jar”。

Solution:- 解:-

  1. Right click on project, Select Export. 右键单击项目,选择“导出”。
  2. Select Java Folder and in it select Runnable JAR File instead of JAR file. 选择Java Folder并在其中选择Runnable JAR File而不是JAR文件。
  3. Select the proper options and in the Library Handling section select the 3rd option ie (Copy required libraries into a sub-folder next to the generated JAR). 选择正确的选项,然后在Library Handling部分中选择第3个选项,即(将所需的库复制到生成的JAR旁边的子文件夹中)。
  4. Click finish and your JAR is created at the specified position along with a folder that contains the JARS mentioned in the manifest file. 单击“完成”,将在指定位置创建JAR以及包含清单文件中提到的JARS的文件夹。
  5. open the terminal,give the proper path to your jar and run it using this command java -jar abc.jar 打开终端,为你的jar提供正确的路径并使用这个命令java -jar abc.jar运行它

    Now what will happen is the class loader will look in the correct folder for the referenced JARS since now they are present in the same folder that contains your app JAR..There is no "java.lang.NoClassDefFoundError" exception thrown now. 现在将会发生的事情是类加载器将在引用的JARS的正确文件夹中查找,因为现在它们存在于包含应用程序JAR的同一文件夹中。现在没有抛出“java.lang.NoClassDefFoundError”异常。

This worked for me... Hope it works you too!!! 这对我有用...希望它对你有用!!!

The command line options for java can be found here . 可以在此处找到java的命令行选项。

The -jar and -cp/-classpath options are mutually exclusive. -jar-cp/-classpath选项是互斥的。 The -jar option requires the use of a manifest and the relative paths to dependencies should be listed in this file. -jar选项需要使用清单,并且应在此文件中列出依赖关系的相对路径。 But essentially, the manifest is an optional mechanism - you can specify the required information externally at bootstrap time. 但实质上,清单是一种可选机制 - 您可以在引导时从外部指定所需信息。 If the manifest is causing you problems, don't use one. 如果清单导致您出现问题,请不要使用清单。

I would test that you have you have located all your dependencies with a command like this: 我会测试你是否已使用如下命令找到所有依赖项:

java -cp /usr/local/lib/libthrift.jar:my_jar.jar  MyClass

Note that the compiler may successfully compile your classes even if all the classes that might be required at runtime are not present. 请注意,即使运行时可能需要的所有类都不存在,编译器也可能成功编译您的类。 Compilation will succeed if the direct dependencies of your classes are present. 如果存在类的直接依赖性,编译将成功。 The dependencies of your dependencies are not necessary to create the binary and the compiler will not inspect them needlessly. 创建二进制文件不需要依赖项的依赖项,编译器也不会不必要地检查它们。

The message about org/apache/log4j/Logger suggests that you have a missing dependency on log4j . 有关org/apache/log4j/Logger的消息表明您对log4j缺少依赖性。 It will be necessary to add this library to the classpath. 有必要将此库添加到类路径中。 Check the documentation for the Thrift library to determine its dependencies. 检查Thrift库的文档以确定其依赖性。

The class path references in the manifest file are relative refs. 清单文件中的类路径引用是相对引用。 Just to debug, you might want to copy all the jars into the same location as my_jar.jar and attempt it again. 只是为了调试,您可能希望将所有罐子复制到与my_jar.jar相同的位置并再次尝试。

reference : http://www.rgagnon.com/javadetails/java-0587.html 参考: http//www.rgagnon.com/javadetails/java-0587.html

You might try adding the jars to the domain of the server. 您可以尝试将jar添加到服务器的域中。 I had a similar problem and this worked for me when I was running it on glassfish. 我遇到了类似的问题,当我在glassfish上运行时,这对我有用。 I would get those not found exceptions. 我会得到那些未找到的例外。 Eclipse recognized it and it compiled fine but when ran on the server it couldn't find the file. Eclipse认识到它并且编译得很好,但是当在服务器上运行时它无法找到该文件。 Try adding it to whatever lib directory the server is installed to. 尝试将其添加到服务器安装到的任何lib目录中。

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

相关问题 运行jar时java.lang.ClassNotFoundException且其依赖项位于同一目录中 - java.lang.ClassNotFoundException when running a jar and its dependency is in the same directory 运行JAR时出现“ java.lang.ClassNotFoundException:javax.ejb.EJBObject” - “java.lang.ClassNotFoundException: javax.ejb.EJBObject” when running JAR 从jar文件加载类时出现java.lang.ClassNotFoundException - java.lang.ClassNotFoundException when loading a class from a jar file 带jar文件的Crontab java.lang.ClassNotFoundException - Crontab java.lang.ClassNotFoundException with a jar file 运行appium脚本时出现java.lang.ClassNotFoundException - java.lang.ClassNotFoundException is comming when running appium script 在Spark集群上运行程序时出现java.lang.ClassNotFoundException - java.lang.ClassNotFoundException when running program on spark cluster 在 IntelliJ IDEA 中运行时出现 java.lang.ClassNotFoundException - java.lang.ClassNotFoundException when running in IntelliJ IDEA 尝试注入正在运行的 VM 时出现 java.lang.ClassNotFoundException 错误 - java.lang.ClassNotFoundException Error when trying to inject into running VM 从控制台运行java.lang.ClassNotFoundException - java.lang.ClassNotFoundException running from the console 抛出java.lang.ClassNotFoundException - java.lang.ClassNotFoundException
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM