Including all the jars in a directory within the Java classpath
有没有一种方法可以在类路径的目录中包含所有JAR文件?
我正在尝试
使用Java 6或更高版本,CLSSPATH选项支持通配符。注意以下事项:
- 使用直引号(
" ) - 使用
* ,不使用*.jar 。
窗户
java -cp"Test.jar;lib/*" my.package.MainClass
UNIX
java -cp"Test.jar:lib/*" my.package.MainClass
这类似于Windows,但使用
java -cp $(echo lib/*.jar | tr ' ' ':')
(请注意,使用类路径与
了解通配符
从类路径文档:
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 entryfoo/* 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/* orfoo/*;foo . The order chosen determines whether the
classes and resources infoo are loaded before JAR files infoo , or
vice versa.Subdirectories are not searched recursively. For example,
foo/* looks
for JAR files only infoo , not infoo/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 directoryfoo containsa.jar ,b.jar , andc.jar , then
the class pathfoo/* is expanded intofoo/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 theClass-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文件
因此,如果您将主
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
简短回答:
Oracle提供了关于在Java 6中使用ClasSPaTs的通配符和Java 7的通配符的文档,在理解类路径通配符的标题下。(在我写这篇文章的时候,这两页包含了相同的信息。)下面是重点的摘要:
通常,要在给定目录中包含所有jar,可以使用通配符
* (而不是*.jar )。通配符只匹配jar,而不是类文件;要获取目录中的所有类,只需在目录名处结束classpath条目。
以上两个选项可以组合在一起,将所有JAR和类文件包含在一个目录中,并应用通常的类路径优先规则。如
-cp /classes;/jars/* 。通配符不会在子目录中搜索jar。
如果使用
CLASSPATH 系统属性或-cp 或-classpath 命令行标志,则上述要点是正确的。但是,如果您使用Class-Path jar清单头(就像对一个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问题。
解决方法是在通配符后面放一个分号。
致有关人士,
我在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 './*' ./* |
(也使用了另一个程序,而不是内置的
我认为正是
这是
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命令包括挤压瓶子的
WindowsP></
compiling:
LinuxP></
compiling: