协慌网

登录 贡献 社区

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

有没有办法在类路径中的目录中包含所有 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/barfoo/baz等中查找。

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

在类加载过程本身期间,在调用程序的 main 方法之前,而不是迟到,扩展通配符是在早期完成的。包含通配符的输入类路径的每个元素都由枚举命名目录中的 JAR 文件生成的(可能为空)元素序列替换。例如,如果目录foo包含a.jarb.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

在 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 上启动。