我有一个应用程序,我正在尝试将其包装到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.(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文件(是的,它确实存在):
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
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 ...)
是的,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
这让我感到难过,而且我现在已经超过一天的任何同事了.只是为了剔除答案,至少现在,由于许可限制和公司政策(例如:创建exe或打包罐子的工具),第三方解决方案可能已经解决了.最终目标是创建一个可以从我的开发Windows框复制到Linux服务器(带有任何依赖的jar)的jar,并用于填充数据库(因此类路径可能会在开发和部署环境之间变得不同).任何关于这个谜团的线索将不胜感激!
-jar选项与-classpath互斥.请在此处查看旧说明
-罐
执行封装在JAR文件中的程序.第一个参数是JAR文件的名称而不是启动类名称.为了使此选项起作用,JAR文件的清单必须包含Main-Class:classname形式的一行.这里,classname标识具有public static void main(String [] args)方法的类,该方法充当应用程序的起点.
有关使用Jar文件和Jar文件清单的信息,请参阅Jar工具参考页面和Java Tutorial的Jar跟踪.
使用此选项时,JAR文件是所有用户类的源,并忽略其他用户类路径设置.
快速而肮脏的黑客是将类路径附加到引导类路径:
-Xbootclasspath/a:path
指定以冒号分隔的directires,JAR存档和ZIP存档路径,以附加到默认引导类路径.
但是,正如@Dan正确地说的那样,正确的解决方案是确保您的JAR Manifest包含所需的所有JAR的类路径.
您可以省略该-jar
选项并启动jar文件,如下所示:
java -cp MyJar.jar;C:\externalJars\* mainpackage.MyMainClass
这是正在发生的问题,
如果JAR文件是从"C:\ java\apps\appli.jar"加载的,并且您的清单文件具有Class-Path:引用"lib/other.jar",则类加载器将查看"C:\ java"\apps\lib \"for"other.jar".它不会查看JAR文件条目"lib/other.jar".
解:-
右键单击项目,选择"导出".
选择Java Folder并在其中选择Runnable JAR File而不是JAR文件.
选择正确的选项,然后在Library Handling部分中选择第3个选项,即(将所需的库复制到生成的JAR旁边的子文件夹中).
[ EDIT = 3rd选项除了jar之外还生成一个文件夹,第二个选项("将所需的包打包到生成的JAR中")也可以用作jar.]
单击"完成",将在指定位置创建JAR以及包含清单文件中提到的JARS的文件夹.
打开终端,给你的jar正确的路径并使用这个命令java -jar abc.jar运行它
现在将会发生的事情是类加载器将在引用的JARS的正确文件夹中查找,因为现在它们存在于包含应用程序JAR的同一文件夹中.现在没有抛出"java.lang.NoClassDefFoundError"异常.
这对我有用...希望它也适合你!