当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《将所有jar包含在Java类路径中的目录中》经验,为你挑选了14个好方法。

有没有办法在类路径中的目录中包含所有jar文件?

我正在尝试java -classpath lib/*.jar:. my.package.Program,它无法找到肯定在那些罐子里的类文件.我是否需要将每个jar文件分别添加到类路径中?



1> basszero..:

使用Java 6或更高版本,classpath选项支持通配符.请注意以下事项:

使用直引号(")

使用*,而不是*.jar

视窗

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

Unix的

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

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

java -cp $(echo lib/*.jar | tr ' ' ':')

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

了解通配符

从Classpath文档:

类路径条目可以包含基本名称通配符*,该字符被认为等同于指定具有扩展名.jar或目录的目录中的所有文件的列表.JAR.例如,类路径条目foo/*指定名为foo的目录中的所有JAR文件.一个只包含的类路径条目*扩展为当前目录中所有jar文件的列表.

包含的类路径条目*与类文件不匹配.要在单个目录foo中匹配类和JAR文件,请使用 foo;foo/*foo/*;foo.选择的顺序确定是否foo在JAR文件之前加载类和资源,foo反之亦然.

不会递归搜索子目录.例如,foo/*仅在查找JAR文件foo,而不是在foo/bar,foo/baz

未指定在扩展类路径中枚举目录中的JAR文件的顺序,并且可能因平台而异,甚至在同一台机器上不时.构造良好的应用程序不应该依赖于任何特定的顺序.如果需要特定顺序,则可以在类路径中显式枚举JAR文件.

在类加载过程本身期间,在调用程序的main方法之前,而不是迟到,扩展通配符是在早期完成的.包含通配符的输入类路径的每个元素都由枚举命名目录中的JAR文件生成的(可能为空)元素序列替换.例如,如果目录foo包含a.jar,b.jarc.jar,则将类路径foo/*扩展为foo/a.jar;foo/b.jar;foo/c.jar,并且该字符串将是系统属性的值 java.class.path.

CLASSPATH环境变量未从处理过的任何不同的-classpath(或-cp)的命令行选项.也就是说,在所有这些情况下,通配符都很荣幸.但是,Class-Path jar-manifest标题中不支持类路径通配符.

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


也不要在-cp中使用`~`
该特征记录很少,并且似乎需要满足一些不太明显的前提条件才能按预期工作.

2> davorp..:

在Windows下,这工作:

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

这不起作用:

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

注意*.jar,所以*通配符应该单独使用.


在Linux上,以下工作:

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

分隔符是冒号而不是分号.


完美的答案.需要注意的两件重要事项:1)使用引号和2)仅使用*,而不是*.jar
一年零8个月之后,我所做的编辑包括UNIX版本再次保存了我.:)有趣的是如何用`*.jar`识别我的jar文件,但只能用`*`.
第三个例子适用于Linux(Ubuntu 12.04 LTS).

3> oxbow_lakes..:

我们通过部署一个 jar文件解决了这个问题,该文件myapp.jar包含一个manifest(Manifest.mf)文件,该文件指定了一个带有其他所需jar的类路径,然后将其与它一起部署.在这种情况下,您只需要java -jar myapp.jar在运行代码时声明.

因此,如果将main部署jar到某个目录中,然后将依赖的jar放入其lib下的文件夹中,则清单如下所示:

Manifest-Version: 1.0
Implementation-Title: myapp
Implementation-Version: 1.0.1
Class-Path: lib/dep1.jar lib/dep2.jar

注意:这是独立于平台的 - 我们可以使用相同的jar在UNIX服务器或Windows PC上启动.


oxbow_lakes的答案并不完全正确; 如果你用java -jar myapp.jar启动这个jar,那么Class-Path的东西很荣幸(并且只有被尊重; -cp/-classpath被忽略!).我认为oxbow_lakes的意思是当他写'java -classpath myapp.jar'时写的.

4> Habi..:

我的解决方案在Ubuntu 10.04上使用java-sun 1.6.0_24,所有jar都在"lib"目录中:

java -cp .:lib/* my.main.Class

如果失败,则以下命令应该有效(将lib目录中的所有*.jars打印到classpath参数)

java -cp $(for i in lib/*.jar ; do echo -n $i: ; done). my.main.Class


一个有趣的笔记.java -cp lib/*my.main.Class总是失败因为lib/*的shell glob扩展,而java -cp.:lib/*my.main.Class不会因为.:lib/*不是有效的glob路径.花点时间注意一下

5> Pops..:

简短回答: java -classpath lib/*:. my.package.Program

Oracle提供了有关在类路径中使用通配符的文档,这些通配符用于Java 6,此处用于Java 7,在标题" 理解类路径通配符 "一节中.(在我写这篇文章时,这两个页面包含相同的信息.)以下是重点摘要:

通常,要在给定目录中包含所有JAR,可以使用通配符*(不是 *.jar).

通配符仅匹配JAR,而不匹配类文件; 要获取目录中的所有类,只需在目录名称处结束类路径条目.

可以组合上述两个选项以包括目录中的所有JAR和类文件,并应用通常的类路径优先级规则.例如-cp /classes;/jars/*

通配符不会在子目录中搜索JAR.

如果使用CLASSPATH系统属性-cp-classpath命令行标志,则上述要点为true .但是,如果使用Class-PathJAR清单标头(就像使用ant构建文件一样),则不会遵循通配符.

是的,我的第一个链接与得分最高的答案中提供的链接相同(我没有超车的希望),但这个答案并没有提供超出链接的解释.由于这些天 Stack Upflow 不鼓励这种行为,我想我会扩展它.



6> SANN3..:

对我来说,这适用于Windows.

java -cp "/lib/*;" sample

对于Linux

java -cp "/lib/*:" sample

我使用的是Java 6



7> Wender..:

Windows:
java -cp file.jar; dir/*my.app.ClassName

Linux:
java -cp file.jar:dir/*my.app.ClassName

提醒:
- Windows路径分隔符是" ; "
- Linux路径分隔符是" : "
- 在Windows中,如果cp参数不包含空格,则"引号"是可选的



8> Navi..:

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

运行java时外部jar的目录


java.ext.dirs与classpath中的普通jar有很大的不同.它具有更高的优先级和权限,可以以某种方式覆盖bootstamp中的类(rt.jar)
这可行,但请注意,传递`-Djava.ext.dirs =`BEFORE` -jar`

9> rvernica..:

正确:

java -classpath "lib/*:." my.package.Program

不正确:

java -classpath "lib/a*.jar:." my.package.Program
java -classpath "lib/a*:."     my.package.Program
java -classpath "lib/*.jar:."  my.package.Program
java -classpath  lib/*:.       my.package.Program



10> 小智..:

如果您确实需要动态指定所有.jar文件,则可以使用shell脚本或Apache Ant.有一个名为Commons Launcher的公共项目,它基本上允许您将启动脚本指定为ant构建文件(如果您看到我的意思).

然后,您可以指定以下内容:


    
    
    

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



11> 小智..:

如果您使用的是Java 6,则可以在类路径中使用通配符.

现在可以在类路径定义中使用通配符:

javac -cp libs/* -verbose -encoding UTF-8 src/mypackage/*.java  -d build/classes

参考:http://www.rekk.de/bloggy/2008/add-all-jars-in-a-directory-to-classpath-with-java-se-6-using-wildcards/



12> Jake Toronto..:

请注意,Windows上的Java 7通配符扩展已中断.

有关更多信息,请查看此StackOverflow问题.

解决方法是在通配符后面加上分号. java -cp "somewhere/*;"



13> Evgeni Serge..:

敬启者,

我在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  
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



14> realPK..:

如果您在Eclipse或Netbeans之类的任何IDE之外开发和运行Java应用程序,那么上述所有解决方案都将非常有用。

如果您使用的是Windows 7并且使用Java的Eclipse IDE进行开发,则在使用命令提示符运行Eclipse内置的类文件时,可能会遇到问题。

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

您将json.jar作为Main.java的外部依赖项

当您尝试从Eclipse中运行Main.java时,它将正常运行。

但是,当您在Eclipse中编译Main.java之后尝试使用命令提示符运行此命令时,它将发出一些奇怪的错误,提示“ ClassNotDef错误等等”。

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

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

    javac -cp “。; json.jar” Main.java

    java -cp “。; json.jar” edu.sjsu.myapp.Main

    [不要错过。以上]

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

希望能帮助到你 !!

推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!