Monday, April 2, 2012

Avoiding long classpath issue in Ant

Recently i faced a hard time to fix the long classpath issue which occurred in windows, when we use Ant as our building tool.. I looked for various options in the net but none of them worked..

My initial build script was like this;
 <target name="init">
        <mkdir dir="${class.dir}"/>
        <mkdir dir="./../../work/temp/sampleClient"/>
        <path id="javac.classpath">
            <pathelement path="${class.dir}"/>
              <fileset dir="../../repository/components/plugins">        
                <include name="**/*.jar"/>
            </fileset>
            <fileset dir="../../lib">
                <include name="*.jar"/>
            </fileset>                
        </path>
</target>


<target name="compile" depends="init" description="Compile all Java"> 
        <javac srcdir="src" destdir="${class.dir}" includeantruntime="false" >         
            <classpath refid="javac.classpath"/>         
        </javac>     
</target>
According to following Ant guide[1], Manifestclasspath, which did the trick to solve the windows long classpath  issue



I corrected my script as follows using Manifestclasspath..Here the pathing.jar which contains a single manifest file where all classpaths are defined. In manifest file, to get references for the actual paths, we define another path which contains all the jars locations explicitly defined. Then we can refer the pathing.jar inside our path element, which should be pointed as "javac.classpath's" classpath reference.
Eg:
<path id="jar.classpath">
            <pathelement path="${class.dir}"/>
            <pathelement path="../../lib"/>         
            <fileset dir="../../repository/components/plugins">            
                <include name="**/*.jar"/>
            </fileset>
            <fileset dir="../../lib">
                <include name="*.jar"/>
            </fileset>        
  </path>

<target name="init">
        <mkdir dir="${class.dir}"/>
        <mkdir dir="./../../work/temp/sampleClient"/>
        <manifestclasspath property="tem.classpath" jarfile="pathing.jar">
            <classpath refid="jar.classpath"/>
        </manifestclasspath>      
        <jar destfile="pathing.jar" basedir="target\classes">
            <manifest>            
                <attribute name="Class-Path" value="${tem.classpath}"/>
            </manifest>
        </jar>
        <path id="javac.classpath">
            <pathelement path="${class.dir}"/>
            <pathelement path="pathing.jar"/>          
        </path>
 </target>

 <target name="compile" depends="init" description="Compile all Java">
        <javac srcdir="src" destdir="${class.dir}" includeantruntime="false">
            <classpath refid="javac.classpath"/>
        </javac>
  </target>

[1]http://ant.apache.org/manual/Tasks/manifestclasspath.html

3 comments:

  1. Many thanks for publishing this solution.

    It took a fair bit of Googling to find it, but it resolved my issue in 10 mins, having previously spent about a day and a half wrestling with Ant.

    Kind regards,
    Big Mert

    ReplyDelete
    Replies
    1. Glad to know, you solved the issue..You are welcome :)

      Delete
  2. Very helpful - Thank You!! :)
    In case helpful for anyone else, I did run into 1 small problem receiving a "No suitable relative path" error. This can be resolved by including the attribute maxParentLevels on the manifestclasspath tag and try using a value greater than the default of "2".

    ReplyDelete