如何在Windows中设置长Java类路径?

时间:2008-10-14 16:08:54

标签: java junit classpath

我正在尝试在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测试,因此没有关于将我的目录结构重新安排到更合理的建议的建议,这些类型的解决方案目前还没有。我只是试图对这个项目进行快速测试并在命令行上运行它,控制台正在阻止我。救命啊!

13 个答案:

答案 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

中的所有.jar文件
  • 这不会匹配类文件(只有jar文件)。要同时使用:foo;foo/*foo/*;foo。该订单确定首先加载的内容。
  • 搜索不是递归的

答案 2 :(得分:6)

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

在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

如果您在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%