java 带有可执行 Jar 的 NoClassDefFoundError

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4518957/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 06:43:41  来源:igfitidea点击:

NoClassDefFoundError with Executable Jar

javaclasspathmanifestexecutable-jar

提问by Swift-Tuttle

Probably a very usual problem with exec jar. I am trying to create and run an executable jar and its driving me crazy.

exec jar 可能是一个非常常见的问题。我正在尝试创建和运行一个可执行的 jar,它让我发疯。

I have couple of classes(with package stmts), one of which has a main method, a simple empty constructor and ofcourse few biz methods, these form part of a small eclipse project.
I am bundling both these and a manifest file into a jar(arc.jar) using a build.xml. My program uses jdom library and also references from one of my other eclipse projects, so I am including both the jdom libray and other biz library while building my arc.jar.

我有几个类(带有包 stmts),其中一个有一个 main 方法,一个简单的空构造函数,当然还有几个 biz 方法,这些构成了一个小型 eclipse 项目的一部分。
我正在使用 build.xml 将这些文件和清单文件捆绑到一个 jar(arc.jar) 中。我的程序使用 jdom 库以及来自我的其他 eclipse 项目之一的引用,因此我在构建 arc.jar 时同时包含 jdom 库和其他 biz 库。

This is the Manifest.MF I wrote, there is a new lineafter Main-Class

这是我写的Manifest.MF,Main-Class之后有一个新的line

Manifest-Version: 1.2  
Class-Path: jdom.jar other.jar
Main-class: uk.co.Art 

When I unzip this arc.jar, it contains jdom.jar, other.jar, META-INF/Manifest.mf and the package with my classes. Funnily, the Manifest file in jar looks like this -

当我解压这个 arc.jar 时,它包含 jdom.jar、other.jar、META-INF/Manifest.mf 和我的类的包。有趣的是,jar 中的 Manifest 文件看起来像这样 -

Manifest-Version: 1.2 
Created-By: 14.2-b01 (Sun Microsystems Inc.) 
Main-class: uk.co.Art
Class-Path: jdom.jar other.jar

I got the ClassNotFoundException ClassNotFoundException: uk.co.Artwhen the value of Main class was without the package. With package the error changed to ClassNotFoundException: org.jdom.JDOMException.
So just for testing purpose, I tried giving the fullpaths with c:\for both my executing class and the jars but still it is not able to locate the main class, errors out ClassNotFoundException: uk.co.Art.
I cant seem to understand why.
The command line I am using is - java -jar Arc.jar
The version on cmd prompt is -
java version "1.6.0_16"
Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
Java HotSpot(TM) Client VM (build 14.2-b01, mixed mode)

while the eclipse installed jre is jre6

ClassNotFoundException: uk.co.Art当 Main 类的值没有包时,我得到了 ClassNotFoundException 。使用包,错误更改为ClassNotFoundException: org.jdom.JDOMException.
因此,仅出于测试目的,我尝试c:\为我的执行类和 jar提供完整路径,但仍然无法找到主类,错误输出ClassNotFoundException: uk.co.Art
我似乎无法理解为什么。
我使用的命令行是 - java -jar Arc.jar
cmd 提示上的版本是 - 而 eclipse 安装的 jre 是 jre6
java version "1.6.0_16"
Java(TM) SE Runtime Environment (build 1.6.0_16-b01)
Java HotSpot(TM) Client VM (build 14.2-b01, mixed mode)

What can you folks suggest ?

你们有什么建议?

Alex' solution did solve the problem for local execution.
I am also thinking of another way(as an extra option) of execution, to deploy the Arc.jar on server and run a batch on that machine which basically sets the java classpath and then calls either the jar or directly the class whichever way it works. But its only an option, not a preferred one though.
Or, also, set that classpath in my manifest and build jar locally and deploy on the server.
Would like to try out a few things though. But now I understand that the basic problem was jars into jar and hence classpath issue.

Alex 的解决方案确实解决了本地执行的问题。
我也在考虑另一种执行方式(作为额外的选项),在服务器上部署 Arc.jar 并在该机器上运行批处理,这基本上设置了 java 类路径,然后以任何方式调用 jar 或直接调用类作品。But its only an option, not a preferred one though.
或者,也可以在我的清单中设置该类路径并在本地构建 jar 并在服务器上部署。
虽然想尝试一些事情。But now I understand that the basic problem was jars into jar and hence classpath issue.

Thanks a lot folks.

非常感谢各位。

回答by BalusC

You cannot bundle other JAR's in a JAR. They have to go in the same folder or at least in a folder relative to the Arc.jar. You specify then its relative path in the Class-Pathentry.

您不能在 JAR 中捆绑其他 JAR。它们必须位于同一个文件夹中,或者至少位于与Arc.jar. 然后在Class-Path条目中指定其相对路径。

Eclipse however has an useful export tool which allows you to embed the contents of other JAR's in your JAR so that you don't end up with multiple loose JAR's which are required to be placed in a specific location. Check the 2nd Library Handlingoption when you choose Export > Runnable JAR file.

然而,Eclipse 有一个有用的导出工具,它允许您将其他 JAR 的内容嵌入到您的 JAR 中,这样您就不会得到多个需要放置在特定位置的松散 JAR。当您选择Export > Runnable JAR file时,请检查 2nd Library Handling选项。

alt text

替代文字

When choosing Package required libraries into generated JAR, then Eclipse will add a special classloader which will load those JAR's transparently for you before executing the main class. It's doing that with help of JarRsrcLoader.

需要将程序包选择到生成的jar中时,Eclipse将添加一个特殊的类加载器,然后在执行主类之前为您透明地加载那些jar。它是在 的帮助下做到这一点的JarRsrcLoader

回答by AlexR

You do not have to pack your additional jars into your jar. These jars should be in the same directory as your application jar. By other words: put all jars into one directory and run. Everything will work.

您不必将额外的罐子装入罐子中。这些 jar 应该与您的应用程序 jar 位于同一目录中。换句话说:将所有 jars 放入一个目录并运行。一切都会好起来的。

Reasons: think what does executable jar mean. If you jar is not "executable" you run it as following:

原因:想想可执行jar是什么意思。如果您的 jar 不是“可执行的”,则按如下方式运行它:

java -cp art.jar;ldom.jar;other.jar uk.co.Art

when your jar is executable you use the following command line:

当您的 jar 可执行文件时,您可以使用以下命令行:

java -jar art.jar

No magic: jvm opens manifest and takes name of main class and other jars from there and virtually creates command line like first one. Now you understand that all jars in your case must be in the same directory.

没有魔法:jvm 打开清单并从那里获取主类和其他 jar 的名称,并像第一个一样虚拟地创建命令行。现在您了解您案例中的所有 jar 文件都必须在同一目录中。

回答by bluish

Maybe the .jar is corrupt, like sometimes happened to me. Take a look at this.

也许 .jar 已损坏,就像有时发生在我身上一样。看看这个

回答by Vivek

Just couple of things to be noted when exporting.

导出时需要注意的几件事。

  1. JRE associated to the project is consistent with the JRE that would be used to run it.

  2. Please export your project into a local drive, then move it into any shared drive (this fixed my issue).

  1. 与项目关联的 JRE 与将用于运行它的 JRE 一致。

  2. 请将您的项目导出到本地驱动器,然后将其移动到任何共享驱动器(这解决了我的问题)。

Thank you.

谢谢你。