尝试使用 java.exe -jar 运行我的 jar 时出现 NoClassDefFoundError ......出了什么问题? [英] NoClassDefFoundError while trying to run my jar with java.exe -jar...what's wrong?

查看:17
本文介绍了尝试使用 java.exe -jar 运行我的 jar 时出现 NoClassDefFoundError ......出了什么问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,我正尝试将其包装到 jar 中以便于部署.当作为一组可从 CLASSPATH 访问的类运行时,应用程序编译并正常运行(在 Windows cmd 窗口中).但是当我打开我的类并尝试在同一个 cmd 窗口中使用 java 1.6 运行它时,我开始收到异常:

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:

C:devmyappsrccommondatagen>C:/apps/jdk1.6.0_07/bin/java.exe -classpath C:myapplibscommons -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

有趣的是,有问题的 LogFactory 似乎在 commons-logging-1.1.jar 中,它位于指定的类路径中.jar 文件(是的,它确实存在):

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):

C:devmyappsrccommondatagen>dir C:myapplibscommons-logging-1.1.jar
 Volume in drive C is Local Disk
 Volume Serial Number is ECCD-A6A7

 Directory of C:myapplibs

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

commons-logging-1.1.jar文件的内容:

The contents of the commons-logging-1.1.jar file:

C:devmyappsrccommondatagen>jar -tf C:myapplibscommons-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 ...)

是的,commons-logging 有 LogFactory 类.最后,我的 jar 清单的内容:

Yep, commons-logging has the LogFactory class. 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

这让我和我已经烦扰了一天多的所有同事都难住了.只是为了挑选答案,至少现在,由于许可限制和公司政策(例如:用于创建 exe 或打包 jar 的工具),第三方解决方案可能已经过时了.最终目标是创建一个 jar,它可以从我的开发 Windows 机器复制到 Linux 服务器(带有任何依赖的 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!

推荐答案

-jar 选项与 -classpath 是互斥的.在此处

The -jar option is mutually exclusive of -classpath. See an old description here

-jar

执行封装在 JAR 文件中的程序.第一个参数是 JAR 文件的名称,而不是启动类名称.为了使这个选项起作用,JAR 文件的清单必须包含一行 Main-Class: classname 形式.此处,classname 标识具有 public static void main(String[] args) 方法的类,该方法用作应用程序的起点.

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.

有关使用 Jar 文件和 Jar 文件清单的信息,请参阅 Jar 工具参考页面和 Java 教程的 Jar 跟踪.

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 文件是所有用户类的来源,其他用户类路径设置将被忽略.

一个快速而肮脏的黑客是将你的类路径附加到引导类路径:

A quick and dirty hack is to append your classpath to the bootstrap classpath:

-Xbootclasspath/a:路径

-Xbootclasspath/a:path

指定以冒号分隔的目录、JAR 档案和 ZIP 档案的路径以附加到默认引导程序类路径.

Specify a colon-separated path of directires, JAR archives, and ZIP archives to append to the default bootstrap class path.

然而,正如 @Dan 所说的那样,正确的解决方案是确保您的 JAR 清单包含用于它需要的所有 JAR.

However, as @Dan rightly says, the correct solution is to ensure your JARs Manifest contains the classpath for all JARs it will need.

这篇关于尝试使用 java.exe -jar 运行我的 jar 时出现 NoClassDefFoundError ......出了什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆