我正在尝试在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
(其他变体是将classpath全部设置在一行上,通过-classpath将类路径设置为java的参数“)。它始终归结为控制台抛出它的错误:
The input line is too long.
The syntax of the command is incorrect.
这是一个测试相当大的现有遗留项目的JUnit测试,因此没有关于将我的目录结构重新安排到更合理的建议的建议,这些类型的解决方案目前还没有。我只是试图对这个项目进行快速测试并在命令行上运行它,控制台正在阻止我。救命啊!
答案 0 :(得分:52)
Windows命令行在这方面非常有限。解决方法是创建一个“路径jar”。这是一个只包含Manifest.mf
文件的jar,其Class-Path
指定了长长的jar列表的磁盘路径等。现在只需将 pathing 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>
答案 1 :(得分:20)
从Java 6开始,您可以使用classpath wildcards。
示例:foo/*
,指的是目录foo
foo;foo/*
或foo/*;foo
。该订单确定首先加载的内容。答案 2 :(得分:6)
在Java 9+中,java可执行文件支持通过文件提供参数。看到 https://docs.oracle.com/javase/9/tools/java.htm#JSWOR-GUID-4856361B-8BFD-4964-AE84-121F5F6CF111。
此机制专门用于解决OS对命令长度的限制问题:
您可以使用@argument文件来缩短或简化Java命令 指定包含参数的文本文件,例如选项和 类名,传递给java命令。 让您创建Java 任何操作系统上任何长度的命令。
在命令行中,使用at符号(@)前缀来标识一个 包含Java选项和类名的参数文件。当。。。的时候 java命令遇到一个以at符号(@)开头的文件,它 将文件内容扩展为参数列表,就像它们 将在命令行上指定。
如果您正在运行版本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"
如果您在Gradle中遇到此问题,请参阅此插件,该插件会自动将类路径转换为“参数文件”,并在Windows上执行执行或测试任务时将其提供给JVM。在Linux或其他操作系统上,默认情况下不执行任何操作,尽管可以使用可选的配置值来应用转换,而与OS无关。
https://github.com/redocksoft/classpath-to-file-gradle-plugin
(免责声明:我是作者)
另请参阅相关的Gradle问题-希望此功能最终将集成到Gradle核心:https://github.com/gradle/gradle/issues/1989。
答案 3 :(得分:4)
(我想你并不是指DOS,而是指cmd.exe。)
我认为它不是CLASSPATH限制而是环境大小/环境变量大小限制。在XP上,单个环境变量的大小可以是8k,整个环境限制为64k。我看不出你会达到这个极限。
限制命令行长度的窗口有限制,在WindowsNT +上,cmd.exe为8k。 set命令受该限制的约束。您可以在set命令中拥有超过8k的目录吗?那么你可能会运气不好 - 即使你像Nick Berardi建议的那样将它们分开。
答案 4 :(得分:1)
如果我在你的鞋子里,我会从MS下载结合实用程序:http://technet.microsoft.com/en-us/sysinternals/bb896768.aspx然后映射你的
“C:\ path”说,“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
,它可能会执行更多操作。
答案 5 :(得分:0)
我认为你在没有桨的情况下上了小溪。 命令行对调用程序的参数有限制。
我可以尝试2次消化。 首先,在运行junit测试之前,您可以让脚本/ ant_task在类路径上创建各种类的JAR。 然后你可以把JAR放在类路径上,这应该更短。
你可以尝试的另一种方法是创建一个运行JUNIT的antscript, 在ANT中,类路径条目不应该有这样的限制。
答案 6 :(得分:0)
正如HuibertGill所提到的,我会将它包装在Ant构建脚本中,这样您就不必自己管理所有这些。
答案 7 :(得分:0)
你可以试试这个
@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也仅为当前命令提示会话设置
答案 8 :(得分:0)
除了通过将jar文件移动到像“C:\ jars”这样的文件夹中以某种方式缩短类路径之外,没有解决问题的方法。
答案 9 :(得分:0)
感谢 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 = ''
}
}
}
答案 10 :(得分:0)
修复了Windows Gradle长类路径问题。修复了错误消息为“ CreateProcess error = 206,文件名或扩展名太长”的JavaExec任务
使用插件DSL:
plugins {
id "com.github.ManifestClasspath" version "0.1.0-RELEASE"
}
使用旧版插件应用程序:
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "gradle.plugin.com.github.viswaramamoorthy:gradle-util-plugins:0.1.0-RELEASE"
}
}
apply plugin: "com.github.ManifestClasspath"
答案 11 :(得分:0)
我在这里遇到了类似的问题,在 .bat 文件中有一个巨大的类路径定义。 问题是这个类路径也包含了进入巨型路径的执行路径,这很好,很有意义。 在这种情况下,软件无法运行,每次都出现“输入行太长”的消息。
解决办法: 我只是将所有文件移到了较短的位置。 例如,我试图在目录树中执行该软件,例如: c:\softwares\testing\testing_solution\one
然后我将整个结构移动到这样的点
c:\test
该软件运行良好。 我知道这不是最好的选择,但可能会对寻求快速解决方案的人有所帮助。
谢谢
答案 12 :(得分:-2)
你试过堆叠它们吗?
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%