Hitachi Vantara Pentaho Community Wiki
Child pages
  • Working around long Classpath issue in Windows
Skip to end of metadata
Go to start of metadata

Running ant task on windows

If you are building the code in linux or mac, you will not have to worry about the long classpath error. But you are using windows, then it is likely that you will run into following errors while running an Ant build

java.io.IOException: Cannot run program "C:\Program Files\Java\jdk1.8.0_73\bin\javac.exe"
(in directory "c:\<workspace folder>\pentaho-platform-ee\bi-platform-ee"): CreateProcess error=206, The filename or extension is too long

Possible solutions

Searching for the solutions on the web, I found a few workarounds 

  • Reduce the classpath
  • Use directories instead of jar files. For example, if the directory foo contains a.jar and b.jar, then the foo/* can be specified in the classpath. The only limitation is you cannot specify the order in which the jar files will be added in the classpath.
  • Use the classpath attribute inside of manifest file to point to other jars.

Classpath attribute of manifest file

In this approach, you can create an empty jar file and specify all the jars in the classpath attribute of the manifest. For example, following section list the content of manifest file inside of jar.

Manifest file entries
Manifest-Version: 1.0
Class-Path:
 activation-1.1.jar
 annogen-0.1.0.jar
 antlr-complete-3.5.2.jar

Ant version 1.7, includes a new task 'manifestclasspath', which converts the classpath into space separated list of items. This can be used to set the class-path attribute of the manifest. 

<manifestclasspath property="jar.classpath"
                       jarfile="MyJar.jar">
      <classpath refid="classpath" />
</manifestclasspath>

Example Usage

Here is an example of using the above approach to resolve the long classpath issue while building pentaho-platform-extensions

  • Copy the following target into subfloor.xml,. This creates Manifest-path.jar using the classpath refid - 'classpath'. The classpath refid in subfloor.xml, includes all the jars that are present in lib and dev-lib folder. So essentially, class-path attribute of manifest of Manifest-path.jar will have all the jars that are present in lib and dev-lib folder. The path element of the target then adds the newly created Manifest-path.jar in the manifest.classpath.
    <target name="manifest.jar">
          <manifestclasspath property="jar.classpath" jarfile="${bin.dir}/Manifest-path.jar">
                <classpath refid="classpath"/>
          </manifestclasspath>
          <jar destfile="${bin.dir}/Manifest-path.jar">
             <manifest>
                  <attribute name="Built-By" value="${user.name}" />
                  <attribute name="Class-Path" value="${jar.classpath}"/>
             </manifest>
          </jar>
          <path id="manifest.classpath">
             <pathelement path="${bin.dir}/Manifest-path.jar"/>
          </path>
    </target>
    
  •  In the compile.compile target, change the path refid from classpath to manifest.classpath. Add the new target 'manifest.jar' as dependency to make sure it gets executed first.
     
     <target name="compile.compile" depends="init, manifest.jar">
        <javac destdir="${classes.dir}"
               debug="${javac.debug}"
               deprecation="${javac.deprecation}"
               fork="true"
               memorymaximumsize="${javac.maxmemory}"
               source="${javac.source}"
               target="${javac.target}"
               encoding="UTF-8">
          <classpath>
            <!-- path refid="classpath"/ -->
          	<path refid="manifest.classpath"/>
          </classpath>
          <src path="${src.dir}"/>
          <compilerarg value="${javac.xlint}"/>
        </javac>
      </target>
  • No labels