如何在Windows中设置长Java类路径?
我正试图在WindowsXP命令行上手动运行一个特定的JUnit测试,该命令行在类路径中包含异常多的元素。我尝试了几种变体,例如:如何在Windows中设置长Java类路径?,java,junit,classpath,Java,Junit,Classpath,我正试图在WindowsXP命令行上手动运行一个特定的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
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将类路径设置为java的参数”)。它总是归结为控制台抛出此错误:
The input line is too long.
The syntax of the command is incorrect.
这是一个JUnit测试,测试的是一个相当大的现有遗留项目,因此没有关于将我的目录结构重新安排到更合理的位置的建议,这些类型的解决方案现在已经过时了。我只是尝试对这个项目进行一个快速测试,并在命令行上运行它,控制台正在阻止我。帮助!Ha你试过把它们叠起来吗
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%
我认为你在这里没有划桨,处境艰难。 命令行对调用程序的参数有限制 我有两个建议你可以试试。 首先,在运行junit测试之前,可以让脚本/ant_任务在类路径上创建各种类的JAR。 然后可以将jar放在类路径上,该路径应该更短 您可以尝试的另一种方法是创建一个antscript来运行JUNIT, 在ANT中,类路径条目不应该有这样的限制。(我想你不是指DOS,而是指cmd.exe。) 我认为这与其说是一个类路径限制,不如说是一个环境大小/环境变量大小限制。在XP上,单个环境变量的大小可以是8k,整个环境的大小限制为64k。我看不出你会达到这个限制
windows上有一个限制命令行长度的限制,在WindowsNT+上,cmd.exe的长度是8k。set命令受此限制。set命令中是否有超过8k的目录?那么,您可能运气不好,即使按照建议将它们拆分。windows命令行非常有限解决方法是创建一个“路径jar”“。这是一个仅包含
Manifest.mf
文件的jar,其类路径
指定了jar长列表的磁盘路径等。现在只需将此路径jar添加到命令行类路径中即可。这通常比将实际资源打包在一起更方便
我记得,磁盘路径可以是相对于路径jar本身的。因此,Manifest.mf
可能看起来像这样:
Class-Path: this.jar that.jar ../lib/other.jar
如果您的pathing jar主要包含基础资源,那么它不会经常更改,但您可能仍然希望在构建中的某个地方生成它。例如:
<jar destfile="pathing.jar">
<manifest>
<attribute name="Class-Path" value="this.jar that.jar ../lib/other.jar"/>
</manifest>
</jar>
因为您可以使用Java 6
示例:foo/*
,引用目录foo
- 这与类文件(仅jar文件)不匹配。要匹配两者,请使用:
或foo;foo/*
。顺序决定首先加载的内容foo/*;foo
- 搜索不是递归的
类路径中,每个项目将减少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;
根据实际的类路径,它可能会做得更多。您可以试试这个
转到命令提示符并运行两次(不知道为什么…我必须在windows XP机器上这样做)
此外,仅为当前命令提示符会话设置的路径r也没有解决此问题的方法,只能通过将jar文件移动到“C:\jars”这样的文件夹中,以某种方式缩短类路径。在Java 9上使用“参数文件”+
在Java9+中,Java可执行文件支持通过文件提供参数。看见
此机制明确旨在解决操作系统对命令长度的限制问题:
您可以使用@argument文件来缩短或简化java命令
指定包含参数的文本文件,如选项和
类名称,传递给java命令这让您可以创建java
任何操作系统上任意长度的命令。
在命令行中,使用at符号(@)前缀标识
包含java选项和类名的参数文件。当
java命令遇到一个以at符号(@)开头的文件,它
将该文件的内容展开为参数列表,就像它们一样
将在命令行上指定
如果您运行的是版本9或更高版本,这是“正确”的解决方案。这种机制只是修改了参数提供给JVM的方式,因此与任何框架或应用程序都是100%兼容的,不管它们如何进行类加载,也就是说,它完全等同于像往常一样在命令行上提供参数。对于基于清单的解决方案,此操作系统限制并非如此
这方面的一个例子是:
原始命令:
java-cpc:\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上执行exec或测试任务时提供给JVM。在Linux或其他操作系统上,默认情况下它什么也不做,尽管可以使用可选的配置值来应用转换,而不考虑操作系统
(免责声明:我是作者)
另请参见相关的Gradle问题——希望是这一上限
-cp "\
c:\foo\bar.jar;\
c:\foo\baz.jar"
// 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 = ''
}
}
}
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"