关于命令行:包括Java类路径中目录中的所有jar

Including all the jars in a directory within the Java classpath

有没有一种方法可以在类路径的目录中包含所有JAR文件?

我正在尝试java -classpath lib/*.jar:. my.package.Program,但它找不到那些jar中的类文件。是否需要将每个JAR文件分别添加到类路径?


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

  • 使用直引号(")
  • 使用*,不使用*.jar

窗户

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

UNIX

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

这类似于Windows,但使用:而不是;。如果不能使用通配符,EDCOX1 OR 10允许使用以下语法(其中EDCOX1×4)是包含所有Java存档文件的目录:

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

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

了解通配符

从类路径文档:

Class path entries can contain the basename wildcard character *, which is considered equivalent to specifying a list of all the files
in the directory with the extension .jar or .JAR. For example, the
class path entry foo/* specifies all JAR files in the directory named
foo. A classpath entry consisting simply of * expands to a list of all
the jar files in the current directory.

A class path entry that contains * will not match class files. To
match both classes and JAR files in a single directory foo, use either
foo;foo/* or foo/*;foo. The order chosen determines whether the
classes and resources in foo are loaded before JAR files in foo, or
vice versa.

Subdirectories are not searched recursively. For example, foo/* looks
for JAR files only in foo, not in foo/bar, foo/baz, etc.

The order in which the JAR files in a directory are enumerated in the
expanded class path is not specified and may vary from platform to
platform and even from moment to moment on the same machine. A
well-constructed application should not depend upon any particular
order. If a specific order is required then the JAR files can be
enumerated explicitly in the class path.

Expansion of wildcards is done early, prior to the invocation of a
program's main method, rather than late, during the class-loading
process itself. Each element of the input class path containing a
wildcard is replaced by the (possibly empty) sequence of elements
generated by enumerating the JAR files in the named directory. For
example, if the directory foo contains a.jar, b.jar, and c.jar, then
the class path foo/* is expanded into foo/a.jar;foo/b.jar;foo/c.jar,
and that string would be the value of the system property
java.class.path.

The CLASSPATH environment variable is not treated any differently from
the -classpath (or -cp) command-line option. That is, wildcards are
honored in all these cases. However, class path wildcards are not
honored in the Class-Path jar-manifest header.

注意:由于Java 8中已知的bug,Windows示例必须使用带有尾随星号的反斜杠:HTTPS://Bug.OpenJDK.JavaNET/BROSESE/JDK-8131329。


在Windows下,这是有效的:

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

但这不起作用:

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

注意*.jar,因此*通配符应该单独使用。

在Linux上,以下功能可用:

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

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


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

因此,如果您将主jar部署到某个目录中,然后将从属jar放入该目录下的lib文件夹中,那么清单如下:

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

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


我在Ubuntu 10.04上使用JavaSun1.60Y24在"LIB"目录中的所有jar的解决方案:

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

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

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


对我来说,这在Windows中有效。

1
java -cp"/lib/*;" sample

对于Linux

1
java -cp"/lib/*:" sample

我使用Java 6


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

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

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

  • 通配符只匹配jar,而不是类文件;要获取目录中的所有类,只需在目录名处结束classpath条目。

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

  • 通配符不会在子目录中搜索jar。

  • 如果使用CLASSPATH系统属性或-cp-classpath命令行标志,则上述要点是正确的。但是,如果您使用Class-Pathjar清单头(就像对一个Ant构建文件所做的那样),通配符将不会被使用。

是的,我的第一个链接与得分最高的答案中提供的链接相同(我不希望超车),但这个答案除了链接之外没有提供太多的解释。由于这些天堆栈溢出时不鼓励这种行为,所以我想我会扩展它。


您可以尝试Java EDCOX1 13http://docs.oracle.com/javase/6/docs/technotes/guides/extensions/spec.html

运行Java时外部容器的目录


对的:

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

不正确的:

1
2
3
4
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

Windows:
P></

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

Linux:
P></

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

哦!提醒:
Windows路径是;
separatorLinux下的路径是:
separator如果在Windows argument does not CP contains the"白色空间,quotes is optional"P></


如果您真的需要动态地指定所有的.jar文件,您可以使用shell脚本或ApacheAnt。有一个名为commons launcher的commons项目,它基本上允许您将启动脚本指定为一个Ant构建文件(如果您明白我的意思的话)。

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

1
2
3
4
5
<path id="base.class.path">
    <pathelement path="${resources.dir}"/>
    <fileset dir="${extensions.dir}" includes="*.jar" />
    <fileset dir="${lib.dir}" includes="*.jar"/>
</path>

在启动生成文件中,它将使用正确的类路径启动应用程序。


如果使用Java 6,那么可以在类路径中使用通配符。

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

1
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-通配符/


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

有关详细信息,请查看此StackOverflow问题。

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


致有关人士,

我在MSYS/MingW外壳下的窗户上发现了这种奇怪的行为。

作品:

1
$ javac -cp '.;c:\Programs\COMSOL44\plugins\*' Reclaim.java

不起作用:

1
2
3
4
$ 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扩展,因为例如

1
2
$ echo './*'
./*

(也使用了另一个程序,而不是内置的echo,结果相同。)

我认为正是javac试图扩展它,无论参数中是否有分号,它的行为都是不同的。首先,它可能试图扩展所有看起来像路径的参数。只有到那时,它才会解析它们,而-cp只获取以下令牌。(注意,com.comsol.aco_1.0.0.jar是该目录中的第二个jar。)这只是猜测。

这是

1
2
$ javac -version
javac 1.7.0


如果您在Eclipse或NETBESE等IDE之外开发和运行Java应用程序,上述所有解决方案都非常有效。

如果您在Windows 7上,并且使用Eclipse IDE在爪哇进行开发,如果使用命令提示符运行Eclipse中构建的类文件,则可能会遇到问题。

例如,Eclipse中的源代码具有以下包层次结构:edu.sjsu.myapp.main.java版

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

当您尝试在Eclipse中运行main.java时,它将毫无问题地运行。

但是,当您在Eclipse中编译main.java之后尝试使用命令提示符运行这个命令时,它会发出一些奇怪的错误,并说"classnotdef error blah blah blah"。

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

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

  • javac -cp".;json.jar" Main.java

  • java -cp".;json.jar" edu.sjsu.myapp.Main

    [不要错过。以上

  • 这是因为您已经将main.java放在包edu.sjsu.myapp中,java.exe将查找准确的模式。

    希望它有帮助!!


    简短的形式:如果您的主目录在一个jar中,那么您可能需要一个额外的'-jar路径到/yourjar/yourjarsname.jar'来让它工作(即使'yourjarsname.jar'在类路径上)。(或者,明确回答5年前提出的原始问题:您不需要显式地重新声明每个jar,但似乎,即使使用java6,您也需要重新声明自己的jar…)

    长形:(我已经明确指出,我希望即使是Java的介入者也可以利用这一点)

    像这里的许多人一样,我正在使用Eclipse导出jar:(file->export-->'runnable jar file')。"库处理"Eclipse(JUNO)提供三个选项:

    1
    2
    3
    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绝对是破坏性的),但是我使用的jar中的本地代码,我发现了一个使用方便的"jarinjar"技巧的破坏,Eclipse在选择该选项时利用了这个技巧。即使在意识到我需要opt3,然后找到这个stackoverflow条目之后,我仍然花了一些时间来弄清楚如何在Eclipse之外启动我的主服务器,所以这里是我的工作,因为它对其他人很有用……

    如果将jar命名为:"foobarthejarfile.jar"全部设置为导出到目录:"/thefully/qualifiedpath/toyourchosendir"。

    (表示"导出目标"字段将读取:"/thefully/qualifiedpath/toyourchosendir/foobarthejarfile.jar")

    单击"完成"后,您将发现Eclipse,然后将所有库放在该导出目录中名为"foobarthejarfile_lib"的文件夹中,这样您就可以:

    1
    2
    3
    4
    5
    /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

    然后,您可以从系统上的任何位置启动:

    1
    java -classpath"/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" -jar  /theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar   package.path_to.the_class_with.your_main.TheClassWithYourMain

    (对于JavaNeavys:'Pult.PaseTo.To.CaseLy.Auth.YouTrime'是在CulasHouthYouMeave.java文件的顶部找到的声明包路径,其中包含"希望从爪哇外部运行的主(String [AR]){…}"

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

    例如,此中断:

    1
     java -classpath"/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar;/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*"  somepackages.inside.yourJar.leadingToTheMain.TheClassWithYourMain

    用相对路径重述:

    1
    2
    3
    4
    5
    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.60Y27";通过Ubuntu 12.04上的OpenJDK 64位服务器VM)


    对于Windows,需要引号;应用作分隔符。例如。:

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

    weapp中的类:

    1
    2
    3
      > mvn clean install

      > java -cp"webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/tool-jar-1.17.0-SNAPSHOT.jar;webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/*" com.xx.xx.util.EncryptorUtils param1 param2

    我知道的唯一方法是单独做,例如:

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

    希望有帮助!


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

    1
     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"。


    您需要单独添加它们。或者,如果您确实需要指定一个目录,您可以将所有内容取消链接到一个目录中,并将其添加到类路径中。不过,我不推荐这种方法,因为您可能会在类路径版本控制和不可维护性方面遇到奇怪的问题。


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

    1
    2
    3
    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

    把JAR文件看作目录结构的根目录。是的,您需要单独添加它们。


    我试图运行的Java类文件或JAR或者AS AS在Ubuntu。在两个期权的失败。the following is its数据库输出。P></

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

    java org.statmetrics.Statmetric

    前P></

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

    前P></

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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

    的答案:found theP></

    我stupidity。P></

    第一步:你必须集对应的Java的Java:有11集的Java库,但As the version 8路径!- You can do the from here:Java版本集P></

    1
      sudo update-alternatives --config java

    第二步:然后Run by changing the following命令,文件路径和文件路径和名称你的对比:P></

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

    succesfully外面跑!P></


    瓶子在我多在folder。我在the below for命令包括挤压瓶子的JDK1.8to present in the folder。请注意,如果你有一个包括在quotes to the CLASSPATH中去太空P></

    WindowsP></

    compiling:javac -classpath"C:\My Jars\sdk\lib\*" c:\programs\MyProgram.javaP></

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

    LinuxP></

    compiling:javac -classpath"/home/guestuser/My Jars/sdk/lib/*" MyProgram.javaP></

    java -classpath"/home/guestuser/My Jars/sdk/lib/*:/home/guestuser/programs" MyProgram运行:P></