2013-07-08 24 views
3

加载类我有内容($ unzip -l output.jar)一个jar文件:的META-INF/MANIFEST.MF的Java无法从CLASSPATH

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 

内容是:

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的工作是应该的方式?

回答

5

如果按照doc使用-jar开关,则会忽略其他类路径设置。

4

将JAR添加到MANIFEST.MFClass-Path条目中,或将两个JAR添加到CLASSPATH变量中,但不要使用-jar标志。

+0

因此,我应该添加到我的CLASSPATH每一个我想永远执行的JAR?真? – Honza

+0

不,你通常从shell脚本中为每个应用程序设置CLASSPATH,或者将必要的JAR添加到应用程序的'MANIFEST.MF'中。 – davidfmatheson

+0

另一种方法是构建一个包含所有依赖关系的胖jar包。 – Hiro2k

0

我也有这个问题。我终于想出了如何规避这个问题。所以,下面的答案不是直接解决你的问题的答案,但它可能适用于你。

我写了一个脚本,可以将代码编译(不只是运行)到jar文件中。它看起来是这样的(在UNIX上):

rm filelist 
find foldername | grep .java >> filelist 
javac -classpath .:/path/external.jar -d ../bin @filelist 

然后,在目录中,我想我的运行jar文件,我有external.jar有作为:

[email protected]:$ ls 
external.jar myfile.jar 

这似乎到目前为止工作。

+0

已经发布了所有内容,我认为David的答案是需要完成的简短版本。 –