--- old/src/hotspot/share/classfile/classFileParser.cpp 2018-04-05 09:15:12.549602606 -0400 +++ new/src/hotspot/share/classfile/classFileParser.cpp 2018-04-05 09:15:11.930297581 -0400 @@ -57,6 +57,7 @@ #include "oops/symbol.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" +#include "runtime/arguments.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" #include "runtime/perfData.hpp" @@ -89,6 +90,7 @@ #define JAVA_CLASSFILE_MAGIC 0xCAFEBABE #define JAVA_MIN_SUPPORTED_VERSION 45 +#define JAVA_PREVIEW_MINOR_VERSION 65535 // Used for two backward compatibility reasons: // - to check for new additions to the class file format in JDK1.5 @@ -4700,12 +4702,57 @@ (is_protected && is_private)); } -static bool is_supported_version(u2 major, u2 minor){ +static void verify_class_version(u2 major, u2 minor, Symbol* class_name, TRAPS){ const u2 max_version = JVM_CLASSFILE_MAJOR_VERSION; - return (major >= JAVA_MIN_SUPPORTED_VERSION) && - (major <= max_version) && - ((major != max_version) || - (minor <= JVM_CLASSFILE_MINOR_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 (!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; + } + + } 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); + } + } + } } void ClassFileParser::verify_legal_field_modifiers(jint flags, @@ -5549,6 +5596,13 @@ ik->print_class_load_logging(_loader_data, module_name, _stream); } + if (ik->minor_version() == JAVA_PREVIEW_MINOR_VERSION && + ik->major_version() != JAVA_MIN_SUPPORTED_VERSION && + log_is_enabled(Info, class, preview)) { + ResourceMark rm; + log_info(class, preview)("Loading preview feature type %s", ik->external_name()); + } + if (log_is_enabled(Debug, class, resolve)) { ResourceMark rm; // print out the superclass. @@ -5864,20 +5918,7 @@ } // Check version numbers - we check this even with verifier off - if (!is_supported_version(_major_version, _minor_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.%u", - _class_name->as_C_string(), - _major_version, - _minor_version, - JVM_CLASSFILE_MAJOR_VERSION, - JVM_CLASSFILE_MINOR_VERSION); - return; - } + verify_class_version(_major_version, _minor_version, _class_name, CHECK); stream->guarantee_more(3, CHECK); // length, first cp tag u2 cp_size = stream->get_u2_fast();