Wednesday, September 5, 2012

Windows XP and Windows 2003 command-line string limitation

Came across a very weird phenomena that I'd like to share. It took me a while to pin point the problem, so I thought I might shed some light to save others the time. To make a long story short...In our company we use ant scripts in a continuous build process. If the process fails, people get really mad. So, last week I failed the build...a moment before a big delivery...

So, as I said, we use ant to compile our java projects, and have one project that compiles all the other java projects. Before my commit I checked that everything compiled fine on my machine, and then committed the code to our svn which triggers an automatic build process on our continuous build machines. Guess what? It failed. So, what went wrong? How can it compile on one platform and not on the other. I checked the Java revision, and update them to match. Would it then compile? No. I then checked the ant version and matched them (1.8). Would it then compile? No. However, I knew that the builder and my machine run different OS (2003 vs 7). The biggest problem was that the error message was quite ambiguous, and it failed in different locations at each build process. So, first an foremost, run ant -verbose to make life easier. I then got a stack trace which helped me to understand the error better. I then googled the stack-trace, and got a hint here, which referenced me to this support entry on Microsoft. To summarize:
On computers running Microsoft Windows XP or later, the maximum length of the string that you can use at the command prompt is 8191 characters. On computers running Microsoft Windows 2000 or Windows NT 4.0, the maximum length of the string that you can use at the command prompt is 2047 characters. See here.
So what was the problem? We compiled the projects by using:
...
<path id="lib.class.path">
        <fileset dir="${deploy.dir}" includes="*.jar"/>

</path>
...
 <javac...>
            ...

            <classpath refid="lib.class.path"/>
            ...
</javac>
...
This will create a command line that will eventually include all jar files in the deploy directory concatenated as a string explicitly. As a result  we overloaded this command line and passed the string length limitation, which led to compilation errors.

How can this be solved? Simply by removing the fileset property and the using the pathelement property:
...
<path id="lib.class.path">
        <pathelement path="${deploy.dir}/*"/>

</path>
...
 <javac...>
            ...

            <classpath refid="lib.class.path"/>
            ...
</javac>
...
This will create a shorter command line with only the class-path variable and all jar files implicitly will be referenced. That's it - hope it will help