是否有一种方法将所有jar文件包含在类路径的目录中?

我正在尝试java -classpath lib/*.jar:。program,它不能找到在这些罐子里的类文件。我是否需要将每个jar文件分别添加到类路径中?


当前回答

我知道的唯一方法是单独做,例如:

setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:.

希望有帮助!

其他回答

简写形式:如果你的main在一个jar中,你可能需要一个额外的“-jar pathTo/yourJar/YourJarsName.jar”显式声明来让它工作(即使“YourJarsName.jar”在类路径中) (或者,回答5年前提出的原始问题:你不需要显式地重新声明每个jar,但看起来,即使在java6中,你也需要重新声明自己的jar…)


长形式: (我已经明确说明了这一点,我希望即使是java的闯入者也可以使用它)

像这里的许多人一样,我使用eclipse导出JAR:(File-> export ->'可运行的JAR文件')。eclipse (Juno)提供了三个“库处理”选项:

opt1: "Extract required libraries into generated JAR"
opt2: "Package required libraries into generated JAR"
opt3: "Copy required libraries into a sub-folder next to the generated JAR"

通常我会使用opt2 (opt1肯定会破坏),但是我正在使用的一个jar中的本机代码,当您选择该选项时,我发现eclipse利用了方便的“jarinjar”技巧。即使在意识到我需要opt3之后,然后找到这个StackOverflow条目,我仍然花了一些时间来弄清楚如何在eclipse之外启动我的main,所以这里是对我有用的,因为它对其他人很有用……


如果你将罐子命名为fooBarTheJarFile.jar 和所有设置导出到目录:“/theFully/qualifiedPath/toYourChosenDir”。

(意味着“导出目的地”字段将读取:“/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar”)

当你点击finish后,你会发现eclipse将所有的库放在一个名为“fooBarTheJarFile_lib”的文件夹中,就像这样:

/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar01.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar02.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar03.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar04.jar

然后,您可以从系统上的任何地方启动:

java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" -jar  /theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar   package.path_to.the_class_with.your_main.TheClassWithYourMain

(对于Java新手来说:` package.path_to.the_class_with. path `。your_main'是声明的包路径,你可以在' classwithyourmain .java'文件的顶部找到,该文件包含'main(String[] args){…}'你希望在java之外运行)


要注意的陷阱:在你声明的类路径上的jar列表中有'fooBarTheJarFile.jar'是不够的。您需要显式地声明'-jar',并重新声明该jar的位置。

例如:

 java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar;/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*"  somepackages.inside.yourJar.leadingToTheMain.TheClassWithYourMain

用相对路径重申:

cd /theFully/qualifiedPath/toYourChosenDir/;
BREAKS:  java -cp "fooBarTheJarFile_lib/*"                                package.path_to.the_class_with.your_main.TheClassWithYourMain    
BREAKS:  java -cp ".;fooBarTheJarFile_lib/*"                              package.path_to.the_class_with.your_main.TheClassWithYourMain   
BREAKS:  java -cp ".;fooBarTheJarFile_lib/*"   -jar                       package.path_to.the_class_with.your_main.TheClassWithYourMain   
WORKS:   java -cp ".;fooBarTheJarFile_lib/*"   -jar  fooBarTheJarFile.jar package.path_to.the_class_with.your_main.TheClassWithYourMain   

(使用Java版本“1.6.0_27”;通过OpenJDK 64位服务器虚拟机安装在ubuntu 12.04上)

使用Java 6或更高版本,类路径选项支持通配符。注意事项:

使用直引号(") 使用*,而不是*.jar

窗户

lib/*" my.package.MainClass . java -cp "Test.jar

Unix

java -cp "Test.jar:lib/*" my.package.MainClass .jar:lib/*

这类似于Windows,但使用:而不是;。如果你不能使用通配符,bash允许以下语法(其中lib是包含所有Java存档文件的目录):

Java -cp "$(printf %s: lib/*.jar)"

(注意,使用类路径与-jar选项不兼容。参见:从命令提示符执行带有多个类路径库的jar文件)

理解通配符

从类路径文档中:

Class path entries can contain the basename wildcard character *, which is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR. For example, the class path entry foo/* specifies all JAR files in the directory named foo. A classpath entry consisting simply of * expands to a list of all the jar files in the current directory. A class path entry that contains * will not match class files. To match both classes and JAR files in a single directory foo, use either foo;foo/* or foo/*;foo. The order chosen determines whether the classes and resources in foo are loaded before JAR files in foo, or vice versa. Subdirectories are not searched recursively. For example, foo/* looks for JAR files only in foo, not in foo/bar, foo/baz, etc. The order in which the JAR files in a directory are enumerated in the expanded class path is not specified and may vary from platform to platform and even from moment to moment on the same machine. A well-constructed application should not depend upon any particular order. If a specific order is required then the JAR files can be enumerated explicitly in the class path. Expansion of wildcards is done early, prior to the invocation of a program's main method, rather than late, during the class-loading process itself. Each element of the input class path containing a wildcard is replaced by the (possibly empty) sequence of elements generated by enumerating the JAR files in the named directory. For example, if the directory foo contains a.jar, b.jar, and c.jar, then the class path foo/* is expanded into foo/a.jar;foo/b.jar;foo/c.jar, and that string would be the value of the system property java.class.path. The CLASSPATH environment variable is not treated any differently from the -classpath (or -cp) command-line option. That is, wildcards are honored in all these cases. However, class path wildcards are not honored in the Class-Path jar-manifest header.

注意:由于java 8中的一个已知错误,windows示例必须在条目前使用反斜杠,后面带星号:https://bugs.openjdk.java.net/browse/JDK-8131329

致相关人士:

我在Windows MSYS/MinGW shell下发现了这种奇怪的行为。

工作原理:

$ javac -cp '.;c:\Programs\COMSOL44\plugins\*' Reclaim.java

不工作:

$ javac -cp 'c:\Programs\COMSOL44\plugins\*' Reclaim.java
javac: invalid flag: c:\Programs\COMSOL44\plugins\com.comsol.aco_1.0.0.jar
Usage: javac <options> <source files>
use -help for a list of possible options

我很确定通配符没有被shell扩展,因为例如。

$ echo './*'
./*

(我也用另一个程序试过,而不是内置的echo,结果是一样的。)

我相信是javac试图展开它,无论参数中是否有分号,它的行为都是不同的。首先,它可能试图展开所有看起来像路径的参数。只有这样,它才会解析它们,-cp只接受以下标记。(注意com.comsol.aco_1.0.0.jar是该目录中的第二个JAR。)这都是猜测。

这是

$ javac -version
javac 1.7.0

你可以试试java -Djava.ext.dirs=jarDirectory http://docs.oracle.com/javase/6/docs/technotes/guides/extensions/spec.html

运行java时用于外部jar的目录

如果您在Eclipse或Netbeans等任何IDE之外开发和运行Java应用程序,以上所有解决方案都非常有效。

如果您在Windows 7上使用Eclipse IDE for Development in Java,那么如果使用命令提示符运行Eclipse内部构建的类文件,可能会遇到问题。

例如,你在Eclipse中的源代码具有以下包层次结构: edu.sjsu.myapp.Main.java

json.jar是Main.java的外部依赖项

当您尝试从Eclipse中运行Main.java时,它将毫无问题地运行。

但是当你在Eclipse中编译Main.java后尝试使用命令提示符运行这个命令时,它会抛出一些奇怪的错误,比如“ClassNotDef Error blah blah”。

我假设你在源代码的工作目录中!!

使用下面的语法从命令提示符运行它:

json.jar" Main.java .jar" java -cp ".;json.jar" edu.sjsu.myapp.Main 不要错过。以上)

这是因为您已经将Main.java放在包edu.sjsu.myapp中,java.exe将查找确切的模式。

希望能有所帮助!!