FULL PRODUCT VERSION :
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
I encountered an AssertionError when compiling a work project with Java 1.8. It seems to be a bug when processing type annotations in some particular cases.
As far as I can tell, it happens only if I try to instantiate (1) an anonymous class (2) based on a generic superclass (3) with a generic constructor argument (4) that has a type annotation on one of its generic arguments (5) using an in-line constructor call expression for the constructor argument.
See the source files below for a minimal test case. My original code uses Eclipse’s nullness annotations package, I just copied one of them in the test case to make reproduction easier.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Place the two source files below in two appropriately named files/folders. Try compiling the Test class to check that it works. Then uncomment the line starting with “//~” and compile it again.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code should compile.
ACTUAL -
With the last expression uncommented, the compiler throws an AssertionError.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
D:\debug>javac test\Test.java
An exception has occurred in the compiler (1.8.0_60). Please file a bug at the Java Bug Database (http://bugreport.java.com/bugreport/) after checking the database for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.AssertionError: annotation tree hasn't been attributed yet: @NonNull()
at com.sun.tools.javac.util.Assert.error(Assert.java:133)
at com.sun.tools.javac.util.Assert.checkNonNull(Assert.java:118)
at com.sun.tools.javac.comp.Check.validateTypeAnnotation(Check.java:2745)
at com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitAnnotation(Attr.java:4461)
at com.sun.tools.javac.tree.JCTree$JCAnnotation.accept(JCTree.java:2317)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:57)
at com.sun.tools.javac.tree.TreeScanner.visitAnnotatedType(TreeScanner.java:324)
at com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitAnnotatedType(Attr.java:4466)
at com.sun.tools.javac.tree.JCTree$JCAnnotatedType.accept(JCTree.java:2373)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:57)
at com.sun.tools.javac.tree.TreeScanner.visitTypeApply(TreeScanner.java:287)
at com.sun.tools.javac.tree.JCTree$JCTypeApply.accept(JCTree.java:2135)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.tree.TreeScanner.visitNewClass(TreeScanner.java:206)
at com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitNewClass(Attr.java:4529)
at com.sun.tools.javac.tree.JCTree$JCNewClass.accept(JCTree.java:1516)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:57)
at com.sun.tools.javac.tree.TreeScanner.visitNewClass(TreeScanner.java:207)
at com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitNewClass(Attr.java:4529)
at com.sun.tools.javac.tree.JCTree$JCNewClass.accept(JCTree.java:1516)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.tree.TreeScanner.visitExec(TreeScanner.java:175)
at com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1296)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:57)
at com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitBlock(Attr.java:4557)
at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:909)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitClassDef(Attr.java:4552)
at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:693)
at com.sun.tools.javac.comp.Attr.validateTypeAnnotations(Attr.java:4450)
at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:4374)
at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4249)
at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4178)
at com.sun.tools.javac.comp.Attr.attrib(Attr.java:4153)
at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1248)
at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:901)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:860)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
at com.sun.tools.javac.main.Main.compile(Main.java:381)
at com.sun.tools.javac.main.Main.compile(Main.java:370)
at com.sun.tools.javac.main.Main.compile(Main.java:361)
at com.sun.tools.javac.Main.compile(Main.java:56)
at com.sun.tools.javac.Main.main(Main.java:42)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
// file test/Test.java:
// -----------------------------------------
package test;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicReference;
import test.NonNull;
public class Test
{
{
// This works:
new AtomicReference<ArrayList<@NonNull Long>>(new ArrayList<@NonNull Long>());
// This also works:
ArrayList<@NonNull Long> list = new ArrayList<@NonNull Long>();
new AtomicReference<ArrayList<@NonNull Long>>(list) {};
// This crashes if uncommented:
//~ new AtomicReference<ArrayList<@NonNull Long>>(new ArrayList<@NonNull Long>()) {};
}
}
// file test/NonNull.java
// -----------------------------------------
package test;
import static java.lang.annotation.ElementType.TYPE_USE;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.CLASS)
@Target({ TYPE_USE })
public @interface NonNull {
// marker annotation with no members
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
As can be seen from the test case, using a temporary variable ("list" in my case) for the argument avoids the problem. Not sure if this can be triggered in other conditions.
The issue is that it’s pretty hard to figure out where the problem is, because the assertion does not say what line in the source code triggers it.
In my case I used “javac -verbose” to find the problem file, and then I used binary search to find which line caused the problem.
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
I encountered an AssertionError when compiling a work project with Java 1.8. It seems to be a bug when processing type annotations in some particular cases.
As far as I can tell, it happens only if I try to instantiate (1) an anonymous class (2) based on a generic superclass (3) with a generic constructor argument (4) that has a type annotation on one of its generic arguments (5) using an in-line constructor call expression for the constructor argument.
See the source files below for a minimal test case. My original code uses Eclipse’s nullness annotations package, I just copied one of them in the test case to make reproduction easier.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Place the two source files below in two appropriately named files/folders. Try compiling the Test class to check that it works. Then uncomment the line starting with “//~” and compile it again.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code should compile.
ACTUAL -
With the last expression uncommented, the compiler throws an AssertionError.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
D:\debug>javac test\Test.java
An exception has occurred in the compiler (1.8.0_60). Please file a bug at the Java Bug Database (http://bugreport.java.com/bugreport/) after checking the database for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.AssertionError: annotation tree hasn't been attributed yet: @NonNull()
at com.sun.tools.javac.util.Assert.error(Assert.java:133)
at com.sun.tools.javac.util.Assert.checkNonNull(Assert.java:118)
at com.sun.tools.javac.comp.Check.validateTypeAnnotation(Check.java:2745)
at com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitAnnotation(Attr.java:4461)
at com.sun.tools.javac.tree.JCTree$JCAnnotation.accept(JCTree.java:2317)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:57)
at com.sun.tools.javac.tree.TreeScanner.visitAnnotatedType(TreeScanner.java:324)
at com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitAnnotatedType(Attr.java:4466)
at com.sun.tools.javac.tree.JCTree$JCAnnotatedType.accept(JCTree.java:2373)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:57)
at com.sun.tools.javac.tree.TreeScanner.visitTypeApply(TreeScanner.java:287)
at com.sun.tools.javac.tree.JCTree$JCTypeApply.accept(JCTree.java:2135)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.tree.TreeScanner.visitNewClass(TreeScanner.java:206)
at com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitNewClass(Attr.java:4529)
at com.sun.tools.javac.tree.JCTree$JCNewClass.accept(JCTree.java:1516)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:57)
at com.sun.tools.javac.tree.TreeScanner.visitNewClass(TreeScanner.java:207)
at com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitNewClass(Attr.java:4529)
at com.sun.tools.javac.tree.JCTree$JCNewClass.accept(JCTree.java:1516)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.tree.TreeScanner.visitExec(TreeScanner.java:175)
at com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1296)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:57)
at com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitBlock(Attr.java:4557)
at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:909)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.comp.Attr$TypeAnnotationsValidator.visitClassDef(Attr.java:4552)
at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:693)
at com.sun.tools.javac.comp.Attr.validateTypeAnnotations(Attr.java:4450)
at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:4374)
at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4249)
at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4178)
at com.sun.tools.javac.comp.Attr.attrib(Attr.java:4153)
at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1248)
at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:901)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:860)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
at com.sun.tools.javac.main.Main.compile(Main.java:381)
at com.sun.tools.javac.main.Main.compile(Main.java:370)
at com.sun.tools.javac.main.Main.compile(Main.java:361)
at com.sun.tools.javac.Main.compile(Main.java:56)
at com.sun.tools.javac.Main.main(Main.java:42)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
// file test/Test.java:
// -----------------------------------------
package test;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicReference;
import test.NonNull;
public class Test
{
{
// This works:
new AtomicReference<ArrayList<@NonNull Long>>(new ArrayList<@NonNull Long>());
// This also works:
ArrayList<@NonNull Long> list = new ArrayList<@NonNull Long>();
new AtomicReference<ArrayList<@NonNull Long>>(list) {};
// This crashes if uncommented:
//~ new AtomicReference<ArrayList<@NonNull Long>>(new ArrayList<@NonNull Long>()) {};
}
}
// file test/NonNull.java
// -----------------------------------------
package test;
import static java.lang.annotation.ElementType.TYPE_USE;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.CLASS)
@Target({ TYPE_USE })
public @interface NonNull {
// marker annotation with no members
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
As can be seen from the test case, using a temporary variable ("list" in my case) for the argument avoids the problem. Not sure if this can be triggered in other conditions.
The issue is that it’s pretty hard to figure out where the problem is, because the assertion does not say what line in the source code triggers it.
In my case I used “javac -verbose” to find the problem file, and then I used binary search to find which line caused the problem.
- duplicates
-
JDK-8057685 javac should not crash compiling type annotations
-
- Closed
-