Ant’s tasks throws StackOverflowException

I’m trying to compile over 100 java classes from different packages from a clean directory (no incremental compiles) using the following ant tasks:

<target name="-main-src-depend">
    <depend srcdir="${src.dir}" 
            destdir="${bin.dir}" 
            cache="${cache.dir}"
            closure="true"/>
</target>   

<target name="compile" depends="-main-src-depend"
        description="Compiles the project.">

    <echo>Compiling</echo>

    <javac  target="${javac.target}"
            source="${javac.source}"
            debug="${javac.debug}"
            srcdir="${src.dir}"
            destdir="${bin.dir}">
        <classpath>
            <path refid="runtime.classpath"/>
            <path refid="compile.classpath"/>
        </classpath>
    </javac>
</target>

However, the first time I run the compile task I always get a StackOverflowException. If I run the task again the compiler does an incremental build and everything works fine. This is undesirable since we are using CruiseControl to do an automatic daily build and this is causing false build failures.

As a quick-and-dirty solution I have created 2 separate tasks, compiling portions of the project in each. I really don’t think this solution will hold as more classes are added in the future, and I don’t want to be adding new compile tasks every time we hit the “compile limit”.

Answer

It will be nice to know; what can cause or causes a StackOverflowError during compilation of Java code?

It is probable that evaluating the long expression in your java file consumes lots of memory and because this is being done in conjunction with the compilation of other classes, the VM just runs out of stack space. Your generated class is perhaps pushing the legal limits for its contents. See chapter 4.10 Limitations of the Java Virtual Machine in The Java Virtual Machine Specification, Second Edition.

Fix 1: refactor the class

Since your class is being generated, this might not be an option. Still, it is worth looking at the options your class generation tool offers to see if it can produce something less troublesome.

Fix 2: increase the stack size

I think Kieron has one solution when he mentions the -Xss argument. javac takes a number of non-standard arguments that will vary between versions and compiler vendors.

My compiler:

$ javac -version
javac 1.6.0_05

To list all the options for it, I’d use these commands:

javac -help
javac -X
javac -J-X

I think the stack limit for javac is 512Kb by default. You can increase the stack size for this compiler to 10Mb with this command:

javac -J-Xss10M Foo.java

You might be able to pass this in an Ant file with a compilerarg element nested in your javac task.

<javac srcdir="gen" destdir="gen-bin" debug="on" fork="true">
    <compilerarg value="-J-Xss10M" />
</javac>