[lworld] RFR: 8261019: [lworld] valhalla/valuetypes/QTypeDescriptorTest.java "Illegal class name "QLine; " in class file $Proxy5"

Mandy Chung mchung at openjdk.java.net
Thu Feb 4 18:14:56 UTC 2021


On Thu, 4 Feb 2021 15:57:30 GMT, Yang Yi <github.com+5010047+kelthuzadx at openjdk.org> wrote:

> Hi all,
> 
> QTypeDescriptorTest.java[0] also fails on my machine, this is occurred after merging JDK[1], I did some investigation. The root cause of the problem is that after the JDK was merged[1], the value of the constant CONSTANT_CLASS_DESCRIPTORS was changed from 61 to 62, but the major version of the class bytes generated dynamically by java.lang.reflect.ProxyGenerator was not updated simultaneously, it remained at the value 60:
> private byte[] generateClassFile() {
>   // V16 == 60
>   visit(V16, accessFlags, dotToSlash(className), null,
>           JLR_PROXY, typeNames(interfaces));
> ...
> }
> ClassFileParser::verify_legal_class_name would go to an unexpected branch, which causes ClassFormatError.
> void ClassFileParser::verify_legal_class_name(...) const {
>   ...
>   if (length > 0) {
>     ...
>     // read _major_version(60) from dynamically generated class bytes,
>     // compare with updated CONSTANT_CLASS_DESCRIPTORS(61)
>     else if (_major_version >= CONSTANT_CLASS_DESCRIPTORS && bytes[length - 1] == ';' ) {
>       // EXPECTED HERE
>       legal = verify_unqualified_name(bytes + 1, length - 2, LegalClass);
>     } else {
>       // GO TO HERE
>       legal = verify_unqualified_name(bytes, length, LegalClass);
>     }
>   }
>   if (!legal) {
>     ResourceMark rm(THREAD);
>     assert(_class_name != NULL, "invariant");
>     Exceptions::fthrow(
>       THREAD_AND_LOCATION,
>       vmSymbols::java_lang_ClassFormatError(),
>       "Illegal class name "%.*s" in class file %s", length, bytes,
>       _class_name->as_C_string()
>     );
>     return;
>   }
> }
> JDK-826101 suspects that JDK-8261021[2]  has the same problem since their exception messages are relatively similar. But according to their stack traces, they might be caused by different but related problems.
> 
> [0] https://bugs.openjdk.java.net/browse/JDK-8261019
> [1] https://github.com/openjdk/valhalla/pull/316
> [2] https://bugs.openjdk.java.net/browse/JDK-8261021

Thanks for fixing it.

src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java line 456:

> 454:      */
> 455:     private byte[] generateClassFile() {
> 456:         visit(V17, accessFlags, dotToSlash(className), null,

Alternatively, we can use the value of the system property `java.class.version` to prepare for future class file version change.  But this requires parsing it to extract the major version.

I'm okay with this simple approach and remember to update it if the class file version is bumped.

-------------

Marked as reviewed by mchung (Committer).

PR: https://git.openjdk.java.net/valhalla/pull/320


More information about the valhalla-dev mailing list