有没有办法在类路径中的目录中包含所有jar文件?
我正在尝试java -classpath lib/*.jar:. my.package.Program
,它无法找到肯定在那些罐子里的类文件。我是否需要将每个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
选项不兼容。另请参阅:Execute jar file with multiple classpath libraries from command prompt)
了解通配符
来自Classpath文件:
类路径条目可以包含基本名称通配符
*
,它被认为等同于指定目录中扩展名为.jar
或.JAR
的所有文件的列表。例如,类路径条目foo/*
指定名为foo的目录中的所有JAR文件。简单地由*
组成的类路径条目扩展为当前目录中所有jar文件的列表。包含
*
的类路径条目与类文件不匹配。要在单个目录foo中匹配类和JAR文件,请使用foo;foo/*
或foo/*;foo
。选择的顺序决定foo
中的类和资源是否在foo
中的JAR文件之前加载,反之亦然。不会递归搜索子目录。例如,
foo/*
仅在foo
中查找JAR文件,而不是在foo/bar
,foo/baz
等中查找JAR文件。未指定在扩展类路径中枚举目录中的JAR文件的顺序,并且可能因平台而异,甚至在同一台机器上不时。构造良好的应用程序不应该依赖于任何特定的顺序。如果需要特定顺序,则可以在类路径中显式枚举JAR文件。
在类加载过程本身期间,在调用程序的main方法之前,而不是迟到,扩展通配符是在早期完成的。包含通配符的输入类路径的每个元素都由枚举命名目录中的JAR文件生成的(可能为空)元素序列替换。例如,如果目录
foo
包含a.jar
,b.jar
和c.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
如果您确实需要动态指定所有.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>
在启动构建文件中,该文件将使用正确的类路径启动应用程序。
如果您使用的是Java 6,则可以在类路径中使用通配符。
现在可以在类路径定义中使用通配符:
javac -cp libs/* -verbose -encoding UTF-8 src/mypackage/*.java -d build/classes
请注意,Windows上的Java 7通配符扩展已中断。
查看this StackOverflow issue了解更多信息。
解决方法是在通配符后面加上分号。 java -cp "somewhere/*;"
敬启者,
我在MSYS / MinGW shell下的Windows上发现了这种奇怪的行为。
作品:
$ 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
我很确定外壳没有扩展通配符,因为例如
$ echo './*'
./*
(也用另一个程序尝试,而不是内置的echo
,结果相同。)
我相信它是javac
试图扩展它,并且无论论证中是否有分号,它的行为都不同。首先,它可能试图扩展看起来像路径的所有参数。只有这样它才会解析它们,而-cp
只接受以下标记。 (请注意,com.comsol.aco_1.0.0.jar
是该目录中的第二个JAR。)这都是猜测。
这是
$ javac -version
javac 1.7.0
如果您在Eclipse或Netbeans之类的任何IDE之外开发和运行Java应用程序,则上述所有解决方案都能很好地运行。
如果您使用的是Windows 7并使用Eclipse IDE进行Java开发,则在使用命令提示符运行Eclipse内部构建的类文件时可能会遇到问题。
例如。您在Eclipse中的源代码具有以下包层次结构:edu.sjsu.myapp.Main.java
您将json.jar作为Main.java的外部依赖项
当您尝试从Eclipse中运行Main.java时,它将运行没有任何问题。
但是当你在Eclipse中编译Main.java后尝试使用命令提示符运行它时,它会发出一些奇怪的错误,说“ClassNotDef错误等等”。
我假设你在源代码的工作目录中!
使用以下语法从命令提示符运行它:
这是因为您已将Main.java放在包edu.sjsu.myapp中,java.exe将查找确切的模式。
希望能帮助到你 !!
对于窗户报价是必需的;应该用作分隔符。例如。:
java -cp "target\\*;target\\dependency\\*" my.package.Main
简短形式:如果你的主要在一个jar中,你可能需要一个额外的'-jar pathTo / yourJar / YourJarsName.jar'显式声明它才能使它工作(即使'YourJarsName.jar'在类路径上)(或者,表示回答5年前提出的原始问题:你不需要明确地重新声明每个jar,但看起来,即使使用java6你需要重新声明你自己的jar ......)
Long Form :(我已明确指出,我希望即使是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肯定会破坏),但是我正在使用的其中一个罐子中的本机代码打破了当你选择该选项时eclipse利用的方便的“jarinjar”技巧。即使在意识到我需要opt3,然后找到这个StackOverflow条目之后,我仍然花了一些时间来弄清楚如何在Eclipse之外启动我的主要功能,所以这对我有用,因为它对其他人有用...
如果你命名你的jar:“fooBarTheJarFile.jar”并且所有设置都导出到dir:“/ 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的位置。
例如这打破了:
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)
我知道如何单独进行的唯一方法,例如:
setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:.
希望有所帮助!
来自网络应用的课程:
> 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
不是能够设置/ *到-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”。
在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文件视为目录结构的根。是的,您需要单独添加它们。
以适合多个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
我在一个文件夹中有多个罐子。以下命令在JDK1.8
中为我工作,包括文件夹中的所有jar。请注意,如果您在类路径中有空格,请包含在引号中
视窗
编译: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
我试图在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,但我将Java lib路径设置为第8版! - 您可以从此处设置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
它运行成功!
我们通过部署一个主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上启动。
我的解决方案在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
简短的回答:java -classpath lib/*:. my.package.Program
Oracle提供了有关在类路径here for Java 6和here for Java 7中使用通配符的文档,该文章在标题了解类路径通配符一节下。 (在我写这篇文章时,这两个页面包含相同的信息。)以下是重点摘要:
*
(而不是*.jar
)。-cp /classes;/jars/*
CLASSPATH
系统属性或-cp
或-classpath
命令行标志,则上述要点为true。但是,如果您使用Class-Path
JAR清单标头(就像您可能使用ant构建文件一样),则不会遵循通配符。是的,我的第一个链接与得分最高的答案中提供的链接相同(我无法超越),但该答案并未提供超出链接的解释。由于这种行为是堆栈溢出discouraged上的these days,我以为我会扩展它。
你可以试试java -Djava.ext.dirs=jarDirectory
http://docs.oracle.com/javase/6/docs/technotes/guides/extensions/spec.html
运行java时外部jar的目录
视窗:
java -cp file.jar;dir/* my.app.ClassName
Linux的:
java -cp file.jar:dir/* my.app.ClassName
提醒:
- Windows路径分隔符是;
- Linux路径分隔符是:
- 在Windows中,如果cp参数不包含空格,则“引号”是可选的
正确:
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