尝试使用 java.exe -jar 运行我的 jar 时出现 NoClassDefFoundError ......出了什么问题?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/250166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NoClassDefFoundError while trying to run my jar with java.exe -jar...what's wrong?
提问by Ogre Psalm33
I have an application that I'm trying to wrap into a jar for easier deployment. The application compiles and runs fine (in a Windows cmd window) when run as a set of classes reachable from the CLASSPATH. But when I jar up my classes and try to run it with java 1.6 in the same cmd window, I start getting exceptions:
我有一个应用程序,我试图将其包装到 jar 中以便于部署。当作为一组可从 CLASSPATH 访问的类运行时,应用程序编译并正常运行(在 Windows cmd 窗口中)。但是当我打开我的类并尝试在同一个 cmd 窗口中使用 java 1.6 运行它时,我开始收到异常:
C:\dev\myapp\src\common\datagen>C:/apps/jdk1.6.0_07/bin/java.exe -classpath C:\myapp\libs\commons -logging-1.1.jar -server -jar DataGen.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at com.example.myapp.fomc.common.datagen.DataGenerationTest.<clinit>(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader.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:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
... 1 more
The funny thing is, the offending LogFactory seems to be in commons-logging-1.1.jar, which is in the class path specified. The jar file (yep, it's really there):
有趣的是,有问题的 LogFactory 似乎在 commons-logging-1.1.jar 中,它位于指定的类路径中。jar 文件(是的,它确实存在):
C:\dev\myapp\src\common\datagen>dir C:\myapp\libs\commons-logging-1.1.jar
Volume in drive C is Local Disk
Volume Serial Number is ECCD-A6A7
Directory of C:\myapp\libs
12/11/2007 11:46 AM 52,915 commons-logging-1.1.jar
1 File(s) 52,915 bytes
0 Dir(s) 10,956,947,456 bytes free
The contents of the commons-logging-1.1.jar file:
commons-logging-1.1.jar 文件的内容:
C:\dev\myapp\src\common\datagen>jar -tf C:\myapp\libs\commons-logging-1.1.jar
META-INF/
META-INF/MANIFEST.MF
org/
org/apache/
org/apache/commons/
org/apache/commons/logging/
org/apache/commons/logging/impl/
META-INF/LICENSE.txt
META-INF/NOTICE.txt
org/apache/commons/logging/Log.class
org/apache/commons/logging/LogConfigurationException.class
org/apache/commons/logging/LogFactory.class
org/apache/commons/logging/LogFactory.class
org/apache/commons/logging/LogFactory.class
org/apache/commons/logging/LogFactory.class
org/apache/commons/logging/LogFactory.class
org/apache/commons/logging/LogFactory.class
... (more classes in commons-logging-1.1 ...)
Yep, commons-logging has the LogFactory class. And finally, the contents of my jar's manifest:
是的,commons-logging 有 LogFactory 类。最后,我的 jar 清单的内容:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 10.0-b23 (Sun Microsystems Inc.)
Main-Class: com.example.myapp.fomc.common.datagen.DataGenerationTest
Class-Path: commons-logging-1.1.jar commons-lang.jar antlr.jar toplink
.jar GroboTestingJUnit-1.2.1-core.jar junit.jar
This has stumped me, and any coworkers I've bugged for more than a day now. Just to cull the answers, for now at least, third party solutions to this are probably out due to licensing restrictions and company policies (e.g.: tools for creating exe's or packaging up jars). The ultimate goal is to create a jar that can be copied from my development Windows box to a Linux server (with any dependent jars) and used to populate a database (so classpaths may wind up being different between development and deployment environments). Any clues to this mystery would be greatly appreciated!
这让我和我已经窃听了一天多的所有同事都难住了。只是为了找出答案,至少现在,由于许可限制和公司政策(例如:用于创建 exe 或打包 jar 的工具),第三方解决方案可能已经过时了。最终目标是创建一个 jar,它可以从我的开发 Windows 机器复制到 Linux 服务器(带有任何依赖的 jar)并用于填充数据库(因此类路径可能最终在开发和部署环境之间有所不同)。任何有关这个谜团的线索将不胜感激!
采纳答案by toolkit
The -jar option is mutually exclusive of -classpath. See an old description here
-jar 选项与 -classpath 互斥。在此处查看旧描述
-jar
Execute a program encapsulated in a JAR file. The first argument is the name of a JAR file instead of a startup class name. In order for this option to work, the manifest of the JAR file must contain a line of the form Main-Class: classname. Here, classname identifies the class having the public static void main(String[] args) method that serves as your application's starting point.
See the Jar tool reference page and the Jar trail of the Java Tutorial for information about working with Jar files and Jar-file manifests.
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
-罐
执行封装在 JAR 文件中的程序。第一个参数是 JAR 文件的名称,而不是启动类名称。为了使该选项起作用,JAR 文件的清单必须包含 Main-Class: classname 形式的一行。在这里, classname 标识具有 public static void main(String[] args) 方法的类,该方法用作应用程序的起点。
有关使用 Jar 文件和 Jar 文件清单的信息,请参阅 Jar 工具参考页面和 Java 教程的 Jar 跟踪。
使用此选项时,JAR 文件是所有用户类的来源,其他用户类路径设置将被忽略。
A quick and dirty hack is to append your classpath to the bootstrap classpath:
一个快速而肮脏的 hack 是将您的类路径附加到引导类路径:
-Xbootclasspath/a:path
Specify a colon-separated path of directires, JAR archives, and ZIP archives to append to the default bootstrap class path.
-Xbootclasspath/a:路径
指定以冒号分隔的指令、JAR 档案和 ZIP 档案的路径以附加到默认引导程序类路径。
However, as @Danrightly says, the correct solution is to ensure your JARs Manifest contains the classpath for all JARs it will need.
但是,正如@Dan所说的那样,正确的解决方案是确保您的 JAR 清单包含它需要的所有 JAR 的类路径。
回答by flash
回答by g_tom
You can omit the -jar
option and start the jar file like this:
您可以省略该-jar
选项并像这样启动 jar 文件:
java -cp MyJar.jar;C:\externalJars\* mainpackage.MyMainClass
java -cp MyJar.jar;C:\externalJars\* mainpackage.MyMainClass
回答by Mary C
I have found when I am using a manifest that the listing of jars for the classpath need to have a space after the listing of each jar e.g. "required_lib/sun/pop3.jar required_lib/sun/smtp.jar ". Even if it is the last in the list.
我发现当我使用清单时,类路径的 jar 列表需要在每个 jar 列表后有一个空格,例如“required_lib/sun/pop3.jar required_lib/sun/smtp.jar”。即使它是列表中的最后一个。
回答by Gautam Mandsorwale
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". It won't look at the JAR file entry "lib/other.jar".
如果 JAR 文件是从“C:\java\apps\appli.jar”加载的,并且您的清单文件具有 Class-Path: 引用“lib/other.jar”,则类加载器将在“C:\java \apps\lib\" 表示“other.jar”。它不会查看 JAR 文件条目“lib/other.jar”。
Solution:-
解决方案:-
- Right click on project, Select Export.
- Select Java Folder and in it select Runnable JAR File instead of JAR file.
- Select the proper options and in the Library Handling section select the 3rd option i.e. (Copy required libraries into a sub-folder next to the generated JAR).
- 右键单击项目,选择导出。
- 选择 Java 文件夹并在其中选择 Runnable JAR File 而不是 JAR 文件。
- 选择适当的选项,然后在库处理部分选择第三个选项,即(将所需的库复制到生成的 JAR 旁边的子文件夹中)。
[ EDIT= 3rd option generates a folder in addition to the jar, 2nd option ("Package required libraries into generated JAR") can also be used as you have the jar. ]
[ EDIT= 3rd 选项除了 jar 之外还会生成一个文件夹,第二个选项(“将所需的库打包到生成的 JAR 中”)也可以在您拥有 jar 时使用。]
- Click finish and your JAR is created at the specified position along with a folder that contains the JARS mentioned in the manifest file.
open the terminal,give the proper path to your jar and run it using this command 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.
- 单击完成,您的 JAR 将在指定位置创建,其中包含清单文件中提到的 JARS 的文件夹。
打开终端,为您的 jar 提供正确的路径并使用此命令运行它 java -jar abc.jar
现在会发生什么是类加载器将在正确的文件夹中查找引用的 JARS,因为现在它们存在于包含您的应用程序 JAR 的同一文件夹中。现在没有抛出“java.lang.NoClassDefFoundError”异常。
This worked for me... Hope it works for you too!!!
这对我有用......希望它也对你有用!!!
回答by mouhcine
i had the same problem with my jar the solution
我的 jar 有同样的问题解决方案
- Create the MANIFEST.MF file:
- 创建 MANIFEST.MF 文件:
Manifest-Version: 1.0
Sealed: true
Class-Path: . lib/jarX1.jar lib/jarX2.jar lib/jarX3.jar
Main-Class: com.MainClass
清单版本:1.0
密封:真实
类路径:。lib/jarX1.jar lib/jarX2.jar lib/jarX3.jar
主类:com.MainClass
- Right click on project, Select Export.
- 右键单击项目,选择导出。
select export all outpout folders for checked project
选择导出已检查项目的所有输出文件夹
- select using existing manifest from workspace and select the MANIFEST.MF file
- 从工作区中选择使用现有清单并选择 MANIFEST.MF 文件
This worked for me :)
这对我有用:)