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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/219585/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:35:21  来源:igfitidea点击:

Including all the jars in a directory within the Java classpath

javacommand-lineclasspath

提问by Chris Serra

Is there a way to include all the jar files within a directory in the classpath?

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

I'm trying java -classpath lib/*.jar:. my.package.Programand it is not able to find class files that are certainly in those jars. Do I need to add each jar file to the classpath separately?

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

回答by Daniel Spiewak

You need to add them all separately. Alternatively, if you reallyneed to just specify a directory, you can unjar everything into one dir and add that to your classpath. I don't recommend this approach however as you risk bizarre problems in classpath versioning and unmanagability.

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

回答by Robert Van Hoose

Think of a jar file as the root of a directory structure. Yes, you need to add them all separately.

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

回答by Robert Van Hoose

If you really need to specify all the .jar files dynamically you could use shell scripts, or Apache Ant. There's a commons project called Commons Launcherwhich basically lets you specify your startup script as an ant build file (if you see what I mean).

如果您确实需要动态指定所有 .jar 文件,您可以使用 shell 脚本或Apache Ant。有一个名为Commons Launcher的公共项目,它基本上允许您将启动脚本指定为 ant 构建文件(如果您明白我的意思)。

Then, you can specify something like:

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

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

In your launch build file, which will launch your application with the correct classpath.

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

回答by oxbow_lakes

We get around this problem by deploying a mainjar file myapp.jarwhich contains a manifest(Manifest.mf) file specifying a classpath with the other required jars, which are then deployed alongside it. In this case, you only need to declare java -jar myapp.jarwhen running the code.

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

So if you deploy the main jarinto some directory, and then put the dependent jars into a libfolder beneath that, the manifest looks like:

因此,如果您将 main 部署jar到某个目录中,然后将依赖的 jars 放入其lib下方的文件夹中,则清单如下所示:

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

NB: this is platform-independent - we can use the same jars to launch on a UNIX server or on a Windows PC.

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

回答by basszero

Using Java 6 or later, the classpath option supports wildcards. Note the following:

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

  • Use straight quotes (")
  • Use *, not *.jar
  • 使用直引号 ( ")
  • 使用*,不*.jar

Windows

视窗

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

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

Unix

Unix

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

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

This is similar to Windows, but uses :instead of ;. If you cannot use wildcards, bashallows the following syntax (where libis the directory containing all the Java archive files):

这是类似Windows,但使用:的替代;。如果您不能使用通配符,则bash允许使用以下语法(lib包含所有 Java 存档文件的目录在哪里):

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

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

(Note that using a classpath is incompatible with the -jaroption. See also: Execute jar file with multiple classpath libraries from command prompt)

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

Understanding Wildcards

了解通配符

From the Classpathdocument:

类路径文档:

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 .jaror .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 fooare 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 foocontains 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 CLASSPATHenvironment 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-manifestheader.

类路径条目可以包含基本名称通配符*,这被认为等同于指定目录中所有文件的列表,扩展名为.jar.JAR。例如,类路径条目foo/*指定名为 foo 的目录中的所有 JAR 文件。一个仅由 组成的类路径条目*扩展为当前目录中所有 jar 文件的列表。

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

不递归搜索子目录。例如,foo/*验看JAR文件只有在foo,不foo/barfoo/baz等等。

目录中的 JAR 文件在扩展类路径中枚举的顺序没有指定,并且可能因平台而异,甚至在同一台机器上有时也会不同。一个构建良好的应用程序不应依赖于任何特定的顺序。如果需要特定顺序,则可以在类路径中显式枚举 JAR 文件。

在类加载过程本身期间,通配符的扩展在调用程序的主要方法之前进行,而不是在后期进行。包含通配符的输入类路径的每个元素都被替换为通过枚举指定目录中的 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标题中不支持类路径通配符。

Note: due to a known bug in java 8, the windows examples must use a backslash preceding entries with a trailing asterisk: https://bugs.openjdk.java.net/browse/JDK-8131329

注意:由于 java 8 中的一个已知错误,windows 示例必须在条目前使用反斜杠并带有星号:https: //bugs.openjdk.java.net/browse/JDK-8131329

回答by ParseTheData

The only way I know how is to do it individually, for example:

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

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

Hope that helps!

希望有帮助!

回答by davorp

Under windows this works:

在 Windows 下这有效:

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

and this does not work:

这不起作用:

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

notice the *.jar, so the * wildcard should be used alone.

注意 *.jar,所以 * 通配符应该单独使用



On Linux, the following works:

在 Linux 上,以下工作有效:

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

The separators are colons instead of semicolons.

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

回答by Alexey

For windows quotes are required and ; should be used as separator. e.g.:

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

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

回答by Navi

You can try java -Djava.ext.dirs=jarDirectoryhttp://docs.oracle.com/javase/6/docs/technotes/guides/extensions/spec.html

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

Directory for external jars when running java

运行java时外部jar的目录

回答by prakash

If you are using Java 6, then you can use wildcards in the classpath.

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

Now it is possible to use wildcards in classpath definition:

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

javac -cp libs/* -verbose -encoding UTF-8 src/mypackage/*.java  -d build/classes

Ref: http://www.rekk.de/bloggy/2008/add-all-jars-in-a-directory-to-classpath-with-java-se-6-using-wildcards/

参考:http: //www.rekk.de/bloggy/2008/add-all-jars-in-a-directory-to-classpath-with-java-se-6-using-wildcards/