2015-10-23 20 views
6

Mam problem z kompilatorem Java. I uproszczone mojego kodu:Kompilator Java kończy się niepowodzeniem podczas kompilowania prostego programu

package a; 

public class Base { 
    // compiles if this is made public or an int 
    protected Integer value = 0; 
} 

--- 

package b; // must be in a separate package 

import a.Base; 

public class Sub extends Base { 
    public void increment() { 
    System.out.println(super.value); 
    value++; 
    super.value = 1; 
    super.value = super.value + 1; 
    // this line crashes the compiler; the others all work 
    super.value++; 
    } 
} 

po kompilacji dostaję:

Information:java: An exception has occurred in the compiler (1.8.0_51). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you. 
Information:java: java.lang.NullPointerException 
Information:java: at com.sun.tools.javac.code.Symbol$ClassSymbol.isSubClass(Symbol.java:1020) 
Information:java: at com.sun.tools.javac.comp.Lower.accessClass(Lower.java:1108) 
Information:java: at com.sun.tools.javac.comp.Lower.accessSymbol(Lower.java:983) 
Information:java: at com.sun.tools.javac.comp.Lower.access(Lower.java:1220) 
Information:java: at com.sun.tools.javac.comp.Lower.visitSelect(Lower.java:3855) 
Information:java: at com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1897) 
Information:java: at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58) 
Information:java: at com.sun.tools.javac.comp.Lower.translate(Lower.java:2371) 
Information:java: at com.sun.tools.javac.comp.Lower.translate(Lower.java:2382) 
Information:java: at com.sun.tools.javac.comp.Lower.visitVarDef(Lower.java:3547) 
Information:java: at com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:852) 
Information:java: at com.sun.tools.javac.tree.TreeTranslator.translateVarDefs(TreeTranslator.java:78) 
Information:java: at com.sun.tools.javac.comp.Lower.visitLetExpr(Lower.java:3859) 
Information:java: at com.sun.tools.javac.tree.JCTree$LetExpr.accept(JCTree.java:2426) 
Information:java: at com.sun.tools.javac.comp.Lower.visitLetExpr(Lower.java:3860) 
Information:java: at com.sun.tools.javac.comp.Lower.visitUnary(Lower.java:3319) 
Information:java: at com.sun.tools.javac.tree.JCTree$JCUnary.accept(JCTree.java:1746) 
Information:java: at com.sun.tools.javac.tree.TreeTranslator.visitExec(TreeTranslator.java:245) 
Information:java: at com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1296) 
Information:java: at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:70) 
Information:java: at com.sun.tools.javac.tree.TreeTranslator.visitBlock(TreeTranslator.java:162) 
Information:java: at com.sun.tools.javac.comp.Lower.visitBlock(Lower.java:3561) 
Information:java: at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:909) 
Information:java: at com.sun.tools.javac.tree.TreeTranslator.visitMethodDef(TreeTranslator.java:145) 
Information:java: at com.sun.tools.javac.comp.Lower.visitMethodDefInternal(Lower.java:2828) 
Information:java: at com.sun.tools.javac.comp.Lower.visitMethodDef(Lower.java:2737) 
Information:java: at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:778) 
Information:java: at com.sun.tools.javac.comp.Lower.visitClassDef(Lower.java:2508) 
Information:java: at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:693) 
Information:java: at com.sun.tools.javac.comp.Lower.translate(Lower.java:2390) 
Information:java: at com.sun.tools.javac.comp.Lower.translateTopLevelClass(Lower.java:3932) 
Information:java: at com.sun.tools.javac.main.JavaCompiler.desugar(JavaCompiler.java:1512) 
Information:java: at com.sun.tools.javac.main.JavaCompiler.desugar(JavaCompiler.java:1356) 
Information:java: at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:901) 
Information:java: at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:860) 
Information:java: at com.sun.tools.javac.main.Main.compile(Main.java:523) 
Information:java: at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129) 
Information:java: at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138) 
Information:java: at org.jetbrains.jps.javac.JavacMain.compile(JavacMain.java:168) 
Information:java: at org.jetbrains.jps.incremental.java.JavaBuilder.compileJava(JavaBuilder.java:382) 
Information:java: at org.jetbrains.jps.incremental.java.JavaBuilder.compile(JavaBuilder.java:296) 
Information:java: at org.jetbrains.jps.incremental.java.JavaBuilder.doBuild(JavaBuilder.java:204) 
Information:java: at org.jetbrains.jps.incremental.java.JavaBuilder.build(JavaBuilder.java:176) 
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.runModuleLevelBuilders(IncProjectBuilder.java:1202) 
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk(IncProjectBuilder.java:877) 
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.buildTargetsChunk(IncProjectBuilder.java:948) 
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected(IncProjectBuilder.java:840) 
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunks(IncProjectBuilder.java:665) 
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.runBuild(IncProjectBuilder.java:372) 
Information:java: at org.jetbrains.jps.incremental.IncProjectBuilder.build(IncProjectBuilder.java:193) 
Information:java: at org.jetbrains.jps.cmdline.BuildRunner.runBuild(BuildRunner.java:137) 
Information:java: at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:293) 
Information:java: at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:124) 
Information:java: at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler$1.run(BuildMain.java:242) 
Information:java: at org.jetbrains.jps.service.impl.SharedThreadPoolImpl$1.run(SharedThreadPoolImpl.java:41) 
Information:java: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
Information:java: at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
Information:java: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
Information:java: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
Information:java: at java.lang.Thread.run(Thread.java:745) 
Information:java: Errors occurred while compiling module 'testAGH' 
Information:2015-10-23 14:23 - Compilation completed with 1 error and 0 warnings in 671ms 
Error:java: Compilation failed: internal java compiler error 

Dlaczego Java nie skompilować ten?

+2

To samo zachowanie z 1.8.0_60. Bez względu na to, czy programujesz kompilacje, czy nie, kompilator nie powinien wyrzucać wyjątku, więc prawdopodobnie powinieneś zgłosić błąd. – assylias

+2

* Dlaczego java nie kompiluje *: komunikat o błędzie mówi, dlaczego: w kompilatorze występuje błąd. –

+2

Zaktualizowałem do wersji 1.8.0_66, a kompilator java wciąż ulega awarii.Złożę błąd. – Yozer

Odpowiedz

4

Jest to oczywiście błąd kompilatora. Należy zgłosić błąd jak wyjście instruuje, ale skoro pytasz dlaczego Postaram się zbadać że :)

JDK langtools repo zawiera kod javac. Przeglądałem kilka różnych builds, ale nie byłem w stanie znaleźć wersji z numerami linii, które pasowały do ​​śladu stosu (nie jestem pewien jak do match a Java version to a build number), więc wychodzę z najnowszej wersji, b132.

Jak widać, podstawowy problem to NullPointerException w com.sun.tools.javac.code.Symbol w Symbol.ClassSymbol.isSubClass(). To jest źródło problemu. Patrząc wyżej w ślad stosu, możemy zobaczyć access() połączeń accessSymbol(), a następnie accessClass() przed osiągnięciem isSubClass(). Możemy więc wywnioskować, że kompilator próbuje zweryfikować, czy podklasa ma dostęp do super.value w momencie, gdy się nie powiedzie.

Nie wiedząc, która linia pojawia się na NPE, trudno jest dokładnie określić dokładny problem, więc niestety tutaj sytuacja staje się niewyraźna. Ponieważ to niepowodzenie występuje tylko wtedy, gdy próbujemy zwiększać i ustawiać (++ lub +=) pole i tylko wtedy, gdy będziemy go odnosić do niego jako super.value, spodziewamy się zobaczyć kod związany z rzutowaniem, autoboxingiem, przypisaniem lub arytmetyczną . Niestety nic w isSubClass() naprawdę wydaje się być związane z tym wszystkim.

Zgaduję, zważywszy, że nie wydaje się być cokolwiek obciążające w isSubClass(), że Lower.accessClass() jest przepuszczanie null do isSubClass(). Istnieją trzy wartości przekazywane do isSubClass() w tej metodzie: pole currentClass (jak c, to jest „klasa obecnie załączając”), sym.owner (myślę sym jest nasz value pole, nie wiem co jej owner jest jednak przypuszczalnie klasa, w której została zadeklarowana) i types, która zawsze będzie ustawiona na wartość inną niż null. Tak więc jest to albo currentClass lub sym.owner i istnieją odniesienia do sym.owner, które wcześniej miałyby wartość NPE w Lower.access(), więc również wydaje się, że ma wartość inną niż null.

Tak więc zaryzykuję, że winowajca jest Lower.currentClass z jakiegoś powodu jest pusty. Ponieważ currentClass jest nieprywatnym pakietem prywatnym, nie zamierzam próbować ustalić, czy może to być obecnie null, ale wydaje się to możliwe. Istnieje kilka innych możliwych winowajców, oczywiście w isSubClass(), więc mógłbym się mylić.

Niezrozumiałe, ale mam nadzieję, że to było pouczające! Z pewnością zaktualizuję, jeśli nauczę się więcej.

Powiązane problemy