Issue #5475 - Changing ASM API version lookup to use Reflection against ASM Opcodes.

Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
Joakim Erdfelt 2020-10-20 09:34:38 -05:00
parent fa713979c0
commit a3e3632340
No known key found for this signature in database
GPG Key ID: 2D0E1FB8FE4B68B4
1 changed files with 27 additions and 20 deletions

View File

@ -30,6 +30,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -47,6 +48,7 @@ import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/** /**
* AnnotationParser * AnnotationParser
@ -81,31 +83,36 @@ public class AnnotationParser
/** /**
* Determine the runtime version of asm. * Determine the runtime version of asm.
* *
* @return the org.objectweb.asm.Opcode matching the runtime version of asm. * @return the {@link org.objectweb.asm.Opcodes} ASM value matching the runtime version of asm.
*/ */
private static int asmVersion() private static int asmVersion()
{ {
// We need to search for the highest known ASM version. // Find the highest available ASM version on the runtime/classpath, because
// If we run with a lower than known ASM version, then if run on a JVM with new language features // if we run with a lower than available ASM version, against a class with
// we will get UnsupportedOperationsExceptions, even if the version of ASM is updated to support them. // new language features we'll get an UnsupportedOperationException, even if
// If we run with a higher than known ASM version, then we will get a unknown version exception. // the ASM version supports the new language features.
// So we need the Goldilocks version! // Also, if we run with a higher than available ASM version, we'll get
int asmVersion = 7; // an IllegalArgumentException from org.objectweb.asm.ClassVisitor.
while (true) // So must find exactly the maximum ASM api version available.
Optional<Integer> asmVersion = Arrays.stream(Opcodes.class.getFields()).sequential()
.filter((f) -> f.getName().matches("ASM[0-9]+"))
.map((f) -> f.getName().substring(3))
.map(Integer::parseInt)
.max(Integer::compareTo);
if (!asmVersion.isPresent())
throw new IllegalStateException("Invalid " + Opcodes.class.getName());
int asmFieldId = asmVersion.get();
try
{ {
try return (int)Opcodes.class.getField("ASM" + asmFieldId).get(null);
{ }
int nextVersion = asmVersion + 1; catch (Throwable e)
new ClassVisitor(nextVersion << 16, null) {
{}; throw new IllegalStateException(e);
asmVersion = nextVersion;
}
catch (Throwable th)
{
break;
}
} }
return asmVersion << 16;
} }
/** /**