8224952: RI deviates from JVMS - non-zero minor_version for class files throws UnsupportedClassVersionError
Change the JVM to follow the JVM Spec and accept non-zero minor_version for appropriate older class file versions. Reviewed-by: acorn, dholmes, iignatyev
This commit is contained in:
parent
6d3f5f851e
commit
9ee5ab5124
src/hotspot/share/classfile
test/hotspot/jtreg/runtime/ClassFile
@ -4754,60 +4754,62 @@ static bool has_illegal_visibility(jint flags) {
|
||||
|
||||
// A legal major_version.minor_version must be one of the following:
|
||||
//
|
||||
// Major_version = 45, any minor_version.
|
||||
// Major_version >= 46 and major_version <= current_major_version and minor_version = 0.
|
||||
// Major_version = current_major_version and minor_version = 65535 and --enable-preview is present.
|
||||
// Major_version >= 45 and major_version < 56, any minor_version.
|
||||
// Major_version >= 56 and major_version <= JVM_CLASSFILE_MAJOR_VERSION and minor_version = 0.
|
||||
// Major_version = JVM_CLASSFILE_MAJOR_VERSION and minor_version = 65535 and --enable-preview is present.
|
||||
//
|
||||
static void verify_class_version(u2 major, u2 minor, Symbol* class_name, TRAPS){
|
||||
ResourceMark rm(THREAD);
|
||||
const u2 max_version = JVM_CLASSFILE_MAJOR_VERSION;
|
||||
if (major != JAVA_MIN_SUPPORTED_VERSION) { // All 45.* are ok including 45.65535
|
||||
if (minor == JAVA_PREVIEW_MINOR_VERSION) {
|
||||
if (major != max_version) {
|
||||
ResourceMark rm(THREAD);
|
||||
Exceptions::fthrow(
|
||||
THREAD_AND_LOCATION,
|
||||
vmSymbols::java_lang_UnsupportedClassVersionError(),
|
||||
"%s (class file version %u.%u) was compiled with preview features that are unsupported. "
|
||||
"This version of the Java Runtime only recognizes preview features for class file version %u.%u",
|
||||
class_name->as_C_string(), major, minor, JVM_CLASSFILE_MAJOR_VERSION, JAVA_PREVIEW_MINOR_VERSION);
|
||||
return;
|
||||
}
|
||||
if (major < JAVA_MIN_SUPPORTED_VERSION) {
|
||||
Exceptions::fthrow(
|
||||
THREAD_AND_LOCATION,
|
||||
vmSymbols::java_lang_UnsupportedClassVersionError(),
|
||||
"%s (class file version %u.%u) was compiled with an invalid major version",
|
||||
class_name->as_C_string(), major, minor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Arguments::enable_preview()) {
|
||||
ResourceMark rm(THREAD);
|
||||
Exceptions::fthrow(
|
||||
THREAD_AND_LOCATION,
|
||||
vmSymbols::java_lang_UnsupportedClassVersionError(),
|
||||
"Preview features are not enabled for %s (class file version %u.%u). Try running with '--enable-preview'",
|
||||
class_name->as_C_string(), major, minor);
|
||||
return;
|
||||
}
|
||||
if (major > max_version) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
} else { // minor != JAVA_PREVIEW_MINOR_VERSION
|
||||
if (major > max_version) {
|
||||
ResourceMark rm(THREAD);
|
||||
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);
|
||||
} else if (major < JAVA_MIN_SUPPORTED_VERSION) {
|
||||
ResourceMark rm(THREAD);
|
||||
Exceptions::fthrow(
|
||||
THREAD_AND_LOCATION,
|
||||
vmSymbols::java_lang_UnsupportedClassVersionError(),
|
||||
"%s (class file version %u.%u) was compiled with an invalid major version",
|
||||
class_name->as_C_string(), major, minor);
|
||||
} else if (minor != 0) {
|
||||
ResourceMark rm(THREAD);
|
||||
Exceptions::fthrow(
|
||||
THREAD_AND_LOCATION,
|
||||
vmSymbols::java_lang_UnsupportedClassVersionError(),
|
||||
"%s (class file version %u.%u) was compiled with an invalid non-zero minor version",
|
||||
class_name->as_C_string(), major, minor);
|
||||
}
|
||||
if (major < JAVA_12_VERSION || minor == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (minor == JAVA_PREVIEW_MINOR_VERSION) {
|
||||
if (major != max_version) {
|
||||
Exceptions::fthrow(
|
||||
THREAD_AND_LOCATION,
|
||||
vmSymbols::java_lang_UnsupportedClassVersionError(),
|
||||
"%s (class file version %u.%u) was compiled with preview features that are unsupported. "
|
||||
"This version of the Java Runtime only recognizes preview features for class file version %u.%u",
|
||||
class_name->as_C_string(), major, minor, JVM_CLASSFILE_MAJOR_VERSION, JAVA_PREVIEW_MINOR_VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Arguments::enable_preview()) {
|
||||
Exceptions::fthrow(
|
||||
THREAD_AND_LOCATION,
|
||||
vmSymbols::java_lang_UnsupportedClassVersionError(),
|
||||
"Preview features are not enabled for %s (class file version %u.%u). Try running with '--enable-preview'",
|
||||
class_name->as_C_string(), major, minor);
|
||||
return;
|
||||
}
|
||||
|
||||
} else { // minor != JAVA_PREVIEW_MINOR_VERSION
|
||||
Exceptions::fthrow(
|
||||
THREAD_AND_LOCATION,
|
||||
vmSymbols::java_lang_UnsupportedClassVersionError(),
|
||||
"%s (class file version %u.%u) was compiled with an invalid non-zero minor version",
|
||||
class_name->as_C_string(), major, minor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5641,11 +5643,11 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa
|
||||
}
|
||||
|
||||
if (ik->minor_version() == JAVA_PREVIEW_MINOR_VERSION &&
|
||||
ik->major_version() != JAVA_MIN_SUPPORTED_VERSION &&
|
||||
ik->major_version() == JVM_CLASSFILE_MAJOR_VERSION &&
|
||||
log_is_enabled(Info, class, preview)) {
|
||||
ResourceMark rm;
|
||||
log_info(class, preview)("Loading class %s that depends on preview features (class file version %d.65535)",
|
||||
ik->external_name(), ik->major_version());
|
||||
ik->external_name(), JVM_CLASSFILE_MAJOR_VERSION);
|
||||
}
|
||||
|
||||
if (log_is_enabled(Debug, class, resolve)) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -73,7 +73,7 @@ public class PreviewVersion {
|
||||
|
||||
// Subtract 1 from class's major version. The class should fail to load
|
||||
// because its major_version does not match the JVM current version.
|
||||
int prev_major_version = Runtime.version().feature() - 1;
|
||||
int prev_major_version = (klassbuf[6] << 8 | klassbuf[7]) - 1;
|
||||
klassbuf[6] = (byte)((prev_major_version >> 8) & 0xff);
|
||||
klassbuf[7] = (byte)(prev_major_version & 0xff);
|
||||
try {
|
||||
@ -81,8 +81,8 @@ public class PreviewVersion {
|
||||
throw new RuntimeException("UnsupportedClassVersionError exception not thrown");
|
||||
} catch (java.lang.UnsupportedClassVersionError e) {
|
||||
if (!e.getMessage().contains("compiled with preview features that are unsupported")) {
|
||||
throw new RuntimeException(
|
||||
"Wrong UnsupportedClassVersionError exception: " + e.getMessage());
|
||||
throw new RuntimeException(
|
||||
"Wrong UnsupportedClassVersionError exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,10 +97,10 @@ public class PreviewVersion {
|
||||
"Unexpected UnsupportedClassVersionError exception thrown: " + e.getMessage());
|
||||
}
|
||||
|
||||
// Check that a class with a recent older major version and a non-zero
|
||||
// minor version fails to load.
|
||||
// Check that a class with a recent older major version > JDK-11 and a minor version
|
||||
// that is neither 0 nor 65535 fails to load.
|
||||
klassbuf[6] = 0;
|
||||
klassbuf[7] = 53;
|
||||
klassbuf[7] = 56;
|
||||
klassbuf[4] = 0;
|
||||
klassbuf[5] = 2;
|
||||
try {
|
||||
|
Loading…
x
Reference in New Issue
Block a user