有没有办法在类路径中的目录中包含所有 jar 文件?
我正在尝试java -classpath lib/*.jar:. my.package.Program
,它无法找到肯定在这些 jar 中的类文件。我是否需要将每个 jar 文件分别添加到类路径中?
使用 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/*
只在foo
查找 JAR 文件,而不是在foo/bar
,foo/baz
等中查找。未指定在扩展类路径中枚举目录中的 JAR 文件的顺序,并且可能因平台而异,甚至在同一台机器上不时。构造良好的应用程序不应该依赖于任何特定的顺序。如果需要特定顺序,则可以在类路径中显式枚举 JAR 文件。
在类加载过程本身期间,在调用程序的 main 方法之前,而不是迟到,扩展通配符是在早期完成的。包含通配符的输入类路径的每个元素都由枚举命名目录中的 JAR 文件生成的(可能为空)元素序列替换。例如,如果目录
foo
包含a.jar
,b.jar
和c.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
在 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
分隔符是冒号而不是分号。
我们通过部署一个主 jar 文件myapp.jar
解决了这个问题,该文件包含一个清单 ( Manifest.mf
)文件,该文件指定了带有其他所需 jar 的类路径,然后将其部署在其中。在这种情况下,您只需在运行代码时声明java -jar myapp.jar
。
因此,如果您将主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 上启动。