2015-10-23 26 views
6

Tôi gặp sự cố với trình biên dịch Java. Tôi đơn giản hóa mã của tôi để:Trình biên dịch Java không thành công khi biên dịch chương trình đơn giản

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++; 
    } 
} 

sau khi biên soạn tôi nhận được:

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 

Tại sao Java không biên dịch này?

+2

Hành vi tương tự với 1.8.0_60. Cho dù bạn lập trình biên dịch hay không trình biên dịch không nên ném một ngoại lệ, do đó bạn có lẽ nên nộp một lỗi. – assylias

+2

* Tại sao java không biên dịch *: thông báo lỗi cho biết tại sao: có lỗi trong trình biên dịch. –

+2

Tôi đã nâng cấp lên 1.8.0_66 và trình biên dịch java vẫn bị lỗi.Tôi sẽ gửi một lỗi. – Yozer

Trả lời

4

Đây rõ ràng là lỗi trình biên dịch. Bạn nên nộp một lỗi như đầu ra chỉ thị, nhưng kể từ khi bạn hỏi tại sao Tôi sẽ cố gắng để khám phá mà :)

Các JDK langtools repo chứa mã cho javac. Tôi đã duyệt qua một số khác nhau builds nhưng không thể tìm thấy phiên bản có số dòng khớp với dấu vết ngăn xếp (tôi không chắc chắn cách match a Java version to a build number), vì vậy tôi sẽ tắt phiên bản mới nhất, b132.

Như bạn có thể thấy, vấn đề cơ bản là NullPointerException trong com.sun.tools.javac.code.Symbol trong Symbol.ClassSymbol.isSubClass(). Đó là nguồn gốc của vấn đề. Nhìn cao hơn trong theo dõi ngăn xếp, chúng tôi có thể thấy số access() gọi accessSymbol() rồi accessClass() trước khi đến isSubClass(). Vì vậy, chúng tôi có thể suy ra rằng trình biên dịch đang cố gắng xác minh phân lớp được phép truy cập super.value tại thời điểm nó không thành công.

Không biết dòng NPE nào đang xảy ra trên khó xác định được vấn đề chính xác, vì vậy rất tiếc ở đây mọi thứ bị mờ. Vì lỗi này chỉ xảy ra khi chúng tôi cố gắng tăng và đặt (++ hoặc +=) trường và chỉ khi chúng tôi gọi nó là super.value, chúng tôi hy vọng sẽ thấy một số mã liên quan đến truyền, tự động chuyển, gán hoặc số học . Không có gì trong số isSubClass() thực sự có vẻ liên quan đến bất kỳ điều gì trong số đó.

Tôi đoán, cho rằng dường như không có bất kỳ điều gì bị buộc tội trong isSubClass(), là Lower.accessClass() đang chuyển một số null vào isSubClass(). Có ba giá trị truyền cho isSubClass() trong phương pháp này: lĩnh vực currentClass (như c, đây là "lớp hiện kèm theo"), sym.owner (Tôi nghĩ sym là lĩnh vực value của chúng tôi, tôi không biết owner của nó là gì nhưng có lẽ các lớp được khai báo) và types, có vẻ luôn được đặt thành giá trị không null. Vì vậy, hoặc là currentClass hoặc sym.owner và có các tham chiếu đến sym.owner sẽ là NPE trong Lower.access() trước đó, do đó dường như cũng không phải là rỗng.

Vì vậy, tôi sẽ gây nguy hiểm cho thủ phạm là Lower.currentClass không có lý do nào. Vì currentClass là trường không phải là gói cuối cùng riêng tư, tôi sẽ không bận tâm cố gắng xác định xem nó có thể là null vào lúc này hay không, nhưng nó có thể xuất hiện. Có một số thủ phạm có thể khác trong số isSubClass() tất nhiên, vì vậy tôi cũng có thể sai.

Không kết luận, nhưng tôi hy vọng điều này mang tính thông tin! Tôi chắc chắn sẽ cập nhật nếu tôi tìm hiểu thêm.

Các vấn đề liên quan