読者です 読者をやめる 読者になる 読者になる

エンジニア的なネタを毎週書くブログ

東京でWebサービスの開発をしています 【英語版やってみました】http://taichiw-e.hatenablog.com/

レガシーコードを JDK 8 でビルドしようとしたら "The system is out of resources" が出た話

今までJDK7でビルドされていたJavaプログラムをJDK8でビルドしようとしたところ、コンパイル時にこんなエラーが出ました。

The system is out of resources.
Consult the following stack trace for details.
java.lang.StackOverflowError
	at com.sun.tools.javac.code.Type.hasTag(Type.java:112)
	at com.sun.tools.javac.code.Types$13.visitClassType(Types.java:1967)
	at com.sun.tools.javac.code.Types$13.visitClassType(Types.java:1955)
	at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:786)
	at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:4571)
	at com.sun.tools.javac.code.Types.asSuper(Types.java:1952)
	at com.sun.tools.javac.code.Types$13.visitClassType(Types.java:1968)
	at com.sun.tools.javac.code.Types$13.visitClassType(Types.java:1955)
	at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:786)
	at com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:4571)
	at com.sun.tools.javac.code.Types.asSuper(Types.java:1952)
	at com.sun.tools.javac.code.Types.unboxedType(Types.java:3987)
	at com.sun.tools.javac.code.Types.unboxedTypeOrType(Types.java:3998)
	at com.sun.tools.javac.comp.DeferredAttr$ArgumentExpressionKind.standaloneKind(DeferredAttr.java:1135)
	at com.sun.tools.javac.comp.DeferredAttr$DeferredChecker.visitLiteral(DeferredAttr.java:1296)
	at com.sun.tools.javac.tree.JCTree$JCLiteral.accept(JCTree.java:2037)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
	at com.sun.tools.javac.comp.DeferredAttr$FilterScanner.scan(DeferredAttr.java:913)
	at com.sun.tools.javac.comp.DeferredAttr.isDeferred(DeferredAttr.java:1100)
	at com.sun.tools.javac.comp.Attr.attribArgs(Attr.java:660)
	at com.sun.tools.javac.comp.Attr.visitApply(Attr.java:1806)
	at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1465)
	at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:566)
	at com.sun.tools.javac.comp.Attr.visitSelect(Attr.java:3226)
	at com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1897)
	at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:566)
	at com.sun.tools.javac.comp.Attr.visitApply(Attr.java:1815)
	at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1465)
	at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:566)
	at com.sun.tools.javac.comp.Attr.visitSelect(Attr.java:3226)
	at com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1897)
	at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:566)
	at com.sun.tools.javac.comp.Attr.visitApply(Attr.java:1815)
	at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1465)
        (以降、繰り返し)

事象
・チームで使っているJenkinsと私のマシンのローカルだと本事象が発生
・他の2人に、ローカルでビルドを試してもらったら正常ビルドできた

mavenビルド時にjavacのログを出す方法を見つけたので試してみる。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <compilerArguments>
            <verbose/>
        </compilerArguments>
    </configuration>
</plugin>

http://stackoverflow.com/questions/2210005/config-maven-2-to-print-out-javac-commands-during-compile-phase

[checking xx.xx.xxxxx.xxxxx.xxxx..XxxxxXxxxxxXxxxx]


The system is out of resources.
Consult the following stack trace for details.
java.lang.StackOverflowError
	at com.sun.tools.javac.comp.Resolve.findIdent(Resolve.java:2104)

数回試したけど毎回同じクラスで落ちてる!

で、そのクラスを覗いてみると…

private static String SQL = new StringBuilder().append(LINE).append(
"SELECT XXXXXXXX        ").append(LINE).append(
"     , XXXXXXXXXXXXXXXX").append(LINE).append(
"     , XXXXXXXXXXXXXXXX").append(LINE).append(
"     , XXXXXXXXXX      ").append(LINE).append(
"     , XXXXXXXX        ").append(LINE).append(
"     , XXXXXXXXXXXX    ").append(LINE).append(
"     , XXXXXXXXXX      ").append(LINE).append(
"     , XXXXXXX         ").append(LINE).append(

 ※以降、400行ほど続く

800を超えるappendによって作られた超巨大SQL

こいつはくせえッー!ゲロ以下のにおいがプンプンするぜッーーーーッ!!

試しにごそっと削ってみたら…

private static String SQL = "";

あっさりビルドが通りました。