将目录中的所有Jar包包含在Java类路径中

1177

有没有一种方法可以在类路径中包含目录内的所有jar文件?

我正在尝试使用java -classpath lib/*.jar:. my.package.Program,但它无法找到肯定在这些jar文件中的类文件。我需要单独将每个jar文件添加到类路径中吗?


4
抱歉,我从未接受过这个。应该是一个社区维护的Wiki页面。我从未使用过提供的任何答案。我相信我创建了一个Shell脚本,只需扫描lib/目录并通过解析文件名来创建类路径。 - Chris Serra
这个新的Java特性存在某种错误,因为它不能按照描述的那样工作。我放弃了并使用Ant来解决它,正如其中一个答案所描述的那样。 - Alex R
1
Windows中通配符处理存在问题。 http://stackoverflow.com/questions/11607873/escape-wildcard-processing-in-java-classpath/11608165#comment15368871_11608165 - Mike
起初我以为 jar: 后面的 . 是错误的,但是...... 在 Unix 和 Windows 系统中,“当前目录”的标准符号是一个单点 (.)。 - KNU
8
简短回答:(1)去掉“.jar”这一部分,(2)在Windows上必须至少有两个部分,用“;”分隔(在其他地方通常是“:”)。例如: java -classpath ".;lib/*" Program - Evgeni Sergeev
非常抱歉,由于这是一个热门问题,我无法提出自己的问题,因此我正在寻求Java专家回答在此处flag create与create new之间的区别。https://github.com/frohoff/jdk8u-jdk/blob/master/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java - Sagar Kharab
25个回答

10
如果您真的需要动态指定所有的 .jar 文件,您可以使用 shell 脚本或 Apache Ant。有一个名为 Commons Launcher 的共同项目,它基本上允许您将启动脚本指定为 ant 构建文件(如果您明白我的意思的话)。
然后,您可以指定类似于:
<path id="base.class.path">
    <pathelement path="${resources.dir}"/>
    <fileset dir="${extensions.dir}" includes="*.jar" />
    <fileset dir="${lib.dir}" includes="*.jar"/>
</path>

在你的启动构建文件中,它将使用正确的类路径启动你的应用程序。

9

敬启者:

我在MSYS/MinGW shell下的Windows系统中发现了一种奇怪的行为。

正常工作:

$ 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

9
请注意,在Windows上,Java 7的通配符展开功能存在问题。
有关更多信息,请查看此StackOverflow问题
解决方法是在通配符后面加上一个分号。 java -cp "somewhere/*;"

6
所有的解决方案都非常好,如果您在Eclipse或Netbeans等IDE之外开发和运行Java应用程序。
如果您正在使用Windows 7并使用Eclipse IDE进行Java开发,则在使用命令提示符运行Eclipse中生成的类文件时可能会遇到问题。
例如,Eclipse中的源代码具有以下包层次结构: edu.sjsu.myapp.Main.java
您将json.jar作为Main.java的外部依赖项。
当您尝试从Eclipse内运行Main.java时,它将无任何问题地运行。
但是,当您尝试在Eclipse中编译Main.java后使用命令提示符运行它时,它将弹出一些奇怪的错误,说"ClassNotDef Error blah blah"。
我假设您在源代码的工作目录中!!
请使用以下语法从命令提示符运行它:
1. javac -cp ".;json.jar" Main.java 2. java -cp ".;json.jar" edu.sjsu.myapp.Main [不要错过以上.]
这是因为您已将Main.java放在edu.sjsu.myapp包中,而java.exe将查找完全匹配的模式。
希望它有所帮助!

5

macOS,当前文件夹

对于在macOS Mojave上的Java 13...

如果您的所有.jar文件都在同一个文件夹中,请使用cd命令将其设置为您的当前工作目录。使用pwd命令进行验证。

对于-classpath参数,您必须首先列出应用程序所需的JAR文件。然后使用冒号字符:作为分隔符,在末尾添加星号*以获取同一文件夹中的所有其他JAR文件。最后,传递带有main方法的类的完整包名称。

例如,如果一个名为my_app.jar的JAR文件包含名为App的类中的main方法,并且该类位于名为com.example的包中,同时在同一文件夹中还需要一些JAR文件:

java -classpath my_app.jar:* com.example.App

4
简要概述:如果你的主程序在一个jar包中,你可能需要显式声明一个额外的“-jar pathTo/yourJar/YourJarsName.jar”才能使其正常工作(即使“YourJarsName.jar”已经在类路径上)。
长篇说明: (我已经将其明确到希望即使是对Java不熟悉的人也能使用)
和许多人一样,我正在使用Eclipse导出JAR文件:(文件->导出->'Runnable 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中的本地代码会受到“jarinjar”技巧的影响,因为当您选择该选项时,它会破坏eclipse。即使在意识到我需要opt3之后,并找到了这个StackOverflow条目,仍然花费了一些时间来弄清楚如何在eclipse之外启动我的主要程序,所以对于其他人来说,这是对我有用的,以下是我使用的方法...

如果你将你的jar文件命名为:“fooBarTheJarFile.jar”,并且所有东西都设置为导出到目录:“/theFully/qualifiedPath/toYourChosenDir”。

(意味着“导出目标”字段将显示为:'/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar')

完成后,您会发现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.your_main'是在包含您希望从Java外部运行的'main(String[] args){...}'的'TheClassWithYourMain.java'文件顶部找到的声明的包路径)
注意要点:需要注意的陷阱是,在已声明的类路径列表中有'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   
< p >(使用Java版本“1.6.0_27”;通过Ubuntu 12.04上的OpenJDK 64位服务器VM)< / p >

4

对于Windows系统,需要加上引号并使用分号作为分隔符。例如:

java -cp "target\\*;target\\dependency\\*" my.package.Main

3

从webapp中导入的类:

  > mvn clean install

  > java -cp "webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/tool-jar-1.17.0-SNAPSHOT.jar;webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/*" com.xx.xx.util.EncryptorUtils param1 param2

3
我知道的唯一方法是逐个处理,例如:
setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:.

希望这能帮到你!

这可能是在'08年的唯一方式,但现在不再是了。 - simo.3792
这不是最糟糕的事情。虽然有点取巧,但我已经在我的bashrc中设置了这个:for jar in $(ls $HOME/bin/*.jar); do export CLASSPATH=$jar:$CLASSPATH; done - Devon Peticolas

3

您需要分别添加它们。或者,如果您确实只需指定一个目录,则可以将所有内容解压缩到一个目录中,并将其添加到类路径中。但我不建议使用这种方法,因为您会冒着类路径版本和无法管理的奇怪问题的风险。


3
也许在'08年这是唯一的方法,但现在不再是了。 - simo.3792

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接