从命令行运行JAR文件并指定类路径

154

我已经编译了一个JAR文件,并在清单中指定了主类(我使用了Eclipse的Export功能)。 我的依赖项都在一个名为lib的目录中。 我似乎无法得到关于如何执行我的JAR文件并指定它应该使用lib/*作为类路径的直接答案。

我尝试过:

]$ java -jar -cp .:lib/* MyJar.jar
]$ java -cp .:lib/* -jar MyJar.jar
]$ java -cp .:lib/* com.somepackage.subpackage.Main

每个都会出现以下错误:

Error: Could not find or load main class ....

或者给出NoClassDefFoundError,表明找不到库。

我甚至尝试重新制作JAR文件并包括lib目录和内容,但仍然不起作用...

我该如何在命令行中执行JAR文件并指定要使用的类路径?


可能是从命令提示符执行具有多个类路径库的jar文件的重复问题。 - Adam Michalik
5个回答

262
当你指定了-jar参数时,-cp参数将被忽略。
根据文档使用此选项时,JAR文件是所有用户类的源,其他用户类路径设置将被忽略。 你也不能将需要的jar文件“包含”到另一个jar文件中(你需要提取它们的内容并将.class文件放入你的jar文件中)
你有两个选择:
1.将lib目录下的所有jar文件包含在清单中(你可以在那里使用相对路径)
2.在命令行上使用-cp指定所有东西(包括你的jar):
java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main

28
如果你在Windows系统上使用以下命令 java -cp MyJar.jar;lib/* com.somepackage.subpackage.Main,需改为使用冒号分隔路径:java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main。请注意,这是因为Windows和Unix系统在路径分隔符方面有所不同。 - Error
你也不能将所需的jar文件“包含”到另一个jar文件中。当然可以。如果是为了内部使用(即,您希望用户具有一定的技术能力等),您只需要求在尝试运行jar之前运行步骤1:“解压缩MyJar.jar lib / * .jar”。然后,就像您建议的那样,他们可以运行java -cp MyJar.jar:lib / * ... - Roger
4
遗憾的是,将“全包含”Uber jar与外部服务器特定属性文件的引用一起运行是一个常见的用例。显然不会阻塞程序,但如果您可以使用“-jar”而不必指定主要文件,那么这将是一个更简洁的命令。 - Andrew Norman
1
我花了一些时间才弄明白。而且需要大约6行代码来显式加载一个log4j文件。又是一个永远不会被修复的Java bug。 - Tuntable
3
请注意,manifest文件中的Class-Path只能用于加载jar文件,不能用于查找log4j3.xml等文件。这个意思是让我措手不及。 - Tuntable

49

运行一个jar文件并指定类路径,可以像这样:

java -cp <jar_name.jar:libs/*> com.test.App

jar_name.jar 是您要执行的 JAR 文件的完整名称。

libs/* 是您依赖的 JAR 文件的路径。

com.test.App 是 JAR 文件中具有 main(String[]) 方法的类的完全限定名。

JAR 文件和依赖的 JAR 文件应具有执行权限。


有时需要在类路径周围加上引号。例如,在我的 Mac 上,<java -cp test:test/lib/* org.Application> 不起作用,而 <java -cp "test:test/lib/*" org.Application> 起作用了。有什么想法,为什么会这样? - Abhishek Chatterjee
冒号?还是分号?其他答案使用的是分号... - john k
冒号?还是分号?其他答案使用的是分号... - undefined

16

你可以在Unix Shell中执行以下操作:

java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main

你可以在Windows PowerShell中执行以下操作:

java -cp "MyJar.jar;lib\*" com.somepackage.subpackage.Main

6

如果您愿意的话,可以使用清单文件来指定类路径和主类,这样您就不需要使用-cp或指定主类了。在您的情况下,它应该包含以下这些行:

Main-Class: com.test.App
Class-Path: lib/one.jar lib/two.jar

不幸的是,您需要在清单中拼写出每个jar文件(这并不是什么大问题,因为您只需执行一次,并且可以使用脚本构建文件或使用构建工具如ANT或Maven或Gradle)。而且引用必须是相对或绝对目录,以便在运行java -jar MyJar.jar时找到。

然后使用以下命令执行:

java -jar MyJar.jar

1
我认为Class-Path需要引用外部jar文件中的文件。我无法通用地使其工作,以引用MyJar.jar之外的配置文件。 - Tuntable

0
你可以使用Runtime.getRuntime.exec(command)来重新启动包括类路径和参数的jar文件。

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