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

时间:2008-10-20 19:32:46

标签: java command-line classpath

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

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

25 个答案:

答案 0 :(得分:1062)

使用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选项不兼容。另请参阅:Execute jar file with multiple classpath libraries from command prompt

了解通配符

来自Classpath文件:

  

类路径条目可以包含基本名称通配符*,这被视为等同于指定所有文件的列表   在扩展名为.jar.JAR的目录中。例如,   class path entry foo/*指定名为的目录中的所有JAR文件   FOO。简单地由*组成的类路径条目扩展为所有的列表   当前目录中的jar文件。

     

包含*的类路径条目与类文件不匹配。至   将类和JAR文件匹配在一个目录foo中,使用其中一个   foo;foo/*foo/*;foo。选择的顺序决定了   foo中的类和资源在foo中的JAR文件之前加载,或者   反之亦然。

     

不会递归搜索子目录。例如,foo/*看起来   仅适用于foo的JAR文件,而不是foo/barfoo/baz等。

     

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

     

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

答案 1 :(得分:214)

在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

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

答案 2 :(得分:63)

我们通过部署 jar文件myapp.jar来解决此问题,该文件包含清单Manifest.mf)文件,指定类路径其他必需的罐子,然后与它一起部署。在这种情况下,您只需在运行代码时声明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上启动。

答案 3 :(得分:43)

我的解决方案在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

答案 4 :(得分:33)

对我而言,这适用于Windows。

java -cp "/lib/*;" sample

对于linux

java -cp "/lib/*:" sample

我正在使用Java 6

答案 5 :(得分:32)

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

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

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

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

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

  • 通配符将在子目录中搜索JAR。

  • 如果您使用CLASSPATH系统属性或-cp-classpath命令行标志,则上述要点均为真。但是,如果您使用Class-Path JAR清单标头(就像您对ant构建文件所做的那样),通配符将被尊重。

是的,我的第一个链接与得分最高的答案中提供的链接相同(我无法超越),但该答案并未提供超出链接的解释。由于Stack Overflow discouraged上的这种行为是these days,我认为我会扩展它。

答案 6 :(得分:26)

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

运行java时外部jar的目录

答案 7 :(得分:21)

<强>窗

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

<强>的Linux

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

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

答案 8 :(得分:21)

<强>正确

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

答案 9 :(得分:9)

如果您使用的是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/

答案 10 :(得分:9)

如果您确实需要动态指定所有.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>

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

答案 11 :(得分:8)

请注意,Windows上的Java 7会破坏通配符扩展。

查看this StackOverflow issue了解详情。

解决方法是在通配符后面放置一个分号。 java -cp "somewhere/*;"

答案 12 :(得分:6)

可能涉及的人,

我在Windows上的MSYS / MinGW shell下发现了这种奇怪的行为。

<强>使用:

$ 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

答案 13 :(得分:4)

对于Windows报价是必需的;应该用作分隔符。 e.g:

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

答案 14 :(得分:4)

简短形式:如果你的主要在一个jar中,你可能需要一个额外的'-jar pathTo / yourJar / YourJarsName.jar'显式声明它才能使它工作(即使'YourJarsName.jar'在类路径上) (或者,表示回答5年前提出的原始问题:你不需要明确重新声明每个jar,但看起来似乎,即使使用java6,你需要重新声明自己的jar ...)


长表: (我已经明确指出,我希望即使是java的闯入者也可以利用这个)

像许多人一样,我使用eclipse导出jar :( File-&gt; Export - &gt;'Runnable JAR File')。 '库处理'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肯定会破坏),但是我正在使用的其中一个罐子中的本机代码打破了当您选择该选项时eclipse利用的方便的“jarinjar”技巧。即使在意识到我需要opt3,然后找到这个StackOverflow条目之后,我还是花了一些时间来弄清楚如何在Eclipse之外启动我的主要功能,所以这对我有用,因为它对其他人有用......


如果你给你的罐子命名:“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'是声明的包路径,您可以在'TheClassWithYourMain.java'文件的顶部找到包含'main(String [] args)的文件{...}'您希望从外部java运行


要注意的陷阱:在声明的类路径中的jar列表中包含'fooBarTheJarFile.jar'是不够的。您需要显式声明'-jar',然后重新声明该jar的位置。

e.g。这打破了:

 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   

(使用java版“1.6.0_27”;通过ubuntu 12.04上的OpenJDK 64位服务器VM)

答案 15 :(得分:3)

我知道如何单独进行的唯一方法,例如:

setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:.

希望有所帮助!

答案 16 :(得分:3)

来自wepapp的

类:

var panel = document.querySelector(".panel");

panel.addEventListener("click", handleClick);

答案 17 :(得分:2)

不是能够将/ *设置为-cp的直接解决方案,但我希望您可以使用以下脚本来简化动态类路径和lib目录的情况。

 libDir2Scan4jars="../test";cp=""; for j in `ls ${libDir2Scan4jars}/*.jar`; do if [ "$j" != "" ]; then cp=$cp:$j; fi; done; echo $cp| cut -c2-${#cp} > .tmpCP.tmp; export tmpCLASSPATH=`cat .tmpCP.tmp`; if [ "$tmpCLASSPATH" != "" ]; then echo .; echo "classpath set, you can now use  ~>         java -cp \$tmpCLASSPATH"; echo .; else echo .; echo "Error please check libDir2Scan4jars path"; echo .; fi; 

针对Linux的脚本,也可能有一个类似于Windows的脚本。如果提供了正确的目录作为“libDir2Scan4jars”的输入;该脚本将扫描所有jar并创建一个类路径字符串并将其导出到env变量“tmpCLASSPATH”。

答案 18 :(得分:1)

将jar文件视为目录结构的根目录。是的,您需要单独添加它们。

答案 19 :(得分:1)

以适合多个jar和当前目录的类文件的方式设置类路径。

CLASSPATH=${ORACLE_HOME}/jdbc/lib/ojdbc6.jar:${ORACLE_HOME}/jdbc/lib/ojdbc14.jar:${ORACLE_HOME}/jdbc/lib/nls_charset12.jar; 
CLASSPATH=$CLASSPATH:/export/home/gs806e/tops/jconn2.jar:.;
export CLASSPATH

答案 20 :(得分:1)

您需要单独添加它们。或者,如果确实需要只指定一个目录,则可以将所有内容解压缩到一个目录中并将其添加到类路径中。我不推荐这种方法,因为你冒着类路径版本控制和不可管理性的奇怪问题。

答案 21 :(得分:0)

我在一个文件夹中有多个jar。以下命令在JDK1.8中为我工作,以包含该文件夹中存在的所有jar。请注意,如果类路径中有空格,请在引号中添加

Windows

编译:{{1​​}}

运行:javac -classpath "C:\My Jars\sdk\lib\*" c:\programs\MyProgram.java

Linux

编译:{{1​​}}

运行:java -classpath "C:\My Jars\sdk\lib\*;c:\programs" MyProgram

答案 22 :(得分:0)

我正在尝试以jar或Ubuntu中的类的形式运行Java文件。我在两个选项中都失败了。以下是其输出。

Download link: https://upload.cat/f694139f88c663b1
  

java org.statmetrics.Statmetric

  

java -cp /home/elias/statmetrics/statmetrics.jar:。   org.statmetrics.Statmetrics

  

java -classpath“ /usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/*” -jar   /home/elias/statmeics/statmetrics.jar org.statmetrics.Statmetrics

Exception in thread "Thread-0" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/adapters/XmlAdapter
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:802)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:700)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:623)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at org.statmetrics.c.a(Unknown Source)
    at org.statmetrics.dw.a(Unknown Source)
    at org.statmetrics.dx.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.adapters.XmlAdapter
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 12 more

我找到了答案:

我的愚蠢。

第一步:必须设置相应的Java:我有Java 11,但是我将第8版设置为Java lib path! -您可以从此处设置Java版本:

  sudo update-alternatives --config java

第二步:然后,通过将路径和文件名更改为相应的路径和文件,运行以下命令:

  java -classpath "/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/*" -jar /home/elias/statmetrics/statmetrics.jar org.statmetrics.Statmetrics

运行成功!

答案 23 :(得分:0)

macOS,当前文件夹

对于macOS Mojave上的Java 13…

如果所有.jar文件都位于同一文件夹中,请使用cd来确定您的current working directory。使用pwd进行验证。

对于-classpath,您必须首先为您的应用列出JAR file。使用冒号:作为分隔符,在星号*后面附加星号my_app.jar,以获取同一文件夹中的所有其他JAR文件。最后,用您的main method传递类的完整程序包名称。

例如,对于名为main的JAR文件中的应用程序,在名为App的程序包中名为com.example的类中具有java -classpath my_app.jar:* com.example.App 方法,并带有一些需要的jar在同一文件夹中:

choice_array = np.array([
 "item0",
 "item1",
 "item2",
 "item3",
 "item4",
], dtype=str)

item1 = test_class("name1", 50, "50p")
item2 = test_class("name2", 50, "50p")
item3 = test_class("name3", 50, "50p")

def payment_coins(item_selection):
  x = choice_array[item_selection]
  print(x)
  print("You have selected: ", x.beverage, "\n")
  cost_item = str(input("Please enter " + x.cost_str + " -> "))

答案 24 :(得分:0)

java 命令的参数顺序也很重要:

c:\projects\CloudMirror>java Javaside -cp "jna-5.6.0.jar;.\"
Error: Unable to initialize main class Javaside
Caused by: java.lang.NoClassDefFoundError: com/sun/jna/Callback

对比

c:\projects\CloudMirror>java -cp "jna-5.6.0.jar;.\" Javaside
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable