我正在尝试从命令行构建一个可执行jar(我不想使用ant或OneJar)。这是我的file.jar的内容:
jar tvf file.jar
0 Mon Sep 20 17:16:12 CEST 2010 lib/
45396 Mon Sep 20 17:16:12 CEST 2010 lib/org.apache.commons.logging_1.0.4.v201005080501.jar
321330 Mon Sep 20 17:16:12 CEST 2010 lib/org.apache.commons.httpclient_3.1.0.v201005080502.jar
55003 Mon Sep 20 17:16:12 CEST 2010 lib/org.apache.commons.codec_1.3.0.v20100518-1140.jar
0 Mon Sep 20 19:15:00 CEST 2010 META-INF/
265 Mon Sep 20 19:12:44 CEST 2010 META-INF/MANIFEST.MF
530609 Mon Sep 20 17:16:12 CEST 2010 ped.jar
META-INF / MANIFEST.MF的内容:
Manifest-Version: 1.0
Class-Path: ped.jar lib/org.apache.commons.codec_1.3.0.v20100518-1140.jar lib/org.apache.commons.httpclient_3.1.0.v201005080502.jar lib/org.apache.commons.logging_1.0.4.v201005080501.jar
Main-Class: fr.inserm.umr915.bomcat.ped.PedigreeDrawer
并且ped.jar包含Main-Class
jar tvf ped.jar | grep PedigreeDrawer.class
39541 Mon Sep 20 17:16:10 CEST 2010 fr/inserm/umr915/bomcat/ped/PedigreeDrawer.class
但是当我尝试执行file.jar时,我收到了一个错误:
java -jar file.jar
Exception in thread "main" java.lang.NoClassDefFoundError: fr/inserm/umr915/bomcat/ped/PedigreeDrawer
Caused by: java.lang.ClassNotFoundException: fr.inserm.umr915.bomcat.ped.PedigreeDrawer
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
所以,我在这里遗漏了一些东西。我不能通过包含依赖项来打包可执行jar吗?
感谢您的帮助
皮尔
答案 0 :(得分:1)
什么是 file.jar ?
您可以尝试像这样设置类路径:
Class-Path: lib/org.apache.commons.codec_1.3.0.v20100518-1140.jar lib/org.apache.commons.httpclient_3.1.0.v201005080502.jar lib/org.apache.commons.logging_1.0.4.v201005080501.jar
并像这样运行你的jar文件:
java -jar ped.jar
答案 1 :(得分:1)
文件manifest.mf
中的“类路径”值指定了您的类路径,就像您在没有-jar
但具有-classpath lib/...
参数的情况下启动应用程序一样。 pathes在本地解释,而不是在jar文件中。
另一种方法是使用one-jar或使用特殊的类加载器来查看外部jar文件中包含的jar文件。
使用JCL,您可以直接从嵌入式jar中加载您的类,如下所示:
JarClassLoader jcl=new JarClassLoader();
jcl.add("myjar.jar"); // Add some class source
jcl.getSystemLoader().setOrder(1); // Look in system class loader first
jcl.getLocalLoader().setOrder(2); // if not found look in local class loader
jcl.getParentLoader().setOrder(3); // if not found look in parent class loader
jcl.getThreadLoader().setOrder(4); // if not found look in thread context class loader
jcl.getCurrentLoader().setOrder(5); // if not found look in current class loader
// A custom class loader that extends org.xeustechnologies.jcl.ProxyClassLoader
MyLoader loader=new MyLoader();
loader.setOrder(6);
jcl.addLoader(loader); //Add custom loader
但是你必须将jcl添加到你的类路径中......或者在你的jar中添加一个爆炸的jcl。
答案 2 :(得分:1)
如果没有特殊包装(例如OneJar等),您不能在Jar内包含Jar。
如果您真的不想使用OneJar(或其他类似工具),则需要在可分发中包含多个Jar文件。
答案 3 :(得分:1)
如前所述,Class-Path:
属性中的jar相对于jar文件的loaction而不是jar文件中的jar。这可能是Java用于运行applet的日子里的残余。
你需要使用像maven uberjar这样的工具在一个jar中一起破解所有需要的类,以创建一个独立的可执行jar。
当然,您也可以将所有jar解压缩到一个目录中,如果您绝对不想使用工具,请添加META-INF并清单并再次压缩所有内容。
答案 4 :(得分:0)
OneJar旨在解决这类问题。您可以编写自定义类加载器以达到同样的效果。