Maven and Ant Can't run Java - CreateProcess error=206, The filename or extension is too long
Asked Answered
M

5

7

When maven via antrun executes this java code I get the dreaded error=206, The filename or extension is too long

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

Mango answered 19/7, 2013 at 14:44 Comment(0)
M
6

Maven creates lengthy classpaths due to the structure and location of the local maven repo. We need to use a pathing jar.

  • Convert Classpath into string
  • Escape windows drive letter (C: = bad \C: = good)
  • Create manifest only jar with class path attribute
  • Use the pathing jar instead of the maven compile classpath

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

Mango answered 19/7, 2013 at 14:44 Comment(2)
Where do you paste this? build section of a pom file?Hyo
@Hyo You put this as part of the maven antrun plugin, in the <plugins> section of your pom. Do refer to the maven antrun plugin and things should be clearCompiler
D
4

Extending the answer provided by @user4386022: You can define (starting with Ant 1.8) this macro which can help you if you have the same problem in different places in your build process (and you cannot just copy-paste the same snippet everywhere because Ant does not allow re-defining properties, so you will get an error saying that "manifest.classpath" is already defined.)

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

To use the macro in your targets or tasks, then simply use it like this:

<path id="myclasspath">
   .........
</path>
<create-classpath-jar classpathjar="classpath-compile.jar" classpathref="myclasspath" />
Derekderelict answered 31/3, 2015 at 11:12 Comment(1)
Note that the same macro can be used to solve the problem with "CreateProcess error=87, The parameter is incorrect" that you can get on Windows when using org.apache.axis.wsdl.WSDL2JavaDerekderelict
I
2

If using Ant 1.7 or newer you can utilize the manifestclasspath task to generate a manifest file then include it in a jar for use on the javac classpath

<!-- 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>
Iinde answered 22/12, 2014 at 17:13 Comment(0)
E
0

Fixed problem by removing fork="true" from javac target in build.xml file. Please refer to solutions above if forking is mandatory for your build process.

Ezana answered 12/2, 2020 at 14:33 Comment(0)
M
0

Java offers a simple mechanism to fix this issue for good, and it's called @argfile. The idea is simple:

  1. Instead of appending all arguments to the java command as command line arguments, you write them into a simple text file where each argument is in a separate line, e.g., using the echo task.
  2. You then specify the location of said text file like so: java @myArguments.txt

Java then reads the text file and expands anything it finds in there as arguments. Since you use Ant, your configuration might look like so:

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

Some additional explanations:

  • &#xD;&#xA; is the XML-encoded version of CRLF, the windows newline-character.
  • For reference, the generated text file would look something like this:
-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

Marileemarilin answered 12/12, 2023 at 13:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.