题
我试图运行的特定JUnit测试手上Windows XP的命令行,这具有非常多的元素在类的道路。我已经尝试了几个变化,例如:
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
(其他变化是设置的所有类路径上的一线,设定类路径通类路径参数java").它总是来到控制台扔了它的手与这个错误:
The input line is too long.
The syntax of the command is incorrect.
这是一个JUnit测试测试一个相当大的现有传统项目,因此不建议关于重新安排我的目录结构更合理的,这些类型的解决方案是出于现在。我只是想艮了一个快速测试对这个项目,运行它的命令行,并控制台拖延我。帮助!
解决方案
Windows命令行在这方面非常有限。解决方法是创建“路径jar”。这是一个只包含 Manifest.mf
文件的jar,其 Class-Path
指定了长长的jar列表的磁盘路径等。现在只需添加此将jar 路径化到命令行类路径。这通常比将实际资源打包在一起更方便。
我记得,磁盘路径可以相对于路径jar 本身。所以 Manifest.mf
可能看起来像这样:
Class-Path: this.jar that.jar ../lib/other.jar
如果您的路径jar 主要包含基础资源,那么它不会太频繁地更改,但您可能仍希望在构建中的某处生成它。例如:
<jar destfile="pathing.jar">
<manifest>
<attribute name="Class-Path" value="this.jar that.jar ../lib/other.jar"/>
</manifest>
</jar>
其他提示
由于Java6您可以使用 类路径通配符的.
例如: foo/*
, 是指所有。罐子文件的目录 foo
- 这将不匹配的类文件(只有罐子文件)。以配合这两个用途:
foo;foo/*
或foo/*;foo
.顺序确定什么是载入第一次。 - 搜索不递
使用"参数的文件"在Java9+
在Java9+、java可执行的支持提供论据通过的文件。看看 https://docs.oracle.com/javase/9/tools/java.htm#JSWOR-GUID-4856361B-8BFD-4964-AE84-121F5F6CF111.
这种机制明确地旨在解决问题的操作系统上的限制命令长度:
你可以缩短或简化java命令通过使用@论文件 指定文本的文件,该文件包含的论据,如选择和 类名称,通过java命令。 这让你创造java 命令的任何长度在任何操作系统。
在命令行的,使用符号(@)的前缀以识别一个 论文件,该文件包含java选择和类名称。时 java命令时遇到的文件开始在签署(@), 扩大该文件的内容变成一个参数清单只是因为他们 会上指定的命令行。
这是"正确"的解决方案,如果你正在运行的第9版或以上。这一机制简单的修改如何的说法是提供给JVM, 因此,100%的兼容的任何框架或应用程序, 无论如何,他们做的类加载即它完全等同于只是提供辩论的命令行为平常。这是不正确的,基于清单的解决办法这个操作系统的限制。
这样的一个例子是:
原命令:
java -cp c:\foo\bar.jar;c:\foo\baz.jar
可以改写为:
java @c:\path\to\cparg
哪里 c:\path\to\cparg
是一个文件,该文件包含:
-cp c:\foo\bar.jar;c:\foo\baz.jar
这个"论点文件"也支持行继续符并引进适当地处理空间路径,例如
-cp "\
c:\foo\bar.jar;\
c:\foo\baz.jar"
摇篮
如果你遇到这个问题的实例,请参见这个插件,它把你的类路径自动进入一个"论点文件"和提供,以JVM当做exec或试验任务。在Linux上或其他操作系统,它并没有默认,虽然一个可选的结构值可用于申请转换无论操作系统。
https://github.com/redocksoft/classpath-to-file-gradle-plugin
(免责声明:我是作者)
也看到这个相关实例的问题--我们希望这一能力最终将纳入摇篮核心: https://github.com/gradle/gradle/issues/1989.
(我想你并不是指DOS,而是指cmd.exe。)
我认为它不是CLASSPATH限制而是环境大小/环境变量大小限制。在XP上,单个环境变量的大小可以是8k,整个环境限制为64k。我看不出你会达到这个极限。
限制命令行长度的窗口有限制,在WindowsNT +上,cmd.exe为8k。 set命令受该限制的约束。您可以在set命令中拥有超过8k的目录吗?那么你可能会运气不好 - 即使你把它们拆分成 Nick Berardi 建议。
如果我在你的鞋子里,我会从MS下载连接工具: http://technet.microsoft.com/en-us/sysinternals/bb896768.aspx 然后映射你的
&QUOT; C:\路径&QUOT;说,“z:\”和“c:\ path2”说,“y:\”。这样,您将在 classpath
中减少每个项目4个字符。结果
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;
现在,您的类路径将是:
set CLASS_PATH=z\a\b\c;z\e\f\g;
set CLASS_PATH=%CLASS_PATH%;y:\a\b\c;y:\e\f\g;
根据您的实际 classpath
,它可能会执行更多操作。
我认为你在没有桨的情况下上了小溪。 命令行对调用程序的参数有限制。
我可以尝试2次消化。 首先,在运行junit测试之前,您可以让脚本/ ant_task在类路径上创建各种类的JAR。 然后你可以把JAR放在类路径上,这应该更短。
你可以尝试的另一种方法是创建一个运行JUNIT的antscript, 在ANT中,类路径条目不应该有这样的限制。
正如HuibertGill所提到的,我会将它包装在Ant构建脚本中,这样您就不必自己管理所有这些。
你可以试试这个
@echo off
set A=D:\jdk1.6.0_23\bin
set B=C:\Documents and Settings\674205\Desktop\JavaProj
set PATH="%PATH%;%A%;"
set CLASSPATH="%CLASSPATH%;%B%;"
转到命令提示符并运行两次(不知道为什么......我必须在Windows XP机器上执行此操作) 路径r也仅为当前命令提示会话设置
除了通过将jar文件移动到像“C:\ jars”之类的文件夹中以某种方式缩短类路径之外,没有解决问题的方法。
感谢 Raman 为Java 9+引入路径问题的新解决方案。我对 bootRun
任务进行了攻击,该任务允许使用gradle已经评估的所有内容来运行带有参数文件的java。不是很优雅,但工作。
// Fix long path problem on Windows by utilizing java Command-Line Argument Files
// https://docs.oracle.com/javase/9/tools/java.htm#JSWOR-GUID-4856361B-8BFD-4964-AE84-121F5F6CF111
// The task creates the command-line argument file with classpath
// Then we specify the args parameter with path to command-line argument file and main class
// Then we clear classpath and main parameters
// As arguments are applied after applying classpath and main class last step
// is done to cheat gradle plugin: we will skip classpath and main and manually
// apply them through args
// Hopefully at some point gradle will do this automatically
// https://github.com/gradle/gradle/issues/1989
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
bootRun {
doFirst {
def argumentFilePath = "build/javaArguments.txt"
def argumentFile = project.file(argumentFilePath)
def writer = argumentFile.newPrintWriter()
writer.print('-cp ')
writer.println(classpath.join(';'))
writer.close()
args = ["@${argumentFile.absolutePath}", main]
classpath = project.files()
main = ''
}
}
}
你试过堆叠它们吗?
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%