代码之家  ›  专栏  ›  技术社区  ›  Elliot Vargas

Ant的<javac>任务引发StackOverflowException

  •  6
  • Elliot Vargas  · 技术社区  · 18 年前

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

    <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>
    

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

    作为一个快速而肮脏的解决方案,我创建了2个单独的任务,在每个任务中编译项目的一部分。我真的不认为这个解决方案会持续下去,因为将来会添加更多的类,而且我不想每次达到“编译限制”时都添加新的编译任务。

    7 回复  |  直到 17 年前
        1
  •  4
  •   Community Mohan Dere    9 年前

    很高兴知道;什么可以 导致堆栈溢出错误 在编译Java代码期间?

    评估java文件中的长表达式可能会消耗大量内存,而且由于这是与其他类的编译一起完成的,VM只是耗尽了堆栈空间。您生成的类可能正在突破其内容的法律限制。见第章 4.10 Limitations of the Java Virtual Machine 在……里面 The Java Virtual Machine Specification, Second Edition .

    修复1:重构类

    由于您的类正在生成中,因此这可能不是一个选项。尽管如此,还是值得看看你的类生成工具提供的选项,看看它是否可以产生一些不那么麻烦的东西。

    修复2:增加堆栈大小

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

    我的编译器:

    $ javac -version
    javac 1.6.0_05
    

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

    javac -help
    javac -X
    javac -J-X
    

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

    javac -J-Xss10M Foo.java
    

    您或许可以在Ant文件中使用 compilerarg 元素嵌套在您的 javac 任务。

    <javac srcdir="gen" destdir="gen-bin" debug="on" fork="true">
        <compilerarg value="-J-Xss10M" />
    </javac>
    
        2
  •  1
  •   Community Mohan Dere    9 年前
      <javac srcdir="gen" destdir="gen-bin" debug="on" fork="true">
          <compilerarg value="-J-Xss10M" />
        </javac>
    

    comment above 不正确。在-J和-X之间需要一个空格,如下所示:

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

    为了避免以下错误:

     [javac] 
    [javac] The ' characters around the executable and arguments are
    [javac] not part of the command.
    [javac] Files to be compiled:
    

    ... [javac]javac:无效标志:-J-Xss1m [javac]用法:javac

        3
  •  1
  •   martin clayton egrunin    15 年前

    尝试将这些属性的一些变体添加到 Ant javac task 线路:

    memoryinitialsize="256M" memorymaximumsize="1024M"
    

    你也可以试试 fork="true" ,不确定这是否允许您设置堆栈和堆的值(又名-Xm1024),但它可能会有所帮助(如果它可以从命令行工作,但不能在Ant中工作)。

    [编辑]: 添加链接-- javac task 页面似乎暗示,上述参数要求您也进行设置 fork=“真” .

        4
  •  1
  •   martin clayton egrunin    15 年前

    从命令行运行javac命令时会发生这种情况吗?你可能想试试 fork 属性。

        5
  •  0
  •   Kieron    18 年前

    这很奇怪,100节课真的不多。当堆栈溢出时,编译器会做什么?是否生成了有用的堆栈跟踪?如果你跑步会发生什么 javac 直接在命令行而不是though ant上?

    一种可能的解决方法是使用 -Xss JVM的参数;要么运行JVM ant 或通过设置 fork="true" 以及a <compilerarg> <javac> 任务。事实上,现在我想起来了,只要把问题放在 fork=“真” ?

        6
  •  0
  •   Elliot Vargas    18 年前

    这是我发现的。 在发布我的问题后,我继续使用属性修改了编译任务 fork="true" , memoryinitialsize="256m" memorymaximumsize="1024m" (今天发现这是Kieron和jmanning2k提出的,谢谢你的时间)。尽管如此,这并没有解决问题。

    我决定开始从源代码树中删除类,看看是否可以找出问题所在。原来我们有一个Web服务客户端类 Axis 1.4 它是从WSDL文件自动生成的。现在,这个类是一个怪物(就像弗兰肯斯坦一样),它有167个字段成员(都是String类型),167个getter/setter对(每个字段1个),一个接收所有167个字段作为参数的构造函数,一个以奇怪的方式比较所有167个域的equals方法。对于每个字段,比较如下:

    (this.A == null && other.getA() == null) || (this.A != null && this.A.equals(other.getA()))
    

    此比较的结果与下一个字段的比较结果“合并”(&&),以此类推。该类继续使用一个hashCode方法,该方法还使用所有字段、一些自定义XML序列化方法和一个返回描述该类并使用所有字段成员的Axis特定元数据对象的方法。

    这个类永远不会被修改,所以我只是把一个编译后的版本放在应用程序类路径中,项目编译后没有问题。

    现在,我知道删除这个单一的源文件解决了这个问题。然而,我完全不知道为什么这门课会引起这个问题。很高兴知道;在编译Java代码时,什么会导致StackOverflowError?我想我会把这个问题贴出来。

    对于感兴趣的人:

    • Windows XP SP2
    • SUN的JDK 1.4.2_17
    • 蚂蚁1.7.0
    推荐文章