Maven 和 Ant 无法运行 Java - CreateProcess error=206,文件名或扩展名太长

问题描述 投票:0回答:5

当 maven 通过 antrun 执行此 java 代码时,我收到可怕的错误=206,文件名或扩展名太长

<java classname="com.me.api" failonerror="true" fork="true" maxmemory="128m" output="${wsdlFile}.out">
  <arg value="${className}" />
  <arg value="${name}" />
  <arg value="${wsdlFile}" />
  <classpath>
    <path refid="maven.test.classpath" />
  </classpath>

maven ant maven-antrun-plugin
5个回答
6
投票

由于本地 Maven 存储库的结构和位置,Maven 创建了冗长的类路径。我们需要使用路径 jar。

  • 将类路径转换为字符串
  • 转义 Windows 驱动器号(C: = 坏 \C: = 好)
  • 创建具有类路径属性的仅清单 jar
  • 使用路径jar而不是maven编译类路径

<mkdir dir="${classpath-compile.dir}"/>

<!-- Convert into usable string .   -->
<pathconvert property="compile_classpath_raw" pathsep=" ">
    <path refid="maven.compile.classpath"/>                        
</pathconvert>

<!-- escape windows drive letters (remove C: from paths -- need to wrap with a condition os.family="windows")-->
<propertyregex property="compile_classpath_prep" 
  input="${compile_classpath_raw}"
  regexp="([A-Z]:)"
  replace="\\\\\1"
  casesensitive="false"
  global="true"/>

<!-- Create pathing Jars -->
<jar destfile="${classpath-compile.jar}">
  <manifest>
    <attribute name="Class-Path" value="${compile_classpath_prep}"/>
  </manifest>                      
</jar>

<java classname="com.me.api" failonerror="true" fork="true" maxmemory="128m" output="${wsdlFile}.out">
  <arg value="${className}" />
  <arg value="${name}" />
  <arg value="${wsdlFile}" />
  <classpath>
    <pathelement location="${classpath-compile.jar}" />
  </classpath>


4
投票

扩展@user4386022提供的答案:您可以定义(从Ant 1.8开始)这个宏,如果您在构建过程中的不同位置遇到相同的问题,它可以帮助您(并且您不能只是在各处复制粘贴相同的代码片段,因为Ant 不允许重新定义属性,因此您将收到错误消息,指出“manifest.classpath”已定义。)

<macrodef name="create-classpath-jar" description="Create classpath Jar, to avoid getting the error about CreateProcess error=206, The filename or extension is too long">
    <attribute name="classpathjar"/>
    <attribute name="classpathref"/>
    <sequential>
        <!-- Turn the classpath into a property formatted for inclusion in a MANIFEST.MF file -->
        <local name="manifest.classpath.property"/>
        <manifestclasspath property="manifest.classpath.property" jarfile="@{classpathjar}">
            <classpath refid="@{classpathref}" />
        </manifestclasspath>
        <!-- Create the Jar -->
        <jar destfile="@{classpathjar}">
            <manifest>
                <attribute name="Class-Path" value="${manifest.classpath.property}"/>
            </manifest>                      
        </jar>
    </sequential>
</macrodef>

要在目标或任务中使用宏,只需像这样使用它:

<path id="myclasspath">
   .........
</path>
<create-classpath-jar classpathjar="classpath-compile.jar" classpathref="myclasspath" />

2
投票

如果使用 Ant 1.7 或更高版本,您可以利用 manifestclasspath 任务生成清单文件,然后将其包含在 jar 中以在 javac 类路径上使用

<!-- turn the classpath into a property formatted for inclusion in a MANIFEST.MF file -->
<manifestclasspath property="manifest.classpath"
                   jarfile="${classpath-compile.jar}">
  <classpath refid="maven.compile.classpath" />
</manifestclasspath>

<!-- Create pathing Jars -->
<jar destfile="${classpath-compile.jar}">
  <manifest>
    <attribute name="Class-Path" value="${manifest.classpath}"/>
  </manifest>                      
</jar>

<java classname="com.me.api" failonerror="true" fork="true" maxmemory="128m" output="${wsdlFile}.out">
  <arg value="${className}" />
  <arg value="${name}" />
  <arg value="${wsdlFile}" />
  <classpath>
    <pathelement location="${classpath-compile.jar}" />
</classpath>

0
投票

通过从 build.xml 文件中的 javac 目标中删除

fork="true"
解决了问题。如果您的构建过程强制要求分叉,请参阅上面的解决方案。


0
投票

Java 提供了一种简单的机制来永久解决这个问题,它被称为

@argfile
。这个想法很简单:

  1. 您无需将所有参数作为命令行参数附加到
    java
    命令,而是将它们写入一个简单的文本文件,其中每个参数位于单独的行中,例如使用
    echo
    任务。
  2. 然后指定所述文本文件的位置,如下所示:
    java @myArguments.txt

Java 然后读取文本文件并展开它在其中找到的任何内容作为参数。由于您使用 Ant,您的配置可能如下所示:

<property name="test_classpath" refid="maven.test.classpath"/>
<echo message="-classpath&#xD;&#xA;${test_classpath}&#xD;&#xA;${className}&#xD;&#xA;${name}&#xD;&#xA;${wsdlFile}"
      file="${project.build.directory}/antJvmArgs.txt"/>
<java classname="com.me.api" failonerror="true" fork="true" maxmemory="128m" output="${wsdlFile}.out">
  <arg value="@${project.build.directory}/antJvmArgs.txt" />
</java>

一些补充说明:

  • &#xD;&#xA;
    CRLF
    (Windows 换行符)的 XML 编码版本。
  • 作为参考,生成的文本文件将如下所示:
-classpath
C:\Users\username\git\myProject\target\test-classes;C:\Users\username\git\myProject\target\classes
what.ever.the.value.of.className.Is
ValueOfTheNameVariable
C:\Users\username\git\myProject\target\wsdlFile.wsdl

© www.soinside.com 2019 - 2024. All rights reserved.