-
Bug
-
Resolution: Unresolved
-
P4
-
8, 9
-
generic
-
generic
FULL PRODUCT VERSION :
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+134)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+134, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux eli-desktop 4.4.0-38-generic #57-Ubuntu SMP Tue Sep 6 15:42:33 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
This bug appears to be related toJDK-8146167
Type annotations with placed on the type arguments of a super type do not work in certain cases. As a simple example of such an annotation to aid in description:
class Container {
static class Nested<T> {}
static class NestedExtendsNested extends Nested<@TestAnnotation Object> {} // <- dropped annotation
}
In the case of anonymous classes, the presence of the annotation may even cause a compiler error:
class Container {
class Inner<T> {}
{
new Container().new Inner<Object>() {} // okay
new Container().new Inner<@TestAnnotation Object>() {} // error!
}
}
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to reflect over `NestedExtendsNested` in the example above and you will see that the annotation is not present even if it is specified to have runtime retention.
Try to compile the second example and javac will crash.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code should compile and the annotation should be present in every case.
ACTUAL -
The code may not compile or the annotation may not be present.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
An exception has occurred in the compiler (1.8.0_101). 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: Could not determine position of tree Inner<@TestAnnotation() Object> within frame new Inner<@TestAnnotation() Object>(<*nullchk*>new Container()){
(.Container x0) {
x0.super();
}
}
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import static org.junit.Assert.assertNotNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.AnnotatedType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = ElementType.TYPE_USE)
@interface TestAnnotation {}
class OuterExtendsNested extends Container.Nested<@TestAnnotation Object> {}
class Container {
public class Inner<T> {}
public class InnerExtendsNested extends Nested<@TestAnnotation Object> {}
public static class Nested<T> {}
public static class NestedExtendsNested extends Nested<@TestAnnotation Object> {}
}
/**
* Test for bugJDK-8146167 in javac.
*
* @author Elias N Vasylenko
*/
@SuppressWarnings("javadoc")
@RunWith(Parameterized.class)
public class JavacSupertypeAnnotationsTest {
@Parameters(name = "{0}")
public static Object[][] testClasses() {
class StaticInner<T> {}
class StaticInnerExtendsStaticInner extends StaticInner<@TestAnnotation Object> {}
return new Object[][] {
// ecj and javac fail
{ "outer extends nested", OuterExtendsNested.class },
// ecj and javac fail
{ "inner extends nested", Container.InnerExtendsNested.class },
// ecj and javac fail
{ "nested extends nested", Container.NestedExtendsNested.class },
// ecj and javac fail
{ "anonymous extends nested", new Container.Nested<@TestAnnotation Object>() {}.getClass() },
// ecj fails
{ "static inner extends static inner", StaticInnerExtendsStaticInner.class },
// ecj fails
{ "anonymous extends static inner", new StaticInner<@TestAnnotation Object>() {}.getClass() },
// !javac compiler errors!
{ "anonymous extends inner", new Container().new Inner<@TestAnnotation Object>() {}.getClass() }
};
}
private final Class<?> testClass;
public JavacSupertypeAnnotationsTest(String testName, Class<?> testClass) {
this.testClass = testClass;
}
@Test
public void supertypeParameterAnnotationPresenceTest() {
AnnotatedParameterizedType superType = (AnnotatedParameterizedType) testClass.getAnnotatedSuperclass();
AnnotatedType superTypeParameter = superType.getAnnotatedActualTypeArguments()[0];
assertNotNull(superTypeParameter.getAnnotation(TestAnnotation.class));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
None known!
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+134)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+134, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux eli-desktop 4.4.0-38-generic #57-Ubuntu SMP Tue Sep 6 15:42:33 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
This bug appears to be related to
Type annotations with placed on the type arguments of a super type do not work in certain cases. As a simple example of such an annotation to aid in description:
class Container {
static class Nested<T> {}
static class NestedExtendsNested extends Nested<@TestAnnotation Object> {} // <- dropped annotation
}
In the case of anonymous classes, the presence of the annotation may even cause a compiler error:
class Container {
class Inner<T> {}
{
new Container().new Inner<Object>() {} // okay
new Container().new Inner<@TestAnnotation Object>() {} // error!
}
}
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to reflect over `NestedExtendsNested` in the example above and you will see that the annotation is not present even if it is specified to have runtime retention.
Try to compile the second example and javac will crash.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code should compile and the annotation should be present in every case.
ACTUAL -
The code may not compile or the annotation may not be present.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
An exception has occurred in the compiler (1.8.0_101). 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: Could not determine position of tree Inner<@TestAnnotation() Object> within frame new Inner<@TestAnnotation() Object>(<*nullchk*>new Container()){
(.Container x0) {
x0.super();
}
}
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import static org.junit.Assert.assertNotNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.AnnotatedType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = ElementType.TYPE_USE)
@interface TestAnnotation {}
class OuterExtendsNested extends Container.Nested<@TestAnnotation Object> {}
class Container {
public class Inner<T> {}
public class InnerExtendsNested extends Nested<@TestAnnotation Object> {}
public static class Nested<T> {}
public static class NestedExtendsNested extends Nested<@TestAnnotation Object> {}
}
/**
* Test for bug
*
* @author Elias N Vasylenko
*/
@SuppressWarnings("javadoc")
@RunWith(Parameterized.class)
public class JavacSupertypeAnnotationsTest {
@Parameters(name = "{0}")
public static Object[][] testClasses() {
class StaticInner<T> {}
class StaticInnerExtendsStaticInner extends StaticInner<@TestAnnotation Object> {}
return new Object[][] {
// ecj and javac fail
{ "outer extends nested", OuterExtendsNested.class },
// ecj and javac fail
{ "inner extends nested", Container.InnerExtendsNested.class },
// ecj and javac fail
{ "nested extends nested", Container.NestedExtendsNested.class },
// ecj and javac fail
{ "anonymous extends nested", new Container.Nested<@TestAnnotation Object>() {}.getClass() },
// ecj fails
{ "static inner extends static inner", StaticInnerExtendsStaticInner.class },
// ecj fails
{ "anonymous extends static inner", new StaticInner<@TestAnnotation Object>() {}.getClass() },
// !javac compiler errors!
{ "anonymous extends inner", new Container().new Inner<@TestAnnotation Object>() {}.getClass() }
};
}
private final Class<?> testClass;
public JavacSupertypeAnnotationsTest(String testName, Class<?> testClass) {
this.testClass = testClass;
}
@Test
public void supertypeParameterAnnotationPresenceTest() {
AnnotatedParameterizedType superType = (AnnotatedParameterizedType) testClass.getAnnotatedSuperclass();
AnnotatedType superTypeParameter = superType.getAnnotatedActualTypeArguments()[0];
assertNotNull(superTypeParameter.getAnnotation(TestAnnotation.class));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
None known!