我有一个包含内容($ unzip -l output.jar
)的jar文件:
Archive: output.jar
Length Date Time Name
--------- ---------- ----- ----
0 2013-07-08 17:57 META-INF/
120 2013-07-08 17:57 META-INF/MANIFEST.MF
0 2013-07-08 17:43 some/
0 2013-07-08 17:43 some/package/
1247 2013-07-08 17:57 some/package/Main.class
2032 2013-07-08 17:57 some/package/plsql_o12_lexer$DFA22.class
8022 2013-07-08 17:57 some/package/plsql_o12_lexer$DFA23.class
212573 2013-07-08 17:57 some/package/plsql_o12_lexer.class
--------- -------
223994 11 files
META-INF/MANIFEST.MF
的内容是:
Manifest-Version: 1.0
Created-By: 1.6.0_27 (Sun Microsystems Inc.)
Main-Class: some.package.Main
但是,运行命令$ echo $CLASSPATH; java -jar output.jar
。请注意CLASSPATH变量已设置。
/usr/share/java/antlr3-runtime-3.2.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/antlr/runtime/CharStream
Caused by: java.lang.ClassNotFoundException: org.antlr.runtime.CharStream
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
Could not find the main class: some.package.Main. Program will exit.
运行命令$ java -classpath /usr/share/java/antlr3-runtime-3.2.jar -jar output.jar
会产生完全相同的结果。我也尝试.:/usr/share/java/antlr3-runtime-3.2.jar
和.:./output.jar:/usr/share/java/antlr3-runtime-3.2.jar
作为类路径,结果相同。文件antlr3-runtime-3.2.jar
包含类org.antlr.runtime.CharStream
,我已检查过。
但是,运行java -verbose -jar output.jar
会得到包含以下行的结果:
[Loaded some.package.Main from file:/home/jan/projects/antlr-plsql/output.jar]
我的java是:
java version "1.6.0_27"
OpenJDK Runtime Environment (IcedTea6 1.12.5) (6b27-1.12.5-0ubuntu0.12.04.1)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
为什么Java不按照预期的方式工作?
答案 0 :(得分:5)
如果根据doc使用-jar开关,则忽略其他类路径设置。
答案 1 :(得分:4)
将JAR添加到Class-Path
的{{1}}条目,或将两个JAR添加到CLASSPATH变量中,不要使用MANIFEST.MF
标记。
答案 2 :(得分:0)
我也有这个问题。我最终想出了如何规避这个问题。所以,以下内容并不是直接解决您问题的答案,但它可能对您有用。
我编写了一个脚本,可以将代码编译(而不仅仅是运行)到jar文件中。它看起来像这样(在unix上):
rm filelist
find foldername | grep .java >> filelist
javac -classpath .:/path/external.jar -d ../bin @filelist
然后,在我想运行我的jar文件的目录中,我也有external.jar:
russell@ubuntu:$ ls
external.jar myfile.jar
到目前为止似乎有效。