49

我正在尝试在 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 将类路径设置为 java 的参数)。它总是归结为控制台抛出此错误:

The input line is too long.
The syntax of the command is incorrect.

这是一个 JUnit 测试,测试一个相当大的现有遗留项目,所以没有关于将我的目录结构重新排列为更合理的建议,这些类型的解决方案现在已经出来了。我只是想对这个项目进行快速测试并在命令行上运行它,而控制台让我望而却步。帮助!

4

13 回答 13

59

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>
于 2008-10-14T16:52:51.930 回答
20

从 Java 6 开始,您可以使用类路径通配符

示例:foo/*, 指目录下的所有 .jar 文件foo

  • 这将不匹配类文件(仅 jar 文件)。要匹配两者,请使用:foo;foo/*foo/*;foo。顺序决定了首先加载什么。
  • 搜索不是递归的
于 2008-10-14T17:14:25.680 回答
14

在 Java 9+ 上使用“参数文件”

在 Java 9+ 中,java 可执行文件支持通过文件提供参数。请参阅 https://docs.oracle.com/javase/9​​/tools/java.htm#JSWOR-GUID-4856361B-8BFD-4964-AE84-121F5F6CF111

该机制明确旨在解决操作系统对命令长度的限制问题:

您可以通过使用 @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 上执行 exec 或测试任务时将其提供给 JVM。在 Linux 或其他操作系统上,默认情况下它什么都不做,尽管可以使用可选的配置值来应用转换,而不管操作系统如何。

https://github.com/redocksoft/classpath-to-file-gradle-plugin

(免责声明:我是作者)

另请参阅这个相关的 Gradle 问题——希望这个功能最终会集成到 Gradle 核心中:https ://github.com/gradle/gradle/issues/1989 。

于 2019-01-19T19:52:12.013 回答
4

(我想你不是真的指 DOS,而是指 cmd.exe。)

我认为它不是 CLASSPATH 限制,而是环境大小/环境变量大小限制。在 XP 上,单个环境变量的大小可以是 8k,整个环境限制为 64k。我看不出你会达到那个极限。

Windows 有限制命令行长度的限制,在 WindowsNT+ 上,cmd.exe 为 8k。设置命令受此限制。你的 set 命令中有超过 8k 的目录吗?那么,您可能不走运——即使您像尼克·贝拉迪( Nick Berardi)建议的那样将它们分开。

于 2008-10-14T16:25:10.990 回答
2

感谢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 = ''
        }
    }
}

于 2019-03-22T13:03:16.480 回答
1

如果我站在你的立场上,我会从 MS 下载 junction 实用程序: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;

现在,您的类路径将是:

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

于 2008-10-14T18:08:48.800 回答
0

我想你在这里没有桨就在小溪上。命令行对调用程序的参数有限制。

我有 2 个你可以尝试的建议。首先,在运行 junit 测试之前,您可以让 script/ant_task 在类路径上创建各种类的 JAR。然后您可以将 JAR 放在应该更短的类路径上。

您可以尝试的另一种方法是创建一个 antscript 来运行 JUNIT,在 ANT 中,类路径条目不应该有这样的限制。

于 2008-10-14T16:20:33.650 回答
0

正如 HuibertGill 所提到的,我会将其包装在 Ant 构建脚本中,这样您就不必自己管理所有这些。

于 2008-10-14T17:21:10.407 回答
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 仅为当前命令提示符会话设置

于 2012-07-10T15:04:08.210 回答
0

除了通过将 jar 文件移动到“C:\jars”之类的文件夹中以某种方式缩短类路径之外,没有解决该问题的方法。

于 2016-10-19T10:15:35.513 回答
0

修复了 windows gradle 长类路径问题。修复 JavaExec 任务出错并显示消息“CreateProcess error=206, The filename or extension is too long”

使用插件 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"
于 2019-12-17T09:06:46.603 回答
0

我在这里遇到了类似的问题,在 .bat 文件中定义了一个巨大的类路径。问题是这个类路径也包括执行路径到巨大的路径中,它的好,它是有意义的。在这种情况下,软件无法运行,并且每次都出现“输入行太长”的消息。

解决方案:我只是将所有文件移到较短的位置。例如,我试图在目录树中执行软件,例如:c:\softwares\testing\testing_solution\one

我将整个结构移到了这样的位置

c:\测试

该软件运行良好。我知道,这不是最好的选择,但可能会对寻求快速解决方案的人有所帮助。

Tks

于 2021-06-02T13:12:37.610 回答
-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%
于 2008-10-14T16:20:21.873 回答