简体   繁体   English

调试内部编译器错误(Java)以查找有问题的源代码

[英]Debugging internal compiler error (Java) to find offending source code

I've managed to write some code that causes an error during compilation using JDK 1.8.0_131 due to a JDK bug. 由于JDK错误,我设法编写了一些在使用JDK 1.8.0_131进行编译时导致错误的代码。 I can reproduce the issue with only a few lines of code—but I can't find where in my project the error-causing pattern is being used. 我只用几行代码就可以重现这个问题 - 但是我找不到项目中使用错误的模式的位置。

My goal is to figure out which code in my project is causing this bug, and apply a workaround. 我的目标是弄清楚我的项目中的哪些代码导致了这个错误,并应用了一种解决方法。

Issue & Replication 问题和复制

The issue is outlined in the JDK-8074381 bug report and can be replicated in only a few lines of code. JDK-8074381错误报告中概述了该问题,并且只能在几行代码中复制。

public class Test {
  public interface Foo<L> extends Function<Number, String> {
    String apply(Number p);
  }
  private static final Foo CRASH = p -> "This will crash javac 1.8.0_131";
}

The issue manifests when using non-parameterized lambda instead of a non-parameterized inner class (which should both be valid according to the language spec I believe). 当使用非参数化的lambda而不是非参数化的内部类(根据我认为的语言规范应该都是有效的)时,问题就会出现。 So 所以

private static final Foo INNER = new Foo<Object>() {
  @Override
  public String apply(final Number p) {
    return "This will not crash javac 1.8.0_131";
  }
};

works fine. 工作良好。 The offending stack trace begins (truncated for your sanity): 违规堆栈跟踪开始(为了您的理智而被截断):

An exception has occurred in the compiler (1.8.0_131). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.AssertionError
        at com.sun.tools.javac.util.Assert.error(Assert.java:126)
        at com.sun.tools.javac.util.Assert.check(Assert.java:45)
        at com.sun.tools.javac.code.Types.functionalInterfaceBridges(Types.java:659)
        at com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor$TranslationContext.<init>(LambdaToMethod.java:1770)
        at com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext.<init>(LambdaToMethod.java:1853)
        at com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor.analyzeLambda(LambdaToMethod.java:1337)
        at com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor.visitLambda(LambdaToMethod.java:1322)
        at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1624)
        at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58)
        at com.sun.tools.javac.tree.TreeTranslator.visitVarDef(TreeTranslator.java:153)

Identification 鉴定

I'm aware that this issue is fixed in JDK9 , however this project requires that I use JDK 8. 我知道这个问题在JDK9中已得到修复 ,但是这个项目要求我使用JDK 8。

So rather than updating to JDK9, I need to figure out which code in this project is producing the error. 因此,我需要弄清楚这个项目中的哪些代码产生错误,而不是更新到JDK9。 Here's what I've tried. 这是我尝试过的。

  1. My first thought was to inspect the file that was being compiled when this error occurred. 我的第一个想法是检查发生此错误时正在编译的文件。 However, I'm unable to figure out how to check which source file was being compiled when the error was encountered . 但是, 我无法弄清楚如何在遇到错误时检查正在编译的源文件 If this is possible, that information would be helpful. 如果可以,那么这些信息会有所帮助。

  2. My second thought was to do a regex search of all of my code to look for any type parameterized interfaces or interfaces that extend generic interfaces. 我的第二个想法是对我的所有代码进行正则表达式搜索,以寻找扩展通用接口的任何类型参数化接口或接口。 Neither of these searches yielded code which obviously matches the issue producing code—no unused generics (changing interface Foo<L> to interface Foo in the example would fix the issue). 这些搜索都没有产生明显匹配产生代码的问题的代码 - 没有未使用的泛型(在示例中将interface Foo<L>更改为interface Foo将解决问题)。 Therefore I think that a more subtle understanding of what inside of the compiler actually causes this bug might be helpful in identifying the piece of code responsible , because it might widen my search criteria. 因此,我认为对编译器内部实际导致此错误的更细微的理解可能有助于识别负责的代码段 ,因为它可能会扩大我的搜索条件。 (It's also possible that I'm getting a bug with the exact same stack trace for a completeley different problem, but this seems unlikely to me and I'm not sure where I'd start on that, any ideas?) (这也可能是因为一个完全不同的问题我得到了一个完全相同的堆栈跟踪的错误,但这对我来说似乎不太可能,我不知道我从哪里开始,任何想法?)

I think it would be most worthwhile to be able to inspect a compiler log or something to check what was being compiled when this issue popped up. 我认为能够检查编译器日志或其他内容以检查弹出此问题时正在编译的内容是最有价值的。 Any ideas? 有任何想法吗?

Thanks. 谢谢。

I noticed that the bug report has a .out file that has the class information. 我注意到bug报告有一个包含类信息的.out文件。 The first point of reference is to follow the How to file a JDK Bug Report . 第一个参考点是遵循如何提交JDK错误报告

The javac command has a -verbose option. javac命令有一个-verbose选项。 I tried it using the class of the bug report and it wrote this output : 我尝试使用bug报告的类,它写了这个输出

javac Lib.java -verbose
[parsing started RegularFileObject[Lib.java]]
[parsing completed 26ms]
[search path for source files: .]
[search path for class files: /Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/resources.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/rt.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/sunrsasign.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/jsse.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/jce.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/charsets.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/jfr.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/classes,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/cldrdata.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/dnsns.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/jaccess.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/jfxrt.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/localedata.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/nashorn.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/sunec.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar,/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre/lib/ext/zipfs.jar,/System/Library/Java/Extensions/AppleScriptEngine.jar,/System/Library/Java/Extensions/dns_sd.jar,/System/Library/Java/Extensions/j3daudio.jar,/System/Library/Java/Extensions/j3dcore.jar,/System/Library/Java/Extensions/j3dutils.jar,/System/Library/Java/Extensions/jai_codec.jar,/System/Library/Java/Extensions/jai_core.jar,/System/Library/Java/Extensions/mlibwrapper_jai.jar,/System/Library/Java/Extensions/MRJToolkit.jar,/System/Library/Java/Extensions/vecmath.jar,.]
[loading ZipFileIndexFileObject[/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ct.sym(META-INF/sym/rt.jar/java/util/List.class)]]
[loading ZipFileIndexFileObject[/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ct.sym(META-INF/sym/rt.jar/java/util/function/Predicate.class)]]
[loading ZipFileIndexFileObject[/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ct.sym(META-INF/sym/rt.jar/java/lang/Object.class)]]
[loading ZipFileIndexFileObject[/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ct.sym(META-INF/sym/rt.jar/java/lang/Class.class)]]
[loading ZipFileIndexFileObject[/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ct.sym(META-INF/sym/rt.jar/java/lang/SuppressWarnings.class)]]
[loading ZipFileIndexFileObject[/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ct.sym(META-INF/sym/rt.jar/java/lang/annotation/Annotation.class)]]
[loading ZipFileIndexFileObject[/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ct.sym(META-INF/sym/rt.jar/java/lang/String.class)]]
[loading ZipFileIndexFileObject[/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ct.sym(META-INF/sym/rt.jar/java/lang/annotation/Target.class)]]
[loading ZipFileIndexFileObject[/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ct.sym(META-INF/sym/rt.jar/java/lang/annotation/ElementType.class)]]
[loading ZipFileIndexFileObject[/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ct.sym(META-INF/sym/rt.jar/java/lang/annotation/Retention.class)]]
[loading ZipFileIndexFileObject[/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ct.sym(META-INF/sym/rt.jar/java/lang/annotation/RetentionPolicy.class)]]
[checking Lib]
[loading ZipFileIndexFileObject[/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ct.sym(META-INF/sym/rt.jar/java/io/Serializable.class)]]
[loading ZipFileIndexFileObject[/Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/lib/ct.sym(META-INF/sym/rt.jar/java/lang/AutoCloseable.class)]]
An exception has occurred in the compiler (1.8.0_92). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.AssertionError

Given that it printed out Checking Lib and failed while compiling it makes it a useful tool to find out the source files. 鉴于它打印出来检查Lib并且在编译时失败,这使它成为查找源文件的有用工具。 So you should be able to compile your project in verbose mode and it will fail on the first instance of this error (I think) 所以你应该能够以详细模式编译你的项目,它会在这个错误的第一个实例上失败(我认为)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM