Constants.checkAsm8Experimental prevents using ASM8_EXPERIMENTAL API in classes that were compiled for previous Java major release
Summary
Can't read class files for Java 14 in classes that were compiled for a previous version.
Reproducing
- Compile a Java class for JDK 14, possibly containing a record. (
Foo.java
->Foo.class
) - Create a class (
Reader.java
) that readsFoo.class
using a customClassVisitor
subclass, but compile it to Java 8. - Try running
Reader.class
that readsFoo.class
using theASM8_EXPERIMENTAL
API. - An
IllegalStateException
is thrown due to the checks inConstants.java
.
Expected output
The successful reading of Foo.class
, possibly using record visitors.
Actual output
IllegalStateException
as the ClassVisitor
subclass wasn't compiled with --enable-preview
.
Solution
Remove these checks, or make them bypassable. By having the ASM8_EXPERIMENTAL
declared as deprecated, it is our responsibility to mitigate possible future API changes, not the library's to enforce its possibly breaking usage.
Another solution is to compile the reading classes for JDK 14, however, that would also require the user of the class to use the --enable-preview
flag when running java
, or else the following exception is thrown:
java.lang.UnsupportedClassVersionError: Preview features are not enabled for foo/Bar (class file version 58.65535). Try running with '--enable-preview'
By the way, the callerClass.getClassLoader().getResourceAsStream(internalName + ".class")
way of retrieving the bytes of the caller class is prone to breakage, as some classloaders may not use conventional class loading mechanisms.
Use-case
We're trying to implement Java 14 compilation support for the saker.build system, however, this bug prevents us from properly analyzing the compiled class bytes. (Related issue)
The solution for passing --enable-preview
for the java
process that is running the build is not possible, as it may be embedded in other Java processes (e.g. Eclipse) that we can't have control over.
We also need to be able to run the Java classes that perform the class file reading on older JDK releases.