简体   繁体   English

尝试使用java.exe -jar运行我的jar时出现NoClassDefFoundError ...怎么了?

[英]NoClassDefFoundError while trying to run my jar with java.exe -jar…what's wrong?

I have an application that I'm trying to wrap into a jar for easier deployment. 我有一个要包装到jar中的应用程序,以便于部署。 The application compiles and runs fine (in a Windows cmd window) when run as a set of classes reachable from the CLASSPATH. 作为从CLASSPATH可以访问的一组类运行时,应用程序可以编译并正常运行(在Windows cmd窗口中)。 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: 但是,当我封装类并尝试在同一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$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: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. 有趣的是,令人讨厌的LogFactory似乎位于commons-logging-1.1.jar中,该文件位于指定的类路径中。 The jar file (yep, it's really there): 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$1.class
org/apache/commons/logging/LogFactory$2.class
org/apache/commons/logging/LogFactory$3.class
org/apache/commons/logging/LogFactory$4.class
org/apache/commons/logging/LogFactory$5.class
org/apache/commons/logging/LogFactory.class
... (more classes in commons-logging-1.1 ...)

Yep, commons-logging has the LogFactory class. 是的,commons-logging具有LogFactory类。 And finally, the contents of my jar's manifest: 最后,我罐子清单的内容:

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 (eg: tools for creating exe's or packaging up jars). 只是为了找出答案,至少在目前,第三方的解决方案可能由于许可限制和公司政策(例如:用于创建exe或打包jar的工具)而退出。 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). 最终目标是创建一个jar,该jar可以从我的开发Windows盒中复制到Linux服务器(带有任何依赖的jar),并用于填充数据库(因此,开发和部署环境之间的类路径可能有所不同)。 Any clues to this mystery would be greatly appreciated! 任何有关此谜的线索将不胜感激!

The -jar option is mutually exclusive of -classpath. -jar选项与-classpath互斥。 See an old description here 在这里查看旧说明

-jar -罐

Execute a program encapsulated in a JAR file. 执行封装在JAR文件中的程序。 The first argument is the name of a JAR file instead of a startup class name. 第一个参数是JAR文件的名称,而不是启动类的名称。 In order for this option to work, the manifest of the JAR file must contain a line of the form Main-Class: classname. 为了使此选项起作用,JAR文件的清单必须包含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. 在这里,类名标识具有公共静态void main(String [] args)方法的类,该方法用作应用程序的起点。

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. 有关使用Jar文件和Jar文件清单的信息,请参见Jar工具参考页和Java教程的Jar线索。

When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored. 使用此选项时,JAR文件是所有用户类的源,而其他用户类路径设置将被忽略。

A quick and dirty hack is to append your classpath to the bootstrap classpath: 一个快速而肮脏的技巧是将您的类路径附加到引导类路径中:

-Xbootclasspath/a: path -Xbootclasspath / a: 路径

Specify a colon-separated path of directires, JAR archives, and ZIP archives to append to the default bootstrap class path. 指定目录,JAR归档文件和ZIP归档文件的以冒号分隔的路径,以追加到默认引导程序类路径。

However, as @Dan rightly says, the correct solution is to ensure your JARs Manifest contains the classpath for all JARs it will need. 但是,正如@Dan正确说的那样,正确的解决方案是确保您的JAR清单包含它将需要的所有JAR的类路径。

您可以省略-jar选项,然后像下面那样启动jar文件:

java -cp MyJar.jar;C:\\externalJars\\* mainpackage.MyMainClass

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". 如果从“ C:\\ java \\ apps \\ appli.jar”加载了JAR文件,并且清单文件具有Class-Path:引用“ lib / other.jar”,则类加载器将在“ C:\\ java”中查找\\ apps \\ lib \\“表示“ 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文件夹”,然后在其中选择“可运行的JAR文件”而不是“ 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). 选择适当的选项,然后在“库处理”部分中选择第三个选项,即(将所需的库复制到生成的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 =第3个选项除了jar以外,还会生成一个文件夹,第2个选项(“将所需的库打包到生成的JAR中”)也可以在您拥有jar时使用。 ] ]

  1. 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的文件夹中创建。
  2. 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 for you too!!! 这对我有用...希望它也对您有用!!!

if you use external libraries in your program and you try to pack all together in a jar file it's not that simple, because of classpath issues etc. 如果您在程序中使用外部库,并且由于类路径问题等原因,尝试将所有内容打包到一个jar文件中,就不是那么简单。

I'd prefer to use OneJar for this issue. 我更喜欢使用OneJar来解决此问题。

i had the same problem with my jar the solution 我的罐子有相同的问题解决方案

  1. Create the MANIFEST.MF file: 创建MANIFEST.MF文件:

Manifest-Version: 1.0 清单版本:1.0

Sealed: true 密封:真实

Class-Path: . 类路径:。 lib/jarX1.jar lib/jarX2.jar lib/jarX3.jar lib / jarX1.jar lib / jarX2.jar lib / jarX3.jar

Main-Class: com.MainClass 主类:com.MainClass

  1. Right click on project, Select Export. 右键单击项目,选择“导出”。

select export all outpout folders for checked project 选择导出所有输出文件夹以检查项目

  1. select using existing manifest from workspace and select the MANIFEST.MF file 从工作空间中选择使用现有清单,然后选择MANIFEST.MF文件

This worked for me :) 这对我有用:)

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 eg "required_lib/sun/pop3.jar required_lib/sun/smtp.jar ". 我发现在使用清单时,列出每个类的jar后需要在类路径的jar列表中留一个空格,例如“ required_lib / sun / pop3.jar required_lib / sun / smtp.jar”。 Even if it is the last in the list. 即使它是列表中的最后一个。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM