diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index 541b6eb8655..b5059240db5 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -159,6 +159,8 @@ #define JAVA_28_VERSION 72 +#define JDK_VERSION (7 + (JVM_CLASSFILE_MAJOR_VERSION - JAVA_7_VERSION)) + void ClassFileParser::set_class_bad_constant_seen(short bad_constant) { assert((bad_constant == JVM_CONSTANT_Module || bad_constant == JVM_CONSTANT_Package) && _major_version >= JAVA_9_VERSION, @@ -4576,9 +4578,10 @@ void ClassFileParser::verify_class_version(u2 major, u2 minor, Symbol* class_nam Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_UnsupportedClassVersionError(), - "%s has been compiled by a more recent version of the Java Runtime (class file version %u.%u), " - "this version of the Java Runtime only recognizes class file versions up to %u.0", - class_name->as_C_string(), major, minor, JVM_CLASSFILE_MAJOR_VERSION); + "%s requires a newer Java runtime. The runtime in use, Java %u, supports class file versions up " + "to %u.0, but the class file version of %s is %u.%u.", + class_name->as_C_string(), JDK_VERSION, JVM_CLASSFILE_MAJOR_VERSION, + class_name->as_C_string(), major, minor); return; } diff --git a/test/hotspot/jtreg/runtime/ClassFile/PreviewVersion.java b/test/hotspot/jtreg/runtime/ClassFile/PreviewVersion.java index f58a287a895..6c139931ba5 100644 --- a/test/hotspot/jtreg/runtime/ClassFile/PreviewVersion.java +++ b/test/hotspot/jtreg/runtime/ClassFile/PreviewVersion.java @@ -89,6 +89,21 @@ public class PreviewVersion { } } + // Add 1 to class's major version. The class should fail to load + // because it's major version is too new for this VM. + int next_major_version = prev_major_version + 2; + klassbuf[6] = (byte)((next_major_version >> 8) & 0xff); + klassbuf[7] = (byte)(next_major_version & 0xff); + try { + ByteCodeLoader.load("PVTest", klassbuf); + throw new RuntimeException("UnsupportedClassVersionError exception not thrown"); + } catch (java.lang.UnsupportedClassVersionError e) { + if (!e.getMessage().contains("requires a newer Java runtime")) { + throw new RuntimeException( + "Wrong UnsupportedClassVersionError exception: " + e.getMessage()); + } + } + // Set class's major version to 45. The class should load because class // version 45.65535 is valid. klassbuf[6] = 0; diff --git a/test/jdk/java/lang/System/Versions.java b/test/jdk/java/lang/System/Versions.java index 41041acd188..60398df53e5 100644 --- a/test/jdk/java/lang/System/Versions.java +++ b/test/jdk/java/lang/System/Versions.java @@ -60,6 +60,7 @@ public class Versions { try { Class.forName(className, false, cl); } catch (UnsupportedClassVersionError e) { + System.out.println(e); supported = false; } catch (Throwable t) { // We expect an Exception indicating invalid class file