代码之家  ›  专栏  ›  技术社区  ›  Chris Serra

包括Java类路径中目录中的所有JAR

  •  897
  • Chris Serra  · 技术社区  · 16 年前

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

    我正在努力 java -classpath lib/*.jar:. my.package.Program 而且它无法找到那些jar中的类文件。我需要将每个jar文件分别添加到类路径吗?

    22 回复  |  直到 8 年前
        1
  •  1082
  •   philwalk    7 年前

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

    • 使用直引号( " )
    • 使用 * 不是 *.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 . 例如, 类路径项 foo/* 指定名为 福。一个类路径条目,由 * 展开为全部列表 当前目录中的jar文件。

    包含 * 与类文件不匹配。到 在一个目录foo中同时匹配类和jar文件,使用 foo;foo/* foo/*;foo . 选择的顺序决定 中的类和资源 foo 在jar文件加载之前 或 反之亦然。

    子目录不会递归搜索。例如, Fo/* 看 仅适用于 不在 foo/bar , foo/baz 等。

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

    在调用 程序的主方法,而不是在类加载期间延迟 过程本身。输入类路径的每个元素都包含 通配符被(可能是空的)元素序列替换 通过枚举命名目录中的jar文件生成。为了 例如,如果目录 包含 a.jar , b.jar c.jar 然后 班级路径 Fo/* 扩展到 foo/a.jar;foo/b.jar;foo/c.jar , 该字符串将是系统属性的值 java.class.path .

    这个 CLASSPATH 环境变量与 这个 -classpath (或) -cp )命令行选项。也就是说,通配符是 在所有这些情况下都很荣幸。但是,类路径通配符不是 在 Class-Path jar-manifest 标题。

    注意:由于Java 8中已知的bug,Windows示例必须使用具有尾随星号的条目之前的反斜杠: https://bugs.openjdk.java.net/browse/JDK-8131329

        2
  •  217
  •   jamesmortensen Arjan    13 年前

    在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
    

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

        3
  •  63
  •   bourbert oxbow_lakes    10 年前

    我们通过部署 主要的 jar文件 myapp.jar 其中包含 显示 ( Manifest.mf )使用其他必需的jar指定类路径的文件,然后将这些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
    

    NB:这是平台无关的,我们可以使用相同的JAR来在UNIX服务器或Windows PC上启动。

        4
  •  44
  •   Habi    14 年前

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

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

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

    java -cp $(for i in lib/*.jar ; do echo -n $i: ; done). my.main.Class
        5
  •  34
  •   SANN3    10 年前

    对我来说这是在窗户里用的。

    java -cp "/lib/*;" sample
    

    对于Linux

    java -cp "/lib/*:" sample
    

    我正在使用 Java 6

        6
  •  32
  •   Community CDub    8 年前

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

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

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

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

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

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

    • 如果使用 CLASSPATH 系统属性或 -cp -classpath 命令行标志。但是,如果您使用 Class-Path jar清单头(正如您可能对ant构建文件所做的那样),通配符将 荣幸。

    是的,我的第一个链接与得分最高的答案中提供的链接相同(我不希望超过这个链接),但除了链接之外,这个答案并没有提供太多的解释。因为这种行为是 discouraged 堆栈溢出 these days ,我想我应该扩大一下。

        7
  •  26
  •   Afshin Moazami Darxis    9 年前

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

    运行Java时外部容器的目录

        8
  •  25
  •   Corey    6 年前

    窗户 :

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

    Linux :

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

    提醒:
    - 窗户 路径分隔符是 ;
    - Linux 路径分隔符是 :
    -在windows中,如果cp参数不包含空格,“quotes”是可选的

        9
  •  21
  •   rvernica    13 年前

    对的 :

    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
    
        10
  •  9
  •   user7094    16 年前

    如果您真的需要动态地指定所有的.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
  •  9
  •   SANN3    11 年前

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

        12
  •  8
  •   Community CDub    8 年前

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

    退房 this StackOverflow issue 更多信息。

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

        13
  •  6
  •   Evgeni Sergeev    10 年前

    对相关人员而言,

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

    作品:

    $ 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
    
        14
  •  4
  •   realPK    13 年前

    如果您在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”。

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

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

    1. JavaC-CP “,JSON.jar” 主类

    2. 爪哇 “,JSON.jar” 教育.sjsu.myapp.main

      [不要错过。以上

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

    希望有帮助!!

        15
  •  4
  •   om-nom-nom Dennis Williamson    12 年前

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

    java -cp "target\\*;target\\dependency\\*" my.package.Main
    
        16
  •  4
  •   Sid    8 年前

    简短表单:如果你的主体在一个jar中,你可能需要一个额外的'jar jar路径/ujal/ujARARSAME.jar ''被明确声明以使它工作(即使‘YouJavaSn.jar’在类路径上) (或者,表示回答5年前提出的原始问题:你不需要明确地重新声明每个JAR,但是看起来,即使是Java6,你也需要重新声明你自己的JAR……)


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

    像这里的许多人一样,我使用eclipse导出jar:(file->export-->'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确实是破的),但是我使用的一个JAR中的原生代码,我发现当你选择那个选项时,Eclipse使用的“JARIMANAR”技巧很容易出错。即使在意识到我需要opt3,然后找到这个stackoverflow条目之后,我还是花了一些时间来弄清楚如何在eclipse之外启动我的main,所以这里是对我有用的,因为它对其他人有用……


    如果你把你的jar命名为“foobarthejarfile.jar” 所有设置都导出到目录:“/thefully/qualifiedpath/toyourchosendir”。

    (意思是“export destination”字段将读取:'/thefully/qualifiedpath/toyourchosendir/foobarthejarfile.jar')

    点击finish之后,您会发现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
    

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


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

    例如,这个中断:

     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.60Y27”;通过Ubuntu 12.04上的OpenJDK 64位服务器VM)

        17
  •  3
  •   om-nom-nom Dennis Williamson    12 年前

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

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

    希望能有帮助!

        18
  •  3
  •   Mindaugas K.    10 年前

    WEPAPP课程:

      > 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
    
        19
  •  2
  •   Sreesankar    9 年前

    不是将/*设置为-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并创建一个类路径字符串,并将其导出到环境变量“tmpclasspath”。

        20
  •  1
  •   Daniel Spiewak    16 年前

    你需要把它们分别加起来。或者,如果你 真正地 只需指定一个目录,就可以将所有内容都解压到一个DIR中,并将其添加到类路径中。不过,我不建议使用这种方法,因为您可能在类路径版本控制和不可管理性方面遇到奇怪的问题。

        21
  •  1
  •   Robert Van Hoose    16 年前

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

        22
  •  1
  •   Girdhar Singh Rathore    9 年前

    以适合多个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
    
        23
  •  0
  •   vkrams rolling stone    6 年前

    我在一个文件夹里有多个罐子。下面的命令对我有用 JDK1.8 包括文件夹中的所有罐子。请注意,如果类路径中有空格,则要包含在引号中

    窗户

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

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

    Linux

    编译: javac -classpath "/home/guestuser/My Jars/sdk/lib/*" MyProgram.java

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

        24
  •  0
  •   Elias EstatisticsEU    6 年前

    我试图运行Java文件作为jar或类在Ubuntu中。我两个选择都失败了。以下异常是其输出。

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

    JAVA Org.St.

    Java-CP/HOME/埃利亚斯/StistMeals/StistMulk.jar: 网址:org.statmetrics.statmetrics

    Java-类路径“/UR/LB/JVM/Java1.81-OpenJDK-AMD64/JRE/LIB/*” /主页/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,但我设置为Java LIB路径的第八版本! -您可以从这里设置Java版本:

      sudo update-alternatives --config java
    

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

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

    它成功地运行了!