changeset 40319:b45dd3eb246d

Merge
author duke
date Wed, 05 Jul 2017 22:05:22 +0200
parents 3f7eb1205cee 5f3bf5e4f32e
children 2e83d21d78cd
files hotspot/test/runtime/modules/Visibility/XpatchVisibility.java hotspot/test/runtime/modules/Xpatch/BasicJarBuilder.java hotspot/test/runtime/modules/Xpatch/Xpatch2Dirs.java hotspot/test/runtime/modules/Xpatch/Xpatch2DirsMain.java hotspot/test/runtime/modules/Xpatch/XpatchDupJavaBase.java hotspot/test/runtime/modules/Xpatch/XpatchDupModule.java hotspot/test/runtime/modules/Xpatch/XpatchJavaBase.java hotspot/test/runtime/modules/Xpatch/XpatchMain.java hotspot/test/runtime/modules/Xpatch/XpatchTest.java hotspot/test/runtime/modules/Xpatch/XpatchTestJar.java hotspot/test/runtime/modules/Xpatch/XpatchTestJarDir.java hotspot/test/runtime/modules/Xpatch/XpatchTraceCL.java hotspot/test/runtime/modules/XpatchCDS.java jdk/src/java.base/share/conf/security/cacerts jdk/test/sun/security/mscapi/AccessKeyStore.sh
diffstat 387 files changed, 7292 insertions(+), 3822 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags-top-repo	Mon Aug 15 08:28:26 2016 +0200
+++ b/.hgtags-top-repo	Wed Jul 05 22:05:22 2017 +0200
@@ -373,3 +373,4 @@
 b30ae794d974d7dd3eb4e84203f70021823fa6c6 jdk-9+128
 f5902d3841b82cac6e7716a20c24e8e916fb14a8 jdk-9+129
 d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130
+8728756c2f70a79a90188f4019cfd6b9a275765c jdk-9+131
--- a/common/autoconf/boot-jdk.m4	Mon Aug 15 08:28:26 2016 +0200
+++ b/common/autoconf/boot-jdk.m4	Wed Jul 05 22:05:22 2017 +0200
@@ -305,7 +305,7 @@
   BOOT_JDK_SOURCETARGET="-source 8 -target 8"
   AC_SUBST(BOOT_JDK_SOURCETARGET)
 
-  ADD_JVM_ARG_IF_OK([-Xpatch:foo=bar], dummy, [$JAVA])
+  ADD_JVM_ARG_IF_OK([--patch-module foo=bar], dummy, [$JAVA])
   AC_MSG_CHECKING([if Boot JDK supports modules])
   if test "x$JVM_ARG_OK" = "xtrue"; then
     AC_MSG_RESULT([yes])
--- a/common/autoconf/generated-configure.sh	Mon Aug 15 08:28:26 2016 +0200
+++ b/common/autoconf/generated-configure.sh	Wed Jul 05 22:05:22 2017 +0200
@@ -5095,7 +5095,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1470415803
+DATE_WHEN_GENERATED=1470863189
 
 ###############################################################################
 #
@@ -30596,13 +30596,13 @@
 
 
 
-  $ECHO "Check if jvm arg is ok: -Xpatch:foo=bar" >&5
-  $ECHO "Command: $JAVA -Xpatch:foo=bar -version" >&5
-  OUTPUT=`$JAVA -Xpatch:foo=bar -version 2>&1`
+  $ECHO "Check if jvm arg is ok: --patch-module foo=bar" >&5
+  $ECHO "Command: $JAVA --patch-module foo=bar -version" >&5
+  OUTPUT=`$JAVA --patch-module foo=bar -version 2>&1`
   FOUND_WARN=`$ECHO "$OUTPUT" | $GREP -i warn`
   FOUND_VERSION=`$ECHO $OUTPUT | $GREP " version \""`
   if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
-    dummy="$dummy -Xpatch:foo=bar"
+    dummy="$dummy --patch-module foo=bar"
     JVM_ARG_OK=true
   else
     $ECHO "Arg failed:" >&5
--- a/common/autoconf/spec.gmk.in	Mon Aug 15 08:28:26 2016 +0200
+++ b/common/autoconf/spec.gmk.in	Wed Jul 05 22:05:22 2017 +0200
@@ -585,7 +585,7 @@
     jdk.jdeps jdk.javadoc jdk.rmic
 ifeq ($(BOOT_JDK_MODULAR), true)
   INTERIM_OVERRIDE_MODULES_ARGS = $(foreach m, $(INTERIM_OVERRIDE_MODULES), \
-      -Xpatch:$m=$(BUILDTOOLS_OUTPUTDIR)/override_modules/$m)
+      --patch-module $m=$(BUILDTOOLS_OUTPUTDIR)/override_modules/$m)
   INTERIM_LANGTOOLS_ARGS = $(INTERIM_OVERRIDE_MODULES_ARGS)
   JAVAC_MAIN_CLASS = -m jdk.compiler/com.sun.tools.javac.Main
   JAVADOC_MAIN_CLASS = -m jdk.javadoc/jdk.javadoc.internal.tool.Main
--- a/common/conf/jib-profiles.js	Mon Aug 15 08:28:26 2016 +0200
+++ b/common/conf/jib-profiles.js	Wed Jul 05 22:05:22 2017 +0200
@@ -417,7 +417,7 @@
         jtreg: {
             server: "javare",
             revision: "4.2",
-            build_number: "b02",
+            build_number: "b03",
             checksum_file: "MD5_VALUES",
             file: "jtreg_bin-4.2.zip",
             environment_name: "JT_HOME"
--- a/corba/.hgtags	Mon Aug 15 08:28:26 2016 +0200
+++ b/corba/.hgtags	Wed Jul 05 22:05:22 2017 +0200
@@ -373,3 +373,4 @@
 1f093d3f8cd99cd37c3b0af4cf5c3bffaa9c8b98 jdk-9+128
 c3e83ccab3bb1733ae903d681879a33f85ed465c jdk-9+129
 77f9692d5976ae155773dd3e07533616bb95bae1 jdk-9+130
+f7e1d5337c2e550fe553df7a3886bbed80292ecd jdk-9+131
--- a/hotspot/.hgtags	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/.hgtags	Wed Jul 05 22:05:22 2017 +0200
@@ -533,3 +533,4 @@
 22bf6db9767b1b3a1994cbf32eb3331f31ae2093 jdk-9+128
 e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129
 7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130
+943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java	Wed Jul 05 22:05:22 2017 +0200
@@ -109,6 +109,9 @@
             if (!s.getReturnType(CLASS).equals(resultType)) {
                 return false;
             }
+            if (s.getParameterCount(false) != parameterTypes.length) {
+                return false;
+            }
             for (int i = 0; i < s.getParameterCount(false); ++i) {
                 if (!s.getParameterType(i, CLASS).equals(parameterTypes[i])) {
                     return false;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java	Wed Jul 05 22:05:22 2017 +0200
@@ -57,7 +57,7 @@
         if (jvmci != requestorModule) {
             for (String pkg : jvmci.getPackages()) {
                 // Export all JVMCI packages dynamically instead
-                // of requiring a long list of -XaddExports
+                // of requiring a long list of --add-exports
                 // options on the JVM command line.
                 if (!jvmci.isExported(pkg, requestorModule)) {
                     jvmci.addExports(pkg, requestorModule);
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Wed Jul 05 22:05:22 2017 +0200
@@ -140,7 +140,7 @@
 PerfCounter*    ClassLoader::_isUnsyncloadClass = NULL;
 PerfCounter*    ClassLoader::_load_instance_class_failCounter = NULL;
 
-GrowableArray<ModuleClassPathList*>* ClassLoader::_xpatch_entries = NULL;
+GrowableArray<ModuleClassPathList*>* ClassLoader::_patch_mod_entries = NULL;
 GrowableArray<ModuleClassPathList*>* ClassLoader::_exploded_entries = NULL;
 ClassPathEntry* ClassLoader::_jrt_entry = NULL;
 ClassPathEntry* ClassLoader::_first_append_entry = NULL;
@@ -685,27 +685,27 @@
 }
 #endif
 
-// Construct the array of module/path pairs as specified to -Xpatch
+// Construct the array of module/path pairs as specified to --patch-module
 // for the boot loader to search ahead of the jimage, if the class being
-// loaded is defined to a module that has been specified to -Xpatch.
-void ClassLoader::setup_xpatch_entries() {
+// loaded is defined to a module that has been specified to --patch-module.
+void ClassLoader::setup_patch_mod_entries() {
   Thread* THREAD = Thread::current();
-  GrowableArray<ModuleXPatchPath*>* xpatch_args = Arguments::get_xpatchprefix();
-  int num_of_entries = xpatch_args->length();
+  GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
+  int num_of_entries = patch_mod_args->length();
 
-  assert(!DumpSharedSpaces, "DumpSharedSpaces not supported with -Xpatch");
-  assert(!UseSharedSpaces, "UseSharedSpaces not supported with -Xpatch");
+  assert(!DumpSharedSpaces, "DumpSharedSpaces not supported with --patch-module");
+  assert(!UseSharedSpaces, "UseSharedSpaces not supported with --patch-module");
 
-  // Set up the boot loader's _xpatch_entries list
-  _xpatch_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
+  // Set up the boot loader's _patch_mod_entries list
+  _patch_mod_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
 
   for (int i = 0; i < num_of_entries; i++) {
-    const char* module_name = (xpatch_args->at(i))->module_name();
+    const char* module_name = (patch_mod_args->at(i))->module_name();
     Symbol* const module_sym = SymbolTable::lookup(module_name, (int)strlen(module_name), CHECK);
     assert(module_sym != NULL, "Failed to obtain Symbol for module name");
     ModuleClassPathList* module_cpl = new ModuleClassPathList(module_sym);
 
-    char* class_path = (xpatch_args->at(i))->path_string();
+    char* class_path = (patch_mod_args->at(i))->path_string();
     int len = (int)strlen(class_path);
     int end = 0;
     // Iterate over the module's class path entries
@@ -735,10 +735,10 @@
       }
     }
 
-    // Record the module into the list of -Xpatch entries only if
+    // Record the module into the list of --patch-module entries only if
     // valid ClassPathEntrys have been created
     if (module_cpl->module_first_entry() != NULL) {
-      _xpatch_entries->push(module_cpl);
+      _patch_mod_entries->push(module_cpl);
     }
   }
 }
@@ -1020,9 +1020,9 @@
   ClassPathEntry* e;
   tty->print("[bootclasspath= ");
 
-  // Print -Xpatch module/path specifications first
-  if (_xpatch_entries != NULL) {
-    print_module_entry_table(_xpatch_entries);
+  // Print --patch-module module/path specifications first
+  if (_patch_mod_entries != NULL) {
+    print_module_entry_table(_patch_mod_entries);
   }
 
   // [jimage | exploded modules build]
@@ -1341,7 +1341,7 @@
   return file_name;
 }
 
-// Search either the xpatch or exploded build entries for class
+// Search either the patch-module or exploded build entries for class
 ClassFileStream* ClassLoader::search_module_entries(const GrowableArray<ModuleClassPathList*>* const module_list,
                                                     const char* const class_name, const char* const file_name, TRAPS) {
   ClassFileStream* stream = NULL;
@@ -1366,7 +1366,7 @@
     int num_of_entries = module_list->length();
     const Symbol* class_module_name = mod_entry->name();
 
-    // Loop through all the modules in either the xpatch or exploded entries looking for module
+    // Loop through all the modules in either the patch-module or exploded entries looking for module
     for (int i = 0; i < num_of_entries; i++) {
       ModuleClassPathList* module_cpl = module_list->at(i);
       Symbol* module_cpl_name = module_cpl->module_name();
@@ -1378,7 +1378,7 @@
         while (e != NULL) {
           stream = e->open_stream(file_name, CHECK_NULL);
           // No context.check is required since CDS is not supported
-          // for an exploded modules build or if -Xpatch is specified.
+          // for an exploded modules build or if --patch-module is specified.
           if (NULL != stream) {
             return stream;
           }
@@ -1420,32 +1420,32 @@
 
   // If DumpSharedSpaces is true boot loader visibility boundaries are set to:
   //   - [jimage] + [_first_append_entry to _last_append_entry] (all path entries).
-  // No -Xpatch entries or exploded module builds are included since CDS
-  // is not supported if -Xpatch or exploded module builds are used.
+  // No --patch-module entries or exploded module builds are included since CDS
+  // is not supported if --patch-module or exploded module builds are used.
   //
   // If search_append_only is true, boot loader visibility boundaries are
   // set to be _first_append_entry to the end. This includes:
   //   [-Xbootclasspath/a]; [jvmti appended entries]
   //
   // If both DumpSharedSpaces and search_append_only are false, boot loader
-  // visibility boundaries are set to be the -Xpatch entries plus the base piece.
+  // visibility boundaries are set to be the --patch-module entries plus the base piece.
   // This would include:
-  //   [-Xpatch:<module>=<file>(<pathsep><file>)*]; [jimage | exploded module build]
+  //   [--patch-module=<module>=<file>(<pathsep><file>)*]; [jimage | exploded module build]
   //
   // DumpSharedSpaces and search_append_only are mutually exclusive and cannot
   // be true at the same time.
   assert(!(DumpSharedSpaces && search_append_only), "DumpSharedSpaces and search_append_only are both true");
 
-  // Load Attempt #1: -Xpatch
-  // Determine the class' defining module.  If it appears in the _xpatch_entries,
+  // Load Attempt #1: --patch-module
+  // Determine the class' defining module.  If it appears in the _patch_mod_entries,
   // attempt to load the class from those locations specific to the module.
-  // Specifications to -Xpatch can contain a partial number of classes
+  // Specifications to --patch-module can contain a partial number of classes
   // that are part of the overall module definition.  So if a particular class is not
   // found within its module specification, the search should continue to Load Attempt #2.
-  // Note: The -Xpatch entries are never searched if the boot loader's
+  // Note: The --patch-module entries are never searched if the boot loader's
   //       visibility boundary is limited to only searching the append entries.
-  if (_xpatch_entries != NULL && !search_append_only && !DumpSharedSpaces) {
-    stream = search_module_entries(_xpatch_entries, class_name, file_name, CHECK_NULL);
+  if (_patch_mod_entries != NULL && !search_append_only && !DumpSharedSpaces) {
+    stream = search_module_entries(_patch_mod_entries, class_name, file_name, CHECK_NULL);
   }
 
   // Load Attempt #2: [jimage | exploded build]
@@ -1650,11 +1650,11 @@
   // Create the moduleEntry for java.base
   create_javabase();
 
-  // Setup the list of module/path pairs for -Xpatch processing
+  // Setup the list of module/path pairs for --patch-module processing
   // This must be done after the SymbolTable is created in order
   // to use fast_compare on module names instead of a string compare.
-  if (Arguments::get_xpatchprefix() != NULL) {
-    setup_xpatch_entries();
+  if (Arguments::get_patch_mod_prefix() != NULL) {
+    setup_patch_mod_entries();
   }
 
   // Setup the initial java.base/path pair for the exploded build entries.
--- a/hotspot/src/share/vm/classfile/classLoader.hpp	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp	Wed Jul 05 22:05:22 2017 +0200
@@ -150,7 +150,7 @@
 
 // ModuleClassPathList contains a linked list of ClassPathEntry's
 // that have been specified for a specific module.  Currently,
-// the only way to specify a module/path pair is via the -Xpatch
+// the only way to specify a module/path pair is via the --patch-module
 // command line option.
 class ModuleClassPathList : public CHeapObj<mtClass> {
 private:
@@ -213,8 +213,8 @@
   static PerfCounter* _load_instance_class_failCounter;
 
   // The boot class path consists of 3 ordered pieces:
-  //  1. the module/path pairs specified to -Xpatch
-  //    -Xpatch:<module>=<file>(<pathsep><file>)*
+  //  1. the module/path pairs specified to --patch-module
+  //    --patch-module=<module>=<file>(<pathsep><file>)*
   //  2. the base piece
   //    [jimage | build with exploded modules]
   //  3. boot loader append path
@@ -223,8 +223,8 @@
   // The boot loader must obey this order when attempting
   // to load a class.
 
-  // 1. Contains the module/path pairs specified to -Xpatch
-  static GrowableArray<ModuleClassPathList*>* _xpatch_entries;
+  // 1. Contains the module/path pairs specified to --patch-module
+  static GrowableArray<ModuleClassPathList*>* _patch_mod_entries;
 
   // 2. the base piece
   //    Contains the ClassPathEntry of the modular java runtime image.
@@ -256,11 +256,11 @@
 
   // Initialization:
   //   - setup the boot loader's system class path
-  //   - setup the boot loader's xpatch entries, if present
+  //   - setup the boot loader's patch mod entries, if present
   //   - create the ModuleEntry for java.base
   static void setup_bootstrap_search_path();
   static void setup_search_path(const char *class_path, bool setting_bootstrap);
-  static void setup_xpatch_entries();
+  static void setup_patch_mod_entries();
   static void create_javabase();
 
   static void load_zip_library();
@@ -363,7 +363,7 @@
   // Add a module's exploded directory to the boot loader's exploded module build list
   static void add_to_exploded_build_list(Symbol* module_name, TRAPS);
 
-  // Attempt load of individual class from either the xpatch or exploded modules build lists
+  // Attempt load of individual class from either the patched or exploded modules build lists
   static ClassFileStream* search_module_entries(const GrowableArray<ModuleClassPathList*>* const module_list,
                                                 const char* const class_name,
                                                 const char* const file_name, TRAPS);
--- a/hotspot/src/share/vm/memory/filemap.cpp	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/src/share/vm/memory/filemap.cpp	Wed Jul 05 22:05:22 2017 +0200
@@ -911,8 +911,8 @@
     return false;
   }
 
-  if (Arguments::get_xpatchprefix() != NULL) {
-    FileMapInfo::fail_continue("The shared archive file cannot be used with -Xpatch.");
+  if (Arguments::get_patch_mod_prefix() != NULL) {
+    FileMapInfo::fail_continue("The shared archive file cannot be used with --patch-module.");
     return false;
   }
 
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Wed Jul 05 22:05:22 2017 +0200
@@ -24,6 +24,8 @@
 
 #include "precompiled.hpp"
 #include "classfile/classLoaderExt.hpp"
+#include "classfile/javaClasses.inline.hpp"
+#include "classfile/stringTable.hpp"
 #include "classfile/modules.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
@@ -224,6 +226,7 @@
   return JVMTI_ERROR_NONE;
 } /* end GetNamedModule */
 
+
   //
   // Class functions
   //
@@ -3465,28 +3468,35 @@
 JvmtiEnv::GetSystemProperties(jint* count_ptr, char*** property_ptr) {
   jvmtiError err = JVMTI_ERROR_NONE;
 
-  *count_ptr = Arguments::PropertyList_count(Arguments::system_properties());
-
+  // Get the number of readable properties.
+  *count_ptr = Arguments::PropertyList_readable_count(Arguments::system_properties());
+
+  // Allocate memory to hold the exact number of readable properties.
   err = allocate(*count_ptr * sizeof(char *), (unsigned char **)property_ptr);
   if (err != JVMTI_ERROR_NONE) {
     return err;
   }
-  int i = 0 ;
-  for (SystemProperty* p = Arguments::system_properties(); p != NULL && i < *count_ptr; p = p->next(), i++) {
-    const char *key = p->key();
-    char **tmp_value = *property_ptr+i;
-    err = allocate((strlen(key)+1) * sizeof(char), (unsigned char**)tmp_value);
-    if (err == JVMTI_ERROR_NONE) {
-      strcpy(*tmp_value, key);
-    } else {
-      // clean up previously allocated memory.
-      for (int j=0; j<i; j++) {
-        Deallocate((unsigned char*)*property_ptr+j);
+  int readable_count = 0;
+  // Loop through the system properties until all the readable properties are found.
+  for (SystemProperty* p = Arguments::system_properties(); p != NULL && readable_count < *count_ptr; p = p->next()) {
+    if (p->is_readable()) {
+      const char *key = p->key();
+      char **tmp_value = *property_ptr+readable_count;
+      readable_count++;
+      err = allocate((strlen(key)+1) * sizeof(char), (unsigned char**)tmp_value);
+      if (err == JVMTI_ERROR_NONE) {
+        strcpy(*tmp_value, key);
+      } else {
+        // clean up previously allocated memory.
+        for (int j=0; j<readable_count; j++) {
+          Deallocate((unsigned char*)*property_ptr+j);
+        }
+        Deallocate((unsigned char*)property_ptr);
+        break;
       }
-      Deallocate((unsigned char*)property_ptr);
-      break;
     }
   }
+  assert(err != JVMTI_ERROR_NONE || readable_count == *count_ptr, "Bad readable property count");
   return err;
 } /* end GetSystemProperties */
 
@@ -3498,7 +3508,8 @@
   jvmtiError err = JVMTI_ERROR_NONE;
   const char *value;
 
-  value = Arguments::PropertyList_get_value(Arguments::system_properties(), property);
+  // Return JVMTI_ERROR_NOT_AVAILABLE if property is not readable or doesn't exist.
+  value = Arguments::PropertyList_get_readable_value(Arguments::system_properties(), property);
   if (value == NULL) {
     err =  JVMTI_ERROR_NOT_AVAILABLE;
   } else {
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 22:05:22 2017 +0200
@@ -110,7 +110,7 @@
 SystemProperty *Arguments::_java_class_path = NULL;
 SystemProperty *Arguments::_jdk_boot_class_path_append = NULL;
 
-GrowableArray<ModuleXPatchPath*> *Arguments::_xpatchprefix = NULL;
+GrowableArray<ModulePatchPath*> *Arguments::_patch_mod_prefix = NULL;
 PathString *Arguments::_system_boot_class_path = NULL;
 bool Arguments::_has_jimage = false;
 
@@ -161,6 +161,30 @@
   }
 }
 
+bool needs_module_property_warning = false;
+
+#define MODULE_PROPERTY_PREFIX "jdk.module"
+#define MODULE_PROPERTY_PREFIX_LEN 10
+#define MODULE_MAIN_PROPERTY "jdk.module.main"
+#define MODULE_MAIN_PROPERTY_LEN 15
+
+// Return TRUE if option matches property, or property=, or property..
+static bool matches_property_prefix(const char* option, const char* property, size_t len) {
+  return (strncmp(option, property, len) == 0) &&
+          (option[len] == '=' || option[len] == '.' || option[len] == '\0');
+}
+
+// Return true if the property is either "jdk.module" or starts with "jdk.module.",
+// but does not start with "jdk.module.main".
+// Return false if jdk.module.main because jdk.module.main and jdk.module.main.class
+// are valid non-internal system properties.
+// "property" should be passed without the leading "-D".
+bool Arguments::is_internal_module_property(const char* property) {
+  assert((strncmp(property, "-D", 2) != 0), "Unexpected leading -D");
+  return (matches_property_prefix(property, MODULE_PROPERTY_PREFIX, MODULE_PROPERTY_PREFIX_LEN) &&
+          !matches_property_prefix(property, MODULE_MAIN_PROPERTY, MODULE_MAIN_PROPERTY_LEN));
+}
+
 // Process java launcher properties.
 void Arguments::process_sun_java_launcher_properties(JavaVMInitArgs* args) {
   // See if sun.java.launcher, sun.java.launcher.is_altjvm or
@@ -197,7 +221,7 @@
   _system_boot_class_path = new PathString(NULL);
 
   PropertyList_add(&_system_properties, new SystemProperty("java.vm.specification.name",
-                                                                 "Java Virtual Machine Specification",  false));
+                                                           "Java Virtual Machine Specification",  false));
   PropertyList_add(&_system_properties, new SystemProperty("java.vm.version", VM_Version::vm_release(),  false));
   PropertyList_add(&_system_properties, new SystemProperty("java.vm.name", VM_Version::vm_name(),  false));
   PropertyList_add(&_system_properties, new SystemProperty("java.vm.info", VM_Version::vm_info_string(),  true));
@@ -1198,7 +1222,7 @@
   return PropertyList_get_value(system_properties(), key);
 }
 
-bool Arguments::add_property(const char* prop) {
+bool Arguments::add_property(const char* prop, PropertyWriteable writeable, PropertyInternal internal) {
   const char* eq = strchr(prop, '=');
   const char* key;
   const char* value = "";
@@ -1228,7 +1252,9 @@
     // private and are processed in process_sun_java_launcher_properties();
     // the sun.java.launcher property is passed on to the java application
   } else if (strcmp(key, "sun.boot.library.path") == 0) {
-    PropertyList_unique_add(&_system_properties, key, value, true);
+    // append is true, writable is true, internal is false
+    PropertyList_unique_add(&_system_properties, key, value, AppendProperty,
+                            WriteableProperty, ExternalProperty);
   } else {
     if (strcmp(key, "sun.java.command") == 0) {
       char *old_java_command = _java_command;
@@ -1248,7 +1274,7 @@
     }
 
     // Create new property and add at the end of the list
-    PropertyList_unique_add(&_system_properties, key, value);
+    PropertyList_unique_add(&_system_properties, key, value, AddProperty, writeable, internal);
   }
 
   if (key != prop) {
@@ -1260,9 +1286,9 @@
   return true;
 }
 
-// sets or adds a module name to the jdk.launcher.addmods property
+// sets or adds a module name to the jdk.module.addmods property
 bool Arguments::append_to_addmods_property(const char* module_name) {
-  const char* key = "jdk.launcher.addmods";
+  const char* key = "jdk.module.addmods";
   const char* old_value = Arguments::get_property(key);
   size_t buf_len = strlen(key) + strlen(module_name) + 2;
   if (old_value != NULL) {
@@ -1277,7 +1303,7 @@
   } else {
     jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name);
   }
-  bool added = add_property(new_value);
+  bool added = add_property(new_value, UnwriteableProperty, InternalProperty);
   FreeHeap(new_value);
   return added;
 }
@@ -1287,14 +1313,14 @@
   assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
   const char* unsupported_properties[5] = { "jdk.module.main",
                                            "jdk.module.path",
-                                           "jdk.upgrade.module.path",
-                                           "jdk.launcher.addmods",
-                                           "jdk.launcher.limitmods" };
+                                           "jdk.module.upgrade.path",
+                                           "jdk.module.addmods",
+                                           "jdk.module.limitmods" };
   const char* unsupported_options[5] = { "-m",
-                                        "-modulepath",
-                                        "-upgrademodulepath",
-                                        "-addmods",
-                                        "-limitmods" };
+                                        "--module-path",
+                                        "--upgrade-module-path",
+                                        "--add-modules",
+                                        "--limit-modules" };
   SystemProperty* sp = system_properties();
   while (sp != NULL) {
     for (int i = 0; i < 5; i++) {
@@ -1326,7 +1352,7 @@
   // Ensure Agent_OnLoad has the correct initial values.
   // This may not be the final mode; mode may change later in onload phase.
   PropertyList_unique_add(&_system_properties, "java.vm.info",
-                          VM_Version::vm_info_string(), false);
+                          VM_Version::vm_info_string(), AddProperty, UnwriteableProperty, ExternalProperty);
 
   UseInterpreter             = true;
   UseCompiler                = true;
@@ -2516,6 +2542,41 @@
   return false;
 }
 
+unsigned int addreads_count = 0;
+unsigned int addexports_count = 0;
+unsigned int patch_mod_count = 0;
+const char* add_modules_value = NULL;
+
+bool Arguments::create_property(const char* prop_name, const char* prop_value, PropertyInternal internal) {
+  size_t prop_len = strlen(prop_name) + strlen(prop_value) + 2;
+  char* property = AllocateHeap(prop_len, mtArguments);
+  int ret = jio_snprintf(property, prop_len, "%s=%s", prop_name, prop_value);
+  if (ret < 0 || ret >= (int)prop_len) {
+    FreeHeap(property);
+    return false;
+  }
+  bool added = add_property(property, UnwriteableProperty, internal);
+  FreeHeap(property);
+  return added;
+}
+
+bool Arguments::create_numbered_property(const char* prop_base_name, const char* prop_value, unsigned int count) {
+  // Make sure count is < 1,000. Otherwise, memory allocation will be too small.
+  if (count < 1000) {
+    size_t prop_len = strlen(prop_base_name) + strlen(prop_value) + 5;
+    char* property = AllocateHeap(prop_len, mtArguments);
+    int ret = jio_snprintf(property, prop_len, "%s.%d=%s", prop_base_name, count, prop_value);
+    if (ret < 0 || ret >= (int)prop_len) {
+      FreeHeap(property);
+      return false;
+    }
+    bool added = add_property(property, UnwriteableProperty, InternalProperty);
+    FreeHeap(property);
+    return added;
+  }
+  return false;
+}
+
 Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
                                                   julong* long_arg,
                                                   julong min_size) {
@@ -2528,7 +2589,7 @@
 jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
                                    const JavaVMInitArgs *java_options_args,
                                    const JavaVMInitArgs *cmd_line_args) {
-  bool xpatch_javabase = false;
+  bool patch_mod_javabase = false;
 
   // Save default settings for some mode flags
   Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods;
@@ -2545,20 +2606,20 @@
 
   // Parse args structure generated from JAVA_TOOL_OPTIONS environment
   // variable (if present).
-  jint result = parse_each_vm_init_arg(java_tool_options_args, &xpatch_javabase, Flag::ENVIRON_VAR);
+  jint result = parse_each_vm_init_arg(java_tool_options_args, &patch_mod_javabase, Flag::ENVIRON_VAR);
   if (result != JNI_OK) {
     return result;
   }
 
   // Parse args structure generated from the command line flags.
-  result = parse_each_vm_init_arg(cmd_line_args, &xpatch_javabase, Flag::COMMAND_LINE);
+  result = parse_each_vm_init_arg(cmd_line_args, &patch_mod_javabase, Flag::COMMAND_LINE);
   if (result != JNI_OK) {
     return result;
   }
 
   // Parse args structure generated from the _JAVA_OPTIONS environment
   // variable (if present) (mimics classic VM)
-  result = parse_each_vm_init_arg(java_options_args, &xpatch_javabase, Flag::ENVIRON_VAR);
+  result = parse_each_vm_init_arg(java_options_args, &patch_mod_javabase, Flag::ENVIRON_VAR);
   if (result != JNI_OK) {
     return result;
   }
@@ -2617,7 +2678,35 @@
   return false;
 }
 
-jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_javabase, Flag::Flags origin) {
+int Arguments::process_patch_mod_option(const char* patch_mod_tail, bool* patch_mod_javabase) {
+  // --patch-module=<module>=<file>(<pathsep><file>)*
+  assert(patch_mod_tail != NULL, "Unexpected NULL patch-module value");
+  // Find the equal sign between the module name and the path specification
+  const char* module_equal = strchr(patch_mod_tail, '=');
+  if (module_equal == NULL) {
+    jio_fprintf(defaultStream::output_stream(), "Missing '=' in --patch-module specification\n");
+    return JNI_ERR;
+  } else {
+    // Pick out the module name
+    size_t module_len = module_equal - patch_mod_tail;
+    char* module_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, module_len+1, mtArguments);
+    if (module_name != NULL) {
+      memcpy(module_name, patch_mod_tail, module_len);
+      *(module_name + module_len) = '\0';
+      // The path piece begins one past the module_equal sign
+      add_patch_mod_prefix(module_name, module_equal + 1, patch_mod_javabase);
+      FREE_C_HEAP_ARRAY(char, module_name);
+      if (!create_numbered_property("jdk.module.patch", patch_mod_tail, patch_mod_count++)) {
+        return JNI_ENOMEM;
+      }
+    } else {
+      return JNI_ENOMEM;
+    }
+  }
+  return JNI_OK;
+}
+
+jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, Flag::Flags origin) {
   // For match_option to return remaining or value part of option string
   const char* tail;
 
@@ -2701,6 +2790,34 @@
 #endif // !INCLUDE_JVMTI
         add_init_library(name, options);
       }
+    } else if (match_option(option, "--add-reads=", &tail)) {
+      if (!create_numbered_property("jdk.module.addreads", tail, addreads_count++)) {
+        return JNI_ENOMEM;
+      }
+    } else if (match_option(option, "--add-exports=", &tail)) {
+      if (!create_numbered_property("jdk.module.addexports", tail, addexports_count++)) {
+        return JNI_ENOMEM;
+      }
+    } else if (match_option(option, "--add-modules=", &tail)) {
+      add_modules_value = tail;
+    } else if (match_option(option, "--limit-modules=", &tail)) {
+      if (!create_property("jdk.module.limitmods", tail, InternalProperty)) {
+        return JNI_ENOMEM;
+      }
+    } else if (match_option(option, "--module-path=", &tail)) {
+      if (!create_property("jdk.module.path", tail, ExternalProperty)) {
+        return JNI_ENOMEM;
+      }
+    } else if (match_option(option, "--upgrade-module-path=", &tail)) {
+      if (!create_property("jdk.module.upgrade.path", tail, ExternalProperty)) {
+        return JNI_ENOMEM;
+      }
+    } else if (match_option(option, "--patch-module=", &tail)) {
+      // --patch-module=<module>=<file>(<pathsep><file>)*
+      int res = process_patch_mod_option(tail, patch_mod_javabase);
+      if (res != JNI_OK) {
+        return res;
+      }
     // -agentlib and -agentpath
     } else if (match_option(option, "-agentlib:", &tail) ||
           (is_absolute_path = match_option(option, "-agentpath:", &tail))) {
@@ -2992,6 +3109,13 @@
           "-Djava.ext.dirs=%s is not supported.  Use -classpath instead.\n", value);
         return JNI_EINVAL;
       }
+      // Check for module related properties.  They must be set using the modules
+      // options. For example: use "--add-modules=java.sql", not
+      // "-Djdk.module.addmods=java.sql"
+      if (is_internal_module_property(option->optionString + 2)) {
+        needs_module_property_warning = true;
+        continue;
+      }
 
       if (!add_property(tail)) {
         return JNI_ENOMEM;
@@ -3012,33 +3136,6 @@
         return JNI_ERR;
 #endif
       }
-      if (match_option(option, "-Djdk.launcher.patch.", &tail)) {
-        // -Djdk.launcher.patch.#=<module>=<file>(<pathsep><file>)*
-        // The number, #, specified will be increasing with each -Xpatch
-        // specified on the command line.
-        // Pick up module name, following the -D property's equal sign.
-        const char* property_equal = strchr(tail, '=');
-        if (property_equal == NULL) {
-          jio_fprintf(defaultStream::output_stream(), "Missing '=' in -Xpatch specification\n");
-          return JNI_ERR;
-        } else {
-          // Find the equal sign between the module name and the path specification
-          const char* module_equal = strchr(property_equal + 1, '=');
-          if (module_equal == NULL) {
-            jio_fprintf(defaultStream::output_stream(), "Bad value for -Xpatch, no module name specified\n");
-            return JNI_ERR;
-          } else {
-            // Pick out the module name, in between the two equal signs
-            size_t module_len = module_equal - property_equal - 1;
-            char* module_name = NEW_C_HEAP_ARRAY(char, module_len+1, mtArguments);
-            memcpy(module_name, property_equal + 1, module_len);
-            *(module_name + module_len) = '\0';
-            // The path piece begins one past the module_equal sign
-            Arguments::add_xpatchprefix(module_name, module_equal + 1, xpatch_javabase);
-            FREE_C_HEAP_ARRAY(char, module_name);
-          }
-        }
-      }
     // -Xint
     } else if (match_option(option, "-Xint")) {
           set_mode_flags(_int);
@@ -3298,25 +3395,25 @@
   return JNI_OK;
 }
 
-void Arguments::add_xpatchprefix(const char* module_name, const char* path, bool* xpatch_javabase) {
-  // For java.base check for duplicate -Xpatch options being specified on the command line.
+void Arguments::add_patch_mod_prefix(const char* module_name, const char* path, bool* patch_mod_javabase) {
+  // For java.base check for duplicate --patch-module options being specified on the command line.
   // This check is only required for java.base, all other duplicate module specifications
   // will be checked during module system initialization.  The module system initialization
   // will throw an ExceptionInInitializerError if this situation occurs.
   if (strcmp(module_name, "java.base") == 0) {
-    if (*xpatch_javabase) {
-      vm_exit_during_initialization("Cannot specify java.base more than once to -Xpatch");
+    if (*patch_mod_javabase) {
+      vm_exit_during_initialization("Cannot specify java.base more than once to --patch-module");
     } else {
-      *xpatch_javabase = true;
+      *patch_mod_javabase = true;
     }
   }
 
-  // Create GrowableArray lazily, only if -Xpatch has been specified
-  if (_xpatchprefix == NULL) {
-    _xpatchprefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModuleXPatchPath*>(10, true);
-  }
-
-  _xpatchprefix->push(new ModuleXPatchPath(module_name, path));
+  // Create GrowableArray lazily, only if --patch-module has been specified
+  if (_patch_mod_prefix == NULL) {
+    _patch_mod_prefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModulePatchPath*>(10, true);
+  }
+
+  _patch_mod_prefix->push(new ModulePatchPath(module_name, path));
 }
 
 // Remove all empty paths from the app classpath (if IgnoreEmptyClassPaths is enabled)
@@ -3441,6 +3538,15 @@
     return JNI_ERR;
   }
 
+  // Append the value of the last --add-modules option specified on the command line.
+  // This needs to be done here, to prevent overwriting possible values written
+  // to the jdk.module.addmods property by -javaagent and other options.
+  if (add_modules_value != NULL) {
+    if (!append_to_addmods_property(add_modules_value)) {
+      return JNI_ENOMEM;
+    }
+  }
+
   // This must be done after all arguments have been processed.
   // java_compiler() true means set to "NONE" or empty.
   if (java_compiler() && !xdebug_mode()) {
@@ -3795,9 +3901,9 @@
 
 void Arguments::set_shared_spaces_flags() {
   if (DumpSharedSpaces) {
-    if (Arguments::get_xpatchprefix() != NULL) {
+    if (Arguments::get_patch_mod_prefix() != NULL) {
       vm_exit_during_initialization(
-        "Cannot use the following option when dumping the shared archive", "-Xpatch");
+        "Cannot use the following option when dumping the shared archive: --patch-module");
     }
 
     if (RequireSharedSpaces) {
@@ -4180,6 +4286,11 @@
             hotspotrc, hotspotrc);
   }
 
+  if (needs_module_property_warning) {
+    warning("Ignoring system property options whose names start with '-Djdk.module'."
+            "  They are reserved for internal use.");
+  }
+
 #if defined(_ALLBSD_SOURCE) || defined(AIX)  // UseLargePages is not yet supported on BSD and AIX.
   UNSUPPORTED_OPTION(UseLargePages);
 #endif
@@ -4404,6 +4515,18 @@
   return count;
 }
 
+// Return the number of readable properties.
+int Arguments::PropertyList_readable_count(SystemProperty* pl) {
+  int count = 0;
+  while(pl != NULL) {
+    if (pl->is_readable()) {
+      count++;
+    }
+    pl = pl->next();
+  }
+  return count;
+}
+
 const char* Arguments::PropertyList_get_value(SystemProperty *pl, const char* key) {
   assert(key != NULL, "just checking");
   SystemProperty* prop;
@@ -4413,6 +4536,27 @@
   return NULL;
 }
 
+// Return the value of the requested property provided that it is a readable property.
+const char* Arguments::PropertyList_get_readable_value(SystemProperty *pl, const char* key) {
+  assert(key != NULL, "just checking");
+  SystemProperty* prop;
+  // Return the property value if the keys match and the property is not internal or
+  // it's the special internal property "jdk.boot.class.path.append".
+  for (prop = pl; prop != NULL; prop = prop->next()) {
+    if (strcmp(key, prop->key()) == 0) {
+      if (!prop->internal()) {
+        return prop->value();
+      } else if (strcmp(key, "jdk.boot.class.path.append") == 0) {
+        return prop->value();
+      } else {
+        // Property is internal and not jdk.boot.class.path.append so return NULL.
+        return NULL;
+      }
+    }
+  }
+  return NULL;
+}
+
 const char* Arguments::PropertyList_get_key_at(SystemProperty *pl, int index) {
   int count = 0;
   const char* ret_val = NULL;
@@ -4457,11 +4601,12 @@
   }
 }
 
-void Arguments::PropertyList_add(SystemProperty** plist, const char* k, const char* v) {
+void Arguments::PropertyList_add(SystemProperty** plist, const char* k, const char* v,
+                                 bool writeable, bool internal) {
   if (plist == NULL)
     return;
 
-  SystemProperty* new_p = new SystemProperty(k, v, true);
+  SystemProperty* new_p = new SystemProperty(k, v, writeable, internal);
   PropertyList_add(plist, new_p);
 }
 
@@ -4470,7 +4615,9 @@
 }
 
 // This add maintains unique property key in the list.
-void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v, jboolean append) {
+void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v,
+                                        PropertyAppendable append, PropertyWriteable writeable,
+                                        PropertyInternal internal) {
   if (plist == NULL)
     return;
 
@@ -4478,16 +4625,16 @@
   SystemProperty* prop;
   for (prop = *plist; prop != NULL; prop = prop->next()) {
     if (strcmp(k, prop->key()) == 0) {
-      if (append) {
+      if (append == AppendProperty) {
         prop->append_value(v);
       } else {
-        prop->set_writeable_value(v);
+        prop->set_value(v);
       }
       return;
     }
   }
 
-  PropertyList_add(plist, k, v);
+  PropertyList_add(plist, k, v, writeable == WriteableProperty, internal == InternalProperty);
 }
 
 // Copies src into buf, replacing "%%" with "%" and "%p" with pid
--- a/hotspot/src/share/vm/runtime/arguments.hpp	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.hpp	Wed Jul 05 22:05:22 2017 +0200
@@ -43,7 +43,7 @@
 
 // PathString is used as:
 //  - the underlying value for a SystemProperty
-//  - the path portion of an -Xpatch module/path pair
+//  - the path portion of an --patch-module module/path pair
 //  - the string that represents the system boot class path, Arguments::_system_boot_class_path.
 class PathString : public CHeapObj<mtArguments> {
  protected:
@@ -107,13 +107,13 @@
   }
 };
 
-// ModuleXPatchPath records the module/path pair as specified to -Xpatch.
-class ModuleXPatchPath : public CHeapObj<mtInternal> {
+// ModulePatchPath records the module/path pair as specified to --patch-module.
+class ModulePatchPath : public CHeapObj<mtInternal> {
 private:
   char* _module_name;
   PathString* _path;
 public:
-  ModuleXPatchPath(const char* module_name, const char* path) {
+  ModulePatchPath(const char* module_name, const char* path) {
     assert(module_name != NULL && path != NULL, "Invalid module name or path value");
     size_t len = strlen(module_name) + 1;
     _module_name = AllocateHeap(len, mtInternal);
@@ -121,7 +121,7 @@
     _path =  new PathString(path);
   }
 
-  ~ModuleXPatchPath() {
+  ~ModulePatchPath() {
     if (_module_name != NULL) {
       FreeHeap(_module_name);
       _module_name = NULL;
@@ -158,6 +158,10 @@
   SystemProperty* next() const        { return _next; }
   void set_next(SystemProperty* next) { _next = next; }
 
+  bool is_readable() const {
+    return !_internal || strcmp(_key, "jdk.boot.class.path.append") == 0;
+  }
+
   // A system property should only have its value set
   // via an external interface if it is a writeable property.
   // The internal, non-writeable property jdk.boot.class.path.append
@@ -325,6 +329,21 @@
     arg_in_range   = 0
   };
 
+  enum PropertyAppendable {
+    AppendProperty,
+    AddProperty
+  };
+
+  enum PropertyWriteable {
+    WriteableProperty,
+    UnwriteableProperty
+  };
+
+  enum PropertyInternal {
+    InternalProperty,
+    ExternalProperty
+  };
+
  private:
 
   // a pointer to the flags file name if it is specified
@@ -348,18 +367,18 @@
   static SystemProperty *_java_class_path;
   static SystemProperty *_jdk_boot_class_path_append;
 
-  // -Xpatch:module=<file>(<pathsep><file>)*
+  // --patch-module=module=<file>(<pathsep><file>)*
   // Each element contains the associated module name, path
-  // string pair as specified to -Xpatch.
-  static GrowableArray<ModuleXPatchPath*>* _xpatchprefix;
+  // string pair as specified to --patch-module.
+  static GrowableArray<ModulePatchPath*>* _patch_mod_prefix;
 
   // The constructed value of the system class path after
   // argument processing and JVMTI OnLoad additions via
   // calls to AddToBootstrapClassLoaderSearch.  This is the
   // final form before ClassLoader::setup_bootstrap_search().
-  // Note: since -Xpatch is a module name/path pair, the system
-  // boot class path string no longer contains the "prefix" to
-  // the boot class path base piece as it did when
+  // Note: since --patch-module is a module name/path pair, the
+  // system boot class path string no longer contains the "prefix"
+  // to the boot class path base piece as it did when
   // -Xbootclasspath/p was supported.
   static PathString *_system_boot_class_path;
 
@@ -462,7 +481,13 @@
   static vfprintf_hook_t  _vfprintf_hook;
 
   // System properties
-  static bool add_property(const char* prop);
+  static bool add_property(const char* prop, PropertyWriteable writeable=WriteableProperty,
+                           PropertyInternal internal=ExternalProperty);
+
+  static bool create_property(const char* prop_name, const char* prop_value, PropertyInternal internal);
+  static bool create_numbered_property(const char* prop_base_name, const char* prop_value, unsigned int count);
+
+  static int process_patch_mod_option(const char* patch_mod_tail, bool* patch_mod_javabase);
 
   // Miscellaneous system property setter
   static bool append_to_addmods_property(const char* module_name);
@@ -500,7 +525,7 @@
   static jint parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
                                  const JavaVMInitArgs *java_options_args,
                                  const JavaVMInitArgs *cmd_line_args);
-  static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_javabase, Flag::Flags origin);
+  static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, Flag::Flags origin);
   static jint finalize_vm_init_args();
   static bool is_bad_option(const JavaVMOption* option, jboolean ignore, const char* option_type);
 
@@ -708,16 +733,20 @@
   // Property List manipulation
   static void PropertyList_add(SystemProperty *element);
   static void PropertyList_add(SystemProperty** plist, SystemProperty *element);
-  static void PropertyList_add(SystemProperty** plist, const char* k, const char* v);
-  static void PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v) {
-    PropertyList_unique_add(plist, k, v, false);
-  }
-  static void PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v, jboolean append);
+  static void PropertyList_add(SystemProperty** plist, const char* k, const char* v, bool writeable, bool internal);
+
+  static void PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v,
+                                      PropertyAppendable append, PropertyWriteable writeable,
+                                      PropertyInternal internal);
   static const char* PropertyList_get_value(SystemProperty* plist, const char* key);
+  static const char* PropertyList_get_readable_value(SystemProperty* plist, const char* key);
   static int  PropertyList_count(SystemProperty* pl);
+  static int  PropertyList_readable_count(SystemProperty* pl);
   static const char* PropertyList_get_key_at(SystemProperty* pl,int index);
   static char* PropertyList_get_value_at(SystemProperty* pl,int index);
 
+  static bool is_internal_module_property(const char* option);
+
   // Miscellaneous System property value getter and setters.
   static void set_dll_dir(const char *value) { _sun_boot_library_path->set_value(value); }
   static void set_java_home(const char *value) { _java_home->set_value(value); }
@@ -725,7 +754,7 @@
   static void set_ext_dirs(char *value)     { _ext_dirs = os::strdup_check_oom(value); }
 
   // Set up the underlying pieces of the system boot class path
-  static void add_xpatchprefix(const char *module_name, const char *path, bool* xpatch_javabase);
+  static void add_patch_mod_prefix(const char *module_name, const char *path, bool* patch_mod_javabase);
   static void set_sysclasspath(const char *value, bool has_jimage) {
     // During start up, set by os::set_boot_path()
     assert(get_sysclasspath() == NULL, "System boot class path previously set");
@@ -737,7 +766,7 @@
     _jdk_boot_class_path_append->append_value(value);
   }
 
-  static GrowableArray<ModuleXPatchPath*>* get_xpatchprefix() { return _xpatchprefix; }
+  static GrowableArray<ModulePatchPath*>* get_patch_mod_prefix() { return _patch_mod_prefix; }
   static char* get_sysclasspath() { return _system_boot_class_path->value(); }
   static char* get_jdk_boot_class_path_append() { return _jdk_boot_class_path_append->value(); }
   static bool has_jimage() { return _has_jimage; }
--- a/hotspot/src/share/vm/utilities/ostream.cpp	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/src/share/vm/utilities/ostream.cpp	Wed Jul 05 22:05:22 2017 +0200
@@ -703,13 +703,15 @@
       // System properties don't generally contain newlines, so don't bother with unparsing.
       outputStream *text = xs->text();
       for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {
-        // Print in two stages to avoid problems with long
-        // keys/values.
         assert(p->key() != NULL, "p->key() is NULL");
-        text->print_raw(p->key());
-        text->put('=');
-        assert(p->value() != NULL, "p->value() is NULL");
-        text->print_raw_cr(p->value());
+        if (p->is_readable()) {
+          // Print in two stages to avoid problems with long
+          // keys/values.
+          text->print_raw(p->key());
+          text->put('=');
+          assert(p->value() != NULL, "p->value() is NULL");
+          text->print_raw_cr(p->value());
+        }
       }
       xs->tail("properties");
     }
--- a/hotspot/test/TEST.ROOT	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/TEST.ROOT	Wed Jul 05 22:05:22 2017 +0200
@@ -46,12 +46,12 @@
     vm.gc.Parallel \
     vm.gc.ConcMarkSweep
 
-# Tests using jtreg 4.2 b02 features
-requiredVersion=4.2 b02
+# Tests using jtreg 4.2 b03 features
+requiredVersion=4.2 b03
 
 # Path to libraries in the topmost test directory. This is needed so @library
 # does not need ../../ notation to reach them
 external.lib.roots = ../../
 
-# Use new form of -Xpatch
-useNewXpatch=true
+# Use new module options
+useNewOptions=true
--- a/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java	Wed Jul 05 22:05:22 2017 +0200
@@ -40,7 +40,7 @@
  *                                 -XX:CompileCommand=dontinline,compiler.unsafe.UnsafeGetConstantField::checkGetAddress
  *                                 -XX:CompileCommand=dontinline,*::test*
  *                                 -XX:+UseUnalignedAccesses
- *                                 -XaddReads:java.base=ALL-UNNAMED
+ *                                 --add-reads=java.base=ALL-UNNAMED
  *                                 compiler.unsafe.UnsafeGetConstantField
  *
  * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions
@@ -50,7 +50,7 @@
  *                                 -XX:CompileCommand=dontinline,*::test*
  *                                 -XX:CompileCommand=inline,*Unsafe::get*
  *                                 -XX:-UseUnalignedAccesses
- *                                 -XaddReads:java.base=ALL-UNNAMED
+ *                                 --add-reads=java.base=ALL-UNNAMED
  *                                 compiler.unsafe.UnsafeGetConstantField
  */
 
--- a/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java	Wed Jul 05 22:05:22 2017 +0200
@@ -88,7 +88,7 @@
                 (useXmaxf ? "-Xmaxf" + maxRatio / 100.0 : "-XX:MaxHeapFreeRatio=" + maxRatio),
                 "-Xmx" + MAX_HEAP_SIZE,
                 "-Xms" + HEAP_SIZE,
-                "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED",
+                "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
                 "-XX:NewSize=" + NEW_SIZE,
                 "-XX:MaxNewSize=" + MAX_NEW_SIZE,
                 "-XX:" + (shrinkHeapInSteps ? '+' : '-') + "ShrinkHeapInSteps",
@@ -120,7 +120,7 @@
         Collections.addAll(vmOptions,
                 (useXminf ? "-Xminf" + minRatio / 100.0 : "-XX:MinHeapFreeRatio=" + minRatio),
                 (useXmaxf ? "-Xmaxf" + maxRatio / 100.0 : "-XX:MaxHeapFreeRatio=" + maxRatio),
-                "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED",
+                "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
                 "-version"
         );
         ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));
--- a/hotspot/test/gc/arguments/TestSurvivorRatioFlag.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/gc/arguments/TestSurvivorRatioFlag.java	Wed Jul 05 22:05:22 2017 +0200
@@ -74,7 +74,7 @@
 
         Collections.addAll(vmOptions,
                 "-Xbootclasspath/a:.",
-                "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED",
+                "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
                 "-XX:+UnlockDiagnosticVMOptions",
                 "-XX:+WhiteBoxAPI",
                 "-XX:GCLockerEdenExpansionPercent=0",
--- a/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java	Wed Jul 05 22:05:22 2017 +0200
@@ -132,7 +132,7 @@
         LinkedList<String> vmOptions = new LinkedList<>(options);
         Collections.addAll(vmOptions,
                 "-Xbootclasspath/a:.",
-                "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED",
+                "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
                 "-XX:+UnlockDiagnosticVMOptions",
                 "-XX:+WhiteBoxAPI",
                 "-XX:+UseAdaptiveSizePolicy",
--- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData.java	Wed Jul 05 22:05:22 2017 +0200
@@ -53,7 +53,7 @@
         "-Xlog:gc=debug",
         "-XX:+UnlockDiagnosticVMOptions",
         "-XX:+WhiteBoxAPI",
-        "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED",
+        "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
         "-Xbootclasspath/a:.",
     };
 
--- a/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java	Wed Jul 05 22:05:22 2017 +0200
@@ -48,7 +48,7 @@
                                         "-Xmodule:java.base"),
                                         "mods/java.base");
 
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.base=mods/java.base", "-version");
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.base=mods/java.base", "-version");
         new OutputAnalyzer(pb.start())
             .shouldContain("Incompatible definition of java.lang.Object")
             .shouldHaveExitValue(1);
--- a/hotspot/test/runtime/BootClassAppendProp/BootClassPathAppendProp.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/runtime/BootClassAppendProp/BootClassPathAppendProp.java	Wed Jul 05 22:05:22 2017 +0200
@@ -27,7 +27,7 @@
  * @test
  * @build BootClassPathAppendProp
  * @run main/othervm -Xbootclasspath/a:/usr/lib -showversion -Xbootclasspath/a:/i/dont/exist BootClassPathAppendProp
- * @run main/othervm -Xpatch:/not/here -Xbootclasspath/a:/i/may/exist BootClassPathAppendProp
+ * @run main/othervm --patch-module=no_module=/not/here -Xbootclasspath/a:/i/may/exist BootClassPathAppendProp
  * @run main/othervm -Djdk.boot.class.path.append=newdir BootClassPathAppendProp
  * @run main/othervm BootClassPathAppendProp
  */
--- a/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java	Wed Jul 05 22:05:22 2017 +0200
@@ -56,7 +56,7 @@
     public static OutputAnalyzer runTest(String option) throws Exception {
         return new OutputAnalyzer(
             ProcessTools.createJavaProcessBuilder(
-            "-Xmx64m", "-XX:-TransmitErrorReport", "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED", option, Crasher.class.getName())
+            "-Xmx64m", "-XX:-TransmitErrorReport", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", option, Crasher.class.getName())
             .start());
     }
 }
--- a/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java	Wed Jul 05 22:05:22 2017 +0200
@@ -48,7 +48,7 @@
 
     public static void main(String[] args) throws Exception {
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-            "-Xmx64m", "-XX:-TransmitErrorReport", "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED", "-XX:-CreateCoredumpOnCrash", Crasher.class.getName());
+            "-Xmx64m", "-XX:-TransmitErrorReport", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", "-XX:-CreateCoredumpOnCrash", Crasher.class.getName());
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldNotContain("Exception in thread");
         output.shouldNotMatch("error occurred during error reporting \\(printing problematic frame\\)");
--- a/hotspot/test/runtime/SharedArchiveFile/BootAppendTests.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/runtime/SharedArchiveFile/BootAppendTests.java	Wed Jul 05 22:05:22 2017 +0200
@@ -160,10 +160,10 @@
 
     // Test #3: If a class on -Xbootclasspath/a is from a package defined in boot modules,
     //          the class can be loaded from -Xbootclasspath/a when the module is excluded
-    //          using -limitmods. Verify the behavior is the same at runtime when CDS is
-    //          enabled.
+    //          using --limit-modules. Verify the behavior is the same at runtime when CDS
+    //          is enabled.
     //
-    //          The java.desktop module is excluded using -limitmods at runtime,
+    //          The java.desktop module is excluded using --limit-modules at runtime,
     //          javax.sound.sampled.MyClass is archived from -Xbootclasspath/a. It can be
     //          loaded from the archive at runtime.
     public static void testBootAppendExcludedModuleClass() throws Exception {
@@ -174,7 +174,7 @@
                 "-XX:+TraceClassLoading",
                 "-cp", appJar,
                 "-Xbootclasspath/a:" + bootAppendJar,
-                "-limitmods", "java.base",
+                "--limit-modules=java.base",
                 "-Xshare:" + mode,
                 APP_CLASS,
                 BOOT_APPEND_MODULE_CLASS_NAME);
@@ -191,8 +191,8 @@
     // Test #4: If a class on -Xbootclasspath/a has the same fully qualified
     //          name as a class defined in boot modules, the class is loaded
     //          from -Xbootclasspath/a when the boot module is excluded using
-    //          -limitmods. Verify the behavior is the same at runtime when CDS is
-    //          enabled.
+    //          --limit-modules. Verify the behavior is the same at runtime
+    //          when CDS is enabled.
     //
     //          The org.omg.CORBA.Context is a boot module class. The class
     //          on -Xbootclasspath/a that has the same fully-qualified name
@@ -206,7 +206,7 @@
                 "-XX:+TraceClassLoading",
                 "-cp", appJar,
                 "-Xbootclasspath/a:" + bootAppendJar,
-                "-limitmods", "java.base",
+                "--limit-modules=java.base",
                 "-Xshare:" + mode,
                 APP_CLASS,
                 BOOT_APPEND_DUPLICATE_MODULE_CLASS_NAME);
--- a/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTest.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/runtime/SharedArchiveFile/SASymbolTableTest.java	Wed Jul 05 22:05:22 2017 +0200
@@ -89,10 +89,11 @@
         long pid = p.getPid();
         System.out.println("Attaching agent " + pid);
         ProcessBuilder tool = ProcessTools.createJavaProcessBuilder(
-            "-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
-            "-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.memory=ALL-UNNAMED",
-            "-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.runtime=ALL-UNNAMED",
-            "-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.tools=ALL-UNNAMED",
+            "--add-modules=jdk.hotspot.agent",
+            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
+            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.memory=ALL-UNNAMED",
+            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.runtime=ALL-UNNAMED",
+            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.tools=ALL-UNNAMED",
             "SASymbolTableTestAgent",
             Long.toString(pid));
         OutputAnalyzer output = ProcessTools.executeProcess(tool);
--- a/hotspot/test/runtime/Unsafe/RangeCheck.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/runtime/Unsafe/RangeCheck.java	Wed Jul 05 22:05:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -44,7 +44,7 @@
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
                 true,
                 "-Xmx32m",
-                "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED",
+                "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
                 "-XX:-TransmitErrorReport",
                 "-XX:-CreateCoredumpOnCrash",
                 "-XX:-InlineUnsafeOps", // The compiler intrinsics doesn't have the assert
--- a/hotspot/test/runtime/getSysPackage/GetSysPkgTest.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/runtime/getSysPackage/GetSysPkgTest.java	Wed Jul 05 22:05:22 2017 +0200
@@ -98,7 +98,7 @@
             ClassFileInstaller.writeClassToDisk("GetSysPkg_package/GetSysClass", klassbuf);
 
             ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xbootclasspath/a:bl_dir",
-                "-XaddExports:java.base/jdk.internal.loader=ALL-UNNAMED", "-cp", "." + File.pathSeparator +
+                "--add-exports=java.base/jdk.internal.loader=ALL-UNNAMED", "-cp", "." + File.pathSeparator +
                 System.getProperty("test.classes"), "GetSysPkgTest", "do_tests");
             OutputAnalyzer output = new OutputAnalyzer(pb.start());
             output.shouldHaveExitValue(0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/IgnoreModulePropertiesTest.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8136930
+ * @summary Test that the VM ignores explicitly specified module internal properties.
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary
+ */
+
+import jdk.test.lib.*;
+
+// Test that the VM ignores module related properties such as "jdk.module.addmods"
+// and jdk.module.addreads.0" that can only be set using module options.
+public class IgnoreModulePropertiesTest {
+
+    // Test that the specified property and its value are ignored.  If the VM accepted
+    // the property and value then an exception would be thrown because the value is
+    // bogus for that property.  But, since the property is ignored no exception is
+    // thrown.
+    public static void testProperty(String prop, String value) throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "-D" + prop + "=" + value, "-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("java version ");
+        output.shouldHaveExitValue(0);
+
+        // Ensure that the property and its value aren't available.
+        if (System.getProperty(prop) != null) {
+            throw new RuntimeException(
+                "Unexpected non-null value for property " + prop);
+        }
+    }
+
+    // For options of the form "option=value", check that an exception gets thrown for
+    // the illegal value and then check that its corresponding property is handled
+    // correctly.
+    public static void testOption(String option, String value,
+                                  String prop, String result) throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            option + "=" + value, "-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain(result);
+        testProperty(prop, value);
+    }
+
+    public static void main(String[] args) throws Exception {
+        testOption("--add-modules", "java.sqlx", "jdk.module.addmods", "java.lang.module.ResolutionException");
+        testOption("--limit-modules", "java.sqlx", "jdk.module.limitmods", "java.lang.module.ResolutionException");
+        testOption("--add-reads", "xyzz=yyzd", "jdk.module.addreads.0", "java.lang.RuntimeException");
+        testOption("--add-exports", "java.base/xyzz=yyzd", "jdk.module.addexports.0", "java.lang.RuntimeException");
+        testOption("--patch-module", "=d", "jdk.module.patch.0", "IllegalArgumentException");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ModuleOptionsTest.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8136930
+ * @summary Test that the VM only recognizes the last specified --add-modules
+ *          and --list-modules options
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary
+ */
+
+import jdk.test.lib.*;
+
+// Test that the VM behaves correctly when processing module related options.
+public class ModuleOptionsTest {
+
+    public static void main(String[] args) throws Exception {
+
+        // Test that last --add-modules is the only one recognized.  No exception
+        // should be thrown.
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "--add-modules=i_dont_exist", "--add-modules=java.base", "-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+
+        // Test that last --limit-modules is the only one recognized.  No exception
+        // should be thrown.
+        pb = ProcessTools.createJavaProcessBuilder(
+            "--limit-modules=i_dont_exist", "--limit-modules=java.base", "-version");
+        output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/ModuleOptionsWarn.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8162415
+ * @summary Test warnings for ignored properties.
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary
+ */
+
+import jdk.test.lib.*;
+
+// Test that the VM behaves correctly when processing command line module system properties.
+public class ModuleOptionsWarn {
+
+    public static void main(String[] args) throws Exception {
+
+        // Test that a warning is issued for module related properties that get ignored.
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+PrintWarnings", "-Djdk.module.ignored", "-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Ignoring system property option");
+        output.shouldHaveExitValue(0);
+
+        // Test that a warning can be suppressed for module related properties that get ignored.
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-Djdk.module.ignored", "-XX:-PrintWarnings", "-version");
+        output = new OutputAnalyzer(pb.start());
+        output.shouldNotContain("Ignoring system property option");
+        output.shouldHaveExitValue(0);
+
+        // Test that a warning is not issued for properties of the form "jdk.module.main"
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+PrintWarnings", "-Djdk.module.main.ignored", "-version");
+        output = new OutputAnalyzer(pb.start());
+        output.shouldNotContain("Ignoring system property option");
+        output.shouldHaveExitValue(0);
+    }
+}
--- a/hotspot/test/runtime/modules/ModuleStress/ExportModuleStressTest.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/runtime/modules/ModuleStress/ExportModuleStressTest.java	Wed Jul 05 22:05:22 2017 +0200
@@ -62,8 +62,8 @@
         compiled = CompilerUtils.compile(
             SRC_DIR.resolve("jdk.translet"),
             MODS_DIR.resolve("jdk.translet"),
-            "-XaddExports:jdk.test/test=jdk.translet",
-            "-mp", MODS_DIR.toString());
+            "--add-exports=jdk.test/test=jdk.translet",
+            "-p", MODS_DIR.toString());
         if (!compiled) {
             throw new RuntimeException("Test failed to compile module jdk.translet");
         }
@@ -71,7 +71,7 @@
         // Sanity check that the test, jdk.test/test/Main.java
         // runs without error.
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-            "-mp", MODS_DIR.toString(),
+            "-p", MODS_DIR.toString(),
             "-m", "jdk.test/test.Main");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("failed: 0")
--- a/hotspot/test/runtime/modules/ModuleStress/ModuleStressGC.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/runtime/modules/ModuleStress/ModuleStressGC.java	Wed Jul 05 22:05:22 2017 +0200
@@ -62,8 +62,8 @@
         compiled = CompilerUtils.compile(
             SRC_DIR.resolve("jdk.translet"),
             MODS_DIR.resolve("jdk.translet"),
-            "-XaddExports:jdk.test/test=jdk.translet",
-            "-mp", MODS_DIR.toString());
+            "--add-exports=jdk.test/test=jdk.translet",
+            "-p", MODS_DIR.toString());
         if (!compiled) {
             throw new RuntimeException("Test failed to compile module jdk.translet");
         }
@@ -74,7 +74,7 @@
         // GC safepoints.
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-Xlog:modules=trace",
-            "-mp", MODS_DIR.toString(),
+            "-p", MODS_DIR.toString(),
             "-m", "jdk.test/test.MainGC");
         OutputAnalyzer oa = new OutputAnalyzer(pb.start());
         oa.shouldContain("package test defined in module jdk.test, exports list being walked")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/PatchModule/BasicJarBuilder.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @summary Simple jar builder
+ *   Input: jarName className1 className2 ...
+ *     do not specify extensions, just the names
+ *     E.g. prot_domain ProtDomainA ProtDomainB
+ *   Output: A jar containing compiled classes, placed in a test classes folder
+ */
+
+import jdk.test.lib.*;
+
+import java.io.File;
+import java.util.ArrayList;
+import sun.tools.jar.Main;
+
+// Using JarBuilder requires that all to-be-jarred classes should be placed
+// in the current working directory, aka "."
+public class BasicJarBuilder {
+    private static final String classDir = System.getProperty("test.classes");
+
+    public static void build(boolean classesInWorkDir, String jarName,
+        String ...classNames) throws Exception {
+
+        if (classesInWorkDir) {
+            createSimpleJar(".", classDir + File.separator + jarName + ".jar", classNames);
+        } else {
+            build(jarName, classNames);
+        }
+    }
+
+    public static void build(String jarName, String ...classNames) throws Exception {
+        createSimpleJar(classDir, classDir + File.separator + jarName + ".jar",
+            classNames);
+    }
+
+    private static void createSimpleJar(String jarclassDir, String jarName,
+        String[] classNames) throws Exception {
+        ArrayList<String> args = new ArrayList<String>();
+        args.add("cf");
+        args.add(jarName);
+        addClassArgs(args, jarclassDir, classNames);
+        createJar(args);
+    }
+
+    private static void addClassArgs(ArrayList<String> args, String jarclassDir,
+        String[] classNames) {
+
+        for (String name : classNames) {
+            args.add("-C");
+            args.add(jarclassDir);
+            args.add(name + ".class");
+        }
+    }
+
+    private static void createJar(ArrayList<String> args) {
+        Main jarTool = new Main(System.out, System.err, "jar");
+        if (!jarTool.run(args.toArray(new String[1]))) {
+            throw new RuntimeException("jar operation failed");
+        }
+    }
+
+    // Get full path to the test jar
+    public static String getTestJar(String jar) {
+        File dir = new File(System.getProperty("test.classes", "."));
+        File jarFile = new File(dir, jar);
+        if (!jarFile.exists()) {
+            throw new RuntimeException("Cannot find " + jarFile.getPath());
+        }
+        if (!jarFile.isFile()) {
+            throw new RuntimeException("Not a regular file: " + jarFile.getPath());
+        }
+        return jarFile.getPath();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/PatchModule/PatchModule2Dirs.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Make sure --patch-module works with multiple directories.
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary
+ * @compile PatchModule2DirsMain.java
+ * @run main PatchModule2Dirs
+ */
+
+import jdk.test.lib.*;
+import java.io.File;
+
+public class PatchModule2Dirs {
+
+    public static void main(String[] args) throws Exception {
+        String source1 = "package javax.naming.spi; "               +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass one!\"); " +
+                        "    } "                                    +
+                        "}";
+        String source2 = "package java.beans; "                     +
+                        "public class Encoder { "                   +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass two!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source1, "-Xmodule:java.naming"),
+             "mods/java.naming");
+
+        ClassFileInstaller.writeClassToDisk("java/beans/Encoder",
+             InMemoryJavaCompiler.compile("java.beans.Encoder", source2, "-Xmodule:java.desktop"),
+             "mods2/java.desktop");
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+             "--patch-module=java.naming=mods/java.naming",
+             "--patch-module=java.desktop=mods2/java.desktop",
+             "PatchModule2DirsMain", "javax.naming.spi.NamingManager", "java.beans.Encoder");
+
+        OutputAnalyzer oa = new OutputAnalyzer(pb.start());
+        oa.shouldContain("I pass one!");
+        oa.shouldContain("I pass two!");
+        oa.shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/PatchModule/PatchModule2DirsMain.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// This loads the class affected by the --patch-module option.  For the test to pass
+// it must load both classes from the --patch-module directory, not the jimage file.
+public class PatchModule2DirsMain {
+    public static void main(String[] args) throws Exception {
+        Class.forName(args[0]);
+        Class.forName(args[1]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/PatchModule/PatchModuleCDS.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ * @run main PatchModuleCDS
+ */
+
+import java.io.File;
+import jdk.test.lib.*;
+
+public class PatchModuleCDS {
+
+    public static void main(String args[]) throws Throwable {
+        System.out.println("Test that --patch-module and -Xshare:dump are incompatibable");
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=mods/java.naming", "-Xshare:dump");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
+
+        System.out.println("Test that --patch-module and -Xshare:on are incompatibable");
+        String filename = "patch_module.jsa";
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:SharedArchiveFile=" + filename,
+            "-Xshare:dump");
+        output = new OutputAnalyzer(pb.start());
+        output.shouldContain("ro space:"); // Make sure archive got created.
+
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:SharedArchiveFile=" + filename,
+            "-Xshare:on",
+            "--patch-module=java.naming=mods/java.naming",
+            "-version");
+        output = new OutputAnalyzer(pb.start());
+        output.shouldContain("The shared archive file cannot be used with --patch-module");
+
+        output.shouldHaveExitValue(1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/PatchModule/PatchModuleDupJavaBase.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary VM exit initialization results if java.base is specificed more than once to --patch-module.
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary
+ */
+
+import jdk.test.lib.*;
+
+public class PatchModuleDupJavaBase {
+  // The VM should exit initialization if java.base is specified
+  // more than once to --patch-module.
+  public static void main(String args[]) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+      "--patch-module=java.base=javabase_dir",
+      "--patch-module=java.base=javabase_dir",
+      "-version");
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Cannot specify java.base more than once to --patch-module");
+    output.shouldHaveExitValue(1);
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/PatchModule/PatchModuleDupModule.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Module system initialization exception results if a module is specificed twice to --patch-module.
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary
+ */
+
+import jdk.test.lib.*;
+
+public class PatchModuleDupModule {
+
+  // The module system initialization should generate an ExceptionInInitializerError
+  // if --patch-module is specified with the same module more than once.
+
+  public static void main(String args[]) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+      "--patch-module=module1=module1_dir",
+      "--patch-module=module1=module1_dir",
+      "-version");
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldContain("java.lang.ExceptionInInitializerError");
+    output.shouldHaveExitValue(1);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/PatchModule/PatchModuleJavaBase.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8130399
+ * @summary Make sure --patch-module works for java.base.
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary
+ * @compile PatchModuleMain.java
+ * @run main PatchModuleJavaBase
+ */
+
+import jdk.test.lib.*;
+
+public class PatchModuleJavaBase {
+
+    public static void main(String[] args) throws Exception {
+        String source = "package java.lang; "                       +
+                        "public class NewClass { "                  +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("java/lang/NewClass",
+             InMemoryJavaCompiler.compile("java.lang.NewClass", source, "-Xmodule:java.base"),
+             "mods/java.base");
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.base=mods/java.base",
+             "PatchModuleMain", "java.lang.NewClass");
+
+        new OutputAnalyzer(pb.start())
+            .shouldContain("I pass!")
+            .shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/PatchModule/PatchModuleMain.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// This loads the class affected by the --patch-module option.  For the test to pass
+// it must load the class from the --patch-module directory, not the jimage file.
+public class PatchModuleMain {
+    public static void main(String[] args) throws Exception {
+        Class.forName(args[0]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/PatchModule/PatchModuleTest.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8130399
+ * @summary Make sure --patch-module works for modules besides java.base.
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary
+ * @compile PatchModuleMain.java
+ * @run main PatchModuleTest
+ */
+
+import jdk.test.lib.*;
+
+public class PatchModuleTest {
+
+    public static void main(String[] args) throws Exception {
+        String source = "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
+             "mods/java.naming");
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=mods/java.naming",
+             "PatchModuleMain", "javax.naming.spi.NamingManager");
+
+        new OutputAnalyzer(pb.start())
+            .shouldContain("I pass!")
+            .shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/PatchModule/PatchModuleTestJar.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Make sure --patch-module works when a jar file is specified for a module
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @build BasicJarBuilder
+ * @compile PatchModuleMain.java
+ * @run main PatchModuleTestJar
+ */
+
+import jdk.test.lib.*;
+
+public class PatchModuleTestJar {
+    private static String moduleJar;
+
+    public static void main(String[] args) throws Exception {
+
+        // Create a class file in the module java.naming. This class file
+        // will be put in the javanaming.jar file.
+        String source = "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
+             System.getProperty("test.classes"));
+
+        // Build the jar file that will be used for the module "java.naming".
+        BasicJarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
+        moduleJar = BasicJarBuilder.getTestJar("javanaming.jar");
+
+        // Just to make sure we are not fooled by the class file being on the
+        // class path where all the test classes are stored, write the NamingManager.class
+        // file out again with output that does not contain what OutputAnalyzer
+        // expects. This will provide confidence that the contents of the class
+        // is truly coming from the jar file and not the class file.
+        source =        "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"Fail!\"); "   +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
+             System.getProperty("test.classes"));
+
+        // Supply --patch-module with the name of the jar file for the module java.naming.
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=" + moduleJar,
+             "PatchModuleMain", "javax.naming.spi.NamingManager");
+
+        new OutputAnalyzer(pb.start())
+            .shouldContain("I pass!")
+            .shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/PatchModule/PatchModuleTestJarDir.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Make sure --patch-module works when a jar file and a directory is specified for a module
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @build BasicJarBuilder
+ * @compile PatchModule2DirsMain.java
+ * @run main PatchModuleTestJarDir
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import jdk.test.lib.*;
+
+public class PatchModuleTestJarDir {
+    private static String moduleJar;
+
+    public static void main(String[] args) throws Exception {
+
+        // Create a class file in the module java.naming. This class file
+        // will be put in the javanaming.jar file.
+        String source = "package javax.naming.spi; "                    +
+                        "public class NamingManager1 { "                +
+                        "    static { "                                 +
+                        "        System.out.println(\"I pass one!\"); " +
+                        "    } "                                        +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager1",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager1", source, "-Xmodule:java.naming"),
+             System.getProperty("test.classes"));
+
+        // Build the jar file that will be used for the module "java.naming".
+        BasicJarBuilder.build("javanaming", "javax/naming/spi/NamingManager1");
+        moduleJar = BasicJarBuilder.getTestJar("javanaming.jar");
+
+        // Just to make sure we are not fooled by the class file being on the
+        // class path where all the test classes are stored, write the NamingManager.class
+        // file out again with output that does not contain what OutputAnalyzer
+        // expects. This will provide confidence that the contents of the class
+        // is truly coming from the jar file and not the class file.
+        source = "package javax.naming.spi; "                +
+                 "public class NamingManager1 { "            +
+                 "    static { "                             +
+                 "        System.out.println(\"Fail!\"); "   +
+                 "    } "                                    +
+                 "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager1",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager1", source, "-Xmodule:java.naming"),
+             System.getProperty("test.classes"));
+
+        // Create a second class file in the module java.naming. This class file
+        // will be put in the mods/java.naming directory.
+        source = "package javax.naming.spi; "                    +
+                 "public class NamingManager2 { "                +
+                 "    static { "                                 +
+                 "        System.out.println(\"I pass two!\"); " +
+                 "    } "                                        +
+                 "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager2",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager2", source, "-Xmodule:java.naming"),
+             (System.getProperty("test.classes") + "/mods/java.naming"));
+
+
+        // Supply --patch-module with the name of the jar file for the module java.naming.
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=" +
+                                                                           moduleJar +
+                                                                           File.pathSeparator +
+                                                                           System.getProperty("test.classes") + "/mods/java.naming",
+                                                                  "PatchModule2DirsMain",
+                                                                  "javax.naming.spi.NamingManager1",
+                                                                  "javax.naming.spi.NamingManager2");
+
+        new OutputAnalyzer(pb.start())
+            .shouldContain("I pass one!")
+            .shouldContain("I pass two!")
+            .shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/PatchModule/PatchModuleTraceCL.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8069469
+ * @summary Make sure -Xlog:classload=info works properly with "modules" jimage,
+            --patch-module, and with -Xbootclasspath/a
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary
+ * @compile PatchModuleMain.java
+ * @run main PatchModuleTraceCL
+ */
+
+import java.io.File;
+import jdk.test.lib.*;
+
+public class PatchModuleTraceCL {
+
+    public static void main(String[] args) throws Exception {
+        String source = "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        // Test -Xlog:classload=info output for --patch-module
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
+             "mods/java.naming");
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=mods/java.naming",
+             "-Xlog:class+load=info", "PatchModuleMain", "javax.naming.spi.NamingManager");
+
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        // "modules" jimage case.
+        output.shouldContain("[class,load] java.lang.Thread source: jrt:/java.base");
+        // --patch-module case.
+        output.shouldContain("[class,load] javax.naming.spi.NamingManager source: mods/java.naming");
+        // -cp case.
+        output.shouldContain("[class,load] PatchModuleMain source: file");
+
+        // Test -Xlog:classload=info output for -Xbootclasspath/a
+        source = "package PatchModuleTraceCL_pkg; "                 +
+                 "public class ItIsI { "                          +
+                 "    static { "                                  +
+                 "        System.out.println(\"I also pass!\"); " +
+                 "    } "                                         +
+                 "}";
+
+        ClassFileInstaller.writeClassToDisk("PatchModuleTraceCL_pkg/ItIsI",
+             InMemoryJavaCompiler.compile("PatchModuleTraceCL_pkg.ItIsI", source),
+             "xbcp");
+
+        pb = ProcessTools.createJavaProcessBuilder("-Xbootclasspath/a:xbcp",
+             "-Xlog:class+load=info", "PatchModuleMain", "PatchModuleTraceCL_pkg.ItIsI");
+        output = new OutputAnalyzer(pb.start());
+        // -Xbootclasspath/a case.
+        output.shouldContain("[class,load] PatchModuleTraceCL_pkg.ItIsI source: xbcp");
+        output.shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/Visibility/PatchModuleVisibility.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015, 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Ensure that a newly introduced java.base package placed within the --patch-module
+ *          directory is considered part of the boot loader's visibility boundary
+ * @requires !(os.family == "windows")
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @run main/othervm PatchModuleVisibility
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import jdk.test.lib.*;
+
+public class PatchModuleVisibility {
+
+    public static void main(String[] args) throws Throwable {
+
+      String Vis2_B_src =
+              "package p2;" +
+              "public class Vis2_B {" +
+              "    public void m() {" +
+              "        System.out.println(\"In B's m()\");" +
+              "    }" +
+              "}";
+
+      String Vis2_A_src =
+              "import p2.*;" +
+              "public class Vis2_A {" +
+              "    public static void main(String args[]) throws Exception {" +
+                      // Try loading a class within a newly introduced java.base
+                      // package.  Make sure the class can be found via --patch-module.
+              "        try {" +
+              "            p2.Vis2_B b = new p2.Vis2_B();" +
+              "            if (b.getClass().getClassLoader() != null) {" +
+              "                throw new RuntimeException(\"PatchModuleVisibility FAILED - class B " +
+                                                           "should be loaded by boot class loader\\n\");" +
+              "            }" +
+              "            b.m();" +
+              "        } catch (Throwable e) {" +
+              "            throw new RuntimeException(\"PatchModuleVisibility FAILED - test " +
+                                                       "should not throw an error or exception\\n\");" +
+              "        }" +
+              "        System.out.println(\"PatchModuleVisibility PASSED\\n\");" +
+              "    }" +
+              "}";
+
+      ClassFileInstaller.writeClassToDisk("p2/Vis2_B",
+          InMemoryJavaCompiler.compile("p2.Vis2_B", Vis2_B_src), System.getProperty("test.classes"));
+      ClassFileInstaller.writeClassToDisk("p2/Vis2_B", "mods2/java.base");
+
+      ClassFileInstaller.writeClassToDisk("Vis2_A",
+          InMemoryJavaCompiler.compile("Vis2_A", Vis2_A_src), System.getProperty("test.classes"));
+
+      // Make sure the classes are actually being loaded from mods2
+      Files.delete(Paths.get(System.getProperty("test.classes") +  File.separator +
+                                                           "p2" + File.separator + "Vis2_B.class"));
+
+      new OutputAnalyzer(ProcessTools.createJavaProcessBuilder(
+              "--patch-module=java.base=mods2/java.base",
+              "--add-exports=java.base/p2=ALL-UNNAMED",
+              "Vis2_A")
+          .start()).shouldHaveExitValue(0);
+    }
+}
--- a/hotspot/test/runtime/modules/Visibility/XbootcpNoVisibility.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/runtime/modules/Visibility/XbootcpNoVisibility.java	Wed Jul 05 22:05:22 2017 +0200
@@ -50,7 +50,7 @@
                         // Try loading a class within a named package in a module which has been defined
                         // to the boot loader. In this situation, the class should only be attempted
                         // to be loaded from the boot loader's module path which consists of:
-                        //   [-Xpatch]; exploded build | "modules" jimage
+                        //   [--patch-module]; exploded build | "modules" jimage
                         //
                         // Since the class is located on the boot loader's append path via
                         // -Xbootclasspath/a specification, it should not be found.
--- a/hotspot/test/runtime/modules/Visibility/XpatchVisibility.java	Mon Aug 15 08:28:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @summary Ensure that a newly introduced java.base package placed within the -Xpatch directory
- *          is considered part of the boot loader's visibility boundary
- * @requires !(os.family == "windows")
- * @library /testlibrary
- * @modules java.base/jdk.internal.misc
- *          java.management
- * @run main/othervm XpatchVisibility
- */
-
-import java.io.File;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-import jdk.test.lib.*;
-
-public class XpatchVisibility {
-
-    public static void main(String[] args) throws Throwable {
-
-      String Vis2_B_src =
-              "package p2;" +
-              "public class Vis2_B {" +
-              "    public void m() {" +
-              "        System.out.println(\"In B's m()\");" +
-              "    }" +
-              "}";
-
-      String Vis2_A_src =
-              "import p2.*;" +
-              "public class Vis2_A {" +
-              "    public static void main(String args[]) throws Exception {" +
-                      // Try loading a class within a newly introduced java.base
-                      // package.  Make sure the class can be found via -Xpatch.
-              "        try {" +
-              "            p2.Vis2_B b = new p2.Vis2_B();" +
-              "            if (b.getClass().getClassLoader() != null) {" +
-              "                throw new RuntimeException(\"XpatchVisibility FAILED - class B " +
-                                                           "should be loaded by boot class loader\\n\");" +
-              "            }" +
-              "            b.m();" +
-              "        } catch (Throwable e) {" +
-              "            throw new RuntimeException(\"XpatchVisibility FAILED - test " +
-                                                       "should not throw an error or exception\\n\");" +
-              "        }" +
-              "        System.out.println(\"XpatchVisibility PASSED\\n\");" +
-              "    }" +
-              "}";
-
-      ClassFileInstaller.writeClassToDisk("p2/Vis2_B",
-          InMemoryJavaCompiler.compile("p2.Vis2_B", Vis2_B_src), System.getProperty("test.classes"));
-      ClassFileInstaller.writeClassToDisk("p2/Vis2_B", "mods2/java.base");
-
-      ClassFileInstaller.writeClassToDisk("Vis2_A",
-          InMemoryJavaCompiler.compile("Vis2_A", Vis2_A_src), System.getProperty("test.classes"));
-
-      // Make sure the classes are actually being loaded from mods2
-      Files.delete(Paths.get(System.getProperty("test.classes") +  File.separator +
-                                                           "p2" + File.separator + "Vis2_B.class"));
-
-      new OutputAnalyzer(ProcessTools.createJavaProcessBuilder(
-              "-Xpatch:java.base=mods2/java.base",
-              "-XaddExports:java.base/p2=ALL-UNNAMED",
-              "Vis2_A")
-          .start()).shouldHaveExitValue(0);
-    }
-}
--- a/hotspot/test/runtime/modules/Xpatch/BasicJarBuilder.java	Mon Aug 15 08:28:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @summary Simple jar builder
- *   Input: jarName className1 className2 ...
- *     do not specify extensions, just the names
- *     E.g. prot_domain ProtDomainA ProtDomainB
- *   Output: A jar containing compiled classes, placed in a test classes folder
- */
-
-import jdk.test.lib.*;
-
-import java.io.File;
-import java.util.ArrayList;
-import sun.tools.jar.Main;
-
-// Using JarBuilder requires that all to-be-jarred classes should be placed
-// in the current working directory, aka "."
-public class BasicJarBuilder {
-    private static final String classDir = System.getProperty("test.classes");
-
-    public static void build(boolean classesInWorkDir, String jarName,
-        String ...classNames) throws Exception {
-
-        if (classesInWorkDir) {
-            createSimpleJar(".", classDir + File.separator + jarName + ".jar", classNames);
-        } else {
-            build(jarName, classNames);
-        }
-    }
-
-    public static void build(String jarName, String ...classNames) throws Exception {
-        createSimpleJar(classDir, classDir + File.separator + jarName + ".jar",
-            classNames);
-    }
-
-    private static void createSimpleJar(String jarclassDir, String jarName,
-        String[] classNames) throws Exception {
-        ArrayList<String> args = new ArrayList<String>();
-        args.add("cf");
-        args.add(jarName);
-        addClassArgs(args, jarclassDir, classNames);
-        createJar(args);
-    }
-
-    private static void addClassArgs(ArrayList<String> args, String jarclassDir,
-        String[] classNames) {
-
-        for (String name : classNames) {
-            args.add("-C");
-            args.add(jarclassDir);
-            args.add(name + ".class");
-        }
-    }
-
-    private static void createJar(ArrayList<String> args) {
-        Main jarTool = new Main(System.out, System.err, "jar");
-        if (!jarTool.run(args.toArray(new String[1]))) {
-            throw new RuntimeException("jar operation failed");
-        }
-    }
-
-    // Get full path to the test jar
-    public static String getTestJar(String jar) {
-        File dir = new File(System.getProperty("test.classes", "."));
-        File jarFile = new File(dir, jar);
-        if (!jarFile.exists()) {
-            throw new RuntimeException("Cannot find " + jarFile.getPath());
-        }
-        if (!jarFile.isFile()) {
-            throw new RuntimeException("Not a regular file: " + jarFile.getPath());
-        }
-        return jarFile.getPath();
-    }
-}
--- a/hotspot/test/runtime/modules/Xpatch/Xpatch2Dirs.java	Mon Aug 15 08:28:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @summary Make sure -Xpatch works with multiple directories.
- * @modules java.base/jdk.internal.misc
- * @library /testlibrary
- * @compile Xpatch2DirsMain.java
- * @run main Xpatch2Dirs
- */
-
-import jdk.test.lib.*;
-import java.io.File;
-
-public class Xpatch2Dirs {
-
-    public static void main(String[] args) throws Exception {
-        String source1 = "package javax.naming.spi; "               +
-                        "public class NamingManager { "             +
-                        "    static { "                             +
-                        "        System.out.println(\"I pass one!\"); " +
-                        "    } "                                    +
-                        "}";
-        String source2 = "package java.beans; "                     +
-                        "public class Encoder { "                   +
-                        "    static { "                             +
-                        "        System.out.println(\"I pass two!\"); " +
-                        "    } "                                    +
-                        "}";
-
-        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
-             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source1, "-Xmodule:java.naming"),
-             "mods/java.naming");
-
-        ClassFileInstaller.writeClassToDisk("java/beans/Encoder",
-             InMemoryJavaCompiler.compile("java.beans.Encoder", source2, "-Xmodule:java.desktop"),
-             "mods2/java.desktop");
-
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-             "-Xpatch:java.naming=mods/java.naming",
-             "-Xpatch:java.desktop=mods2/java.desktop",
-             "Xpatch2DirsMain", "javax.naming.spi.NamingManager", "java.beans.Encoder");
-
-        OutputAnalyzer oa = new OutputAnalyzer(pb.start());
-        oa.shouldContain("I pass one!");
-        oa.shouldContain("I pass two!");
-        oa.shouldHaveExitValue(0);
-    }
-}
--- a/hotspot/test/runtime/modules/Xpatch/Xpatch2DirsMain.java	Mon Aug 15 08:28:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2015, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// This loads the class affected by the -Xpatch option.  For the test to pass
-// it must load both classes from the -Xpatch directory, not the jimage file.
-public class Xpatch2DirsMain {
-    public static void main(String[] args) throws Exception {
-        Class.forName(args[0]);
-        Class.forName(args[1]);
-    }
-}
--- a/hotspot/test/runtime/modules/Xpatch/XpatchDupJavaBase.java	Mon Aug 15 08:28:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2016, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @summary VM exit initialization results if java.base is specificed more than once to Xpatch.
- * @modules java.base/jdk.internal.misc
- * @library /testlibrary
- */
-
-import jdk.test.lib.*;
-
-public class XpatchDupJavaBase {
-  // The VM should exit initialization if java.base is specified
-  // more than once to -Xpatch.
-  public static void main(String args[]) throws Exception {
-    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-      "-Xpatch:java.base=javabase_dir",
-      "-Xpatch:java.base=javabase_dir",
-      "-version");
-    OutputAnalyzer output = new OutputAnalyzer(pb.start());
-    output.shouldContain("Cannot specify java.base more than once to -Xpatch");
-    output.shouldHaveExitValue(1);
-  }
-}
-
--- a/hotspot/test/runtime/modules/Xpatch/XpatchDupModule.java	Mon Aug 15 08:28:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2016, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @summary Module system initialization exception results if a module is specificed twice to Xpatch.
- * @modules java.base/jdk.internal.misc
- * @library /testlibrary
- */
-
-import jdk.test.lib.*;
-
-public class XpatchDupModule {
-
-  // The module system initialization should generate an ExceptionInInitializerError
-  // if -Xpatch is specified with the same module more than once.
-
-  public static void main(String args[]) throws Exception {
-    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-      "-Xpatch:module1=module1_dir",
-      "-Xpatch:module1=module1_dir",
-      "-version");
-    OutputAnalyzer output = new OutputAnalyzer(pb.start());
-    output.shouldContain("java.lang.ExceptionInInitializerError");
-    output.shouldHaveExitValue(1);
-  }
-}
-
--- a/hotspot/test/runtime/modules/Xpatch/XpatchJavaBase.java	Mon Aug 15 08:28:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2016, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8130399
- * @summary Make sure -Xpatch works for java.base.
- * @modules java.base/jdk.internal.misc
- * @library /testlibrary
- * @compile XpatchMain.java
- * @run main XpatchJavaBase
- */
-
-import jdk.test.lib.*;
-
-public class XpatchJavaBase {
-
-    public static void main(String[] args) throws Exception {
-        String source = "package java.lang; "                       +
-                        "public class NewClass { "                  +
-                        "    static { "                             +
-                        "        System.out.println(\"I pass!\"); " +
-                        "    } "                                    +
-                        "}";
-
-        ClassFileInstaller.writeClassToDisk("java/lang/NewClass",
-             InMemoryJavaCompiler.compile("java.lang.NewClass", source, "-Xmodule:java.base"),
-             "mods/java.base");
-
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.base=mods/java.base",
-             "XpatchMain", "java.lang.NewClass");
-
-        new OutputAnalyzer(pb.start())
-            .shouldContain("I pass!")
-            .shouldHaveExitValue(0);
-    }
-}
--- a/hotspot/test/runtime/modules/Xpatch/XpatchMain.java	Mon Aug 15 08:28:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2015, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// This loads the class affected by the -Xpatch option.  For the test to pass
-// it must load the class from the -Xpatch directory, not the jimage file.
-public class XpatchMain {
-    public static void main(String[] args) throws Exception {
-        Class.forName(args[0]);
-    }
-}
--- a/hotspot/test/runtime/modules/Xpatch/XpatchTest.java	Mon Aug 15 08:28:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8130399
- * @summary Make sure -Xpatch works for modules besides java.base.
- * @modules java.base/jdk.internal.misc
- * @library /testlibrary
- * @compile XpatchMain.java
- * @run main XpatchTest
- */
-
-import jdk.test.lib.*;
-
-public class XpatchTest {
-
-    public static void main(String[] args) throws Exception {
-        String source = "package javax.naming.spi; "                +
-                        "public class NamingManager { "             +
-                        "    static { "                             +
-                        "        System.out.println(\"I pass!\"); " +
-                        "    } "                                    +
-                        "}";
-
-        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
-             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
-             "mods/java.naming");
-
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming",
-             "XpatchMain", "javax.naming.spi.NamingManager");
-
-        new OutputAnalyzer(pb.start())
-            .shouldContain("I pass!")
-            .shouldHaveExitValue(0);
-    }
-}
--- a/hotspot/test/runtime/modules/Xpatch/XpatchTestJar.java	Mon Aug 15 08:28:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2016, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @summary Make sure -Xpatch works when a jar file is specified for a module
- * @library /testlibrary
- * @modules java.base/jdk.internal.misc
- *          jdk.jartool/sun.tools.jar
- * @build BasicJarBuilder
- * @compile XpatchMain.java
- * @run main XpatchTestJar
- */
-
-import jdk.test.lib.*;
-
-public class XpatchTestJar {
-    private static String moduleJar;
-
-    public static void main(String[] args) throws Exception {
-
-        // Create a class file in the module java.naming. This class file
-        // will be put in the javanaming.jar file.
-        String source = "package javax.naming.spi; "                +
-                        "public class NamingManager { "             +
-                        "    static { "                             +
-                        "        System.out.println(\"I pass!\"); " +
-                        "    } "                                    +
-                        "}";
-
-        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
-             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
-             System.getProperty("test.classes"));
-
-        // Build the jar file that will be used for the module "java.naming".
-        BasicJarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
-        moduleJar = BasicJarBuilder.getTestJar("javanaming.jar");
-
-        // Just to make sure we are not fooled by the class file being on the
-        // class path where all the test classes are stored, write the NamingManager.class
-        // file out again with output that does not contain what OutputAnalyzer
-        // expects. This will provide confidence that the contents of the class
-        // is truly coming from the jar file and not the class file.
-        source =        "package javax.naming.spi; "                +
-                        "public class NamingManager { "             +
-                        "    static { "                             +
-                        "        System.out.println(\"Fail!\"); "   +
-                        "    } "                                    +
-                        "}";
-
-        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
-             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
-             System.getProperty("test.classes"));
-
-        // Supply -Xpatch with the name of the jar file for the module java.naming.
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=" + moduleJar,
-             "XpatchMain", "javax.naming.spi.NamingManager");
-
-        new OutputAnalyzer(pb.start())
-            .shouldContain("I pass!")
-            .shouldHaveExitValue(0);
-    }
-}
--- a/hotspot/test/runtime/modules/Xpatch/XpatchTestJarDir.java	Mon Aug 15 08:28:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2016, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @summary Make sure -Xpatch works when a jar file and a directory is specified for a module
- * @library /testlibrary
- * @modules java.base/jdk.internal.misc
- *          jdk.jartool/sun.tools.jar
- * @build BasicJarBuilder
- * @compile Xpatch2DirsMain.java
- * @run main XpatchTestJarDir
- */
-
-import java.io.File;
-import java.nio.file.Files;
-import jdk.test.lib.*;
-
-public class XpatchTestJarDir {
-    private static String moduleJar;
-
-    public static void main(String[] args) throws Exception {
-
-        // Create a class file in the module java.naming. This class file
-        // will be put in the javanaming.jar file.
-        String source = "package javax.naming.spi; "                    +
-                        "public class NamingManager1 { "                +
-                        "    static { "                                 +
-                        "        System.out.println(\"I pass one!\"); " +
-                        "    } "                                        +
-                        "}";
-
-        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager1",
-             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager1", source, "-Xmodule:java.naming"),
-             System.getProperty("test.classes"));
-
-        // Build the jar file that will be used for the module "java.naming".
-        BasicJarBuilder.build("javanaming", "javax/naming/spi/NamingManager1");
-        moduleJar = BasicJarBuilder.getTestJar("javanaming.jar");
-
-        // Just to make sure we are not fooled by the class file being on the
-        // class path where all the test classes are stored, write the NamingManager.class
-        // file out again with output that does not contain what OutputAnalyzer
-        // expects. This will provide confidence that the contents of the class
-        // is truly coming from the jar file and not the class file.
-        source = "package javax.naming.spi; "                +
-                 "public class NamingManager1 { "            +
-                 "    static { "                             +
-                 "        System.out.println(\"Fail!\"); "   +
-                 "    } "                                    +
-                 "}";
-
-        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager1",
-             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager1", source, "-Xmodule:java.naming"),
-             System.getProperty("test.classes"));
-
-        // Create a second class file in the module java.naming. This class file
-        // will be put in the mods/java.naming directory.
-        source = "package javax.naming.spi; "                    +
-                 "public class NamingManager2 { "                +
-                 "    static { "                                 +
-                 "        System.out.println(\"I pass two!\"); " +
-                 "    } "                                        +
-                 "}";
-
-        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager2",
-             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager2", source, "-Xmodule:java.naming"),
-             (System.getProperty("test.classes") + "/mods/java.naming"));
-
-
-        // Supply -Xpatch with the name of the jar file for the module java.naming.
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=" +
-                                                                           moduleJar +
-                                                                           File.pathSeparator +
-                                                                           System.getProperty("test.classes") + "/mods/java.naming",
-                                                                  "Xpatch2DirsMain",
-                                                                  "javax.naming.spi.NamingManager1",
-                                                                  "javax.naming.spi.NamingManager2");
-
-        new OutputAnalyzer(pb.start())
-            .shouldContain("I pass one!")
-            .shouldContain("I pass two!")
-            .shouldHaveExitValue(0);
-    }
-}
--- a/hotspot/test/runtime/modules/Xpatch/XpatchTraceCL.java	Mon Aug 15 08:28:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2016, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8069469
- * @summary Make sure -Xlog:classload=info works properly with "modules" jimage,
-            -Xpatch, and with -Xbootclasspath/a
- * @modules java.base/jdk.internal.misc
- * @library /testlibrary
- * @compile XpatchMain.java
- * @run main XpatchTraceCL
- */
-
-import java.io.File;
-import jdk.test.lib.*;
-
-public class XpatchTraceCL {
-
-    public static void main(String[] args) throws Exception {
-        String source = "package javax.naming.spi; "                +
-                        "public class NamingManager { "             +
-                        "    static { "                             +
-                        "        System.out.println(\"I pass!\"); " +
-                        "    } "                                    +
-                        "}";
-
-        // Test -Xlog:classload=info output for -Xpatch
-        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
-             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
-             "mods/java.naming");
-
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming",
-             "-Xlog:class+load=info", "XpatchMain", "javax.naming.spi.NamingManager");
-
-        OutputAnalyzer output = new OutputAnalyzer(pb.start());
-        // "modules" jimage case.
-        output.shouldContain("[class,load] java.lang.Thread source: jrt:/java.base");
-        // -Xpatch case.
-        output.shouldContain("[class,load] javax.naming.spi.NamingManager source: mods/java.naming");
-        // -cp case.
-        output.shouldContain("[class,load] XpatchMain source: file");
-
-        // Test -Xlog:classload=info output for -Xbootclasspath/a
-        source = "package XpatchTraceCL_pkg; "                 +
-                 "public class ItIsI { "                          +
-                 "    static { "                                  +
-                 "        System.out.println(\"I also pass!\"); " +
-                 "    } "                                         +
-                 "}";
-
-        ClassFileInstaller.writeClassToDisk("XpatchTraceCL_pkg/ItIsI",
-             InMemoryJavaCompiler.compile("XpatchTraceCL_pkg.ItIsI", source),
-             "xbcp");
-
-        pb = ProcessTools.createJavaProcessBuilder("-Xbootclasspath/a:xbcp",
-             "-Xlog:class+load=info", "XpatchMain", "XpatchTraceCL_pkg.ItIsI");
-        output = new OutputAnalyzer(pb.start());
-        // -Xbootclasspath/a case.
-        output.shouldContain("[class,load] XpatchTraceCL_pkg.ItIsI source: xbcp");
-        output.shouldHaveExitValue(0);
-    }
-}
--- a/hotspot/test/runtime/modules/XpatchCDS.java	Mon Aug 15 08:28:26 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @library /testlibrary
- * @modules java.base/jdk.internal.misc
- * @run main XpatchCDS
- */
-
-import java.io.File;
-import jdk.test.lib.*;
-
-public class XpatchCDS {
-
-    public static void main(String args[]) throws Throwable {
-        System.out.println("Test that -Xpatch and -Xshare:dump are incompatibable");
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming", "-Xshare:dump");
-        OutputAnalyzer output = new OutputAnalyzer(pb.start());
-        output.shouldContain("Cannot use the following option when dumping the shared archive: -Xpatch");
-
-        System.out.println("Test that -Xpatch and -Xshare:on are incompatibable");
-        String filename = "Xpatch.jsa";
-        pb = ProcessTools.createJavaProcessBuilder(
-            "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=" + filename,
-            "-Xshare:dump");
-        output = new OutputAnalyzer(pb.start());
-        output.shouldContain("ro space:"); // Make sure archive got created.
-
-        pb = ProcessTools.createJavaProcessBuilder(
-            "-XX:+UnlockDiagnosticVMOptions",
-            "-XX:SharedArchiveFile=" + filename,
-            "-Xshare:on",
-            "-Xpatch:java.naming=mods/java.naming",
-            "-version");
-        output = new OutputAnalyzer(pb.start());
-        output.shouldContain("The shared archive file cannot be used with -Xpatch");
-
-        output.shouldHaveExitValue(1);
-    }
-}
--- a/hotspot/test/runtime/modules/java.base/java/lang/reflect/ModuleHelper.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/runtime/modules/java.base/java/lang/reflect/ModuleHelper.java	Wed Jul 05 22:05:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -27,7 +27,7 @@
 
 /**
  * A helper class intended to be injected into java.lang.reflect using the
- * java -Xpatch option. The helper class provides access to package private
+ * java --patch-module option. The helper class provides access to package private
  * methods in java.lang.reflect.Module.
  */
 
--- a/hotspot/test/serviceability/sa/TestInstanceKlassSize.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/serviceability/sa/TestInstanceKlassSize.java	Wed Jul 05 22:05:22 2017 +0200
@@ -113,9 +113,10 @@
                                           };
             String[] toolArgs = {
                 "-XX:+UnlockDiagnosticVMOptions",
-                "-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
-                "-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED",
-                "-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
+                "--add-modules=jdk.hotspot.agent",
+                "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
+                "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED",
+                "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
                 "TestInstanceKlassSize",
                 Long.toString(app.getPid())
             };
--- a/hotspot/test/serviceability/sa/TestInstanceKlassSizeForInterface.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/serviceability/sa/TestInstanceKlassSizeForInterface.java	Wed Jul 05 22:05:22 2017 +0200
@@ -107,9 +107,10 @@
         // Grab the pid from the current java process and pass it
         String[] toolArgs = {
             "-XX:+UnlockDiagnosticVMOptions",
-            "-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
-            "-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED",
-            "-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
+            "--add-modules=jdk.hotspot.agent",
+            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
+            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED",
+            "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
             "TestInstanceKlassSizeForInterface",
             Long.toString(ProcessTools.getProcessId())
         };
--- a/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java	Wed Jul 05 22:05:22 2017 +0200
@@ -87,7 +87,7 @@
             String expectedFormat) throws Exception, IOException,
             InterruptedException, FileNotFoundException {
         ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(
-                "-XaddExports:java.management/sun.management=ALL-UNNAMED", vmArgs, "JMapHProfLargeHeapProc", String.valueOf(heapSize));
+                "--add-exports=java.management/sun.management=ALL-UNNAMED", vmArgs, "JMapHProfLargeHeapProc", String.valueOf(heapSize));
         procBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
         Process largeHeapProc = procBuilder.start();
 
--- a/hotspot/test/testlibrary/ctw/Makefile	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/testlibrary/ctw/Makefile	Wed Jul 05 22:05:22 2017 +0200
@@ -58,10 +58,10 @@
 
 ctw.jar: filelist wb.jar
 	@mkdir -p $(OUTPUT_DIR)
-	$(JAVAC) -XaddExports:java.base/jdk.internal.jimage=ALL-UNNAMED \
-		-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED \
-		-XaddExports:java.base/jdk.internal.reflect=ALL-UNNAMED \
-		-sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp wb.jar @filelist
+	$(JAVAC) --add-exports java.base/jdk.internal.jimage=ALL-UNNAMED \
+		 --add-exports java.base/jdk.internal.misc=ALL-UNNAMED \
+		 --add-exports java.base/jdk.internal.reflect=ALL-UNNAMED \
+		 -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp wb.jar @filelist
 	$(JAR) --create --file=$@ --main-class $(MAIN_CLASS) -C $(OUTPUT_DIR) .
 
 wb.jar: wb_filelist
--- a/hotspot/test/testlibrary/jittester/Makefile	Mon Aug 15 08:28:26 2016 +0200
+++ b/hotspot/test/testlibrary/jittester/Makefile	Wed Jul 05 22:05:22 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2016, 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
@@ -95,10 +95,10 @@
 	@echo 'Main-Class: jdk.test.lib.jittester.Automatic' >> $(MANIFEST)
 
 compile_testlib: INIT
-	$(JAVAC) -XDignore.symbol.file -XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED -XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -Xlint $(TESTLIBRARY_SRC_FILES) -d $(CLASSES_DIR)
+	$(JAVAC) -XDignore.symbol.file --add-exports=java.base/jdk.internal.misc=ALL-UNNAMED --add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -Xlint $(TESTLIBRARY_SRC_FILES) -d $(CLASSES_DIR)
 
 COMPILE: INIT filelist compile_testlib
-	$(JAVAC) -cp $(CLASSES_DIR) -XDignore.symbol.file -XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED -XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -Xlint -sourcepath $(SRC_DIR) -d $(CLASSES_DIR) @filelist
+	$(JAVAC) -cp $(CLASSES_DIR) -XDignore.symbol.file --add-exports=java.base/jdk.internal.misc=ALL-UNNAMED --add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -Xlint -sourcepath $(SRC_DIR) -d $(CLASSES_DIR) @filelist
 
 filelist: $(SRC_FILES)
 		@rm -f $@
@@ -109,7 +109,7 @@
 	$(shell if [ ! -d $(CLASSES_DIR) ]; then mkdir -p $(CLASSES_DIR); fi)
 
 install: clean_testbase testgroup testroot copytestlibrary JAR cleantmp
-	$(JAVA) -XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -ea -jar $(DIST_JAR) $(APPLICATION_ARGS)
+	$(JAVA) --add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -ea -jar $(DIST_JAR) $(APPLICATION_ARGS)
 
 clean_testbase:
 	@rm -rf $(TESTBASE_DIR)
--- a/jaxp/.hgtags	Mon Aug 15 08:28:26 2016 +0200
+++ b/jaxp/.hgtags	Wed Jul 05 22:05:22 2017 +0200
@@ -373,3 +373,4 @@
 8a7681a9d70640ac7fbf05c28f53c1d51d8d00a1 jdk-9+128
 74241304e87b0d463391a8ecab40979b5af86dc2 jdk-9+129
 e66cdc2de6b02443911d386fc9217b0d824d0686 jdk-9+130
+874082a9b565a7092a40bfa934a6e3e3c3455a60 jdk-9+131
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message.properties	Mon Aug 15 08:28:26 2016 +0200
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/message.properties	Wed Jul 05 22:05:22 2017 +0200
@@ -37,5 +37,3 @@
 parser.quantifier.3=Invalid quantifier. A digit or '}' is expected.
 parser.quantifier.4=Invalid quantifier. A min quantity must be <= a max quantity.
 parser.quantifier.5=Invalid quantifier. A quantity value overflow.
-null
-null
--- a/jaxp/test/TEST.ROOT	Mon Aug 15 08:28:26 2016 +0200
+++ b/jaxp/test/TEST.ROOT	Wed Jul 05 22:05:22 2017 +0200
@@ -23,4 +23,7 @@
 groups=TEST.groups
 
 # Minimum jtreg version
-requiredVersion=4.2 b02
+requiredVersion=4.2 b03
+
+# Use new module options
+useNewOptions=true
--- a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/BasePolicy.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/BasePolicy.java	Wed Jul 05 22:05:22 2017 +0200
@@ -37,7 +37,7 @@
         try {
             JAXPPolicyManager.teardownPolicyManager();
         } catch (Exception e) {
-            throw new RuntimeException("Failed to teardonw the policy manager", e);
+            throw new RuntimeException("Failed to teardown the policy manager", e);
         }
     }
 
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport2.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport2.java	Wed Jul 05 22:05:22 2017 +0200
@@ -28,10 +28,8 @@
 import static jaxp.library.JAXPTestUtilities.setSystemProperty;
 
 import java.io.File;
-import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.io.StringReader;
-import java.net.SocketTimeoutException;
-
 import javax.xml.transform.Source;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.URIResolver;
@@ -52,7 +50,7 @@
 
 /*
  * @test
- * @bug 8158084 8162438 8162442
+ * @bug 8158084 8162438 8162442 8163535
  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
  * @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport2
  * @run testng/othervm catalog.CatalogSupport2
@@ -97,7 +95,7 @@
     /*
        Verifies the Catalog support on SAXParser.
     */
-    @Test(dataProvider = "data_SAXC", expectedExceptions = FileNotFoundException.class)
+    @Test(dataProvider = "data_SAXC", expectedExceptions = IOException.class)
     public void testSAXC(boolean setUseCatalog, boolean useCatalog, String catalog, String
             xml, MyHandler handler, String expected) throws Exception {
         testSAX(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@@ -106,7 +104,7 @@
     /*
        Verifies the Catalog support on XMLReader.
     */
-    @Test(dataProvider = "data_SAXC", expectedExceptions = FileNotFoundException.class)
+    @Test(dataProvider = "data_SAXC", expectedExceptions = IOException.class)
     public void testXMLReaderC(boolean setUseCatalog, boolean useCatalog, String catalog,
             String xml, MyHandler handler, String expected) throws Exception {
         testXMLReader(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@@ -124,7 +122,7 @@
     /*
        Verifies the Catalog support on DOM parser.
     */
-    @Test(dataProvider = "data_DOMC", expectedExceptions = {FileNotFoundException.class, SocketTimeoutException.class})
+    @Test(dataProvider = "data_DOMC", expectedExceptions = IOException.class)
     public void testDOMC(boolean setUseCatalog, boolean useCatalog, String catalog,
             String xml, MyHandler handler, String expected) throws Exception {
         testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@@ -141,7 +139,7 @@
         testValidation(setUseCatalog, useCatalog, catalog, xsd, resolver) ;
     }
 
-    @Test(dataProvider = "data_ValidatorC", expectedExceptions = {SAXException.class, FileNotFoundException.class})
+    @Test(dataProvider = "data_ValidatorC", expectedExceptions = {SAXException.class, IOException.class})
     public void testValidatorC(boolean setUseCatalog1, boolean setUseCatalog2, boolean useCatalog,
             Source source, LSResourceResolver resolver1, LSResourceResolver resolver2,
             String catalog1, String catalog2)
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport3.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport3.java	Wed Jul 05 22:05:22 2017 +0200
@@ -27,10 +27,8 @@
 import static jaxp.library.JAXPTestUtilities.setSystemProperty;
 
 import java.io.File;
-import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.io.StringReader;
-import java.net.SocketTimeoutException;
-
 import javax.xml.transform.Source;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.URIResolver;
@@ -51,7 +49,7 @@
 
 /*
  * @test
- * @bug 8158084 8162438 8162442
+ * @bug 8158084 8162438 8162442 8163535
  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
  * @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport3
  * @run testng/othervm catalog.CatalogSupport3
@@ -93,7 +91,7 @@
     /*
        Verifies the Catalog support on SAXParser.
     */
-    @Test(dataProvider = "data_SAXC", expectedExceptions = FileNotFoundException.class)
+    @Test(dataProvider = "data_SAXC", expectedExceptions = IOException.class)
     public void testSAXC(boolean setUseCatalog, boolean useCatalog, String catalog,
             String xml, MyHandler handler, String expected) throws Exception {
         testSAX(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@@ -102,7 +100,7 @@
     /*
        Verifies the Catalog support on XMLReader.
     */
-    @Test(dataProvider = "data_SAXC", expectedExceptions = FileNotFoundException.class)
+    @Test(dataProvider = "data_SAXC", expectedExceptions = IOException.class)
     public void testXMLReaderC(boolean setUseCatalog, boolean useCatalog, String catalog,
             String xml, MyHandler handler, String expected) throws Exception {
         testXMLReader(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@@ -120,7 +118,7 @@
     /*
        Verifies the Catalog support on DOM parser.
     */
-    @Test(dataProvider = "data_DOMC", expectedExceptions = {FileNotFoundException.class, SocketTimeoutException.class})
+    @Test(dataProvider = "data_DOMC", expectedExceptions = IOException.class)
     public void testDOMC(boolean setUseCatalog, boolean useCatalog, String catalog,
             String xml, MyHandler handler, String expected) throws Exception {
         testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@@ -141,7 +139,7 @@
        @bug 8158084 8162438 these tests also verifies the fix for 8162438
        Verifies the Catalog support on the Schema Validator.
     */
-    @Test(dataProvider = "data_ValidatorC", expectedExceptions = {SAXException.class, FileNotFoundException.class})
+    @Test(dataProvider = "data_ValidatorC", expectedExceptions = {SAXException.class, IOException.class})
     public void testValidatorC(boolean setUseCatalog1, boolean setUseCatalog2, boolean useCatalog,
             Source source, LSResourceResolver resolver1, LSResourceResolver resolver2,
             String catalog1, String catalog2)
--- a/jaxp/test/javax/xml/jaxp/unittest/validation/Bug6773084Test.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jaxp/test/javax/xml/jaxp/unittest/validation/Bug6773084Test.java	Wed Jul 05 22:05:22 2017 +0200
@@ -32,11 +32,10 @@
 import java.util.concurrent.CyclicBarrier;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 
 import javax.xml.XMLConstants;
-import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.Source;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamSource;
@@ -69,6 +68,7 @@
     private static final ExecutorService EXEC = Executors.newCachedThreadPool();
 
     private static final CyclicBarrier BARRIER = new CyclicBarrier(NTHREADS);
+    private static final int TIMEOUT = 110;
 
     public static final String IN_FOLDER = Bug6773084Test.class.getResource("Bug6773084In").getPath();
     public static final String XSD_PATH = Bug6773084Test.class.getResource("Bug6773084.xsd").getPath();
@@ -93,20 +93,23 @@
             }
         });
 
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        dbf.setNamespaceAware(true);
+
         for (int i = 0; i < files.length; i++) {
-            EXEC.execute(new XMLValiddator(files[i], i));
+            EXEC.execute(new XMLValiddator(dbf.newDocumentBuilder().parse(files[i]), i));
         }
         runWithAllPerm(() -> EXEC.shutdown());
-
+        EXEC.awaitTermination(TIMEOUT, TimeUnit.SECONDS);
     }
 
     private static class XMLValiddator implements Runnable {
 
-        private File file;
+        private Document document;
         private int index;
 
-        public XMLValiddator(File file, int index) {
-            this.file = file;
+        public XMLValiddator(Document document, int index) {
+            this.document = document;
             this.index = index;
         }
 
@@ -117,23 +120,14 @@
                 BARRIER.await();
                 System.out.println("Validating....");
 
-                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-                factory.setNamespaceAware(true);
-
-                DocumentBuilder builder = factory.newDocumentBuilder();
-                Document document = builder.parse(file);
-
                 Validator validator = schema.newValidator();
                 validator.setErrorHandler(new ErrorHandlerImpl());
                 validator.validate(new DOMSource(document));
-
             } catch (IOException e) {
                 e.printStackTrace();
             } catch (SAXException e) {
                 e.printStackTrace();
                 Assert.fail("Test failed.");
-            } catch (ParserConfigurationException e) {
-                e.printStackTrace();
             } catch (BrokenBarrierException e) {
                 e.printStackTrace();
             } catch (InterruptedException e) {
--- a/jaxws/.hgtags	Mon Aug 15 08:28:26 2016 +0200
+++ b/jaxws/.hgtags	Wed Jul 05 22:05:22 2017 +0200
@@ -376,3 +376,4 @@
 fe4e11bd2423635dc0f5f5cb9a64eb2f2cce7f4c jdk-9+128
 46a02f57218e4a8c334dbccf656fb048f823f163 jdk-9+129
 39c6293131d91aec7f2f5120395e070a937b8858 jdk-9+130
+783e7e2c587f2c7e1b9998a46d90ec196ab2a195 jdk-9+131
--- a/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/jxc/SchemaGenerator.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/jxc/SchemaGenerator.java	Wed Jul 05 22:05:22 2017 +0200
@@ -140,7 +140,7 @@
         aptargs.add("-cp");
         aptargs.add(setClasspath(options.classpath)); // set original classpath + jaxb-api to be visible to annotation processor
 
-        aptargs.add("-addmods");
+        aptargs.add("--add-modules");
         aptargs.add("java.xml.bind");
 
         if(options.targetDir!=null) {
--- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wscompile/WsgenTool.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wscompile/WsgenTool.java	Wed Jul 05 22:05:22 2017 +0200
@@ -162,7 +162,7 @@
         boolean bootCP = useBootClasspath(EndpointReference.class) || useBootClasspath(XmlSeeAlso.class);
         List<String> args = new ArrayList<String>(6 + (bootCP ? 1 : 0) + (options.nocompile ? 1 : 0)
                 + (options.encoding != null ? 2 : 0));
-        args.add("-addmods");
+        args.add("--add-modules");
         args.add("java.xml.ws");
         args.add("-d");
         args.add(options.destDir.getAbsolutePath());
--- a/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wscompile/WsimportTool.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/wscompile/WsimportTool.java	Wed Jul 05 22:05:22 2017 +0200
@@ -525,7 +525,7 @@
             String classpathString = createClasspathString();
             boolean bootCP = useBootClasspath(EndpointContext.class) || useBootClasspath(JAXBPermission.class);
             List<String> args = new ArrayList<String>();
-            args.add("-addmods");
+            args.add("--add-modules");
             args.add("java.xml.ws");
             args.add("-d");
             args.add(classDir);
--- a/jdk/.hgtags	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/.hgtags	Wed Jul 05 22:05:22 2017 +0200
@@ -373,3 +373,4 @@
 9446c534f0222b4eecfd9d9e25ab37c4fd4400a5 jdk-9+128
 47699aa2e69ec2702542dc73eb01de3bfb61aea0 jdk-9+129
 6c827500e34587061af97ad6fef0e859280255c5 jdk-9+130
+8c57f4c293bbc5609928308a6d91ba765760b5f9 jdk-9+131
--- a/jdk/make/GenerateModuleSummary.gmk	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/make/GenerateModuleSummary.gmk	Wed Jul 05 22:05:22 2017 +0200
@@ -42,6 +42,6 @@
 
 $(GENGRAPHS_DIR)/module-summary.html: $(BUILD_JIGSAW_TOOLS) $(GENGRAPHS_DIR)/technology-summary.html
 	$(MKDIR) -p $(@D)
-	$(TOOL_MODULESUMMARY) -o $@ -mp $(IMAGES_OUTPUTDIR)/jmods
+	$(TOOL_MODULESUMMARY) -o $@ --module-path $(IMAGES_OUTPUTDIR)/jmods
 
 all: $(GENGRAPHS_DIR)/jdk.dot $(GENGRAPHS_DIR)/module-summary.html
--- a/jdk/make/ModuleTools.gmk	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/make/ModuleTools.gmk	Wed Jul 05 22:05:22 2017 +0200
@@ -36,12 +36,12 @@
     INCLUDES := build/tools/deps \
                 build/tools/jigsaw, \
     BIN := $(TOOLS_CLASSES_DIR), \
-    ADD_JAVAC_FLAGS := -XaddExports:jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED ))
+    ADD_JAVAC_FLAGS := --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED ))
 
 
 TOOL_GENGRAPHS := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
     build.tools.jigsaw.GenGraphs
 
 TOOL_MODULESUMMARY := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
-    -XaddExports:jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \
+    --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \
     build.tools.jigsaw.ModuleSummary
--- a/jdk/make/Tools.gmk	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/make/Tools.gmk	Wed Jul 05 22:05:22 2017 +0200
@@ -38,7 +38,7 @@
 ################################################################################
 
 ifeq ($(BOOT_JDK_MODULAR), true)
-  COMPILEFONTCONFIG_ADD_EXPORTS := -XaddExports:java.desktop/sun.awt=ALL-UNNAMED
+  COMPILEFONTCONFIG_ADD_EXPORTS := --add-exports java.desktop/sun.awt=ALL-UNNAMED
 endif
 
 TOOL_COMPILEFONTCONFIG = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
@@ -94,7 +94,7 @@
 # Nimbus is used somewhere in the swing build.
 
 ifeq ($(BOOT_JDK_MODULAR), true)
-  COMPILENIMBUS_ADD_MODS := -addmods java.xml.bind
+  COMPILENIMBUS_ADD_MODS := --add-modules java.xml.bind
 endif
 
 TOOL_GENERATENIMBUS = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
--- a/jdk/make/copy/Copy-java.base.gmk	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/make/copy/Copy-java.base.gmk	Wed Jul 05 22:05:22 2017 +0200
@@ -203,7 +203,7 @@
 ################################################################################
 
 ifeq ($(CACERTS_FILE), )
-  CACERTS_FILE := $(JDK_TOPDIR)/src/java.base/share/conf/security/cacerts
+  CACERTS_FILE := $(JDK_TOPDIR)/src/java.base/share/lib/security/cacerts
 endif
 
 CACERTS_DST := $(LIB_DST_DIR)/security/cacerts
--- a/jdk/make/gendata/GendataBreakIterator.gmk	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/make/gendata/GendataBreakIterator.gmk	Wed Jul 05 22:05:22 2017 +0200
@@ -63,11 +63,11 @@
 
 ifeq ($(BOOT_JDK_MODULAR), true)
   BREAK_ITERATOR_BOOTCLASSPATH := \
-      -Xpatch:java.base=$(BREAK_ITERATOR_CLASSES)/java.base \
-      -Xpatch:jdk.localedata=$(BREAK_ITERATOR_CLASSES)/jdk.localedata \
-      -XaddExports:java.base/sun.text=ALL-UNNAMED \
-      -XaddExports:java.base/sun.text.resources=ALL-UNNAMED \
-      -XaddExports:jdk.localedata/sun.text.resources.ext=ALL-UNNAMED \
+      --patch-module java.base=$(BREAK_ITERATOR_CLASSES)/java.base \
+      --patch-module jdk.localedata=$(BREAK_ITERATOR_CLASSES)/jdk.localedata \
+      --add-exports java.base/sun.text=ALL-UNNAMED \
+      --add-exports java.base/sun.text.resources=ALL-UNNAMED \
+      --add-exports jdk.localedata/sun.text.resources.ext=ALL-UNNAMED \
       #
 else
   BREAK_ITERATOR_BOOTCLASSPATH := -Xbootclasspath/p:$(call PathList, \
--- a/jdk/make/launcher/Launcher-java.desktop.gmk	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/make/launcher/Launcher-java.desktop.gmk	Wed Jul 05 22:05:22 2017 +0200
@@ -31,7 +31,7 @@
 ifndef BUILD_HEADLESS_ONLY
   $(eval $(call SetupBuildLauncher, appletviewer, \
       MAIN_CLASS := sun.applet.Main, \
-      JAVA_ARGS := -addmods ALL-DEFAULT, \
+      JAVA_ARGS := --add-modules ALL-DEFAULT, \
       LIBS_unix := $(X_LIBS), \
   ))
 endif
--- a/jdk/make/launcher/Launcher-java.scripting.gmk	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/make/launcher/Launcher-java.scripting.gmk	Wed Jul 05 22:05:22 2017 +0200
@@ -27,5 +27,5 @@
 
 $(eval $(call SetupBuildLauncher, jrunscript, \
     MAIN_CLASS := com.sun.tools.script.shell.Main, \
-    JAVA_ARGS := -addmods ALL-DEFAULT, \
+    JAVA_ARGS := --add-modules ALL-DEFAULT, \
 ))
--- a/jdk/make/launcher/Launcher-jdk.compiler.gmk	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/make/launcher/Launcher-jdk.compiler.gmk	Wed Jul 05 22:05:22 2017 +0200
@@ -27,7 +27,7 @@
 
 $(eval $(call SetupBuildLauncher, javac, \
    MAIN_CLASS := com.sun.tools.javac.Main, \
-   JAVA_ARGS := -addmods ALL-DEFAULT, \
+   JAVA_ARGS := --add-modules ALL-DEFAULT, \
    CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
         -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
 ))
--- a/jdk/make/launcher/Launcher-jdk.javadoc.gmk	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/make/launcher/Launcher-jdk.javadoc.gmk	Wed Jul 05 22:05:22 2017 +0200
@@ -27,7 +27,7 @@
 
 $(eval $(call SetupBuildLauncher, javadoc, \
     MAIN_CLASS := jdk.javadoc.internal.tool.Main, \
-    JAVA_ARGS := -addmods ALL-DEFAULT, \
+    JAVA_ARGS := --add-modules ALL-DEFAULT, \
     CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
         -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
 ))
--- a/jdk/make/launcher/Launcher-jdk.jlink.gmk	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/make/launcher/Launcher-jdk.jlink.gmk	Wed Jul 05 22:05:22 2017 +0200
@@ -32,7 +32,7 @@
 
 $(eval $(call SetupBuildLauncher, jlink,\
     MAIN_CLASS := jdk.tools.jlink.internal.Main, \
-    JAVA_ARGS := -addmods ALL-DEFAULT, \
+    JAVA_ARGS :=  --add-modules ALL-DEFAULT, \
     CFLAGS := -DENABLE_ARG_FILES \
         -DEXPAND_CLASSPATH_WILDCARDS \
         -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
--- a/jdk/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk	Wed Jul 05 22:05:22 2017 +0200
@@ -27,6 +27,6 @@
 
 $(eval $(call SetupBuildLauncher, jjs, \
     MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \
-    JAVA_ARGS := -addmods ALL-DEFAULT, \
+    JAVA_ARGS := --add-modules ALL-DEFAULT, \
     CFLAGS := -DENABLE_ARG_FILES, \
 ))
--- a/jdk/make/src/classes/build/tools/jigsaw/ModuleSummary.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/make/src/classes/build/tools/jigsaw/ModuleSummary.java	Wed Jul 05 22:05:22 2017 +0200
@@ -51,7 +51,7 @@
 import static build.tools.jigsaw.ModuleSummary.HtmlDocument.Division.*;
 
 public class ModuleSummary {
-    private static final String USAGE = "Usage: ModuleSummary -mp <dir> -o <outfile> [-root mn]*";
+    private static final String USAGE = "Usage: ModuleSummary --module-path <dir> -o <outfile> [--root mn]*";
 
     public static void main(String[] args) throws Exception {
         int i=0;
@@ -61,13 +61,13 @@
         while (i < args.length && args[i].startsWith("-")) {
             String arg = args[i++];
             switch (arg) {
-                case "-mp":
+                case "--module-path":
                     modpath = Paths.get(args[i++]);
                     break;
                 case "-o":
                     outfile = Paths.get(args[i++]);
                     break;
-                case "-root":
+                case "--root":
                     roots.add(args[i++]);
                 default:
                     System.err.println(USAGE);
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java	Wed Jul 05 22:05:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -53,10 +53,37 @@
     private final int blockLen;
 
     /**
-     * Standard constructor, creates a new HmacCore instance using the
-     * specified MessageDigest object.
+     * Standard constructor, creates a new HmacCore instance instantiating
+     * a MessageDigest of the specified name.
      */
-    HmacCore(MessageDigest md, int bl) {
+    HmacCore(String digestAlgo, int bl) throws NoSuchAlgorithmException {
+        MessageDigest md = MessageDigest.getInstance(digestAlgo);
+        if (!(md instanceof Cloneable)) {
+            // use SUN provider if the most preferred one does not support
+            // cloning
+            Provider sun = Security.getProvider("SUN");
+            if (sun != null) {
+                md = MessageDigest.getInstance(digestAlgo, sun);
+            } else {
+                String noCloneProv = md.getProvider().getName();
+                // if no Sun provider, use provider list
+                Provider[] provs = Security.getProviders();
+                for (Provider p : provs) {
+                    try {
+                        if (!p.getName().equals(noCloneProv)) {
+                            MessageDigest md2 =
+                                MessageDigest.getInstance(digestAlgo, p);
+                            if (md2 instanceof Cloneable) {
+                                md = md2;
+                                break;
+                            }
+                        }
+                    } catch (NoSuchAlgorithmException nsae) {
+                        continue;
+                    }
+                }
+            }
+        }
         this.md = md;
         this.blockLen = bl;
         this.k_ipad = new byte[blockLen];
@@ -65,14 +92,6 @@
     }
 
     /**
-     * Standard constructor, creates a new HmacCore instance instantiating
-     * a MessageDigest of the specified name.
-     */
-    HmacCore(String digestAlgorithm, int bl) throws NoSuchAlgorithmException {
-        this(MessageDigest.getInstance(digestAlgorithm), bl);
-    }
-
-    /**
      * Returns the length of the HMAC in bytes.
      *
      * @return the HMAC length in bytes.
--- a/jdk/src/java.base/share/classes/java/io/CharArrayReader.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/io/CharArrayReader.java	Wed Jul 05 22:05:22 2017 +0200
@@ -131,8 +131,10 @@
             if (pos >= count) {
                 return -1;
             }
-            if (pos + len > count) {
-                len = count - pos;
+
+            int avail = count - pos;
+            if (len > avail) {
+                len = avail;
             }
             if (len <= 0) {
                 return 0;
@@ -158,8 +160,10 @@
     public long skip(long n) throws IOException {
         synchronized (lock) {
             ensureOpen();
-            if (pos + n > count) {
-                n = count - pos;
+
+            long avail = count - pos;
+            if (n > avail) {
+                n = avail;
             }
             if (n < 0) {
                 return 0;
--- a/jdk/src/java.base/share/classes/java/io/StringBufferInputStream.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/io/StringBufferInputStream.java	Wed Jul 05 22:05:22 2017 +0200
@@ -118,8 +118,10 @@
         if (pos >= count) {
             return -1;
         }
-        if (pos + len > count) {
-            len = count - pos;
+
+        int avail = count - pos;
+        if (len > avail) {
+            len = avail;
         }
         if (len <= 0) {
             return 0;
--- a/jdk/src/java.base/share/classes/java/lang/System.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/System.java	Wed Jul 05 22:05:22 2017 +0200
@@ -644,23 +644,20 @@
      * <code>getProperties</code> operation, it may choose to permit the
      * {@link #getProperty(String)} operation.
      *
-     * @implNote In addition to the standard system properties, the {@code
-     * java} launcher may create the Java Virtual Machine with system
-     * properties that have the following keys:
+     * @implNote In addition to the standard system properties, the system
+     * properties may include the following keys:
      * <table summary="Shows property keys and associated values">
      * <tr><th>Key</th>
      *     <th>Description of Associated Value</th></tr>
      * <tr><td>{@code jdk.module.path}</td>
-     *     <td>Application module path</td></tr>
-     * <tr><td>{@code jdk.upgrade.module.path}</td>
+     *     <td>The application module path</td></tr>
+     * <tr><td>{@code jdk.module.upgrade.path}</td>
      *     <td>The upgrade module path</td></tr>
      * <tr><td>{@code jdk.module.main}</td>
      *     <td>The module name of the initial/main module</td></tr>
      * <tr><td>{@code jdk.module.main.class}</td>
      *     <td>The main class name of the initial module</td></tr>
      * </table>
-     * These properties may also be set by custom launchers that use the JNI
-     * invocation API to create the Java Virtual Machine.
      *
      * @return     the system properties
      * @exception  SecurityException  if a security manager exists and its
--- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java	Wed Jul 05 22:05:22 2017 +0200
@@ -587,26 +587,7 @@
             return bmhClass;
         }
 
-        /**
-         * @implNote this method is used by GenerateBMHClassesPlugin to enable
-         * ahead-of-time generation of BMH classes at link time. It does
-         * added validation since this string may be user provided.
-         */
-        static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
-                final String types) {
-            for (char c : types.toCharArray()) {
-                if ("LIJFD".indexOf(c) < 0) {
-                    throw new IllegalArgumentException("All characters must "
-                            + "correspond to a basic field type: LIJFD");
-                }
-            }
-            String shortTypes = LambdaForm.shortenSignature(types);
-            final String className  = speciesInternalClassName(shortTypes);
-            return Map.entry(className,
-                    generateConcreteBMHClassBytes(shortTypes, types, className));
-        }
-
-        private static String speciesInternalClassName(String shortTypes) {
+        static String speciesInternalClassName(String shortTypes) {
             return SPECIES_PREFIX_PATH + shortTypes;
         }
 
@@ -865,7 +846,7 @@
         }
     }
 
-    private static final Lookup LOOKUP = Lookup.IMPL_LOOKUP;
+    static final Lookup LOOKUP = Lookup.IMPL_LOOKUP;
 
     /**
      * All subclasses must provide such a value describing their type signature.
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Wed Jul 05 22:05:22 2017 +0200
@@ -186,7 +186,7 @@
         return mtype.form().setCachedLambdaForm(which, lform);
     }
 
-    private static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
+    static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
         boolean needsInit = (which == LF_INVSTATIC_INIT);
         boolean doesAlloc = (which == LF_NEWINVSPECIAL);
         String linkerName, lambdaName;
@@ -248,20 +248,6 @@
         return lform;
     }
 
-    /*
-     * NOTE: This method acts as an API hook for use by the
-     * GenerateJLIClassesPlugin to generate a class wrapping DirectMethodHandle
-     * methods for an array of method types.
-     */
-    static byte[] generateDMHClassBytes(String className, MethodType[] methodTypes, int[] types) {
-        LambdaForm[] forms = new LambdaForm[methodTypes.length];
-        for (int i = 0; i < forms.length; i++) {
-            forms[i] = makePreparedLambdaForm(methodTypes[i], types[i]);
-            methodTypes[i] = forms[i].methodType();
-        }
-        return InvokerBytecodeGenerator.generateCodeBytesForMultiple(className, forms, methodTypes);
-    }
-
     static Object findDirectMethodHandle(Name name) {
         if (name.function == NF_internalMemberName ||
             name.function == NF_internalMemberNameEnsureInit ||
@@ -273,7 +259,7 @@
     }
 
     private static void maybeCompile(LambdaForm lform, MemberName m) {
-        if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
+        if (lform.vmentry == null && VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
             // Help along bootstrapping...
             lform.compileToBytecode();
     }
@@ -515,7 +501,7 @@
     // Enumerate the different field kinds using Wrapper,
     // with an extra case added for checked references.
     private static final int
-            FT_LAST_WRAPPER    = Wrapper.values().length-1,
+            FT_LAST_WRAPPER    = Wrapper.COUNT-1,
             FT_UNCHECKED_REF   = Wrapper.OBJECT.ordinal(),
             FT_CHECKED_REF     = FT_LAST_WRAPPER+1,
             FT_LIMIT           = FT_LAST_WRAPPER+2;
@@ -576,25 +562,36 @@
         return lform;
     }
 
+    private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
+
     private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
         boolean isGetter  = (formOp & 1) == (AF_GETFIELD & 1);
         boolean isStatic  = (formOp >= AF_GETSTATIC);
         boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
         boolean needsCast = (ftypeKind == FT_CHECKED_REF);
-        Wrapper fw = (needsCast ? Wrapper.OBJECT : Wrapper.values()[ftypeKind]);
+        Wrapper fw = (needsCast ? Wrapper.OBJECT : ALL_WRAPPERS[ftypeKind]);
         Class<?> ft = fw.primitiveType();
         assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
-        String tname  = fw.primitiveSimpleName();
-        String ctname = Character.toUpperCase(tname.charAt(0)) + tname.substring(1);
-        if (isVolatile)  ctname += "Volatile";
-        String getOrPut = (isGetter ? "get" : "put");
-        String linkerName = (getOrPut + ctname);  // getObject, putIntVolatile, etc.
+
+        // getObject, putIntVolatile, etc.
+        StringBuilder nameBuilder = new StringBuilder();
+        if (isGetter) {
+            nameBuilder.append("get");
+        } else {
+            nameBuilder.append("put");
+        }
+        nameBuilder.append(fw.primitiveSimpleName());
+        nameBuilder.setCharAt(3, Character.toUpperCase(nameBuilder.charAt(3)));
+        if (isVolatile) {
+            nameBuilder.append("Volatile");
+        }
+
         MethodType linkerType;
         if (isGetter)
             linkerType = MethodType.methodType(ft, Object.class, long.class);
         else
             linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
-        MemberName linker = new MemberName(Unsafe.class, linkerName, linkerType, REF_invokeVirtual);
+        MemberName linker = new MemberName(Unsafe.class, nameBuilder.toString(), linkerType, REF_invokeVirtual);
         try {
             linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
         } catch (ReflectiveOperationException ex) {
@@ -649,11 +646,16 @@
         if (needsCast && isGetter)
             names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
         for (Name n : names)  assert(n != null);
-        String fieldOrStatic = (isStatic ? "Static" : "Field");
-        String lambdaName = (linkerName + fieldOrStatic);  // significant only for debugging
-        if (needsCast)  lambdaName += "Cast";
-        if (needsInit)  lambdaName += "Init";
-        return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
+        // add some detail to the lambdaForm debugname,
+        // significant only for debugging
+        if (isStatic) {
+            nameBuilder.append("Static");
+        } else {
+            nameBuilder.append("Field");
+        }
+        if (needsCast)  nameBuilder.append("Cast");
+        if (needsInit)  nameBuilder.append("Init");
+        return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.invoke;
+
+import java.util.Map;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * Helper class to assist the GenerateJLIClassesPlugin to get access to
+ * generate classes ahead of time.
+ */
+class GenerateJLIClassesHelper {
+
+    static byte[] generateDMHClassBytes(String className,
+            MethodType[] methodTypes, int[] types) {
+        LambdaForm[] forms = new LambdaForm[methodTypes.length];
+        for (int i = 0; i < forms.length; i++) {
+            forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i],
+                                                                 types[i]);
+            methodTypes[i] = forms[i].methodType();
+        }
+        return generateCodeBytesForLFs(className, forms, methodTypes);
+    }
+
+    /*
+     * Generate customized code for a set of LambdaForms of specified types into
+     * a class with a specified name.
+     */
+    private static byte[] generateCodeBytesForLFs(String className,
+            LambdaForm[] forms, MethodType[] types) {
+        assert(forms.length == types.length);
+
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
+        cw.visit(Opcodes.V1_8, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
+                className, null, InvokerBytecodeGenerator.INVOKER_SUPER_NAME, null);
+        cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null);
+        for (int i = 0; i < forms.length; i++) {
+            InvokerBytecodeGenerator g
+                    = new InvokerBytecodeGenerator(className, forms[i], types[i]);
+            g.setClassWriter(cw);
+            g.addMethod();
+        }
+        return cw.toByteArray();
+    }
+
+    static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
+            final String types) {
+        for (char c : types.toCharArray()) {
+            if ("LIJFD".indexOf(c) < 0) {
+                throw new IllegalArgumentException("All characters must "
+                        + "correspond to a basic field type: LIJFD");
+            }
+        }
+        String shortTypes = LambdaForm.shortenSignature(types);
+        final String className =
+                BoundMethodHandle.Factory.speciesInternalClassName(shortTypes);
+        return Map.entry(className,
+                         BoundMethodHandle.Factory.generateConcreteBMHClassBytes(
+                                 shortTypes, types, className));
+    }
+}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Wed Jul 05 22:05:22 2017 +0200
@@ -40,8 +40,8 @@
 import java.io.IOException;
 import java.lang.reflect.Modifier;
 import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Map;
 import java.util.stream.Stream;
 
 import static java.lang.invoke.LambdaForm.*;
@@ -68,9 +68,10 @@
     private static final String LFN_SIG = "L" + LFN + ";";
     private static final String LL_SIG  = "(L" + OBJ + ";)L" + OBJ + ";";
     private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V";
+    private static final String CLASS_PREFIX = LF + "$";
 
     /** Name of its super class*/
-    private static final String INVOKER_SUPER_NAME = OBJ;
+    static final String INVOKER_SUPER_NAME = OBJ;
 
     /** Name of new class */
     private final String className;
@@ -96,15 +97,15 @@
     /** Main constructor; other constructors delegate to this one. */
     private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
                                      String className, String invokerName, MethodType invokerType) {
-        if (invokerName.contains(".")) {
-            int p = invokerName.indexOf('.');
+        int p = invokerName.indexOf('.');
+        if (p > -1) {
             className = invokerName.substring(0, p);
-            invokerName = invokerName.substring(p+1);
+            invokerName = invokerName.substring(p + 1);
         }
         if (DUMP_CLASS_FILES) {
             className = makeDumpableClassName(className);
         }
-        this.className  = LF + "$" + className;
+        this.className  = CLASS_PREFIX + className;
         this.sourceFile = "LambdaForm$" + className;
         this.lambdaForm = lambdaForm;
         this.invokerName = invokerName;
@@ -124,7 +125,7 @@
     }
 
     /** For generating customized code for a single LambdaForm. */
-    private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) {
+    InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) {
         this(form, form.names.length,
              className, form.debugName, invokerType);
         // Create an array to map name indexes to locals indexes.
@@ -201,38 +202,34 @@
 
     class CpPatch {
         final int index;
-        final String placeholder;
         final Object value;
-        CpPatch(int index, String placeholder, Object value) {
+        CpPatch(int index, Object value) {
             this.index = index;
-            this.placeholder = placeholder;
             this.value = value;
         }
         public String toString() {
-            return "CpPatch/index="+index+",placeholder="+placeholder+",value="+value;
+            return "CpPatch/index="+index+",value="+value;
         }
     }
 
-    Map<Object, CpPatch> cpPatches = new HashMap<>();
+    private final ArrayList<CpPatch> cpPatches = new ArrayList<>();
 
-    int cph = 0;  // for counting constant placeholders
+    private int cph = 0;  // for counting constant placeholders
 
     String constantPlaceholder(Object arg) {
         String cpPlaceholder = "CONSTANT_PLACEHOLDER_" + cph++;
-        if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + debugString(arg) + ">>";  // debugging aid
-        if (cpPatches.containsKey(cpPlaceholder)) {
-            throw new InternalError("observed CP placeholder twice: " + cpPlaceholder);
-        }
+        if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + debugString(arg) + ">>";
+        // TODO check if arg is already in the constant pool
         // insert placeholder in CP and remember the patch
-        int index = cw.newConst((Object) cpPlaceholder);  // TODO check if already in the constant pool
-        cpPatches.put(cpPlaceholder, new CpPatch(index, cpPlaceholder, arg));
+        int index = cw.newConst((Object) cpPlaceholder);
+        cpPatches.add(new CpPatch(index, arg));
         return cpPlaceholder;
     }
 
     Object[] cpPatches(byte[] classFile) {
         int size = getConstantPoolSize(classFile);
         Object[] res = new Object[size];
-        for (CpPatch p : cpPatches.values()) {
+        for (CpPatch p : cpPatches) {
             if (p.index >= size)
                 throw new InternalError("in cpool["+size+"]: "+p+"\n"+Arrays.toString(Arrays.copyOf(classFile, 20)));
             res[p.index] = p.value;
@@ -655,35 +652,11 @@
         return classFile;
     }
 
-    /*
-     * NOTE: This is used from GenerateJLIClassesPlugin via
-     * DirectMethodHandle::generateDMHClassBytes.
-     *
-     * Generate customized code for a set of LambdaForms of specified types into
-     * a class with a specified name.
-     */
-    static byte[] generateCodeBytesForMultiple(String className,
-            LambdaForm[] forms, MethodType[] types) {
-        assert(forms.length == types.length);
-
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
-        cw.visit(Opcodes.V1_8, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
-                className, null, INVOKER_SUPER_NAME, null);
-        cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null);
-        for (int i = 0; i < forms.length; i++) {
-            InvokerBytecodeGenerator g
-                    = new InvokerBytecodeGenerator(className, forms[i], types[i]);
-            g.setClassWriter(cw);
-            g.addMethod();
-        }
-        return cw.toByteArray();
-    }
-
-    private void setClassWriter(ClassWriter cw) {
+    void setClassWriter(ClassWriter cw) {
         this.cw = cw;
     }
 
-    private void addMethod() {
+    void addMethod() {
         methodPrologue();
 
         // Suppress this method in backtraces displayed to the user.
@@ -765,7 +738,7 @@
                     continue;
                 case IDENTITY:
                     assert(name.arguments.length == 1);
-                    emitPushArguments(name);
+                    emitPushArguments(name, 0);
                     continue;
                 case ZERO:
                     assert(name.arguments.length == 0);
@@ -819,7 +792,7 @@
         assert arrayOpcode == Opcodes.AALOAD || arrayOpcode == Opcodes.AASTORE || arrayOpcode == Opcodes.ARRAYLENGTH;
         Class<?> elementType = name.function.methodType().parameterType(0).getComponentType();
         assert elementType != null;
-        emitPushArguments(name);
+        emitPushArguments(name, 0);
         if (arrayOpcode != Opcodes.ARRAYLENGTH && elementType.isPrimitive()) {
             Wrapper w = Wrapper.forPrimitiveType(elementType);
             arrayOpcode = arrayInsnOpcode(arrayTypeCode(w), arrayOpcode);
@@ -848,7 +821,7 @@
         }
 
         // push arguments
-        emitPushArguments(name);
+        emitPushArguments(name, 0);
 
         // invocation
         MethodType type = name.function.methodType();
@@ -947,7 +920,7 @@
         assert(!(member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual));
 
         // push arguments
-        emitPushArguments(name);
+        emitPushArguments(name, 0);
 
         // invocation
         if (member.isMethod()) {
@@ -1468,13 +1441,10 @@
         }
     }
 
-    private void emitPushArguments(Name args) {
-        emitPushArguments(args, 0);
-    }
-
     private void emitPushArguments(Name args, int start) {
+        MethodType type = args.function.methodType();
         for (int i = start; i < args.arguments.length; i++) {
-            emitPushArgument(args, i);
+            emitPushArgument(type.parameterType(i), args.arguments[i]);
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Wed Jul 05 22:05:22 2017 +0200
@@ -149,9 +149,9 @@
         static final int ARG_TYPE_LIMIT = ARG_TYPES.length;
         static final int TYPE_LIMIT = ALL_TYPES.length;
 
-        private final char btChar;
-        private final Class<?> btClass;
-        private final Wrapper btWrapper;
+        final char btChar;
+        final Class<?> btClass;
+        final Wrapper btWrapper;
 
         private BasicType(char btChar, Class<?> btClass, Wrapper wrapper) {
             this.btChar = btChar;
@@ -1366,10 +1366,11 @@
     }
 
     public static String basicTypeSignature(MethodType type) {
-        char[] sig = new char[type.parameterCount() + 2];
+        int params = type.parameterCount();
+        char[] sig = new char[params + 2];
         int sigp = 0;
-        for (Class<?> pt : type.parameterList()) {
-            sig[sigp++] = basicTypeChar(pt);
+        while (sigp < params) {
+            sig[sigp] = basicTypeChar(type.parameterType(sigp++));
         }
         sig[sigp++] = '_';
         sig[sigp++] = basicTypeChar(type.returnType());
@@ -1407,7 +1408,7 @@
 
     static final class Name {
         final BasicType type;
-        private short index;
+        @Stable short index;
         final NamedFunction function;
         final Object constraint;  // additional type information, if not null
         @Stable final Object[] arguments;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java	Wed Jul 05 22:05:22 2017 +0200
@@ -60,7 +60,7 @@
     }
 
     /** A description of a cached transform, possibly associated with the result of the transform.
-     *  The logical content is a sequence of byte values, starting with a Kind.ordinal value.
+     *  The logical content is a sequence of byte values, starting with a kind value.
      *  The sequence is unterminated, ending with an indefinite number of zero bytes.
      *  Sequences that are simple (short enough and with small enough values) pack into a 64-bit long.
      */
@@ -68,17 +68,22 @@
         final long packedBytes;
         final byte[] fullBytes;
 
-        private enum Kind {
-            NO_KIND,  // necessary because ordinal must be greater than zero
-            BIND_ARG, ADD_ARG, DUP_ARG,
-            SPREAD_ARGS,
-            FILTER_ARG, FILTER_RETURN, FILTER_RETURN_TO_ZERO,
-            COLLECT_ARGS, COLLECT_ARGS_TO_VOID, COLLECT_ARGS_TO_ARRAY,
-            FOLD_ARGS, FOLD_ARGS_TO_VOID,
-            PERMUTE_ARGS,
-            LOCAL_TYPES
-            //maybe add more for guard with test, catch exception, pointwise type conversions
-        }
+        // maybe add more for guard with test, catch exception, pointwise type conversions
+        private static final byte
+                BIND_ARG = 1,
+                ADD_ARG = 2,
+                DUP_ARG = 3,
+                SPREAD_ARGS = 4,
+                FILTER_ARG = 5,
+                FILTER_RETURN = 6,
+                FILTER_RETURN_TO_ZERO = 7,
+                COLLECT_ARGS = 8,
+                COLLECT_ARGS_TO_VOID = 9,
+                COLLECT_ARGS_TO_ARRAY = 10,
+                FOLD_ARGS = 11,
+                FOLD_ARGS_TO_VOID = 12,
+                PERMUTE_ARGS = 13,
+                LOCAL_TYPES = 14;
 
         private static final boolean STRESS_TEST = false; // turn on to disable most packing
         private static final int
@@ -131,20 +136,6 @@
             return bytes;
         }
 
-        private byte byteAt(int i) {
-            long pb = packedBytes;
-            if (pb == 0) {
-                if (i >= fullBytes.length)  return 0;
-                return fullBytes[i];
-            }
-            assert(fullBytes == null);
-            if (i > PACKED_BYTE_MAX_LENGTH)  return 0;
-            int pos = (i * PACKED_BYTE_SIZE);
-            return (byte)((pb >>> pos) & PACKED_BYTE_MASK);
-        }
-
-        Kind kind() { return Kind.values()[byteAt(0)]; }
-
         private Transform(long packedBytes, byte[] fullBytes, LambdaForm result) {
             super(result);
             this.packedBytes = packedBytes;
@@ -162,44 +153,39 @@
             assert((b & 0xFF) == b);  // incoming value must fit in *unsigned* byte
             return (byte)b;
         }
-        private static byte bval(Kind k) {
-            return bval(k.ordinal());
-        }
-        static Transform of(Kind k, int b1) {
+        static Transform of(byte k, int b1) {
             byte b0 = bval(k);
             if (inRange(b0 | b1))
                 return new Transform(packedBytes(b0, b1));
             else
                 return new Transform(fullBytes(b0, b1));
         }
-        static Transform of(Kind k, int b1, int b2) {
-            byte b0 = (byte) k.ordinal();
+        static Transform of(byte b0, int b1, int b2) {
             if (inRange(b0 | b1 | b2))
                 return new Transform(packedBytes(b0, b1, b2));
             else
                 return new Transform(fullBytes(b0, b1, b2));
         }
-        static Transform of(Kind k, int b1, int b2, int b3) {
-            byte b0 = (byte) k.ordinal();
+        static Transform of(byte b0, int b1, int b2, int b3) {
             if (inRange(b0 | b1 | b2 | b3))
                 return new Transform(packedBytes(b0, b1, b2, b3));
             else
                 return new Transform(fullBytes(b0, b1, b2, b3));
         }
         private static final byte[] NO_BYTES = {};
-        static Transform of(Kind k, int... b123) {
-            return ofBothArrays(k, b123, NO_BYTES);
+        static Transform of(byte kind, int... b123) {
+            return ofBothArrays(kind, b123, NO_BYTES);
         }
-        static Transform of(Kind k, int b1, byte[] b234) {
-            return ofBothArrays(k, new int[]{ b1 }, b234);
+        static Transform of(byte kind, int b1, byte[] b234) {
+            return ofBothArrays(kind, new int[]{ b1 }, b234);
         }
-        static Transform of(Kind k, int b1, int b2, byte[] b345) {
-            return ofBothArrays(k, new int[]{ b1, b2 }, b345);
+        static Transform of(byte kind, int b1, int b2, byte[] b345) {
+            return ofBothArrays(kind, new int[]{ b1, b2 }, b345);
         }
-        private static Transform ofBothArrays(Kind k, int[] b123, byte[] b456) {
+        private static Transform ofBothArrays(byte kind, int[] b123, byte[] b456) {
             byte[] fullBytes = new byte[1 + b123.length + b456.length];
             int i = 0;
-            fullBytes[i++] = bval(k);
+            fullBytes[i++] = bval(kind);
             for (int bv : b123) {
                 fullBytes[i++] = bval(bv);
             }
@@ -449,7 +435,7 @@
     // Each editing method can (potentially) cache the edited LF so that it can be reused later.
 
     LambdaForm bindArgumentForm(int pos) {
-        Transform key = Transform.of(Transform.Kind.BIND_ARG, pos);
+        Transform key = Transform.of(Transform.BIND_ARG, pos);
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.parameterConstraint(0) == newSpeciesData(lambdaForm.parameterType(pos)));
@@ -484,7 +470,7 @@
     }
 
     LambdaForm addArgumentForm(int pos, BasicType type) {
-        Transform key = Transform.of(Transform.Kind.ADD_ARG, pos, type.ordinal());
+        Transform key = Transform.of(Transform.ADD_ARG, pos, type.ordinal());
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.arity == lambdaForm.arity+1);
@@ -501,7 +487,7 @@
     }
 
     LambdaForm dupArgumentForm(int srcPos, int dstPos) {
-        Transform key = Transform.of(Transform.Kind.DUP_ARG, srcPos, dstPos);
+        Transform key = Transform.of(Transform.DUP_ARG, srcPos, dstPos);
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.arity == lambdaForm.arity-1);
@@ -530,7 +516,7 @@
                 elementTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
             }
         }
-        Transform key = Transform.of(Transform.Kind.SPREAD_ARGS, pos, elementTypeKey, arrayLength);
+        Transform key = Transform.of(Transform.SPREAD_ARGS, pos, elementTypeKey, arrayLength);
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.arity == lambdaForm.arity - arrayLength + 1);
@@ -569,9 +555,9 @@
             return filterArgumentForm(pos, basicType(collectorType.parameterType(0)));
         }
         byte[] newTypes = BasicType.basicTypesOrd(collectorType.parameterArray());
-        Transform.Kind kind = (dropResult
-                ? Transform.Kind.COLLECT_ARGS_TO_VOID
-                : Transform.Kind.COLLECT_ARGS);
+        byte kind = (dropResult
+                ? Transform.COLLECT_ARGS_TO_VOID
+                : Transform.COLLECT_ARGS);
         if (dropResult && collectorArity == 0)  pos = 1;  // pure side effect
         Transform key = Transform.of(kind, pos, collectorArity, newTypes);
         LambdaForm form = getInCache(key);
@@ -598,7 +584,7 @@
             argTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
         }
         assert(collectorType.parameterList().equals(Collections.nCopies(collectorArity, elementType)));
-        Transform.Kind kind = Transform.Kind.COLLECT_ARGS_TO_ARRAY;
+        byte kind = Transform.COLLECT_ARGS_TO_ARRAY;
         Transform key = Transform.of(kind, pos, collectorArity, argTypeKey);
         LambdaForm form = getInCache(key);
         if (form != null) {
@@ -634,7 +620,7 @@
     }
 
     LambdaForm filterArgumentForm(int pos, BasicType newType) {
-        Transform key = Transform.of(Transform.Kind.FILTER_ARG, pos, newType.ordinal());
+        Transform key = Transform.of(Transform.FILTER_ARG, pos, newType.ordinal());
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.arity == lambdaForm.arity);
@@ -710,7 +696,7 @@
     }
 
     LambdaForm filterReturnForm(BasicType newType, boolean constantZero) {
-        Transform.Kind kind = (constantZero ? Transform.Kind.FILTER_RETURN_TO_ZERO : Transform.Kind.FILTER_RETURN);
+        byte kind = (constantZero ? Transform.FILTER_RETURN_TO_ZERO : Transform.FILTER_RETURN);
         Transform key = Transform.of(kind, newType.ordinal());
         LambdaForm form = getInCache(key);
         if (form != null) {
@@ -762,11 +748,11 @@
 
     LambdaForm foldArgumentsForm(int foldPos, boolean dropResult, MethodType combinerType) {
         int combinerArity = combinerType.parameterCount();
-        Transform.Kind kind = (dropResult ? Transform.Kind.FOLD_ARGS_TO_VOID : Transform.Kind.FOLD_ARGS);
+        byte kind = (dropResult ? Transform.FOLD_ARGS_TO_VOID : Transform.FOLD_ARGS);
         Transform key = Transform.of(kind, foldPos, combinerArity);
         LambdaForm form = getInCache(key);
         if (form != null) {
-            assert(form.arity == lambdaForm.arity - (kind == Transform.Kind.FOLD_ARGS ? 1 : 0));
+            assert(form.arity == lambdaForm.arity - (kind == Transform.FOLD_ARGS ? 1 : 0));
             return form;
         }
         form = makeArgumentCombinationForm(foldPos, combinerType, true, dropResult);
@@ -786,7 +772,7 @@
         }
         assert(skip + reorder.length == lambdaForm.arity);
         if (nullPerm)  return lambdaForm;  // do not bother to cache
-        Transform key = Transform.of(Transform.Kind.PERMUTE_ARGS, reorder);
+        Transform key = Transform.of(Transform.PERMUTE_ARGS, reorder);
         LambdaForm form = getInCache(key);
         if (form != null) {
             assert(form.arity == skip+inTypes) : form;
@@ -855,7 +841,7 @@
         int[] desc = BasicType.basicTypeOrds(localTypes);
         desc = Arrays.copyOf(desc, desc.length + 1);
         desc[desc.length - 1] = pos;
-        Transform key = Transform.of(Transform.Kind.LOCAL_TYPES, desc);
+        Transform key = Transform.of(Transform.LOCAL_TYPES, desc);
         LambdaForm form = getInCache(key);
         if (form != null) {
             return form;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java	Wed Jul 05 22:05:22 2017 +0200
@@ -25,8 +25,6 @@
 
 package java.lang.invoke;
 
-import jdk.internal.misc.JavaLangInvokeAccess;
-import jdk.internal.misc.SharedSecrets;
 import sun.invoke.util.BytecodeDescriptor;
 import sun.invoke.util.VerifyAccess;
 
@@ -37,7 +35,6 @@
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Module;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
@@ -81,7 +78,7 @@
     private int      flags;       // modifier bits; see reflect.Modifier
     //@Injected JVM_Method* vmtarget;
     //@Injected int         vmindex;
-    private Object   resolution;  // if null, this guy is resolved
+    Object   resolution;  // if null, this guy is resolved
 
     /** Return the declaring class of this member.
      *  In the case of a bare name and type, the declaring class will be null.
@@ -829,7 +826,7 @@
         return resolution == null;
     }
 
-    private void initResolved(boolean isResolved) {
+    void initResolved(boolean isResolved) {
         assert(this.resolution == null);  // not initialized yet!
         if (!isResolved)
             this.resolution = this;
@@ -1002,7 +999,9 @@
                     Collections.addAll(result, buf0);
                 }
             }
-            result.addAll(Arrays.asList(buf).subList(0, bufCount));
+            for (int i = 0; i < bufCount; i++) {
+                result.add(buf[i]);
+            }
             // Signature matching is not the same as type matching, since
             // one signature might correspond to several types.
             // So if matchType is a Class or MethodType, refilter the results.
@@ -1150,27 +1149,4 @@
             return buf;
         }
     }
-
-    static {
-        // StackFrameInfo stores Member and this provides the shared secrets
-        // for stack walker to access MemberName information.
-        SharedSecrets.setJavaLangInvokeAccess(new JavaLangInvokeAccess() {
-            @Override
-            public Object newMemberName() {
-                return new MemberName();
-            }
-
-            @Override
-            public String getName(Object mname) {
-                MemberName memberName = (MemberName)mname;
-                return memberName.getName();
-            }
-
-            @Override
-            public boolean isNative(Object mname) {
-                MemberName memberName = (MemberName)mname;
-                return memberName.isNative();
-            }
-        });
-    }
 }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Jul 05 22:05:22 2017 +0200
@@ -25,6 +25,8 @@
 
 package java.lang.invoke;
 
+import jdk.internal.misc.JavaLangInvokeAccess;
+import jdk.internal.misc.SharedSecrets;
 import jdk.internal.org.objectweb.asm.AnnotationVisitor;
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
@@ -38,12 +40,11 @@
 import sun.invoke.util.Wrapper;
 
 import java.lang.reflect.Array;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.function.Function;
 import java.util.stream.Stream;
 
@@ -57,19 +58,6 @@
  * @author jrose
  */
 /*non-public*/ abstract class MethodHandleImpl {
-    // Do not adjust this except for special platforms:
-    private static final int MAX_ARITY;
-    static {
-        final Object[] values = { 255 };
-        AccessController.doPrivileged(new PrivilegedAction<>() {
-            @Override
-            public Void run() {
-                values[0] = Integer.getInteger(MethodHandleImpl.class.getName()+".MAX_ARITY", 255);
-                return null;
-            }
-        });
-        MAX_ARITY = (Integer) values[0];
-    }
 
     /// Factory methods to create method handles:
 
@@ -649,7 +637,7 @@
         MethodType srcType = targetType                 // (a..., [b...])=>r
                 .dropParameterTypes(collectArgPos, collectArgPos+collectValCount);
         if (!retainOriginalArgs) {                      // (a..., b...)=>r
-            srcType = srcType.insertParameterTypes(collectArgPos, collectorType.parameterList());
+            srcType = srcType.insertParameterTypes(collectArgPos, collectorType.parameterArray());
         }
         // in  arglist: [0: ...keep1 | cpos: collect...  | cpos+cacount: keep2... ]
         // out arglist: [0: ...keep1 | cpos: collectVal? | cpos+cvcount: keep2... ]
@@ -1094,7 +1082,7 @@
         int arity = type.parameterCount();
         if (arity > 1) {
             MethodHandle mh = throwException(type.dropParameterTypes(1, arity));
-            mh = MethodHandles.dropArguments(mh, 1, type.parameterList().subList(1, arity));
+            mh = MethodHandles.dropArguments(mh, 1, Arrays.copyOfRange(type.parameterArray(), 1, arity));
             return mh;
         }
         return makePairwiseConvert(NF_throwException.resolvedHandle(), type, false, true);
@@ -1710,6 +1698,39 @@
         } catch (ReflectiveOperationException ex) {
             throw newInternalError(ex);
         }
+
+        SharedSecrets.setJavaLangInvokeAccess(new JavaLangInvokeAccess() {
+            @Override
+            public Object newMemberName() {
+                return new MemberName();
+            }
+
+            @Override
+            public String getName(Object mname) {
+                MemberName memberName = (MemberName)mname;
+                return memberName.getName();
+            }
+
+            @Override
+            public boolean isNative(Object mname) {
+                MemberName memberName = (MemberName)mname;
+                return memberName.isNative();
+            }
+
+            @Override
+            public byte[] generateDMHClassBytes(String className,
+            MethodType[] methodTypes, int[] types) {
+                return GenerateJLIClassesHelper
+                        .generateDMHClassBytes(className, methodTypes, types);
+            }
+
+            @Override
+            public Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
+                    final String types) {
+                return GenerateJLIClassesHelper
+                        .generateConcreteBMHClassBytes(types);
+            }
+        });
     }
 
     /** Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore(). */
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java	Wed Jul 05 22:05:22 2017 +0200
@@ -53,6 +53,7 @@
     static final boolean PROFILE_GWT;
     static final int CUSTOMIZE_THRESHOLD;
     static final boolean VAR_HANDLE_GUARDS;
+    static final int MAX_ARITY;
 
     static {
         Properties props = GetPropertyAction.privilegedGetProperties();
@@ -79,6 +80,10 @@
         VAR_HANDLE_GUARDS = Boolean.parseBoolean(
                 props.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_GUARDS", "true"));
 
+        // Do not adjust this except for special platforms:
+        MAX_ARITY = Integer.parseInt(
+                props.getProperty("java.lang.invoke.MethodHandleImpl.MAX_ARITY", "255"));
+
         if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) {
             throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range");
         }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Wed Jul 05 22:05:22 2017 +0200
@@ -77,7 +77,7 @@
 
     private MethodHandles() { }  // do not instantiate
 
-    private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
+    static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
 
     // See IMPL_LOOKUP below.
 
@@ -3115,7 +3115,7 @@
         return dropArguments(zero(type.returnType()), 0, type.parameterList());
     }
 
-    private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.values().length];
+    private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.COUNT];
     private static MethodHandle makeIdentity(Class<?> ptype) {
         MethodType mtype = methodType(ptype, ptype);
         LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
@@ -3133,7 +3133,7 @@
         assert(btw == Wrapper.OBJECT);
         return makeZero(rtype);
     }
-    private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.values().length];
+    private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.COUNT];
     private static MethodHandle makeZero(Class<?> rtype) {
         MethodType mtype = methodType(rtype);
         LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));
@@ -3268,12 +3268,11 @@
      */
     public static
     MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
-        return dropArguments0(target, pos, copyTypes(valueTypes));
+        return dropArguments0(target, pos, copyTypes(valueTypes.toArray()));
     }
 
-    private static List<Class<?>> copyTypes(List<Class<?>> types) {
-        Object[] a = types.toArray();
-        return Arrays.asList(Arrays.copyOf(a, a.length, Class[].class));
+    private static List<Class<?>> copyTypes(Object[] array) {
+        return Arrays.asList(Arrays.copyOf(array, array.length, Class[].class));
     }
 
     private static
@@ -3352,13 +3351,13 @@
      */
     public static
     MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
-        return dropArguments(target, pos, Arrays.asList(valueTypes));
+        return dropArguments0(target, pos, copyTypes(valueTypes));
     }
 
     // private version which allows caller some freedom with error handling
     private static MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, List<Class<?>> newTypes, int pos,
                                       boolean nullOnFailure) {
-        newTypes = copyTypes(newTypes);
+        newTypes = copyTypes(newTypes.toArray());
         List<Class<?>> oldTypes = target.type().parameterList();
         int match = oldTypes.size();
         if (skip != 0) {
@@ -3900,10 +3899,14 @@
         int foldVals = rtype == void.class ? 0 : 1;
         int afterInsertPos = foldPos + foldVals;
         boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
-        if (ok && !(combinerType.parameterList()
-                    .equals(targetType.parameterList().subList(afterInsertPos,
-                                                               afterInsertPos + foldArgs))))
-            ok = false;
+        if (ok) {
+            for (int i = 0; i < foldArgs; i++) {
+                if (combinerType.parameterType(i) != targetType.parameterType(i + afterInsertPos)) {
+                    ok = false;
+                    break;
+                }
+            }
+        }
         if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(foldPos))
             ok = false;
         if (!ok)
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java	Wed Jul 05 22:05:22 2017 +0200
@@ -539,10 +539,10 @@
             return res;
         } else {
             // insert after (if need be), then before
-            if (pos < parameterList().size() - 1) {
-                res = res.insertParameterTypes(arrayLength, parameterList().subList(pos + 1, parameterList().size()));
+            if (pos < ptypes.length - 1) {
+                res = res.insertParameterTypes(arrayLength, Arrays.copyOfRange(ptypes, pos + 1, ptypes.length));
             }
-            return res.insertParameterTypes(0, parameterList().subList(0, pos));
+            return res.insertParameterTypes(0, Arrays.copyOf(ptypes, pos));
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Wed Jul 05 22:05:22 2017 +0200
@@ -281,12 +281,11 @@
                     if (c == TAG_CONST) {
                         Object cnst = constants[constC++];
                         el.add(new RecipeElement(cnst));
-                    }
-                    if (c == TAG_ARG) {
+                    } else if (c == TAG_ARG) {
                         el.add(new RecipeElement(argC++));
                     }
                 } else {
-                    // Not a special characters, this is a constant embedded into
+                    // Not a special character, this is a constant embedded into
                     // the recipe itself.
                     acc.append(c);
                 }
@@ -322,31 +321,31 @@
     private static final class RecipeElement {
         private final Object value;
         private final int argPos;
-        private final Tag tag;
+        private final char tag;
 
         public RecipeElement(Object cnst) {
             this.value = Objects.requireNonNull(cnst);
             this.argPos = -1;
-            this.tag = Tag.CONST;
+            this.tag = TAG_CONST;
         }
 
         public RecipeElement(int arg) {
             this.value = null;
             this.argPos = arg;
-            this.tag = Tag.ARG;
+            this.tag = TAG_ARG;
         }
 
         public Object getValue() {
-            assert (tag == Tag.CONST);
+            assert (tag == TAG_CONST);
             return value;
         }
 
         public int getArgPos() {
-            assert (tag == Tag.ARG);
+            assert (tag == TAG_ARG);
             return argPos;
         }
 
-        public Tag getTag() {
+        public char getTag() {
             return tag;
         }
 
@@ -357,22 +356,18 @@
 
             RecipeElement that = (RecipeElement) o;
 
-            if (tag != that.tag) return false;
-            if (tag == Tag.CONST && (!value.equals(that.value))) return false;
-            if (tag == Tag.ARG && (argPos != that.argPos)) return false;
+            if (this.tag != that.tag) return false;
+            if (this.tag == TAG_CONST && (!value.equals(that.value))) return false;
+            if (this.tag == TAG_ARG && (argPos != that.argPos)) return false;
             return true;
         }
 
         @Override
         public int hashCode() {
-            return tag.hashCode();
+            return (int)tag;
         }
     }
 
-    private enum Tag {
-        CONST, ARG
-    }
-
     /**
      * Facilitates the creation of optimized String concatenation methods, that
      * can be used to efficiently concatenate a known number of arguments of
@@ -649,19 +644,20 @@
      * @return argument types the strategy is going to use
      */
     private static MethodType adaptType(MethodType args) {
-        Class<?>[] ptypes = args.parameterArray();
-        boolean changed = false;
-        for (int i = 0; i < ptypes.length; i++) {
-            Class<?> ptype = ptypes[i];
+        Class<?>[] ptypes = null;
+        for (int i = 0; i < args.parameterCount(); i++) {
+            Class<?> ptype = args.parameterType(i);
             if (!ptype.isPrimitive() &&
                     ptype != String.class &&
                     ptype != Object.class) { // truncate to Object
+                if (ptypes == null) {
+                    ptypes = args.parameterArray();
+                }
                 ptypes[i] = Object.class;
-                changed = true;
             }
             // else other primitives or String or Object (unchanged)
         }
-        return changed
+        return (ptypes != null)
                 ? MethodType.methodType(args.returnType(), ptypes)
                 : args;
     }
@@ -881,11 +877,10 @@
                 int off = 0;
                 for (RecipeElement el : recipe.getElements()) {
                     switch (el.getTag()) {
-                        case CONST: {
+                        case TAG_CONST:
                             // Guaranteed non-null, no null check required.
                             break;
-                        }
-                        case ARG: {
+                        case TAG_ARG:
                             // Null-checks are needed only for String arguments, and when a previous stage
                             // did not do implicit null-checks. If a String is null, we eagerly replace it
                             // with "null" constant. Note, we omit Objects here, because we don't call
@@ -902,7 +897,6 @@
                             }
                             off += getParameterSize(cl);
                             break;
-                        }
                         default:
                             throw new StringConcatException("Unhandled tag: " + el.getTag());
                     }
@@ -926,12 +920,11 @@
 
                 for (RecipeElement el : recipe.getElements()) {
                     switch (el.getTag()) {
-                        case CONST: {
+                        case TAG_CONST:
                             Object cnst = el.getValue();
                             len += cnst.toString().length();
                             break;
-                        }
-                        case ARG: {
+                        case TAG_ARG:
                             /*
                                 If an argument is String, then we can call .length() on it. Sized/Exact modes have
                                 converted arguments for us. If an argument is primitive, we can provide a guess
@@ -953,7 +946,6 @@
                             }
                             off += getParameterSize(cl);
                             break;
-                        }
                         default:
                             throw new StringConcatException("Unhandled tag: " + el.getTag());
                     }
@@ -988,22 +980,21 @@
                 for (RecipeElement el : recipe.getElements()) {
                     String desc;
                     switch (el.getTag()) {
-                        case CONST: {
+                        case TAG_CONST:
                             Object cnst = el.getValue();
                             mv.visitLdcInsn(cnst);
                             desc = getSBAppendDesc(cnst.getClass());
                             break;
-                        }
-                        case ARG: {
+                        case TAG_ARG:
                             Class<?> cl = arr[el.getArgPos()];
                             mv.visitVarInsn(getLoadOpcode(cl), off);
                             off += getParameterSize(cl);
                             desc = getSBAppendDesc(cl);
                             break;
-                        }
                         default:
                             throw new StringConcatException("Unhandled tag: " + el.getTag());
                     }
+
                     mv.visitMethodInsn(
                             INVOKEVIRTUAL,
                             "java/lang/StringBuilder",
@@ -1271,7 +1262,6 @@
                 }
             }
 
-            List<Class<?>> ptypesList = Arrays.asList(ptypes);
             MethodHandle[] lengthers = new MethodHandle[pc];
 
             // Figure out lengths: constants' lengths can be deduced on the spot.
@@ -1280,14 +1270,13 @@
             int initial = 0;
             for (RecipeElement el : recipe.getElements()) {
                 switch (el.getTag()) {
-                    case CONST: {
+                    case TAG_CONST:
                         Object cnst = el.getValue();
                         initial += cnst.toString().length();
                         break;
-                    }
-                    case ARG: {
+                    case TAG_ARG:
                         final int i = el.getArgPos();
-                        Class<?> type = ptypesList.get(i);
+                        Class<?> type = ptypes[i];
                         if (type.isPrimitive()) {
                             MethodHandle est = MethodHandles.constant(int.class, estimateSize(type));
                             est = MethodHandles.dropArguments(est, 0, type);
@@ -1296,14 +1285,13 @@
                             lengthers[i] = STRING_LENGTH;
                         }
                         break;
-                    }
                     default:
                         throw new StringConcatException("Unhandled tag: " + el.getTag());
                 }
             }
 
             // Create (StringBuilder, <args>) shape for appending:
-            MethodHandle builder = MethodHandles.dropArguments(MethodHandles.identity(StringBuilder.class), 1, ptypesList);
+            MethodHandle builder = MethodHandles.dropArguments(MethodHandles.identity(StringBuilder.class), 1, ptypes);
 
             // Compose append calls. This is done in reverse because the application order is
             // reverse as well.
@@ -1312,23 +1300,21 @@
                 RecipeElement el = elements.get(i);
                 MethodHandle appender;
                 switch (el.getTag()) {
-                    case CONST: {
+                    case TAG_CONST:
                         Object constant = el.getValue();
                         MethodHandle mh = appender(adaptToStringBuilder(constant.getClass()));
                         appender = MethodHandles.insertArguments(mh, 1, constant);
                         break;
-                    }
-                    case ARG: {
+                    case TAG_ARG:
                         int ac = el.getArgPos();
-                        appender = appender(ptypesList.get(ac));
+                        appender = appender(ptypes[ac]);
 
                         // Insert dummy arguments to match the prefix in the signature.
                         // The actual appender argument will be the ac-ith argument.
                         if (ac != 0) {
-                            appender = MethodHandles.dropArguments(appender, 1, ptypesList.subList(0, ac));
+                            appender = MethodHandles.dropArguments(appender, 1, Arrays.copyOf(ptypes, ac));
                         }
                         break;
-                    }
                     default:
                         throw new StringConcatException("Unhandled tag: " + el.getTag());
                 }
@@ -1500,7 +1486,6 @@
                     ptypes[i] = filter.type().returnType();
                 }
             }
-            List<Class<?>> ptypesList = Arrays.asList(ptypes);
 
             // Start building the combinator tree. The tree "starts" with (<parameters>)String, and "finishes"
             // with the (int, byte[], byte)String in String helper. The combinators are assembled bottom-up,
@@ -1522,16 +1507,14 @@
             for (RecipeElement el : recipe.getElements()) {
                 MethodHandle prepender;
                 switch (el.getTag()) {
-                    case CONST: {
+                    case TAG_CONST:
                         Object cnst = el.getValue();
                         prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst);
                         break;
-                    }
-                    case ARG: {
+                    case TAG_ARG:
                         int pos = el.getArgPos();
-                        prepender = selectArgument(prepender(ptypesList.get(pos)), 3, ptypesList, pos);
+                        prepender = selectArgument(prepender(ptypes[pos]), 3, ptypes, pos);
                         break;
-                    }
                     default:
                         throw new StringConcatException("Unhandled tag: " + el.getTag());
                 }
@@ -1554,7 +1537,7 @@
             }
 
             // Fold in byte[] instantiation at argument 0.
-            MethodHandle combiner = MethodHandles.dropArguments(NEW_ARRAY, 2, ptypesList);
+            MethodHandle combiner = MethodHandles.dropArguments(NEW_ARRAY, 2, ptypes);
             mh = MethodHandles.foldArguments(mh, combiner);
 
             // Start combining length and coder mixers.
@@ -1574,22 +1557,21 @@
             int initialLen = 0;    // initial length, in characters
             for (RecipeElement el : recipe.getElements()) {
                 switch (el.getTag()) {
-                    case CONST: {
+                    case TAG_CONST:
                         Object constant = el.getValue();
                         String s = constant.toString();
                         initialCoder = (byte) coderMixer(String.class).invoke(initialCoder, s);
                         initialLen += s.length();
                         break;
-                    }
-                    case ARG: {
+                    case TAG_ARG:
                         int ac = el.getArgPos();
 
-                        Class<?> argClass = ptypesList.get(ac);
-                        MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypesList, ac);
+                        Class<?> argClass = ptypes[ac];
+                        MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypes, ac);
                         lm = MethodHandles.dropArguments(lm, 0, byte.class); // (*)
                         lm = MethodHandles.dropArguments(lm, 2, byte.class);
 
-                        MethodHandle cm = selectArgument(coderMixer(argClass),  1, ptypesList, ac);
+                        MethodHandle cm = selectArgument(coderMixer(argClass),  1, ptypes, ac);
                         cm = MethodHandles.dropArguments(cm, 0, int.class);  // (**)
 
                         // Read this bottom up:
@@ -1607,7 +1589,6 @@
 
                         // 1. The mh shape here is ("old-index", "old-coder", <args>)
                         break;
-                    }
                     default:
                         throw new StringConcatException("Unhandled tag: " + el.getTag());
                 }
@@ -1636,14 +1617,14 @@
         }
 
         // Adapts: (...prefix..., parameter[pos])R -> (...prefix..., ...parameters...)R
-        private static MethodHandle selectArgument(MethodHandle mh, int prefix, List<Class<?>> ptypes, int pos) {
+        private static MethodHandle selectArgument(MethodHandle mh, int prefix, Class<?>[] ptypes, int pos) {
             if (pos == 0) {
-                return MethodHandles.dropArguments(mh, prefix + 1, ptypes.subList(1, ptypes.size()));
-            } else if (pos == ptypes.size() - 1) {
-                return MethodHandles.dropArguments(mh, prefix, ptypes.subList(0, ptypes.size() - 1));
+                return MethodHandles.dropArguments(mh, prefix + 1, Arrays.copyOfRange(ptypes, 1, ptypes.length));
+            } else if (pos == ptypes.length - 1) {
+                return MethodHandles.dropArguments(mh, prefix, Arrays.copyOf(ptypes, ptypes.length - 1));
             } else { // 0 < pos < ptypes.size() - 1
-                MethodHandle t = MethodHandles.dropArguments(mh, prefix, ptypes.subList(0, pos));
-                return MethodHandles.dropArguments(t, prefix + 1 + pos, ptypes.subList(pos + 1, ptypes.size()));
+                MethodHandle t = MethodHandles.dropArguments(mh, prefix, Arrays.copyOf(ptypes, pos));
+                return MethodHandles.dropArguments(t, prefix + 1 + pos, Arrays.copyOfRange(ptypes, pos + 1, ptypes.length));
             }
         }
 
@@ -1702,8 +1683,8 @@
         private static final ConcurrentMap<Class<?>, MethodHandle> PREPENDERS;
         private static final ConcurrentMap<Class<?>, MethodHandle> LENGTH_MIXERS;
         private static final ConcurrentMap<Class<?>, MethodHandle> CODER_MIXERS;
-        private static final Class<?> STRING_HELPER;
         private static final byte INITIAL_CODER;
+        static final Class<?> STRING_HELPER;
 
         static {
             try {
@@ -1805,7 +1786,7 @@
 
     /* ------------------------------- Common utilities ------------------------------------ */
 
-    private static MethodHandle lookupStatic(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
+    static MethodHandle lookupStatic(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
         try {
             return lookup.findStatic(refc, name, MethodType.methodType(rtype, ptypes));
         } catch (NoSuchMethodException | IllegalAccessException e) {
@@ -1813,7 +1794,7 @@
         }
     }
 
-    private static MethodHandle lookupVirtual(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
+    static MethodHandle lookupVirtual(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
         try {
             return lookup.findVirtual(refc, name, MethodType.methodType(rtype, ptypes));
         } catch (NoSuchMethodException | IllegalAccessException e) {
@@ -1821,7 +1802,7 @@
         }
     }
 
-    private static MethodHandle lookupConstructor(Lookup lookup, Class<?> refc, Class<?> ptypes) {
+    static MethodHandle lookupConstructor(Lookup lookup, Class<?> refc, Class<?> ptypes) {
         try {
             return lookup.findConstructor(refc, MethodType.methodType(void.class, ptypes));
         } catch (NoSuchMethodException | IllegalAccessException e) {
@@ -1829,7 +1810,7 @@
         }
     }
 
-    private static int estimateSize(Class<?> cl) {
+    static int estimateSize(Class<?> cl) {
         if (cl == Integer.TYPE) {
             return 11; // "-2147483648"
         } else if (cl == Boolean.TYPE) {
@@ -1851,7 +1832,7 @@
         }
     }
 
-    private static Class<?> adaptToStringBuilder(Class<?> c) {
+    static Class<?> adaptToStringBuilder(Class<?> c) {
         if (c.isPrimitive()) {
             if (c == Byte.TYPE || c == Short.TYPE) {
                 return int.class;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java	Wed Jul 05 22:05:22 2017 +0200
@@ -38,7 +38,7 @@
         super(Opcodes.ASM5, mv);
     }
 
-    private static final int NUM_WRAPPERS = Wrapper.values().length;
+    private static final int NUM_WRAPPERS = Wrapper.COUNT;
 
     private static final String NAME_OBJECT = "java/lang/Object";
     private static final String WRAPPER_PREFIX = "Ljava/lang/";
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java	Wed Jul 05 22:05:22 2017 +0200
@@ -31,7 +31,6 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -54,7 +53,8 @@
         List<Class<?>> l = new ArrayList<>();
         if (receiver != null)
             l.add(receiver);
-        l.addAll(Arrays.asList(intermediate));
+        for (Class<?> c : intermediate)
+            l.add(c);
 
         // (Receiver, <Intermediates>)Value
         methodType_table[VarHandle.AccessType.GET.ordinal()] =
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Wed Jul 05 22:05:22 2017 +0200
@@ -1057,57 +1057,11 @@
     Object addAndGet(Object... args);
 
     enum AccessType {
-        GET(Object.class) {
-            @Override
-            MethodType accessModeType(Class<?> receiver, Class<?> value,
-                                      Class<?>... intermediate) {
-                Class<?>[] ps =  allocateParameters(0, receiver, intermediate);
-                fillParameters(ps, receiver, intermediate);
-                return MethodType.methodType(value, ps);
-            }
-        },
-        SET(void.class) {
-            @Override
-            MethodType accessModeType(Class<?> receiver, Class<?> value,
-                                      Class<?>... intermediate) {
-                Class<?>[] ps =  allocateParameters(1, receiver, intermediate);
-                int i = fillParameters(ps, receiver, intermediate);
-                ps[i] = value;
-                return MethodType.methodType(void.class, ps);
-            }
-        },
-        COMPARE_AND_SWAP(boolean.class) {
-            @Override
-            MethodType accessModeType(Class<?> receiver, Class<?> value,
-                                      Class<?>... intermediate) {
-                Class<?>[] ps =  allocateParameters(2, receiver, intermediate);
-                int i = fillParameters(ps, receiver, intermediate);
-                ps[i++] = value;
-                ps[i] = value;
-                return MethodType.methodType(boolean.class, ps);
-            }
-        },
-        COMPARE_AND_EXCHANGE(Object.class) {
-            @Override
-            MethodType accessModeType(Class<?> receiver, Class<?> value,
-                                      Class<?>... intermediate) {
-                Class<?>[] ps =  allocateParameters(2, receiver, intermediate);
-                int i = fillParameters(ps, receiver, intermediate);
-                ps[i++] = value;
-                ps[i] = value;
-                return MethodType.methodType(value, ps);
-            }
-        },
-        GET_AND_UPDATE(Object.class) {
-            @Override
-            MethodType accessModeType(Class<?> receiver, Class<?> value,
-                                      Class<?>... intermediate) {
-                Class<?>[] ps =  allocateParameters(1, receiver, intermediate);
-                int i = fillParameters(ps, receiver, intermediate);
-                ps[i] = value;
-                return MethodType.methodType(value, ps);
-            }
-        };
+        GET(Object.class),
+        SET(void.class),
+        COMPARE_AND_SWAP(boolean.class),
+        COMPARE_AND_EXCHANGE(Object.class),
+        GET_AND_UPDATE(Object.class);
 
         final Class<?> returnType;
         final boolean isMonomorphicInReturnType;
@@ -1117,8 +1071,41 @@
             isMonomorphicInReturnType = returnType != Object.class;
         }
 
-        abstract MethodType accessModeType(Class<?> receiver, Class<?> value,
-                                           Class<?>... intermediate);
+        MethodType accessModeType(Class<?> receiver, Class<?> value,
+                                  Class<?>... intermediate) {
+            Class<?>[] ps;
+            int i;
+            switch (this) {
+                case GET:
+                    ps = allocateParameters(0, receiver, intermediate);
+                    fillParameters(ps, receiver, intermediate);
+                    return MethodType.methodType(value, ps);
+                case SET:
+                    ps = allocateParameters(1, receiver, intermediate);
+                    i = fillParameters(ps, receiver, intermediate);
+                    ps[i] = value;
+                    return MethodType.methodType(void.class, ps);
+                case COMPARE_AND_SWAP:
+                    ps = allocateParameters(2, receiver, intermediate);
+                    i = fillParameters(ps, receiver, intermediate);
+                    ps[i++] = value;
+                    ps[i] = value;
+                    return MethodType.methodType(boolean.class, ps);
+                case COMPARE_AND_EXCHANGE:
+                    ps = allocateParameters(2, receiver, intermediate);
+                    i = fillParameters(ps, receiver, intermediate);
+                    ps[i++] = value;
+                    ps[i] = value;
+                    return MethodType.methodType(value, ps);
+                case GET_AND_UPDATE:
+                    ps = allocateParameters(1, receiver, intermediate);
+                    i = fillParameters(ps, receiver, intermediate);
+                    ps[i] = value;
+                    return MethodType.methodType(value, ps);
+                default:
+                    throw new InternalError("Unknown AccessType");
+            }
+        }
 
         private static Class<?>[] allocateParameters(int values,
                                                      Class<?> receiver, Class<?>... intermediate) {
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReference.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleReference.java	Wed Jul 05 22:05:22 2017 +0200
@@ -169,7 +169,7 @@
 
 
     /**
-     * Returns {@code true} if this module has been patched via -Xpatch.
+     * Returns {@code true} if this module has been patched via --patch-module.
      */
     boolean isPatched() {
         return patched;
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReferences.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleReferences.java	Wed Jul 05 22:05:22 2017 +0200
@@ -68,7 +68,7 @@
 
     /**
      * Creates a ModuleReference to a module or to patched module when
-     * creating modules for the boot Layer and -Xpatch is specified.
+     * creating modules for the boot Layer and --patch-module is specified.
      */
     private static ModuleReference newModule(ModuleDescriptor md,
                                              URI uri,
--- a/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java	Wed Jul 05 22:05:22 2017 +0200
@@ -178,7 +178,7 @@
         ModuleReference mref =
             new ModuleReference(md, uri, readerSupplier, hash);
 
-        // may need a reference to a patched module if -Xpatch specified
+        // may need a reference to a patched module if --patch-module specified
         mref = ModulePatcher.interposeIfNeeded(mref);
 
         return mref;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java	Wed Jul 05 22:05:22 2017 +0200
@@ -147,11 +147,7 @@
      * @return the previous value
      */
     public final boolean getAndSet(boolean newValue) {
-        boolean prev;
-        do {
-            prev = get();
-        } while (!compareAndSet(prev, newValue));
-        return prev;
+        return (int)VALUE.getAndSet(this, (newValue ? 1 : 0)) != 0;
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java	Wed Jul 05 22:05:22 2017 +0200
@@ -263,6 +263,47 @@
      * is theoretically possible, so we additionally add a
      * storeStoreFence after lock acquisition CAS.
      *
+     * ----------------------------------------------------------------
+     * Here's an informal proof that plain reads by _successful_
+     * readers see plain writes from preceding but not following
+     * writers (following Boehm and the C++ standard [atomics.fences]):
+     *
+     * Because of the total synchronization order of accesses to
+     * volatile long state containing the sequence number, writers and
+     * _successful_ readers can be globally sequenced.
+     *
+     * int x, y;
+     *
+     * Writer 1:
+     * inc sequence (odd - "locked")
+     * storeStoreFence();
+     * x = 1; y = 2;
+     * inc sequence (even - "unlocked")
+     *
+     * Successful Reader:
+     * read sequence (even)
+     * // must see writes from Writer 1 but not Writer 2
+     * r1 = x; r2 = y;
+     * acquireFence();
+     * read sequence (even - validated unchanged)
+     * // use r1 and r2
+     *
+     * Writer 2:
+     * inc sequence (odd - "locked")
+     * storeStoreFence();
+     * x = 3; y = 4;
+     * inc sequence (even - "unlocked")
+     *
+     * Visibility of writer 1's stores is normal - reader's initial
+     * read of state synchronizes with writer 1's final write to state.
+     * Lack of visibility of writer 2's plain writes is less obvious.
+     * If reader's read of x or y saw writer 2's write, then (assuming
+     * semantics of C++ fences) the storeStoreFence would "synchronize"
+     * with reader's acquireFence and reader's validation read must see
+     * writer 2's initial write to state and so validation must fail.
+     * But making this "proof" formal and rigorous is an open problem!
+     * ----------------------------------------------------------------
+     *
      * The memory layout keeps lock state and queue pointers together
      * (normally on the same cache line). This usually works well for
      * read-mostly loads. In most other cases, the natural tendency of
@@ -276,14 +317,14 @@
     /** Number of processors, for spin control */
     private static final int NCPU = Runtime.getRuntime().availableProcessors();
 
-    /** Maximum number of retries before enqueuing on acquisition */
-    private static final int SPINS = (NCPU > 1) ? 1 << 6 : 0;
+    /** Maximum number of retries before enqueuing on acquisition; at least 1 */
+    private static final int SPINS = (NCPU > 1) ? 1 << 6 : 1;
 
-    /** Maximum number of retries before blocking at head on acquisition */
-    private static final int HEAD_SPINS = (NCPU > 1) ? 1 << 10 : 0;
+    /** Maximum number of tries before blocking at head on acquisition */
+    private static final int HEAD_SPINS = (NCPU > 1) ? 1 << 10 : 1;
 
     /** Maximum number of retries before re-blocking */
-    private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 16 : 0;
+    private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 16 : 1;
 
     /** The period for yielding when waiting for overflow spinlock */
     private static final int OVERFLOW_YIELD_RATE = 7; // must be power 2 - 1
@@ -1228,6 +1269,11 @@
                         WCOWAIT.compareAndSet(h, c, c.cowait) &&
                         (w = c.thread) != null) // help release
                         LockSupport.unpark(w);
+                    if (Thread.interrupted()) {
+                        if (interruptible)
+                            return cancelWaiter(node, p, true);
+                        wasInterrupted = true;
+                    }
                     if (h == (pp = p.prev) || h == p || pp == null) {
                         long m, s, ns;
                         do {
@@ -1264,11 +1310,6 @@
                                 LockSupport.parkNanos(this, time);
                         }
                         node.thread = null;
-                        if (Thread.interrupted()) {
-                            if (interruptible)
-                                return cancelWaiter(node, p, true);
-                            wasInterrupted = true;
-                        }
                     }
                 }
             }
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java	Wed Jul 05 22:05:22 2017 +0200
@@ -25,19 +25,42 @@
 
 package jdk.internal.misc;
 
+import java.lang.invoke.MethodType;
+import java.util.Map;
+
 public interface JavaLangInvokeAccess {
     /**
-     * Create a new MemberName instance
+     * Create a new MemberName instance. Used by {@see StackFrameInfo}.
      */
     Object newMemberName();
 
     /**
-     * Returns the name for the given MemberName
+     * Returns the name for the given MemberName. Used by {@see StackFrameInfo}.
      */
     String getName(Object mname);
 
     /**
-     * Returns {@code true} if the given MemberName is a native method
+     * Returns {@code true} if the given MemberName is a native method. Used by
+     * {@see StackFrameInfo}.
      */
     boolean isNative(Object mname);
+
+    /**
+     * Returns a {@code byte[]} containing the bytecode for a class implementing
+     * DirectMethodHandle of each pairwise combination of {@code MethodType} and
+     * an {@code int} representing method type.  Used by
+     * GenerateJLIClassesPlugin to generate such a class during the jlink phase.
+     */
+    byte[] generateDMHClassBytes(String className, MethodType[] methodTypes,
+            int[] types);
+
+    /**
+     * Returns a {@code byte[]} containing the bytecode for a BoundMethodHandle
+     * species class implementing the signature defined by {@code types}. Used
+     * by GenerateBMHClassesPlugin to enable generation of such classes during
+     * the jlink phase. Should do some added validation since this string may be
+     * user provided.
+     */
+    Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
+            final String types);
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java	Wed Jul 05 22:05:22 2017 +0200
@@ -95,7 +95,7 @@
     public static JavaLangInvokeAccess getJavaLangInvokeAccess() {
         if (javaLangInvokeAccess == null) {
             try {
-                Class<?> c = Class.forName("java.lang.invoke.MemberName");
+                Class<?> c = Class.forName("java.lang.invoke.MethodHandleImpl");
                 unsafe.ensureClassInitialized(c);
             } catch (ClassNotFoundException e) {};
         }
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Wed Jul 05 22:05:22 2017 +0200
@@ -56,8 +56,8 @@
  * The {@link #boot() boot} method is called early in the startup to initialize
  * the module system. In summary, the boot method creates a Configuration by
  * resolving a set of module names specified via the launcher (or equivalent)
- * -m and -addmods options. The modules are located on a module path that is
- * constructed from the upgrade module path, system modules, and application
+ * -m and --add-modules options. The modules are located on a module path that
+ * is constructed from the upgrade module path, system modules, and application
  * module path. The Configuration is instantiated as the boot Layer with each
  * module in the the configuration defined to one of the built-in class loaders.
  */
@@ -127,16 +127,16 @@
 
         long t2 = System.nanoTime();
 
-        // -upgrademodulepath option specified to launcher
+        // --upgrade-module-path option specified to launcher
         ModuleFinder upgradeModulePath
-            = createModulePathFinder("jdk.upgrade.module.path");
+            = createModulePathFinder("jdk.module.upgrade.path");
         if (upgradeModulePath != null)
             systemModules = ModuleFinder.compose(upgradeModulePath, systemModules);
 
-        // -modulepath option specified to the launcher
+        // --module-path option specified to the launcher
         ModuleFinder appModulePath = createModulePathFinder("jdk.module.path");
 
-        // The module finder: [-upgrademodulepath] system [-modulepath]
+        // The module finder: [--upgrade-module-path] system [--module-path]
         ModuleFinder finder = systemModules;
         if (appModulePath != null)
             finder = ModuleFinder.compose(finder, appModulePath);
@@ -149,11 +149,11 @@
         if (mainModule != null)
             roots.add(mainModule);
 
-        // additional module(s) specified by -addmods
+        // additional module(s) specified by --add-modules
         boolean addAllDefaultModules = false;
         boolean addAllSystemModules = false;
         boolean addAllApplicationModules = false;
-        String propValue = System.getProperty("jdk.launcher.addmods");
+        String propValue = getAndRemoveProperty("jdk.module.addmods");
         if (propValue != null) {
             for (String mod: propValue.split(",")) {
                 switch (mod) {
@@ -172,8 +172,8 @@
             }
         }
 
-        // -limitmods
-        propValue = System.getProperty("jdk.launcher.limitmods");
+        // --limit-modules
+        propValue = getAndRemoveProperty("jdk.module.limitmods");
         if (propValue != null) {
             Set<String> mods = new HashSet<>();
             for (String mod: propValue.split(",")) {
@@ -216,7 +216,7 @@
             }
         }
 
-        // If `-addmods ALL-SYSTEM` is specified then all observable system
+        // If `--add-modules ALL-SYSTEM` is specified then all observable system
         // modules will be resolved.
         if (addAllSystemModules) {
             ModuleFinder f = finder;  // observable modules
@@ -228,9 +228,9 @@
                 .forEach(mn -> roots.add(mn));
         }
 
-        // If `-addmods ALL-MODULE-PATH` is specified then all observable
+        // If `--add-modules ALL-MODULE-PATH` is specified then all observable
         // modules on the application module path will be resolved.
-        if  (appModulePath != null && addAllApplicationModules) {
+        if (appModulePath != null && addAllApplicationModules) {
             ModuleFinder f = finder;  // observable modules
             appModulePath.findAll()
                 .stream()
@@ -250,7 +250,7 @@
         if (baseUri.getScheme().equals("jrt")   // toLowerCase not needed here
                 && (upgradeModulePath == null)
                 && (appModulePath == null)
-                && (System.getProperty("jdk.launcher.patch.0") == null)) {
+                && (!ModulePatcher.isBootLayerPatched())) {
             needPostResolutionChecks = false;
         }
 
@@ -317,7 +317,7 @@
         PerfCounters.loadModulesTime.addElapsedTimeFrom(t5);
 
 
-        // -XaddReads and -XaddExports
+        // --add-reads and --add-exports
         addExtraReads(bootLayer);
         addExtraExports(bootLayer);
 
@@ -394,13 +394,13 @@
 
 
     /**
-     * Process the -XaddReads options to add any additional read edges that
+     * Process the --add-reads options to add any additional read edges that
      * are specified on the command-line.
      */
     private static void addExtraReads(Layer bootLayer) {
 
         // decode the command line options
-        Map<String, Set<String>> map = decode("jdk.launcher.addreads.");
+        Map<String, Set<String>> map = decode("jdk.module.addreads.");
 
         for (Map.Entry<String, Set<String>> e : map.entrySet()) {
 
@@ -431,13 +431,13 @@
 
 
     /**
-     * Process the -XaddExports options to add any additional read edges that
+     * Process the --add-exports options to add any additional read edges that
      * are specified on the command-line.
      */
     private static void addExtraExports(Layer bootLayer) {
 
         // decode the command line options
-        Map<String, Set<String>> map = decode("jdk.launcher.addexports.");
+        Map<String, Set<String>> map = decode("jdk.module.addexports.");
 
         for (Map.Entry<String, Set<String>> e : map.entrySet()) {
 
@@ -483,13 +483,14 @@
 
 
     /**
-     * Decodes the values of -XaddReads or -XaddExports options
+     * Decodes the values of --add-reads or --add-exports options
      *
      * The format of the options is: $KEY=$MODULE(,$MODULE)*
      */
     private static Map<String, Set<String>> decode(String prefix) {
         int index = 0;
-        String value = System.getProperty(prefix + index);
+        // the system property is removed after decoding
+        String value = getAndRemoveProperty(prefix + index);
         if (value == null)
             return Collections.emptyMap();
 
@@ -522,12 +523,18 @@
             }
 
             index++;
-            value = System.getProperty(prefix + index);
+            value = getAndRemoveProperty(prefix + index);
         }
 
         return map;
     }
 
+    /**
+     * Gets and remove the named system property
+     */
+    private static String getAndRemoveProperty(String key) {
+        return (String)System.getProperties().remove(key);
+    }
 
     /**
      * Throws a RuntimeException with the given message
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java	Wed Jul 05 22:05:22 2017 +0200
@@ -58,7 +58,7 @@
 
 
 /**
- * Provides support for patching modules in the boot layer with -Xpatch.
+ * Provides support for patching modules in the boot layer with --patch-module.
  */
 
 public final class ModulePatcher {
@@ -66,28 +66,27 @@
     private static final JavaLangModuleAccess JLMA
         = SharedSecrets.getJavaLangModuleAccess();
 
-    // the prefix of the system properties that encode the value of -Xpatch
-    private static final String PATCH_PROPERTY_PREFIX = "jdk.launcher.patch.";
+    // the prefix of the system properties that encode the value of --patch-module
+    private static final String PATCH_PROPERTY_PREFIX = "jdk.module.patch.";
 
     // module name -> sequence of patches (directories or JAR files)
     private static final Map<String, List<Path>> PATCH_MAP = decodeProperties();
 
     private ModulePatcher() { }
 
-
     /**
-     * Decodes the values of -Xpatch options, returning a Map of module name to
-     * list of file paths.
+     * Decodes the values of --patch-module options, returning a Map of module
+     * name to list of file paths.
      *
      * @throws IllegalArgumentException if the the module name is missing or
-     *         -Xpatch is used more than once to patch the same module
+     *         --patch-module is used more than once to patch the same module
      */
     private static Map<String, List<Path>> decodeProperties() {
 
         int index = 0;
-        String value = System.getProperty(PATCH_PROPERTY_PREFIX + index);
+        String value = getAndRemoveProperty(PATCH_PROPERTY_PREFIX + index);
         if (value == null)
-            return Collections.emptyMap();  // -Xpatch not specified
+            return Collections.emptyMap();  // --patch-module not specified
 
         Map<String, List<Path>> map = new HashMap<>();
         while (value != null) {
@@ -115,7 +114,7 @@
             }
 
             index++;
-            value = System.getProperty(PATCH_PROPERTY_PREFIX + index);
+            value = getAndRemoveProperty(PATCH_PROPERTY_PREFIX + index);
         }
 
         return map;
@@ -123,6 +122,14 @@
 
 
     /**
+     * Returns {@code true} is --patch-module is specified to patch modules
+     * in the boot layer.
+     */
+    static boolean isBootLayerPatched() {
+        return !PATCH_MAP.isEmpty();
+    }
+
+    /**
      * Returns a module reference that interposes on the given module if
      * needed. If there are no patches for the given module then the module
      * reference is simply returned. Otherwise the patches for the module
@@ -537,6 +544,13 @@
     }
 
     /**
+     * Gets and remove the named system property
+     */
+    private static String getAndRemoveProperty(String key) {
+        return (String)System.getProperties().remove(key);
+    }
+
+    /**
      * Derives a package name from the name of an entry in a JAR file.
      */
     private static String toPackageName(Path file, JarEntry entry) {
--- a/jdk/src/java.base/share/classes/module-info.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/module-info.java	Wed Jul 05 22:05:22 2017 +0200
@@ -128,6 +128,7 @@
     exports jdk.internal.logger to
         java.logging;
     exports jdk.internal.org.objectweb.asm to
+        jdk.jartool,
         jdk.jlink,
         jdk.scripting.nashorn,
         jdk.vm.ci;
--- a/jdk/src/java.base/share/classes/sun/invoke/util/ValueConversions.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/ValueConversions.java	Wed Jul 05 22:05:22 2017 +0200
@@ -29,27 +29,32 @@
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.invoke.MethodType;
-import java.util.EnumMap;
+import jdk.internal.vm.annotation.Stable;
 
 public class ValueConversions {
     private static final Class<?> THIS_CLASS = ValueConversions.class;
     private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
 
-    /** Thread-safe canonicalized mapping from Wrapper to MethodHandle
+    /**
+     * Thread-safe canonicalized mapping from Wrapper to MethodHandle
      * with unsynchronized reads and synchronized writes.
-     * It's safe to publish MethodHandles by data race because they are immutable. */
+     * It's safe to publish MethodHandles by data race because they are immutable.
+     */
     private static class WrapperCache {
-        /** EnumMap uses preconstructed array internally, which is constant during it's lifetime. */
-        private final EnumMap<Wrapper, MethodHandle> map = new EnumMap<>(Wrapper.class);
+        @Stable
+        private final MethodHandle[] map = new MethodHandle[Wrapper.COUNT];
 
         public MethodHandle get(Wrapper w) {
-            return map.get(w);
+            return map[w.ordinal()];
         }
         public synchronized MethodHandle put(final Wrapper w, final MethodHandle mh) {
-            // Simulate CAS to avoid racy duplication
-            MethodHandle prev = map.putIfAbsent(w, mh);
-            if (prev != null)  return prev;
-            return mh;
+            MethodHandle prev = map[w.ordinal()];
+            if (prev != null) {
+                return prev;
+            } else {
+                map[w.ordinal()] = mh;
+                return mh;
+            }
         }
     }
 
@@ -623,7 +628,7 @@
         return (x ? (byte)1 : (byte)0);
     }
 
-    private static final WrapperCache[] CONVERT_PRIMITIVE_FUNCTIONS = newWrapperCaches(Wrapper.values().length);
+    private static final WrapperCache[] CONVERT_PRIMITIVE_FUNCTIONS = newWrapperCaches(Wrapper.COUNT);
 
     public static MethodHandle convertPrimitive(Wrapper wsrc, Wrapper wdst) {
         WrapperCache cache = CONVERT_PRIMITIVE_FUNCTIONS[wsrc.ordinal()];
--- a/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java	Wed Jul 05 22:05:22 2017 +0200
@@ -28,6 +28,7 @@
 import java.lang.reflect.Modifier;
 import static java.lang.reflect.Modifier.*;
 import java.lang.reflect.Module;
+import java.util.Objects;
 import jdk.internal.reflect.Reflection;
 
 /**
@@ -330,15 +331,7 @@
             return true;
         if (class1.getClassLoader() != class2.getClassLoader())
             return false;
-        String name1 = class1.getName(), name2 = class2.getName();
-        int dot = name1.lastIndexOf('.');
-        if (dot != name2.lastIndexOf('.'))
-            return false;
-        for (int i = 0; i < dot; i++) {
-            if (name1.charAt(i) != name2.charAt(i))
-                return false;
-        }
-        return true;
+        return Objects.equals(class1.getPackageName(), class2.getPackageName());
     }
 
     /** Return the package name for this class.
--- a/jdk/src/java.base/share/classes/sun/invoke/util/Wrapper.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/Wrapper.java	Wed Jul 05 22:05:22 2017 +0200
@@ -42,6 +42,8 @@
     VOID   (     Void.class,    void.class, 'V',           null, Format.other(    0)),
     ;
 
+    public static final int COUNT = 10;
+
     private final Class<?> wrapperType;
     private final Class<?> primitiveType;
     private final char     basicTypeChar;
@@ -160,7 +162,10 @@
         return true;
     }
 
-    static { assert(checkConvertibleFrom()); }
+    static {
+        assert(checkConvertibleFrom());
+        assert(COUNT == Wrapper.values().length);
+    }
     private static boolean checkConvertibleFrom() {
         // Check the matrix for correct classification of widening conversions.
         for (Wrapper w : values()) {
--- a/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Wed Jul 05 22:05:22 2017 +0200
@@ -60,8 +60,6 @@
 import java.nio.file.DirectoryStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.text.Normalizer;
 import java.text.MessageFormat;
 import java.util.ResourceBundle;
@@ -905,7 +903,7 @@
 
         ModuleFinder finder = jdk.internal.module.ModuleBootstrap.finder();
 
-        int colon = optionFlag.indexOf(':');
+        int colon = optionFlag.indexOf('=');
         if (colon == -1) {
             finder.findAll().stream()
                 .sorted(Comparator.comparing(ModuleReference::descriptor))
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Wed Jul 05 22:05:22 2017 +0200
@@ -27,7 +27,7 @@
 java.launcher.opt.header  =   Usage: {0} [options] class [args...]\n\
 \           (to execute a class)\n   or  {0} [options] -jar jarfile [args...]\n\
 \           (to execute a jar file)\n\
-\   or  {0} [options] -mp <modulepath> -m <modulename>[/<mainclass>] [args...]\n\
+\   or  {0} [options] -p <modulepath> -m <modulename>[/<mainclass>] [args...]\n\
 \           (to execute the main class in a module)\n\
 where options include:\n
 
@@ -41,24 +41,28 @@
 # Translators please note do not translate the options themselves
 java.launcher.opt.footer     =\    -cp <class search path of directories and zip/jar files>\n\
 \    -classpath <class search path of directories and zip/jar files>\n\
+\    --class-path <class search path of directories and zip/jar files>\n\
 \                  A {0} separated list of directories, JAR archives,\n\
 \                  and ZIP archives to search for class files.\n\
-\    -mp <module path>\n\
-\    -modulepath <module path>...\n\
+\    -p <module path>\n\
+\    --module-path <module path>...\n\
 \                  A {0} separated list of directories, each directory\n\
 \                  is a directory of modules.\n\
-\    -upgrademodulepath <module path>...\n\
+\    --upgrade-module-path <module path>...\n\
 \                  A {0} separated list of directories, each directory\n\
 \                  is a directory of modules that replace upgradeable\n\
 \                  modules in the runtime image\n\
-\    -m <modulename>[/<mainclass>]\n\
+\    -m <module>[/<mainclass>]\n\
+\    --module <modulename>[/<mainclass>]\n\
 \                  the initial module to resolve, and the name of the main class\n\
 \                  to execute if not specified by the module\n\
-\    -addmods <modulename>[,<modulename>...]\n\
-\                  root modules to resolve in addition to the initial module\n\
-\    -limitmods <modulename>[,<modulename>...]\n\
+\    --add-modules <modulename>[,<modulename>...]\n\
+\                  root modules to resolve in addition to the initial module.\n\
+\                  <modulename> can also be ALL-DEFAULT, ALL-SYSTEM,\n\
+\                  ALL-MODULE-PATH.\n\
+\    --limit-modules <modulename>[,<modulename>...]\n\
 \                  limit the universe of observable modules\n\
-\    -listmods[:<modulename>[,<modulename>...]]\n\
+\    --list-modules [<modulename>[,<modulename>...]]\n\
 \                  list the observable modules and exit\n\
 \    --dry-run     create VM but do not execute main method.\n\
 \                  This --dry-run option may be useful for validating the\n\
@@ -69,7 +73,8 @@
 \                  enable verbose output\n\
 \    -version      print product version and exit\n\
 \    -showversion  print product version and continue\n\
-\    -? -help      print this help message\n\
+\    -? -help --help\n\
+\                  print this help message\n\
 \    -X            print help on non-standard options\n\
 \    -ea[:<packagename>...|:<classname>]\n\
 \    -enableassertions[:<packagename>...|:<classname>]\n\
@@ -91,6 +96,8 @@
 \    -splash:<imagepath>\n\
 \                  show splash screen with specified image\n\
 \    @<filepath>   read options from the specified file\n\
+\To specify an argument for a long option, you can use --<name>=<value> or\n\
+\--<name> <value>.\n\
 
 See http://www.oracle.com/technetwork/java/javase/documentation/index.html for more details.
 
@@ -123,17 +130,21 @@
 \                      show all property settings and continue\n\
 \    -XshowSettings:locale\n\
 \                      show all locale related settings and continue\n\
-\    -XaddReads:<module>=<other-module>(,<other-module>)*\n\
-\                      <module> reads other modules,\n\
-\                      regardless of module declaration\n\
-\    -XaddExports:<module>/<package>=<other-module>(,<other-module>)*\n\
-\                      <module> exports <package> to other modules,\n\
-\                      regardless of module declaration\n\
-\    -Xpatch:<module>=<file>({0}<file>)*\n\
+\    -Xdisable-@files  disable further argument file expansion\n\
+\    --add-reads <module>=<target-module>(,<target-module>)*\n\
+\                      updates <module> to read <target-module>, regardless\n\
+\                      of module declaration. \n\
+\                      <target-module> can be ALL-UNNAMED to read all unnamed\n\
+\                      modules.\n\
+\    --add-exports <module>/<package>=<target-module>(,<target-module>)*\n\
+\                      updates <module> to export <package> to <target-module>,\n\
+\                      regardless of module declaration.\n\
+\                      <target-module> can be ALL-UNNAMED to export to all\n\
+\                      unnamed modules.\n\
+\    --patch-module <module>=<file>({0}<file>)*\n\
 \                      Override or augment a module with classes and resources\n\
-\                      in JAR files or directories\n\
-\    -Xdisable-@files  disable further argument file expansion\n\n\
-The -X options are non-standard and subject to change without notice.\n
+\                      in JAR files or directories.\n\n\
+These options are non-standard and subject to change without notice.\n
 
 # Translators please note do not translate the options themselves
 java.launcher.X.macosx.usage=\
--- a/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Wed Jul 05 22:05:22 2017 +0200
@@ -580,6 +580,9 @@
             Entry entry;
 
             if (key instanceof PrivateKey) {
+                // Check that all the certs are X.509 certs
+                checkX509Certs(chain);
+
                 PrivateKeyEntry keyEntry = new PrivateKeyEntry();
                 keyEntry.date = new Date();
 
@@ -690,6 +693,9 @@
                                   Certificate[] chain)
         throws KeyStoreException
     {
+        // Check that all the certs are X.509 certs
+        checkX509Certs(chain);
+
         // Private key must be encoded as EncryptedPrivateKeyInfo
         // as defined in PKCS#8
         try {
@@ -960,6 +966,13 @@
     private void setCertEntry(String alias, Certificate cert,
         Set<KeyStore.Entry.Attribute> attributes) throws KeyStoreException {
 
+        // Check that the cert is an X.509 cert
+        if (cert != null && (!(cert instanceof X509Certificate))) {
+            throw new KeyStoreException(
+                "Only X.509 certificates are supported - rejecting class: " +
+                cert.getClass().getName());
+        }
+
         Entry entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
         if (entry != null && entry instanceof KeyEntry) {
             throw new KeyStoreException("Cannot overwrite own certificate");
@@ -1505,6 +1518,21 @@
         return set.size() == certChain.length;
     }
 
+    /*
+     * Check that all the certificates are X.509 certificates
+     */
+    private static void checkX509Certs(Certificate[] certs)
+            throws KeyStoreException {
+        if (certs != null) {
+            for (Certificate cert : certs) {
+                if (!(cert instanceof X509Certificate)) {
+                    throw new KeyStoreException(
+                        "Only X.509 certificates are supported - " +
+                        "rejecting class: " + cert.getClass().getName());
+                }
+            }
+        }
+    }
 
     /*
      * Create PKCS#12 Attributes, friendlyName, localKeyId and trustedKeyUsage.
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Wed Jul 05 22:05:22 2017 +0200
@@ -59,6 +59,11 @@
             "jdk.tls.client.enableStatusRequestExtension", true);
     private final boolean serverEnableStapling = Debug.getBooleanProperty(
             "jdk.tls.server.enableStatusRequestExtension", false);
+    private final static Collection<CipherSuite> clientCustomizedCipherSuites =
+            getCustomizedCipherSuites("jdk.tls.client.cipherSuites");
+    private final static Collection<CipherSuite> serverCustomizedCipherSuites =
+            getCustomizedCipherSuites("jdk.tls.server.cipherSuites");
+
     private volatile StatusResponseManager statusResponseManager;
 
     SSLContextImpl() {
@@ -336,20 +341,52 @@
         return isClient ? clientEnableStapling : serverEnableStapling;
     }
 
+
     /*
-     * Return the list of all available CipherSuites with a priority of
-     * minPriority or above.
+     * Return the list of all available CipherSuites that are supported
+     * using currently installed providers.
+     */
+    private static CipherSuiteList getApplicableSupportedCipherSuiteList(
+            ProtocolList protocols) {
+
+        return getApplicableCipherSuiteList(
+                CipherSuite.allowedCipherSuites(),
+                protocols, CipherSuite.SUPPORTED_SUITES_PRIORITY);
+    }
+
+    /*
+     * Return the list of all available CipherSuites that are default enabled
+     * in client or server side.
+     */
+    private static CipherSuiteList getApplicableEnabledCipherSuiteList(
+            ProtocolList protocols, boolean isClient) {
+
+        if (isClient) {
+            if (!clientCustomizedCipherSuites.isEmpty()) {
+                return getApplicableCipherSuiteList(
+                        clientCustomizedCipherSuites,
+                        protocols, CipherSuite.SUPPORTED_SUITES_PRIORITY);
+            }
+        } else {
+            if (!serverCustomizedCipherSuites.isEmpty()) {
+                return getApplicableCipherSuiteList(
+                        serverCustomizedCipherSuites,
+                        protocols, CipherSuite.SUPPORTED_SUITES_PRIORITY);
+            }
+        }
+
+        return getApplicableCipherSuiteList(
+                CipherSuite.allowedCipherSuites(),
+                protocols, CipherSuite.DEFAULT_SUITES_PRIORITY);
+    }
+
+    /*
+     * Return the list of available CipherSuites which are applicable to
+     * the specified protocols.
      */
     private static CipherSuiteList getApplicableCipherSuiteList(
-            ProtocolList protocols, boolean onlyEnabled) {
-
-        int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY;
-        if (onlyEnabled) {
-            minPriority = CipherSuite.DEFAULT_SUITES_PRIORITY;
-        }
-
-        Collection<CipherSuite> allowedCipherSuites =
-                                    CipherSuite.allowedCipherSuites();
+            Collection<CipherSuite> allowedCipherSuites,
+            ProtocolList protocols, int minPriority) {
 
         TreeSet<CipherSuite> suites = new TreeSet<>();
         if (!(protocols.collection().isEmpty()) &&
@@ -386,6 +423,67 @@
         return new CipherSuiteList(suites);
     }
 
+    /*
+     * Get the customized cipher suites specified by the given system property.
+     */
+    private static Collection<CipherSuite> getCustomizedCipherSuites(
+            String propertyName) {
+
+        String property = GetPropertyAction.privilegedGetProperty(propertyName);
+        if (debug != null && Debug.isOn("sslctx")) {
+            System.out.println(
+                    "System property " + propertyName + " is set to '" +
+                    property + "'");
+        }
+        if (property != null && property.length() != 0) {
+            // remove double quote marks from beginning/end of the property
+            if (property.length() > 1 && property.charAt(0) == '"' &&
+                    property.charAt(property.length() - 1) == '"') {
+                property = property.substring(1, property.length() - 1);
+            }
+        }
+
+        if (property != null && property.length() != 0) {
+            String[] cipherSuiteNames = property.split(",");
+            Collection<CipherSuite> cipherSuites =
+                        new ArrayList<>(cipherSuiteNames.length);
+            for (int i = 0; i < cipherSuiteNames.length; i++) {
+                cipherSuiteNames[i] = cipherSuiteNames[i].trim();
+                if (cipherSuiteNames[i].isEmpty()) {
+                    continue;
+                }
+
+                CipherSuite suite;
+                try {
+                    suite = CipherSuite.valueOf(cipherSuiteNames[i]);
+                } catch (IllegalArgumentException iae) {
+                    if (debug != null && Debug.isOn("sslctx")) {
+                        System.out.println(
+                                "Unknown or unsupported cipher suite name: " +
+                                cipherSuiteNames[i]);
+                    }
+
+                    continue;
+                }
+
+                if (suite.isAvailable()) {
+                    cipherSuites.add(suite);
+                } else {
+                    if (debug != null && Debug.isOn("sslctx")) {
+                        System.out.println(
+                                "The current installed providers do not " +
+                                "support cipher suite: " + cipherSuiteNames[i]);
+                    }
+                }
+            }
+
+            return cipherSuites;
+        }
+
+        return Collections.emptyList();
+    }
+
+
     private static String[] getAvailableProtocols(
             ProtocolVersion[] protocolCandidates) {
 
@@ -481,10 +579,10 @@
                 }));
             }
 
-            supportedCipherSuiteList = getApplicableCipherSuiteList(
-                    supportedProtocolList, false);          // all supported
-            serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    serverDefaultProtocolList, true);       // enabled only
+            supportedCipherSuiteList = getApplicableSupportedCipherSuiteList(
+                    supportedProtocolList);
+            serverDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    serverDefaultProtocolList, false);
         }
 
         @Override
@@ -541,8 +639,8 @@
                 }));
             }
 
-            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);       // enabled only
+            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    clientDefaultProtocolList, true);
         }
 
         @Override
@@ -581,8 +679,9 @@
                 }));
             }
 
-            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);       // enabled only
+            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    clientDefaultProtocolList, true);
+
         }
 
         @Override
@@ -623,8 +722,8 @@
                 }));
             }
 
-            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);       // enabled only
+            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    clientDefaultProtocolList, true);
         }
 
         @Override
@@ -757,8 +856,9 @@
 
                 clientDefaultProtocolList = new ProtocolList(
                         getAvailableProtocols(candidates));
-                clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);   // enabled only
+                clientDefaultCipherSuiteList =
+                        getApplicableEnabledCipherSuiteList(
+                                clientDefaultProtocolList, true);
             } else {
                 clientDefaultProtocolList = null;       // unlikely to be used
                 clientDefaultCipherSuiteList = null;    // unlikely to be used
@@ -1032,10 +1132,10 @@
                 ProtocolVersion.DTLS12
             }));
 
-            supportedCipherSuiteList = getApplicableCipherSuiteList(
-                    supportedProtocolList, false);          // all supported
-            serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    serverDefaultProtocolList, true);       // enabled only
+            supportedCipherSuiteList = getApplicableSupportedCipherSuiteList(
+                    supportedProtocolList);
+            serverDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    serverDefaultProtocolList, false);
         }
 
         @Override
@@ -1090,8 +1190,8 @@
                 ProtocolVersion.DTLS10
             }));
 
-            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);       // enabled only
+            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    clientDefaultProtocolList, true);
         }
 
         @Override
@@ -1122,8 +1222,8 @@
                 ProtocolVersion.DTLS12
             }));
 
-            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);       // enabled only
+            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+                    clientDefaultProtocolList, true);
         }
 
         @Override
@@ -1187,8 +1287,9 @@
 
                 clientDefaultProtocolList = new ProtocolList(
                         getAvailableProtocols(candidates));
-                clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
-                    clientDefaultProtocolList, true);   // enabled only
+                clientDefaultCipherSuiteList =
+                        getApplicableEnabledCipherSuiteList(
+                                clientDefaultProtocolList, true);
             } else {
                 clientDefaultProtocolList = null;       // unlikely to be used
                 clientDefaultCipherSuiteList = null;    // unlikely to be used
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java	Wed Jul 05 22:05:22 2017 +0200
@@ -1994,7 +1994,7 @@
 
     private StaplingParameters processStapling(ClientHello mesg) {
         StaplingParameters params = null;
-        ExtensionType ext;
+        ExtensionType ext = null;
         StatusRequestType type = null;
         StatusRequest req = null;
         Map<X509Certificate, byte[]> responses;
@@ -2012,33 +2012,40 @@
         CertStatusReqListV2Extension statReqExtV2 =
                 (CertStatusReqListV2Extension)mesg.extensions.get(
                         ExtensionType.EXT_STATUS_REQUEST_V2);
-        // Keep processing only if either status_request or status_request_v2
-        // has been sent in the ClientHello.
-        if (statReqExt == null && statReqExtV2 == null) {
-            return null;
-        }
 
         // Determine which type of stapling we are doing and assert the
         // proper extension in the server hello.
         // Favor status_request_v2 over status_request and ocsp_multi
         // over ocsp.
         // If multiple ocsp or ocsp_multi types exist, select the first
-        // instance of a given type
-        ext = ExtensionType.EXT_STATUS_REQUEST;
+        // instance of a given type.  Also since we don't support ResponderId
+        // selection yet, only accept a request if the ResponderId field
+        // is empty.
         if (statReqExtV2 != null) {             // RFC 6961 stapling
             ext = ExtensionType.EXT_STATUS_REQUEST_V2;
             List<CertStatusReqItemV2> reqItems =
                     statReqExtV2.getRequestItems();
             int ocspIdx = -1;
             int ocspMultiIdx = -1;
-            for (int pos = 0; pos < reqItems.size(); pos++) {
+            for (int pos = 0; (pos < reqItems.size() &&
+                    (ocspIdx == -1 || ocspMultiIdx == -1)); pos++) {
                 CertStatusReqItemV2 item = reqItems.get(pos);
-                if (ocspIdx < 0 && item.getType() ==
-                        StatusRequestType.OCSP) {
-                    ocspIdx = pos;
-                } else if (ocspMultiIdx < 0 && item.getType() ==
-                        StatusRequestType.OCSP_MULTI) {
-                    ocspMultiIdx = pos;
+                StatusRequestType curType = item.getType();
+                if (ocspIdx < 0 && curType == StatusRequestType.OCSP) {
+                    OCSPStatusRequest ocspReq =
+                            (OCSPStatusRequest)item.getRequest();
+                    if (ocspReq.getResponderIds().isEmpty()) {
+                        ocspIdx = pos;
+                    }
+                } else if (ocspMultiIdx < 0 &&
+                        curType == StatusRequestType.OCSP_MULTI) {
+                    // If the type is OCSP, then the request
+                    // is guaranteed to be OCSPStatusRequest
+                    OCSPStatusRequest ocspReq =
+                            (OCSPStatusRequest)item.getRequest();
+                    if (ocspReq.getResponderIds().isEmpty()) {
+                        ocspMultiIdx = pos;
+                    }
                 }
             }
             if (ocspMultiIdx >= 0) {
@@ -2047,16 +2054,47 @@
             } else if (ocspIdx >= 0) {
                 type = reqItems.get(ocspIdx).getType();
                 req = reqItems.get(ocspIdx).getRequest();
+            } else {
+                if (debug != null && Debug.isOn("handshake")) {
+                    System.out.println("Warning: No suitable request " +
+                            "found in the status_request_v2 extension.");
+                }
             }
-        } else {                                // RFC 6066 stapling
-            type = StatusRequestType.OCSP;
-            req = statReqExt.getRequest();
+        }
+
+        // Only attempt to process a status_request extension if:
+        // * The status_request extension is set AND
+        // * either the status_request_v2 extension is not present OR
+        // * none of the underlying OCSPStatusRequest structures is suitable
+        // for stapling.
+        // If either of the latter two bullet items is true the ext, type and
+        // req variables should all be null.  If any are null we will try
+        // processing an asserted status_request.
+        if ((statReqExt != null) &&
+               (ext == null || type == null || req == null)) {
+            ext = ExtensionType.EXT_STATUS_REQUEST;
+            type = statReqExt.getType();
+            if (type == StatusRequestType.OCSP) {
+                // If the type is OCSP, then the request is guaranteed
+                // to be OCSPStatusRequest
+                OCSPStatusRequest ocspReq =
+                        (OCSPStatusRequest)statReqExt.getRequest();
+                if (ocspReq.getResponderIds().isEmpty()) {
+                    req = ocspReq;
+                } else {
+                    if (debug != null && Debug.isOn("handshake")) {
+                        req = null;
+                        System.out.println("Warning: No suitable request " +
+                                "found in the status_request extension.");
+                    }
+                }
+            }
         }
 
         // If, after walking through the extensions we were unable to
         // find a suitable StatusRequest, then stapling is disabled.
-        // Both statReqType and statReqData must have been set to continue.
-        if (type == null || req == null) {
+        // The ext, type and req variables must have been set to continue.
+        if (type == null || req == null || ext == null) {
             return null;
         }
 
--- a/jdk/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java	Wed Jul 05 22:05:22 2017 +0200
@@ -63,8 +63,6 @@
         // this class is not meant to be instantiated
     }
 
-    private static final String JKS = "jks";
-
     private static final Collator collator = Collator.getInstance();
     static {
         // this is for case insensitive string comparisons
@@ -113,24 +111,24 @@
     }
 
     /**
+     * Returns the file name of the keystore with the configured CA certificates.
+     */
+    public static String getCacerts() {
+        String sep = File.separator;
+        return System.getProperty("java.home") + sep
+                + "lib" + sep + "security" + sep
+                + "cacerts";
+    }
+
+    /**
      * Returns the keystore with the configured CA certificates.
      */
-    public static KeyStore getCacertsKeyStore()
-        throws Exception
-    {
-        String sep = File.separator;
-        File file = new File(System.getProperty("java.home") + sep
-                             + "lib" + sep + "security" + sep
-                             + "cacerts");
+    public static KeyStore getCacertsKeyStore() throws Exception {
+        File file = new File(getCacerts());
         if (!file.exists()) {
             return null;
         }
-        KeyStore caks = null;
-        try (FileInputStream fis = new FileInputStream(file)) {
-            caks = KeyStore.getInstance(JKS);
-            caks.load(fis, null);
-        }
-        return caks;
+        return KeyStore.getInstance(file, (char[])null);
     }
 
     public static char[] getPassWithModifier(String modifier, String arg,
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Wed Jul 05 22:05:22 2017 +0200
@@ -153,6 +153,7 @@
     private boolean trustcacerts = false;
     private boolean protectedPath = false;
     private boolean srcprotectedPath = false;
+    private boolean cacerts = false;
     private CertificateFactory cf = null;
     private KeyStore caks = null; // "cacerts" keystore
     private char[] srcstorePass = null;
@@ -169,15 +170,15 @@
             STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
             PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
         CHANGEALIAS("Changes.an.entry.s.alias",
-            ALIAS, DESTALIAS, KEYPASS, KEYSTORE, STOREPASS,
+            ALIAS, DESTALIAS, KEYPASS, KEYSTORE, CACERTS, STOREPASS,
             STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
             PROVIDERPATH, V, PROTECTED),
         DELETE("Deletes.an.entry",
-            ALIAS, KEYSTORE, STOREPASS, STORETYPE,
+            ALIAS, KEYSTORE, CACERTS, STOREPASS, STORETYPE,
             PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
             PROVIDERPATH, V, PROTECTED),
         EXPORTCERT("Exports.certificate",
-            RFC, ALIAS, FILEOUT, KEYSTORE, STOREPASS,
+            RFC, ALIAS, FILEOUT, KEYSTORE, CACERTS, STOREPASS,
             STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
             PROVIDERPATH, V, PROTECTED),
         GENKEYPAIR("Generates.a.key.pair",
@@ -196,7 +197,7 @@
             PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
         IMPORTCERT("Imports.a.certificate.or.a.certificate.chain",
             NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN,
-            KEYPASS, KEYSTORE, STOREPASS, STORETYPE,
+            KEYPASS, KEYSTORE, CACERTS, STOREPASS, STORETYPE,
             PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
             PROVIDERPATH, V),
         IMPORTPASS("Imports.a.password",
@@ -215,7 +216,7 @@
             STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
             PROVIDERPATH, V),
         LIST("Lists.entries.in.a.keystore",
-            RFC, ALIAS, KEYSTORE, STOREPASS, STORETYPE,
+            RFC, ALIAS, KEYSTORE, CACERTS, STOREPASS, STORETYPE,
             PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
             PROVIDERPATH, V, PROTECTED),
         PRINTCERT("Prints.the.content.of.a.certificate",
@@ -225,7 +226,7 @@
         PRINTCRL("Prints.the.content.of.a.CRL.file",
             FILEIN, V),
         STOREPASSWD("Changes.the.store.password.of.a.keystore",
-            NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME,
+            NEW, KEYSTORE, CACERTS, STOREPASS, STORETYPE, PROVIDERNAME,
             ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V),
 
         // Undocumented start here, KEYCLONE is used a marker in -help;
@@ -306,6 +307,7 @@
         KEYPASS("keypass", "<arg>", "key.password"),
         KEYSIZE("keysize", "<size>", "key.bit.size"),
         KEYSTORE("keystore", "<keystore>", "keystore.name"),
+        CACERTS("cacerts", null, "access.the.cacerts.keystore"),
         NEW("new", "<arg>", "new.password"),
         NOPROMPT("noprompt", null, "do.not.prompt"),
         OUTFILE("outfile", "<file>", "output.file.name"),
@@ -472,14 +474,16 @@
                 help = true;
             } else if (collator.compare(flags, "-conf") == 0) {
                 i++;
-            }
-
-            /*
-             * specifiers
-             */
-            else if (collator.compare(flags, "-keystore") == 0 ||
-                    collator.compare(flags, "-destkeystore") == 0) {
+            } else if (collator.compare(flags, "-keystore") == 0) {
                 ksfname = args[++i];
+                if (new File(ksfname).getCanonicalPath().equals(
+                        new File(KeyStoreUtil.getCacerts()).getCanonicalPath())) {
+                    System.err.println(rb.getString("warning.cacerts.option"));
+                }
+            } else if (collator.compare(flags, "-destkeystore") == 0) {
+                ksfname = args[++i];
+            } else if (collator.compare(flags, "-cacerts") == 0) {
+                cacerts = true;
             } else if (collator.compare(flags, "-storepass") == 0 ||
                     collator.compare(flags, "-deststorepass") == 0) {
                 storePass = getPass(modifier, args[++i]);
@@ -636,6 +640,15 @@
      * Execute the commands.
      */
     void doCommands(PrintStream out) throws Exception {
+
+        if (cacerts) {
+            if (ksfname != null || storetype != null) {
+                throw new IllegalArgumentException(rb.getString
+                        ("the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option"));
+            }
+            ksfname = KeyStoreUtil.getCacerts();
+        }
+
         if (storetype == null) {
             storetype = KeyStore.getDefaultType();
         }
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java	Wed Jul 05 22:05:22 2017 +0200
@@ -127,6 +127,10 @@
                 "key bit size"}, //-keysize
         {"keystore.name",
                 "keystore name"}, //-keystore
+        {"access.the.cacerts.keystore",
+                "access the cacerts keystore"}, // -cacerts
+        {"warning.cacerts.option",
+                "Warning: use -cacerts option to access cacerts keystore"},
         {"new.password",
                 "new password"}, //-new
         {"do.not.prompt",
@@ -194,6 +198,8 @@
         {"Command.option.flag.needs.an.argument.", "Command option {0} needs an argument."},
         {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.",
                 "Warning:  Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified {0} value."},
+        {"the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option",
+            "The -keystore or -storetype option cannot be used with the -cacerts option"},
         {".keystore.must.be.NONE.if.storetype.is.{0}",
                 "-keystore must be NONE if -storetype is {0}"},
         {"Too.many.retries.program.terminated",
Binary file jdk/src/java.base/share/conf/security/cacerts has changed
Binary file jdk/src/java.base/share/lib/security/cacerts has changed
--- a/jdk/src/java.base/share/native/libjli/args.c	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/native/libjli/args.c	Wed Jul 05 22:05:22 2017 +0200
@@ -102,24 +102,21 @@
 
     // All arguments arrive here must be a launcher argument,
     // ie. by now, all argfile expansions must have been performed.
-    if (*arg++ == '-') {
+    if (*arg == '-') {
         expectingNoDashArg = JNI_FALSE;
-        if (JLI_StrCmp(arg, "cp") == 0 ||
-            JLI_StrCmp(arg, "classpath") == 0 ||
-            JLI_StrCmp(arg, "addmods") == 0 ||
-            JLI_StrCmp(arg, "limitmods") == 0 ||
-            JLI_StrCmp(arg, "mp") == 0 ||
-            JLI_StrCmp(arg, "modulepath") == 0 ||
-            JLI_StrCmp(arg, "upgrademodulepath") == 0) {
+        if (IsWhiteSpaceOption(arg)) {
+            // expect an argument
             expectingNoDashArg = JNI_TRUE;
-        } else if (JLI_StrCmp(arg, "jar") == 0 ||
-                   JLI_StrCmp(arg, "m") == 0) {
-            // This is tricky, we do expect NoDashArg
-            // But that is considered main class to stop expansion
-            expectingNoDashArg = JNI_FALSE;
-            // We can not just update the idx here because if -jar @file
-            // still need expansion of @file to get the argument for -jar
-        } else if (JLI_StrCmp(arg, "Xdisable-@files") == 0) {
+
+            if (JLI_StrCmp(arg, "-jar") == 0 ||
+                JLI_StrCmp(arg, "-m") == 0) {
+                // This is tricky, we do expect NoDashArg
+                // But that is considered main class to stop expansion
+                expectingNoDashArg = JNI_FALSE;
+                // We can not just update the idx here because if -jar @file
+                // still need expansion of @file to get the argument for -jar
+            }
+        } else if (JLI_StrCmp(arg, "-Xdisable-@files") == 0) {
             stopExpansion = JNI_TRUE;
         }
     } else {
--- a/jdk/src/java.base/share/native/libjli/java.c	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/native/libjli/java.c	Wed Jul 05 22:05:22 2017 +0200
@@ -69,7 +69,7 @@
 static jboolean printUsage = JNI_FALSE;   /* print and exit*/
 static jboolean printXUsage = JNI_FALSE;  /* print and exit*/
 static jboolean dryRun = JNI_FALSE;       /* initialize VM and exit */
-static char     *showSettings = NULL;      /* print but continue */
+static char     *showSettings = NULL;     /* print but continue */
 static char     *listModules = NULL;
 
 static const char *_program_name;
@@ -99,17 +99,9 @@
  * Prototypes for functions internal to launcher.
  */
 static void SetClassPath(const char *s);
-static void SetModulePath(const char *s);
-static void SetUpgradeModulePath(const char *s);
 static void SetMainModule(const char *s);
-static void SetAddModulesProp(const char *mods);
-static void SetLimitModulesProp(const char *mods);
-static void SetAddReadsProp(const jint n, const char *s);
-static void SetAddExportsProp(const jint n, const char *s);
-static void SetPatchProp(const jint n, const char *s);
 static void SelectVersion(int argc, char **argv, char **main_class);
 static void SetJvmEnvironment(int argc, char **argv);
-static jboolean IsWhiteSpaceOptionArgument(const char* name);
 static jboolean ParseArguments(int *pargc, char ***pargv,
                                int *pmode, char **pwhat,
                                int *pret, const char *jrepath);
@@ -133,6 +125,18 @@
 static void DumpState();
 static jboolean RemovableOption(char *option);
 
+enum OptionKind {
+    LAUNCHER_OPTION = 0,
+    LAUNCHER_OPTION_WITH_ARGUMENT,
+    LAUNCHER_MAIN_OPTION,
+    VM_LONG_OPTION,
+    VM_LONG_OPTION_WITH_ARGUMENT,
+    VM_OPTION
+};
+
+static int GetOpt(int *pargc, char ***pargv, char **poption, char **pvalue);
+static jboolean IsOptionWithArgument(int argc, char **argv);
+
 /* Maximum supported entries from jvm.cfg. */
 #define INIT_MAX_KNOWN_VMS      10
 
@@ -162,6 +166,19 @@
 static void FreeKnownVMs();
 static jboolean IsWildCardEnabled();
 
+/*
+ * This reports error.  VM will not be created and no usage is printed.
+ */
+#define REPORT_ERROR(AC_ok, AC_failure_message, AC_questionable_arg) \
+    do { \
+        if (!AC_ok) { \
+            JLI_ReportErrorMessage(AC_failure_message, AC_questionable_arg); \
+            printUsage = JNI_FALSE; \
+            *pret = 1; \
+            return JNI_FALSE; \
+        } \
+    } while (JNI_FALSE)
+
 #define ARG_CHECK(AC_arg_count, AC_failure_message, AC_questionable_arg) \
     do { \
         if (AC_arg_count < 1) { \
@@ -511,17 +528,73 @@
 }
 
 /*
- * Test if the given option name has a whitespace separated argument.
+ * Test if the given name is one of the class path options.
+ */
+static jboolean
+IsClassPathOption(const char* name) {
+    return JLI_StrCmp(name, "-classpath") == 0 ||
+           JLI_StrCmp(name, "-cp") == 0 ||
+           JLI_StrCmp(name, "--class-path") == 0;
+}
+
+/*
+ * Test if the given name is a launcher option taking the main entry point.
+ */
+static jboolean
+IsLauncherMainOption(const char* name) {
+    return JLI_StrCmp(name, "--module") == 0 ||
+           JLI_StrCmp(name, "-m") == 0;
+}
+
+/*
+ * Test if the given name is a white-space launcher option.
+ */
+static jboolean
+IsLauncherOption(const char* name) {
+    return IsClassPathOption(name) ||
+           IsLauncherMainOption(name) ||
+           JLI_StrCmp(name, "--list-modules") == 0;
+}
+
+#ifndef OLD_MODULE_OPTIONS
+/*
+ * Old module options for transition
+ */
+static jboolean
+IsOldModuleOption(const char* name) {
+    return JLI_StrCmp(name, "-modulepath") == 0 ||
+    JLI_StrCmp(name, "-mp") == 0 ||
+    JLI_StrCmp(name, "-upgrademodulepath") == 0 ||
+    JLI_StrCmp(name, "-addmods") == 0 ||
+    JLI_StrCmp(name, "-limitmods") == 0;
+}
+#endif
+
+/*
+ * Test if the given name is a module-system white-space option that
+ * will be passed to the VM with its corresponding long-form option
+ * name and "=" delimiter.
+ */
+static jboolean
+IsModuleOption(const char* name) {
+    return JLI_StrCmp(name, "--module-path") == 0 ||
+           JLI_StrCmp(name, "-p") == 0 ||
+           JLI_StrCmp(name, "--upgrade-module-path") == 0 ||
+           JLI_StrCmp(name, "--add-modules") == 0 ||
+           JLI_StrCmp(name, "--limit-modules") == 0 ||
+           JLI_StrCmp(name, "--add-exports") == 0 ||
+           JLI_StrCmp(name, "--add-reads") == 0 ||
+           JLI_StrCmp(name, "--patch-module") == 0 ||
+           IsOldModuleOption(name);
+}
+
+/*
+ * Test if the given name has a white space option.
  */
 jboolean
-IsWhiteSpaceOptionArgument(const char* name) {
-    return JLI_StrCmp(name, "-classpath") == 0 ||
-           JLI_StrCmp(name, "-cp") == 0 ||
-           JLI_StrCmp(name, "-modulepath") == 0 ||
-           JLI_StrCmp(name, "-mp") == 0 ||
-           JLI_StrCmp(name, "-upgrademodulepath") == 0 ||
-           JLI_StrCmp(name, "-addmods") == 0 ||
-           JLI_StrCmp(name, "-limitmods") == 0;
+IsWhiteSpaceOption(const char* name) {
+    return IsModuleOption(name) ||
+           IsLauncherOption(name);
 }
 
 /*
@@ -559,7 +632,7 @@
                 continue;
             }
         } else {
-            if (IsWhiteSpaceOptionArgument(arg)) {
+            if (IsWhiteSpaceOption(arg)) {
                 newArgv[newArgvIdx++] = arg;
                 argi++;
                 if (argi < argc) {
@@ -701,7 +774,7 @@
         if (i > 0) {
             char *prev = argv[i - 1];
             // skip non-dash arg preceded by class path specifiers
-            if (*arg != '-' && IsWhiteSpaceOptionArgument(prev)) {
+            if (*arg != '-' && IsWhiteSpaceOption(prev)) {
                 continue;
             }
 
@@ -709,6 +782,7 @@
                     || JLI_StrCmp(arg, "-version") == 0
                     || JLI_StrCmp(arg, "-fullversion") == 0
                     || JLI_StrCmp(arg, "-help") == 0
+                    || JLI_StrCmp(arg, "--help") == 0
                     || JLI_StrCmp(arg, "-?") == 0
                     || JLI_StrCmp(arg, "-jar") == 0
                     || JLI_StrCmp(arg, "-X") == 0) {
@@ -882,39 +956,16 @@
 }
 
 static void
-SetModulePath(const char *s)
+AddLongFormOption(const char *option, const char *arg)
 {
+    static const char format[] = "%s=%s";
     char *def;
-    const char *orig = s;
-    static const char format[] = "-Djdk.module.path=%s";
-    if (s == NULL)
-        return;
-    s = JLI_WildcardExpandClasspath(s);
-    def = JLI_MemAlloc(sizeof(format)
-                       - 2 /* strlen("%s") */
-                       + JLI_StrLen(s));
-    sprintf(def, format, s);
+    size_t def_len;
+
+    def_len = JLI_StrLen(option) + 1 + JLI_StrLen(arg) + 1;
+    def = JLI_MemAlloc(def_len);
+    JLI_Snprintf(def, def_len, format, option, arg);
     AddOption(def, NULL);
-    if (s != orig)
-        JLI_MemFree((char *) s);
-}
-
-static void
-SetUpgradeModulePath(const char *s)
-{
-    char *def;
-    const char *orig = s;
-    static const char format[] = "-Djdk.upgrade.module.path=%s";
-    if (s == NULL)
-        return;
-    s = JLI_WildcardExpandClasspath(s);
-    def = JLI_MemAlloc(sizeof(format)
-                       - 2 /* strlen("%s") */
-                       + JLI_StrLen(s));
-    sprintf(def, format, s);
-    AddOption(def, NULL);
-    if (s != orig)
-        JLI_MemFree((char *) s);
 }
 
 static void
@@ -939,46 +990,6 @@
     AddOption(def, NULL);
 }
 
-static void
-SetAddModulesProp(const char *mods) {
-    size_t buflen = JLI_StrLen(mods) + 40;
-    char *prop = (char *)JLI_MemAlloc(buflen);
-    JLI_Snprintf(prop, buflen, "-Djdk.launcher.addmods=%s", mods);
-    AddOption(prop, NULL);
-}
-
-static void
-SetLimitModulesProp(const char *mods) {
-    size_t buflen = JLI_StrLen(mods) + 40;
-    char *prop = (char *)JLI_MemAlloc(buflen);
-    JLI_Snprintf(prop, buflen, "-Djdk.launcher.limitmods=%s", mods);
-    AddOption(prop, NULL);
-}
-
-static void
-SetAddReadsProp(const jint n, const char *s) {
-    size_t buflen = JLI_StrLen(s) + 40;
-    char *prop = (char *)JLI_MemAlloc(buflen);
-    JLI_Snprintf(prop, buflen, "-Djdk.launcher.addreads.%d=%s", n, s);
-    AddOption(prop, NULL);
-}
-
-static void
-SetAddExportsProp(const jint n, const char *s) {
-    size_t buflen = JLI_StrLen(s) + 40;
-    char *prop = (char *)JLI_MemAlloc(buflen);
-    JLI_Snprintf(prop, buflen, "-Djdk.launcher.addexports.%d=%s", n, s);
-    AddOption(prop, NULL);
-}
-
-static void
-SetPatchProp(const jint n, const char *s) {
-    size_t buflen = JLI_StrLen(s) + 40;
-    char *prop = (char *)JLI_MemAlloc(buflen);
-    JLI_Snprintf(prop, buflen, "-Djdk.launcher.patch.%d=%s", n, s);
-    AddOption(prop, NULL);
-}
-
 /*
  * The SelectVersion() routine ensures that an appropriate version of
  * the JRE is running.  The specification for the appropriate version
@@ -1003,6 +1014,7 @@
     char    *splash_jar_name = NULL;
     char    *env_in;
     int     res;
+    jboolean has_arg;
 
     /*
      * If the version has already been selected, set *main_class
@@ -1033,9 +1045,11 @@
      * This capability is no longer available with JRE versions 1.9 and later.
      * These command line options are reported as errors.
      */
+
     argc--;
     argv++;
     while ((arg = *argv) != 0 && *arg == '-') {
+        has_arg = IsOptionWithArgument(argc, argv);
         if (JLI_StrCCmp(arg, "-version:") == 0) {
             JLI_ReportErrorMessage(SPC_ERROR1);
         } else if (JLI_StrCmp(arg, "-jre-restrict-search") == 0) {
@@ -1045,10 +1059,12 @@
         } else {
             if (JLI_StrCmp(arg, "-jar") == 0)
                 jarflag = 1;
-            if (IsWhiteSpaceOptionArgument(arg) && (argc >= 2)) {
-                argc--;
-                argv++;
-                arg = *argv;
+            if (IsWhiteSpaceOption(arg)) {
+                if (has_arg) {
+                    argc--;
+                    argv++;
+                    arg = *argv;
+                }
             }
 
             /*
@@ -1140,6 +1156,108 @@
 }
 
 /*
+ * Test if the current argv is an option, i.e. with a leading `-`
+ * and followed with an argument without a leading `-`.
+ */
+static jboolean
+IsOptionWithArgument(int argc, char** argv) {
+    char* option;
+    char* arg;
+
+    if (argc <= 1)
+        return JNI_FALSE;
+
+    option = *argv;
+    arg = *(argv+1);
+    return *option == '-' && *arg != '-';
+}
+
+/*
+ * Gets the option, and its argument if the option has an argument.
+ * It will update *pargc, **pargv to the next option.
+ */
+static int
+GetOpt(int *pargc, char ***pargv, char **poption, char **pvalue) {
+    int argc = *pargc;
+    char** argv = *pargv;
+    char* arg = *argv;
+
+    char* option = arg;
+    char* value = NULL;
+    char* equals = NULL;
+    int kind = LAUNCHER_OPTION;
+    jboolean has_arg = JNI_FALSE;
+
+    // check if this option may be a white-space option with an argument
+    has_arg = IsOptionWithArgument(argc, argv);
+
+    argv++; --argc;
+    if (IsLauncherOption(arg)) {
+        if (has_arg) {
+            value = *argv;
+            argv++; --argc;
+        }
+        kind = IsLauncherMainOption(arg) ? LAUNCHER_MAIN_OPTION
+                                         : LAUNCHER_OPTION_WITH_ARGUMENT;
+    } else if (IsModuleOption(arg)) {
+        kind = VM_LONG_OPTION_WITH_ARGUMENT;
+        if (has_arg) {
+            value = *argv;
+            argv++; --argc;
+        }
+
+        /*
+         * Support short form alias
+         */
+        if (JLI_StrCmp(arg, "-p") == 0) {
+            option = "--module-path";
+        }
+
+    } else if (JLI_StrCCmp(arg, "--") == 0 && (equals = JLI_StrChr(arg, '=')) != NULL) {
+        value = equals+1;
+        if (JLI_StrCCmp(arg, "--list-modules=") == 0 ||
+            JLI_StrCCmp(arg, "--module=") == 0 ||
+            JLI_StrCCmp(arg, "--class-path=") == 0) {
+            kind = LAUNCHER_OPTION_WITH_ARGUMENT;
+        } else {
+            kind = VM_LONG_OPTION;
+        }
+    }
+
+#ifndef OLD_MODULE_OPTIONS
+    // for transition to support both old and new syntax
+    if (JLI_StrCmp(arg, "-modulepath") == 0 ||
+        JLI_StrCmp(arg, "-mp") == 0) {
+        option = "--module-path";
+    } else if (JLI_StrCmp(arg, "-upgrademodulepath") == 0) {
+        option = "--upgrade-module-path";
+    } else if (JLI_StrCmp(arg, "-addmods") == 0) {
+        option = "--add-modules";
+    } else if (JLI_StrCmp(arg, "-limitmods") == 0) {
+        option = "--limit-modules";
+    } else if (JLI_StrCCmp(arg, "-XaddExports:") == 0) {
+        option = "--add-exports";
+        value = arg + 13;
+        kind = VM_LONG_OPTION_WITH_ARGUMENT;
+    } else if (JLI_StrCCmp(arg, "-XaddReads:") == 0) {
+        option = "--add-reads";
+        value = arg + 11;
+        kind = VM_LONG_OPTION_WITH_ARGUMENT;
+    } else if (JLI_StrCCmp(arg, "-Xpatch:") == 0) {
+        option = "--patch-module";
+        value = arg + 8;
+        kind = VM_LONG_OPTION_WITH_ARGUMENT;
+    }
+#endif
+
+    *pargc = argc;
+    *pargv = argv;
+    *poption = option;
+    *pvalue = value;
+    return kind;
+}
+
+/*
  * Parses command line arguments.  Returns JNI_FALSE if launcher
  * should exit without starting vm, returns JNI_TRUE if vm needs
  * to be started to process given options.  *pret (the launcher
@@ -1158,52 +1276,85 @@
     *pret = 0;
 
     while ((arg = *argv) != 0 && *arg == '-') {
-        argv++; --argc;
-        if (JLI_StrCmp(arg, "-classpath") == 0 || JLI_StrCmp(arg, "-cp") == 0) {
-            ARG_CHECK (argc, ARG_ERROR1, arg);
-            SetClassPath(*argv);
+        char *option = NULL;
+        char *value = NULL;
+        int kind = GetOpt(&argc, &argv, &option, &value);
+        jboolean has_arg = value != NULL;
+
+/*
+ * Option to set main entry point
+ */
+        if (JLI_StrCmp(arg, "-jar") == 0) {
+            ARG_CHECK(argc, ARG_ERROR2, arg);
+            mode = LM_JAR;
+        } else if (JLI_StrCmp(arg, "--module") == 0 ||
+                   JLI_StrCCmp(arg, "--module=") == 0 ||
+                   JLI_StrCmp(arg, "-m") == 0) {
+            REPORT_ERROR (has_arg, ARG_ERROR5, arg);
+            SetMainModule(value);
+            mode = LM_MODULE;
+            if (has_arg) {
+               *pwhat = value;
+                break;
+            }
+        } else if (JLI_StrCmp(arg, "--class-path") == 0 ||
+                   JLI_StrCCmp(arg, "--class-path=") == 0 ||
+                   JLI_StrCmp(arg, "-classpath") == 0 ||
+                   JLI_StrCmp(arg, "-cp") == 0) {
+            REPORT_ERROR (has_arg, ARG_ERROR1, arg);
+            SetClassPath(value);
             mode = LM_CLASS;
-            argv++; --argc;
-        } else if (JLI_StrCmp(arg, "-modulepath") == 0 || JLI_StrCmp(arg, "-mp") == 0) {
-            ARG_CHECK (argc, ARG_ERROR4, arg);
-            SetModulePath(*argv);
-            argv++; --argc;
-        } else if (JLI_StrCmp(arg, "-upgrademodulepath") == 0) {
-            ARG_CHECK (argc, ARG_ERROR4, arg);
-            SetUpgradeModulePath(*argv);
-            argv++; --argc;
-        } else if (JLI_StrCmp(arg, "-jar") == 0) {
-            ARG_CHECK (argc, ARG_ERROR2, arg);
-            mode = LM_JAR;
-        } else if (JLI_StrCmp(arg, "-m") == 0) {
-            ARG_CHECK (argc, ARG_ERROR5, arg);
-            SetMainModule(*argv);
-            mode = LM_MODULE;
-        } else if (JLI_StrCmp(arg, "-addmods") == 0) {
-            ARG_CHECK (argc, ARG_ERROR6, arg);
-            SetAddModulesProp(*argv);
-            argv++; --argc;
-        } else if (JLI_StrCmp(arg, "-limitmods") == 0) {
-            ARG_CHECK (argc, ARG_ERROR6, arg);
-            SetLimitModulesProp(*argv);
-            argv++; --argc;
-        } else if (JLI_StrCmp(arg, "-listmods") == 0 ||
-                   JLI_StrCCmp(arg, "-listmods:") == 0) {
+        } else if (JLI_StrCmp(arg, "--list-modules") == 0 ||
+                   JLI_StrCCmp(arg, "--list-modules=") == 0) {
             listModules = arg;
+
+            // set listModules to --list-modules=<module-names> if argument is specified
+            if (JLI_StrCmp(arg, "--list-modules") == 0 && has_arg) {
+                static const char format[] = "%s=%s";
+                size_t buflen = JLI_StrLen(option) + 2 + JLI_StrLen(value);
+                listModules = JLI_MemAlloc(buflen);
+                JLI_Snprintf(listModules, buflen, format, option, value);
+            }
             return JNI_TRUE;
-        } else if (JLI_StrCCmp(arg, "-XaddReads:") == 0) {
-            static jint n;
-            char *value = arg + 11;
-            SetAddReadsProp(n++, value);
-        } else if (JLI_StrCCmp(arg, "-XaddExports:") == 0) {
-            static jint n;
-            char *value = arg + 13;
-            SetAddExportsProp(n++, value);
-        } else if (JLI_StrCCmp(arg, "-Xpatch:") == 0) {
-            static jint n;
-            char *value = arg + 8;
-            SetPatchProp(n++, value);
-        } else if (JLI_StrCmp(arg, "-help") == 0 ||
+/*
+ * Parse white-space options
+ */
+        } else if (has_arg) {
+            if (kind == VM_LONG_OPTION) {
+                AddOption(option, NULL);
+            } else if (kind == VM_LONG_OPTION_WITH_ARGUMENT) {
+                AddLongFormOption(option, value);
+            }
+/*
+ * Error missing argument
+ */
+        } else if (!has_arg && IsWhiteSpaceOption(arg)) {
+            if (JLI_StrCmp(arg, "--module-path") == 0 ||
+                JLI_StrCmp(arg, "-p") == 0 ||
+                JLI_StrCmp(arg, "--upgrade-module-path") == 0) {
+                REPORT_ERROR (has_arg, ARG_ERROR4, arg);
+            } else if (JLI_StrCmp(arg, "--add-modules") == 0 ||
+                       JLI_StrCmp(arg, "--limit-modules") == 0 ||
+                       JLI_StrCmp(arg, "--add-exports") == 0 ||
+                       JLI_StrCmp(arg, "--add-reads") == 0 ||
+                       JLI_StrCmp(arg, "--patch-module") == 0) {
+                REPORT_ERROR (has_arg, ARG_ERROR6, arg);
+            }
+#ifndef OLD_MODULE_OPTIONS
+            else if (JLI_StrCmp(arg, "-modulepath") == 0 ||
+                     JLI_StrCmp(arg, "-mp") == 0 ||
+                     JLI_StrCmp(arg, "-upgrademodulepath") == 0) {
+                REPORT_ERROR (has_arg, ARG_ERROR4, arg);
+            } else if (JLI_StrCmp(arg, "-addmods") == 0 ||
+                       JLI_StrCmp(arg, "-limitmods") == 0) {
+                REPORT_ERROR (has_arg, ARG_ERROR6, arg);
+            }
+#endif
+/*
+ * The following cases will cause the argument parsing to stop
+ */
+        } else if (JLI_StrCmp(arg, "--help") == 0 ||
+                   JLI_StrCmp(arg, "-help") == 0 ||
                    JLI_StrCmp(arg, "-h") == 0 ||
                    JLI_StrCmp(arg, "-?") == 0) {
             printUsage = JNI_TRUE;
@@ -1282,7 +1433,7 @@
         }
     }
 
-    if (--argc >= 0) {
+    if (*pwhat == NULL && --argc >= 0) {
         *pwhat = *argv++;
     }
 
@@ -1692,7 +1843,7 @@
 ListModules(JNIEnv *env, char *optString)
 {
     jmethodID listModulesID;
-    jstring joptString;
+    jstring joptString = NULL;
     jclass cls = GetLauncherHelperClass(env);
     NULL_CHECK(cls);
     NULL_CHECK(listModulesID = (*env)->GetStaticMethodID(env, cls,
--- a/jdk/src/java.base/share/native/libjli/java.h	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/share/native/libjli/java.h	Wed Jul 05 22:05:22 2017 +0200
@@ -161,6 +161,7 @@
 jint ReadKnownVMs(const char *jvmcfg, jboolean speculative);
 char *CheckJvmType(int *argc, char ***argv, jboolean speculative);
 void AddOption(char *str, void *info);
+jboolean IsWhiteSpaceOption(const char* name);
 
 enum ergo_policy {
    DEFAULT_POLICY = 0,
--- a/jdk/src/java.base/windows/lib/security/default.policy	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.base/windows/lib/security/default.policy	Wed Jul 05 22:05:22 2017 +0200
@@ -11,5 +11,6 @@
                    "clearProviderProperties.SunMSCAPI";
     permission java.security.SecurityPermission
                    "removeProviderProperty.SunMSCAPI";
+    permission java.security.SecurityPermission "authProvider.SunMSCAPI";
     permission java.util.PropertyPermission "*", "read";
 };
--- a/jdk/src/java.desktop/unix/native/common/awt/systemscale/systemScale.h	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/common/awt/systemscale/systemScale.h	Wed Jul 05 22:05:22 2017 +0200
@@ -26,7 +26,7 @@
 #include <signal.h>
 #include <stdlib.h>
 
-double getNativeScaleFactor();
+double getNativeScaleFactor(char *output_name);
 
 #endif
 
--- a/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c	Wed Jul 05 22:05:22 2017 +0200
@@ -806,7 +806,7 @@
 #ifndef __linux__
     return JNI_FALSE;
 #endif
-    *scaleFactor = getNativeScaleFactor();
+    *scaleFactor = getNativeScaleFactor(NULL);
     if (*scaleFactor == 2.0) {
         size_t length = 0;
         char *stringToAppend = ".java-scale2x";
--- a/jdk/src/java.httpclient/share/classes/java/net/http/RawChannel.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/RawChannel.java	Wed Jul 05 22:05:22 2017 +0200
@@ -31,7 +31,7 @@
 /*
  * I/O abstraction used to implement WebSocket.
  */
-public interface RawChannel {
+interface RawChannel {
 
     interface RawEvent {
 
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java	Wed Jul 05 22:05:22 2017 +0200
@@ -235,8 +235,11 @@
      */
     public int getInitLifetime() throws GSSException {
         int retVal = 0;
-        retVal = (int)(getEndTime().getTime()
-                       - (new Date().getTime()));
+        Date d = getEndTime();
+        if (d == null) {
+            return 0;
+        }
+        retVal = (int)(d.getTime() - (new Date().getTime()));
 
         return retVal/1000;
     }
--- a/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardPermission.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardPermission.java	Wed Jul 05 22:05:22 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -118,7 +118,7 @@
     /**
      * @serial
      */
-    private volatile String actions;
+    private final String actions;
 
     /**
      * Constructs a new CardPermission with the specified actions.
@@ -143,10 +143,14 @@
             throw new NullPointerException();
         }
         mask = getMask(actions);
+        this.actions = getActions(mask);
     }
 
     private static int getMask(String actions) {
-        if ((actions == null) || (actions.length() == 0)) {
+        if (actions == null) {
+            return 0;
+        }
+        if (actions.length() == 0) {
             throw new IllegalArgumentException("actions must not be empty");
         }
 
@@ -177,6 +181,9 @@
     }
 
     private static String getActions(int mask) {
+        if (mask == 0) {
+            return null;
+        }
         if (mask == A_ALL) {
             return S_ALL;
         }
@@ -200,9 +207,6 @@
      * @return the canonical string representation of the actions.
      */
     public String getActions() {
-        if (actions == null) {
-            actions = getActions(mask);
-        }
         return actions;
     }
 
@@ -278,10 +282,6 @@
 
     private void writeObject(ObjectOutputStream s) throws IOException {
         // Write out the actions. The superclass takes care of the name.
-        // Call getActions to make sure actions field is initialized
-        if (actions == null) {
-            getActions();
-        }
         s.defaultWriteObject();
     }
 
@@ -291,5 +291,4 @@
         s.defaultReadObject();
         mask = getMask(actions);
     }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/FingerPrint.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.jar;
+
+import jdk.internal.org.objectweb.asm.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A FingerPrint is an abstract representation of a JarFile entry that contains
+ * information to determine if the entry represents a class or a
+ * resource, and whether two entries are identical.  If the FingerPrint represents
+ * a class, it also contains information to (1) describe the public API;
+ * (2) compare the public API of this class with another class;  (3) determine
+ * whether or not it's a nested class and, if so, the name of the associated
+ * top level class; and (4) for an canonically ordered set of classes determine
+ * if the class versions are compatible.  A set of classes is canonically
+ * ordered if the classes in the set have the same name, and the base class
+ * precedes the versioned classes and if each versioned class with version
+ * {@code n} precedes classes with versions {@code > n} for all versions
+ * {@code n}.
+ */
+final class FingerPrint {
+    private static final MessageDigest MD;
+
+    private final byte[] sha1;
+    private final ClassAttributes attrs;
+    private final boolean isClassEntry;
+    private final String entryName;
+
+    static {
+        try {
+            MD = MessageDigest.getInstance("SHA-1");
+        } catch (NoSuchAlgorithmException x) {
+            // log big problem?
+            throw new RuntimeException(x);
+        }
+    }
+
+    public FingerPrint(String entryName,byte[] bytes) throws IOException {
+        this.entryName = entryName;
+        if (entryName.endsWith(".class") && isCafeBabe(bytes)) {
+            isClassEntry = true;
+            sha1 = sha1(bytes, 8);  // skip magic number and major/minor version
+            attrs = getClassAttributes(bytes);
+        } else {
+            isClassEntry = false;
+            sha1 = sha1(bytes);
+            attrs = new ClassAttributes();   // empty class
+        }
+    }
+
+    public boolean isClass() {
+        return isClassEntry;
+    }
+
+    public boolean isNestedClass() {
+        return attrs.nestedClass;
+    }
+
+    public boolean isPublicClass() {
+        return attrs.publicClass;
+    }
+
+    public boolean isIdentical(FingerPrint that) {
+        if (that == null) return false;
+        if (this == that) return true;
+        return isEqual(this.sha1, that.sha1);
+    }
+
+    public boolean isCompatibleVersion(FingerPrint that) {
+        return attrs.version >= that.attrs.version;
+    }
+
+    public boolean isSameAPI(FingerPrint that) {
+        if (that == null) return false;
+        return attrs.equals(that.attrs);
+    }
+
+    public String name() {
+        String name = attrs.name;
+        return name == null ? entryName : name;
+    }
+
+    public String topLevelName() {
+        String name = attrs.topLevelName;
+        return name == null ? name() : name;
+    }
+
+    private byte[] sha1(byte[] entry) {
+        MD.update(entry);
+        return MD.digest();
+    }
+
+    private byte[] sha1(byte[] entry, int offset) {
+        MD.update(entry, offset, entry.length - offset);
+        return MD.digest();
+    }
+
+    private boolean isEqual(byte[] sha1_1, byte[] sha1_2) {
+        return MessageDigest.isEqual(sha1_1, sha1_2);
+    }
+
+    private static final byte[] cafeBabe = {(byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe};
+
+    private boolean isCafeBabe(byte[] bytes) {
+        if (bytes.length < 4) return false;
+        for (int i = 0; i < 4; i++) {
+            if (bytes[i] != cafeBabe[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private ClassAttributes getClassAttributes(byte[] bytes) {
+        ClassReader rdr = new ClassReader(bytes);
+        ClassAttributes attrs = new ClassAttributes();
+        rdr.accept(attrs, 0);
+        return attrs;
+    }
+
+    private static final class Field {
+        private final int access;
+        private final String name;
+        private final String desc;
+
+        Field(int access, String name, String desc) {
+            this.access = access;
+            this.name = name;
+            this.desc = desc;
+        }
+
+        @Override
+        public boolean equals(Object that) {
+            if (that == null) return false;
+            if (this == that) return true;
+            if (!(that instanceof Field)) return false;
+            Field field = (Field)that;
+            return (access == field.access) && name.equals(field.name)
+                    && desc.equals(field.desc);
+        }
+
+        @Override
+        public int hashCode() {
+            int result = 17;
+            result = 37 * result + access;
+            result = 37 * result + name.hashCode();
+            result = 37 * result + desc.hashCode();
+            return result;
+        }
+    }
+
+    private static final class Method {
+        private final int access;
+        private final String name;
+        private final String desc;
+        private final Set<String> exceptions;
+
+        Method(int access, String name, String desc, Set<String> exceptions) {
+            this.access = access;
+            this.name = name;
+            this.desc = desc;
+            this.exceptions = exceptions;
+        }
+
+        @Override
+        public boolean equals(Object that) {
+            if (that == null) return false;
+            if (this == that) return true;
+            if (!(that instanceof Method)) return false;
+            Method method = (Method)that;
+            return (access == method.access) && name.equals(method.name)
+                    && desc.equals(method.desc)
+                    && exceptions.equals(method.exceptions);
+        }
+
+        @Override
+        public int hashCode() {
+            int result = 17;
+            result = 37 * result + access;
+            result = 37 * result + name.hashCode();
+            result = 37 * result + desc.hashCode();
+            result = 37 * result + exceptions.hashCode();
+            return result;
+        }
+    }
+
+    private static final class ClassAttributes extends ClassVisitor {
+        private String name;
+        private String topLevelName;
+        private String superName;
+        private int version;
+        private int access;
+        private boolean publicClass;
+        private boolean nestedClass;
+        private final Set<Field> fields = new HashSet<>();
+        private final Set<Method> methods = new HashSet<>();
+
+        public ClassAttributes() {
+            super(Opcodes.ASM5);
+        }
+
+        private boolean isPublic(int access) {
+            return ((access & Opcodes.ACC_PUBLIC) == Opcodes.ACC_PUBLIC)
+                    || ((access & Opcodes.ACC_PROTECTED) == Opcodes.ACC_PROTECTED);
+        }
+
+        @Override
+        public void visit(int version, int access, String name, String signature,
+                          String superName, String[] interfaces) {
+            this.version = version;
+            this.access = access;
+            this.name = name;
+            this.nestedClass = name.contains("$");
+            this.superName = superName;
+            this.publicClass = isPublic(access);
+        }
+
+        @Override
+        public void visitOuterClass(String owner, String name, String desc) {
+            if (!this.nestedClass) return;
+            this.topLevelName = owner;
+        }
+
+        @Override
+        public void visitInnerClass(String name, String outerName, String innerName,
+                                    int access) {
+            if (!this.nestedClass) return;
+            if (outerName == null) return;
+            if (!this.name.equals(name)) return;
+            if (this.topLevelName == null) this.topLevelName = outerName;
+        }
+
+        @Override
+        public FieldVisitor visitField(int access, String name, String desc,
+                                       String signature, Object value) {
+            if (isPublic(access)) {
+                fields.add(new Field(access, name, desc));
+            }
+            return null;
+        }
+
+        @Override
+        public MethodVisitor visitMethod(int access, String name, String desc,
+                                         String signature, String[] exceptions) {
+            if (isPublic(access)) {
+                Set<String> exceptionSet = new HashSet<>();
+                if (exceptions != null) {
+                    for (String e : exceptions) {
+                        exceptionSet.add(e);
+                    }
+                }
+                // treat type descriptor as a proxy for signature because signature
+                // is usually null, need to strip off the return type though
+                int n;
+                if (desc != null && (n = desc.lastIndexOf(')')) != -1) {
+                    desc = desc.substring(0, n + 1);
+                    methods.add(new Method(access, name, desc, exceptionSet));
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public void visitEnd() {
+            this.nestedClass = this.topLevelName != null;
+        }
+
+        @Override
+        public boolean equals(Object that) {
+            if (that == null) return false;
+            if (this == that) return true;
+            if (!(that instanceof ClassAttributes)) return false;
+            ClassAttributes clsAttrs = (ClassAttributes)that;
+            boolean superNameOkay = superName != null
+                    ? superName.equals(clsAttrs.superName) : true;
+            return access == clsAttrs.access
+                    && superNameOkay
+                    && fields.equals(clsAttrs.fields)
+                    && methods.equals(clsAttrs.methods);
+        }
+
+        @Override
+        public int hashCode() {
+            int result = 17;
+            result = 37 * result + access;
+            result = 37 * result + superName != null ? superName.hashCode() : 0;
+            result = 37 * result + fields.hashCode();
+            result = 37 * result + methods.hashCode();
+            return result;
+        }
+    }
+}
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java	Wed Jul 05 22:05:22 2017 +0200
@@ -91,7 +91,7 @@
                     tool.xflag = true;
                 }
             },
-            new Option(false, OptionType.MAIN_OPERATION, "--print-module-descriptor", "-p") {
+            new Option(false, OptionType.MAIN_OPERATION, "--print-module-descriptor", "-d") {
                 void process(Main tool, String opt, String arg) throws BadArgs {
                     if (tool.cflag || tool.iflag  || tool.tflag || tool.uflag || tool.xflag)
                         throw new BadArgs("error.multiple.main.operations").showUsage(true);
@@ -145,7 +145,7 @@
                     }
                 }
             },
-            new Option(true, OptionType.CREATE_UPDATE, "--modulepath", "--mp") {
+            new Option(true, OptionType.CREATE_UPDATE, "--module-path", "-p") {
                 void process(Main jartool, String opt, String arg) {
                     String[] dirs = arg.split(File.pathSeparator);
                     Path[] paths = new Path[dirs.length];
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java	Mon Aug 15 08:28:26 2016 +0200
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java	Wed Jul 05 22:05:22 2017 +0200
@@ -42,6 +42,7 @@
 import java.nio.file.Path;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
 import java.util.*;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -278,23 +279,20 @@
                     }
                 }
             }
+
             if (cflag) {
                 Manifest manifest = null;
-                InputStream in = null;
-
                 if (!Mflag) {
                     if (mname != null) {
-                        in = new FileInputStream(mname);
-                        manifest = new Manifest(new BufferedInputStream(in));
+                        try (InputStream in = new FileInputStream(mname)) {
+                            manifest = new Manifest(new BufferedInputStream(in));
+                        }
                     } else {
                         manifest = new Manifest();
                     }
                     addVersion(manifest);
                     addCreatedBy(manifest);
                     if (isAmbiguousMainClass(manifest)) {
-                        if (in != null) {
-                            in.close();
-                        }
                         return false;
                     }
                     if (ename != null) {
@@ -304,11 +302,13 @@
                         addMultiRelease(manifest);
                     }
                 }
+
                 Map<String,Path> moduleInfoPaths = new HashMap<>();
                 for (int version : filesMap.keySet()) {
                     String[] files = filesMap.get(version);
                     expand(null, files, false, moduleInfoPaths, version);
                 }
+
                 Map<String,byte[]> moduleInfos = new LinkedHashMap<>();
                 if (!moduleInfoPaths.isEmpty()) {
                     if (!checkModuleInfos(moduleInfoPaths))
@@ -332,84 +332,61 @@
                     return false;
                 }
 
-                OutputStream out;
-                if (fname != null) {
-                    out = new FileOutputStream(fname);
-                } else {
-                    out = new FileOutputStream(FileDescriptor.out);
-                    if (vflag) {
-                        // Disable verbose output so that it does not appear
-                        // on stdout along with file data
-                        // error("Warning: -v option ignored");
-                        vflag = false;
-                    }
+                if (vflag && fname == null) {
+                    // Disable verbose output so that it does not appear
+                    // on stdout along with file data
+                    // error("Warning: -v option ignored");
+                    vflag = false;
                 }
-                File tmpfile = null;
-                final OutputStream finalout = out;
+
                 final String tmpbase = (fname == null)
                         ? "tmpjar"
                         : fname.substring(fname.indexOf(File.separatorChar) + 1);
+                File tmpfile = createTemporaryFile(tmpbase, ".jar");
+
+                try (OutputStream out = new FileOutputStream(tmpfile)) {
+                    create(new BufferedOutputStream(out, 4096), manifest, moduleInfos);
+                }
+
                 if (nflag) {
-                    tmpfile = createTemporaryFile(tmpbase, ".jar");
-                    out = new FileOutputStream(tmpfile);
-                }
-                create(new BufferedOutputStream(out, 4096), manifest, moduleInfos);
-
-                if (in != null) {
-                    in.close();
-                }
-                out.close();
-                if (nflag) {
-                    JarFile jarFile = null;
-                    File packFile = null;
-                    JarOutputStream jos = null;
+                    File packFile = createTemporaryFile(tmpbase, ".pack");
                     try {
                         Packer packer = Pack200.newPacker();
                         Map<String, String> p = packer.properties();
                         p.put(Packer.EFFORT, "1"); // Minimal effort to conserve CPU
-                        jarFile = new JarFile(tmpfile.getCanonicalPath());
-                        packFile = createTemporaryFile(tmpbase, ".pack");
-                        out = new FileOutputStream(packFile);
-                        packer.pack(jarFile, out);
-                        jos = new JarOutputStream(finalout);
-                        Unpacker unpacker = Pack200.newUnpacker();
-                        unpacker.unpack(packFile, jos);
-                    } catch (IOException ioe) {
-                        fatalError(ioe);
-                    } finally {
-                        if (jarFile != null) {
-                            jarFile.close();
+                        try (
+                                JarFile jarFile = new JarFile(tmpfile.getCanonicalPath());
+                                OutputStream pack = new FileOutputStream(packFile)
+                        ) {
+                            packer.pack(jarFile, pack);
                         }
-                        if (out != null) {
-                            out.close();
-                        }
-                        if (jos != null) {
-                            jos.close();
-                        }
-                        if (tmpfile != null && tmpfile.exists()) {
+                        if (tmpfile.exists()) {
                             tmpfile.delete();
                         }
-                        if (packFile != null && packFile.exists()) {
-                            packFile.delete();
+                        tmpfile = createTemporaryFile(tmpbase, ".jar");
+                        try (
+                                OutputStream out = new FileOutputStream(tmpfile);
+                                JarOutputStream jos = new JarOutputStream(out)
+                        ) {
+                            Unpacker unpacker = Pack200.newUnpacker();
+                            unpacker.unpack(packFile, jos);
                         }
+                    } finally {
+                        Files.deleteIfExists(packFile.toPath());
                     }
                 }
+
+                validateAndClose(tmpfile);
+
             } else if (uflag) {
                 File inputFile = null, tmpFile = null;
-                FileInputStream in;
-                FileOutputStream out;
                 if (fname != null) {
                     inputFile = new File(fname);
                     tmpFile = createTempFileInSameDirectoryAs(inputFile);
-                    in = new FileInputStream(inputFile);
-                    out = new FileOutputStream(tmpFile);
                 } else {
-                    in = new FileInputStream(FileDescriptor.in);
-                    out = new FileOutputStream(FileDescriptor.out);
                     vflag = false;
+                    tmpFile = createTemporaryFile("tmpjar", ".jar");
                 }
-                InputStream manifest = (!Mflag && (mname != null)) ?
-                    (new FileInputStream(mname)) : null;
 
                 Map<String,Path> moduleInfoPaths = new HashMap<>();
                 for (int version : filesMap.keySet()) {
@@ -421,8 +398,19 @@
                 for (Map.Entry<String,Path> e : moduleInfoPaths.entrySet())
                     moduleInfos.put(e.getKey(), readModuleInfo(e.getValue()));
 
-                boolean updateOk = update(in, new BufferedOutputStream(out),
-                                          manifest, moduleInfos, null);
+                try (
+                        FileInputStream in = (fname != null) ? new FileInputStream(inputFile)
+                                : new FileInputStream(FileDescriptor.in);
+                        FileOutputStream out = new FileOutputStream(tmpFile);
+                        InputStream manifest = (!Mflag && (mname != null)) ?
+                                (new FileInputStream(mname)) : null;
+                ) {
+                        boolean updateOk = update(in, new BufferedOutputStream(out),
+                                manifest, moduleInfos, null);
+                        if (ok) {
+                            ok = updateOk;
+                        }
+                }
 
                 // Consistency checks for modular jars.
                 if (!moduleInfos.isEmpty()) {
@@ -430,23 +418,8 @@
                         return false;
                 }
 
-                if (ok) {
-                    ok = updateOk;
-                }
-                in.close();
-                out.close();
-                if (manifest != null) {
-                    manifest.close();
-                }
-                if (ok && fname != null) {
-                    // on Win32, we need this delete
-                    inputFile.delete();
-                    if (!tmpFile.renameTo(inputFile)) {
-                        tmpFile.delete();
-                        throw new IOException(getMsg("error.write.file"));
-                    }
-                    tmpFile.delete();
-                }
+                validateAndClose(tmpFile);
+
             } else if (tflag) {
                 replaceFSC(filesMap);
                 // For the "list table contents" action, access using the
@@ -520,6 +493,28 @@
         return ok;
     }
 
+    private void validateAndClose(File tmpfile) throws IOException {
+        if (ok && isMultiRelease) {
+            ok = validate(tmpfile.getCanonicalPath());
+            if (!ok) {
+                error(formatMsg("error.validator.jarfile.invalid", fname));
+            }
+        }
+
+        Path path = tmpfile.toPath();
+        try {
+            if (ok) {
+                if (fname != null) {
+                    Files.move(path, Paths.get(fname), StandardCopyOption.REPLACE_EXISTING);
+                } else {
+                    Files.copy(path, new FileOutputStream(FileDescriptor.out));
+                }
+            }
+        } finally {
+            Files.deleteIfExists(path);
+        }
+    }
+
     private String[] filesMapToFiles(Map<Integer,String[]> filesMap) {
         if (filesMap.isEmpty()) return null;
         return filesMap.entrySet()
@@ -534,6 +529,76 @@
                 .map(f -> (new EntryName(f, version)).entryName);
     }
 
+    // sort base entries before versioned entries, and sort entry classes with
+    // nested classes so that the top level class appears before the associated
+    // nested class
+    private Comparator<JarEntry> entryComparator = (je1, je2) ->  {
+        String s1 = je1.getName();
+        String s2 = je2.getName();
+        if (s1.equals(s2)) return 0;
+        boolean b1 = s1.startsWith(VERSIONS_DIR);
+        boolean b2 = s2.startsWith(VERSIONS_DIR);
+        if (b1 && !b2) return 1;
+        if (!b1 && b2) return -1;
+        int n = 0; // starting char for String compare
+        if (b1 && b2) {
+            // normally strings would be sorted so "10" goes before "9", but
+            // version number strings need to be sorted numerically
+            n = VERSIONS_DIR.length();   // skip the common prefix
+            int i1 = s1.indexOf('/', n);
+            int i2 = s1.indexOf('/', n);
+            if (i1 == -1) throw new InvalidJarException(s1);
+            if (i2 == -1) throw new InvalidJarException(s2);
+            // shorter version numbers go first
+            if (i1 != i2) return i1 - i2;
+            // otherwise, handle equal length numbers below
+        }
+        int l1 = s1.length();
+        int l2 = s2.length();
+        int lim = Math.min(l1, l2);
+        for (int k = n; k < lim; k++) {
+            char c1 = s1.charAt(k);
+            char c2 = s2.charAt(k);
+            if (c1 != c2) {
+                // change natural ordering so '.' comes before '$'
+                // i.e. top level classes come before nested classes
+                if (c1 == '$' && c2 == '.') return 1;
+                if (c1 == '.' && c2 == '$') return -1;
+                return c1 - c2;
+            }
+        }
+        return l1 - l2;
+    };
+
+    private boolean validate(String fname) {
+        boolean valid;
+
+        try (JarFile jf = new JarFile(fname)) {
+            Validator validator = new Validator(this, jf);
+            jf.stream()
+                    .filter(e -> !e.isDirectory())
+                    .filter(e -> !e.getName().equals(MANIFEST_NAME))
+                    .filter(e -> !e.getName().endsWith(MODULE_INFO))
+                    .sorted(entryComparator)
+                    .forEachOrdered(validator);
+             valid = validator.isValid();
+        } catch (IOException e) {
+            error(formatMsg2("error.validator.jarfile.exception", fname, e.getMessage()));
+            valid = false;
+        } catch (InvalidJarException e) {
+            error(formatMsg("error.validator.bad.entry.name", e.getMessage()));
+            valid = false;
+        }
+        return valid;
+    }
+
+    private static class InvalidJarException extends RuntimeException {
+        private static final long serialVersionUID = -3642329147299217726L;
+        InvalidJarException(String msg) {
+            super(msg);
+        }
+    }
+
     /**
      * Parses command line arguments.
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java	Wed Jul 05 22:05:22 2017 +0200
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.jar;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+final class Validator implements Consumer<JarEntry> {
+    private final static boolean DEBUG = Boolean.getBoolean("jar.debug");
+    private final  Map<String,FingerPrint> fps = new HashMap<>();
+    private final int vdlen = Main.VERSIONS_DIR.length();
+    private final Main main;
+    private final JarFile jf;
+    private int oldVersion = -1;
+    private String currentTopLevelName;
+    private boolean isValid = true;
+
+    Validator(Main main, JarFile jf) {
+        this.main = main;
+        this.jf = jf;
+    }
+