Ant的<javac>任务抛出StackOverflowException

Ell*_*gas 5 java ant

我正在尝试使用以下ant任务从一个干净的目录(无增量编译)编译来自不同包的100多个Java类:

<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>
Run Code Online (Sandbox Code Playgroud)

但是,第一次运行编译任务时,总是会得到一个StackOverflowException。如果我再次运行任务,编译器将进行增量构建,并且一切正常。这是不可取的,因为我们正在使用CruiseControl进行每日自动构建,这会导致错误的构建失败。

作为一个快捷的解决方案,我创建了2个单独的任务,在每个任务中编译项目的各个部分。我真的不认为此解决方案会随着将来添加更多的类而保持不变,并且我不想每次我们达到“编译限制”时都添加新的编译任务。

McD*_*ell 5

很高兴知道。什么可能导致或导致Java代码编译期间出现StackOverflowError?

评估Java文件中的长表达式很可能会消耗大量内存,并且由于这是与其他类的编译一起完成的,因此VM只会耗尽堆栈空间。您生成的类可能正在推动其内容的法律限制。见章Java虚拟机的局限性4.10的Java虚拟机规范,第二版

修复1:重构类

由于正在生成您的类,因此这可能不是一个选择。尽管如此,还是值得看一下您的类生成工具提供的选项,以查看它是否可以减少麻烦。

修复2:增加堆栈大小

我认为Kieron在提及-Xss参数时有一个解决方案。javac接受许多非标准参数,这些参数在版本和编译器供应商之间会有所不同。

我的编译器:

$ javac -version
javac 1.6.0_05
Run Code Online (Sandbox Code Playgroud)

要列出所有选项,我将使用以下命令:

javac -help
javac -X
javac -J-X
Run Code Online (Sandbox Code Playgroud)

认为默认情况下,javac的堆栈限制为512Kb。您可以使用以下命令将此编译器的堆栈大小增加到10Mb:

javac -J-Xss10M Foo.java
Run Code Online (Sandbox Code Playgroud)

您可能能够在Ant文件以通过这个compilerarg嵌套在元素的javac任务。

<javac srcdir="gen" destdir="gen-bin" debug="on" fork="true">
    <compilerarg value="-J-Xss10M" />
</javac>
Run Code Online (Sandbox Code Playgroud)