如何在 Windows 中设置长的 Java 类路径?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/201816/
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
How to set a long Java classpath in Windows?
提问by Ogre Psalm33
I'm trying to run a particular JUnit test by hand on a Windows XP command line, which has an unusually high number of elements in the class path. I've tried several variations, such as:
我正在尝试在 Windows XP 命令行上手动运行特定的 JUnit 测试,该命令行在类路径中具有异常多的元素。我尝试了几种变体,例如:
set CLASS_PATH=C:\path\a\b\c;C:\path\e\f\g;....
set CLASS_PATH=%CLASS_PATH%;C:\path2\a\b\c;C:\path2\e\f\g;....
...
C:\apps\jdk1.6.0_07\bin\java.exe -client oracle.jdevimpl.junit.runner.TestRunner com.myco.myClass.MyTest testMethod
(Other variations are setting the classpath all on one line, setting the classpath via -classpath as an argument to java"). It always comes down to the console throwing up it's hands with this error:
(其他变体是在一行上设置类路径,通过 -classpath 将类路径设置为 java 的参数”)。它总是归结为控制台抛出这个错误:
The input line is too long.
The syntax of the command is incorrect.
This is a JUnit test testing a rather large existing legacy project, so no suggestions about rearranging my directory structure to something more reasonable, those types of solutions are out for now. I was just trying to gen up a quick test against this project and run it on the command line, and the console is stonewalling me. Help!
这是一个 JUnit 测试,测试一个相当大的现有遗留项目,所以没有关于将我的目录结构重新安排为更合理的建议,这些类型的解决方案现在已经出来了。我只是想针对这个项目生成一个快速测试并在命令行上运行它,而控制台正在阻碍我。帮助!
采纳答案by Chris Noe
The Windows command line is very limiting in this regard. A workaround is to create a "pathing jar". This is a jar containing only a Manifest.mf
file, whose Class-Path
specifies the disk paths of your long list of jars, etc. Now just add this pathing jarto your command line classpath. This is usually more convenient than packaging the actual resources together.
Windows 命令行在这方面非常有限。一种解决方法是创建一个“路径 jar”。这是一个仅包含一个Manifest.mf
文件的 jar ,它Class-Path
指定了长长的 jar 列表等的磁盘路径。现在只需将此路径 jar添加到您的命令行类路径中。这通常比将实际资源打包在一起更方便。
As I recall, the disk paths can be relative to the pathing jaritself. So the Manifest.mf
might look something like this:
我记得,磁盘路径可以相对于路径 jar本身。所以Manifest.mf
可能看起来像这样:
Class-Path: this.jar that.jar ../lib/other.jar
If your pathing jarcontains mainly foundational resources, then it won't change too frequently, but you will probably still want to generate it somewhere in your build. For example:
如果您的路径 jar主要包含基础资源,则它不会更改太频繁,但您可能仍希望在构建中的某个地方生成它。例如:
<jar destfile="pathing.jar">
<manifest>
<attribute name="Class-Path" value="this.jar that.jar ../lib/other.jar"/>
</manifest>
</jar>
回答by Nick Berardi
Have you tried stacking them?
你试过堆叠它们吗?
set CLASS_PATH = c:\path
set ALT_A = %CLASS_PATH%\a\b\c;
set ALT_B = %CLASS_PATH%\e\f\g;
...
set ALL_PATHS = %CLASS_PATH%;%ALT_A%;%ALT_B%
回答by Huibert Gill
I think you are up the creek without a paddle here. The commandline has a limit for arguments to call a programm.
我想你在这里没有桨就在小溪上。命令行对调用程序的参数有限制。
I have 2 sugestion you could try. First, prior to running the junit tests, you can let a script/ant_task create JARs of the various classes on the classpath. Then you can put the JARs on the classpath, which should be shorter.
我有 2 sugestion 你可以尝试。首先,在运行 junit 测试之前,您可以让 script/ant_task 在类路径上创建各种类的 JAR。然后你可以将 JAR 放在类路径上,它应该更短。
Another way you could try is to create an antscript to run JUNIT, in ANT there should not be such a limit for classpath entries.
您可以尝试的另一种方法是创建一个 antscript 来运行 JUNIT,在 ANT 中,类路径条目不应该有这样的限制。
回答by Tomalak
(I suppose you do not really mean DOS, but refer to cmd.exe.)
(我想你的意思并不是真正的 DOS,而是指 cmd.exe。)
I think it is less a CLASSPATH limitation than an environment size/environment variable size limit. On XP, individual environment variables can be 8k in size, the entire environment is limited to 64k. I can't see you would hit that limit.
我认为它不是环境大小/环境变量大小限制的 CLASSPATH 限制。在 XP 上,单个环境变量的大小可以为 8k,整个环境限制为 64k。我看不出你会达到那个极限。
There is a limit on windows that restricts the length of a command line, on WindowsNT+ it is 8k for cmd.exe. A set command is subject to that restriction. Can it be you have more than 8k worth of directories in your set command? You may be out of luck, then - even if you split them up like Nick Berardisuggested.
Windows 上有一个限制命令行长度的限制,在 WindowsNT+ 上,cmd.exe 是 8k。set 命令受该限制的约束。您的 set 命令中是否有超过 8k 的目录?那么你可能不走运——即使你像尼克贝拉迪建议的那样把它们分开。
回答by johnstok
Since Java 6 you can use classpath wildcards.
从 Java 6 开始,您可以使用类路径通配符。
Example: foo/*
, refers to all .jar files in the directory foo
示例:foo/*
, 指的是目录中的所有 .jar 文件foo
- this will not match class files (only jar files). To match both use:
foo;foo/*
orfoo/*;foo
. The order determines what is loaded first. - The search is NOT recursive
- 这将不匹配类文件(仅 jar 文件)。要匹配两者,请使用:
foo;foo/*
或foo/*;foo
。顺序决定了先加载什么。 - 搜索不是递归的
回答by matt b
As HuibertGill mentions, I would wrap this in an Ant build script just so that you don't have to manage all of this yourself.
正如 HuibertGill 所提到的,我会将其包装在 Ant 构建脚本中,这样您就不必自己管理所有这些。
回答by anjanb
If I were in your shoes, I would download the junction utility from MS : http://technet.microsoft.com/en-us/sysinternals/bb896768.aspxand then map your
"C:\path" to say, "z:\" and "c:\path2" to say, "y:\". This way, you will be reducing 4 characters per item in your classpath
.
如果我是你的话,我会从 MS 下载连接实用程序:http: //technet.microsoft.com/en-us/sysinternals/bb896768.aspx然后映射你的“C:\path”说,“z :\" 和 "c:\path2" 表示 "y:\"。这样,您将在您的classpath
.
set CLASS_PATH=C:\path\a\b\c;C:\path\e\f\g;
set CLASS_PATH=%CLASS_PATH%;C:\path2\a\b\c;C:\path2\e\f\g;
Now, your classpath will be :
现在,您的类路径将是:
set CLASS_PATH=z\a\b\c;z\e\f\g;
set CLASS_PATH=%CLASS_PATH%;y:\a\b\c;y:\e\f\g;
It might do more depending on your actual classpath
.
根据您的实际classpath
.
回答by Shivananda Sahu
You could try this
你可以试试这个
@echo off
set A=D:\jdk1.6.0_23\bin
set B=C:\Documents and Settings4205\Desktop\JavaProj
set PATH="%PATH%;%A%;"
set CLASSPATH="%CLASSPATH%;%B%;"
go to a command prompt and run it twice(no idea why....i have to do so on a windows XP machine) also the paths r set only for the current command prompt session
转到命令提示符并运行两次(不知道为什么....我必须在 Windows XP 机器上这样做)以及仅为当前命令提示符会话设置的路径
回答by Snehal Masne
There was no solution to the issue other than somehow making the classpath shorter by moving the jar files into a folder like "C:\jars".
除了通过将 jar 文件移动到“C:\jars”之类的文件夹中以某种方式缩短类路径之外,没有解决此问题的方法。
回答by Raman
Use An "Argument File" on Java 9+
在 Java 9+ 上使用“参数文件”
In Java 9+, the java executable supports providing arguments via a file. See https://docs.oracle.com/javase/9/tools/java.htm#JSWOR-GUID-4856361B-8BFD-4964-AE84-121F5F6CF111.
在 Java 9+ 中,java 可执行文件支持通过文件提供参数。请参阅 https://docs.oracle.com/javase/9/tools/java.htm#JSWOR-GUID-4856361B-8BFD-4964-AE84-121F5F6CF111。
This mechanism is explicitly intended to solve the problem of OS limitations on command lengths:
该机制明确旨在解决操作系统对命令长度的限制问题:
You can shorten or simplify the java command by using @argument files to specify a text file that contains arguments, such as options and class names, passed to the java command. This let's you to create java commands of any length on any operating system.
In the command line, use the at sign (@) prefix to identify an argument file that contains java options and class names. When the java command encounters a file beginning with the at sign (@) , it expands the contents of that file into an argument list just as they would be specified on the command line.
您可以通过使用@argument 文件指定包含传递给 java 命令的参数(例如选项和类名)的文本文件来缩短或简化 java 命令。这让您可以在任何操作系统上创建任何长度的 java 命令。
在命令行中,使用 at 符号 (@) 前缀来标识包含 java 选项和类名的参数文件。当 java 命令遇到以 at 符号 (@) 开头的文件时,它会将该文件的内容扩展为参数列表,就像在命令行中指定的那样。
This is the "right" solution, if you are running version 9 or above. This mechanism simply modifies how the argument is provided to the JVM, and is therefore 100% compatible with any framework or application, regardless of how they do classloading i.e. it is completely equivalent to simply providing the argument on the command line as usual. This is not true for manifest-based workarounds to this OS limitation.
如果您运行的是版本 9 或更高版本,这是“正确”的解决方案。这种机制简单地修改了参数提供给 JVM 的方式,因此与任何框架或应用程序 100% 兼容,无论它们如何进行类加载,即它完全等同于像往常一样在命令行上简单地提供参数。对于此操作系统限制的基于清单的解决方法,情况并非如此。
An example of this is:
这方面的一个例子是:
Original command:
原始命令:
java -cp c:\foo\bar.jar;c:\foo\baz.jar
java -cp c:\foo\bar.jar;c:\foo\baz.jar
can be rewritten as:
可以改写为:
java @c:\path\to\cparg
java @c:\path\to\cparg
where c:\path\to\cparg
is a file which contains:
哪里c:\path\to\cparg
是一个文件,其中包含:
-cp c:\foo\bar.jar;c:\foo\baz.jar
This "argument file" also supports line continuation characters and quoting for properly handling spaces in paths e.g.
这个“参数文件”还支持行继续符和引号以正确处理路径中的空格,例如
-cp "\
c:\foo\bar.jar;\
c:\foo\baz.jar"
Gradle
摇篮
If you are encountering this issue in Gradle, see this plugin, which converts your classpath automatically into an "argument file" and provides that to the JVM when doing exec or test tasks on Windows. On Linux or other operating systems it does nothing by default, though an optional configuration value can be used to apply the transformation regardless of OS.
如果您在 Gradle 中遇到此问题,请参阅此插件,它会自动将您的类路径转换为“参数文件”,并在 Windows 上执行 exec 或 test 任务时将其提供给 JVM。在 Linux 或其他操作系统上,默认情况下它什么都不做,尽管可以使用可选的配置值来应用转换,而不管操作系统如何。
https://github.com/redocksoft/classpath-to-file-gradle-plugin
https://github.com/redocksoft/classpath-to-file-gradle-plugin
(disclaimer: I am the author)
(免责声明:我是作者)
See also this related Gradle issue -- hopefully this capability will eventually be integrated into Gradle core: https://github.com/gradle/gradle/issues/1989.
另请参阅此相关 Gradle 问题 - 希望此功能最终会集成到 Gradle 核心中:https: //github.com/gradle/gradle/issues/1989。