In some cases, ClassReader.readLabel fails when local variables are annotated with non-RetentionPolicy.SOURCE retention policy annotations
Hello,
I'm not sure if it's a right place to ask, but let me try. I'm using RetroLambda in order to backport some of my code to Java 6. During backporting of a particular class I'm getting the following exception:
java.lang.RuntimeException: Failed to backport class: lsh/gtfs/data/feed/CsvDeserializer
at net.orfjackal.retrolambda.Transformers.transform(Transformers.java:129)
at net.orfjackal.retrolambda.Transformers.transform(Transformers.java:107)
at net.orfjackal.retrolambda.Transformers.backportClass(Transformers.java:47)
at net.orfjackal.retrolambda.Retrolambda.run(Retrolambda.java:92)
at net.orfjackal.retrolambda.Main.main(Main.java:28)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 28
at net.orfjackal.retrolambda.asm.ClassReader.readLabel(ClassReader.java:2251)
at net.orfjackal.retrolambda.asm.ClassReader.readTypeAnnotations(ClassReader.java:1678)
at net.orfjackal.retrolambda.asm.ClassReader.readCode(ClassReader.java:1210)
at net.orfjackal.retrolambda.asm.ClassReader.readMethod(ClassReader.java:1032)
at net.orfjackal.retrolambda.asm.ClassReader.accept(ClassReader.java:708)
at net.orfjackal.retrolambda.asm.ClassReader.accept(ClassReader.java:521)
at net.orfjackal.retrolambda.Transformers.lambda$transform$4(Transformers.java:107)
at net.orfjackal.retrolambda.Transformers.transform(Transformers.java:125)
Please note that the array index 28
may be different depending on a length of the method that fails to be backported (if I'm not mistaken while trying to narrow down).
Here is the class that fails (it shrank a lot and now looks weird):
final class CsvDeserializer
implements IDeserializer<Map<String, String>> {
private static final IDeserializer<Map<String, String>> instance = new CsvDeserializer();
private CsvDeserializer() {
}
static IDeserializer<Map<String, String>> get() {
return instance;
}
@Nonnull
@Override
public CalendarDate toCalendarDate(@Nonnull final Map<String, String> row) {
@Nonnull
@Id LocalDate date = As.id(null); // a factory method to check legal values assignment (ids can be only assigned to ids) using Checker Framework
assert date != null; // keep javac from discarding the `date` reference
return null; // no need to instantiate for testing purposes
}
}
Once I remove the @Id
annotation from the date
reference, it succeeds.
However, if I, for example, move the same code to another method (cannot see the reasons clear, and not sure how do I do it) or change the @Id
retention policy to SOURCE
(actually Checker Framework requires CLASS
to work across modules), it succeeds too.
The @Id
annotation is declared as follows:
@SubtypeOf(Any.class)
@Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER })
public @interface Id {
}
How I run it:
java \
-Dretrolambda.bytecodeVersion=50 \
-Dretrolambda.classpath=input \
-Dretrolambda.defaultMethods=true \
-Dretrolambda.inputDir=input \
-Dretrolambda.outputDir=output \
-jar retrolambda-2.5.4.jar[javacbug.zip](/uploads/0a023a9ee93c395aca5d280977aec740/javacbug.zip)
My toolchain:
- Retrolambda 2.5.4 with transitive
asm-debug-all:5.2
- Oracle JDK 1.8.0_151 (Windows/Linux; x64)
I tried to rebuild Retrolambda 2.5.5-SNAPSHOT with asm-debug-all:6.0_BETA
-- the effect is the same.
(Not sure, Retrolambda seems to be unable to be easily upgraded to a newer asm 6+ -- it can use 5.2 only.)
Could you please confirm the issue?
Thanks.