changeset 17033:2f72d8d137d8

Merge
author prr
date Mon, 17 Apr 2017 08:37:15 -0700
parents 61ea362c37f3 d57893482534
children a1a3ef8fd66f
files test/java/net/MulticastSocket/JoinGroup.java test/java/net/MulticastSocket/Leave.java
diffstat 48 files changed, 2776 insertions(+), 355 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/linux/native/libnio/ch/EPoll.c	Fri Apr 14 16:51:31 2017 +0300
+++ b/src/java.base/linux/native/libnio/ch/EPoll.c	Mon Apr 17 08:37:15 2017 -0700
@@ -95,9 +95,3 @@
     }
     return res;
 }
-
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_EPoll_close0(JNIEnv *env, jclass c, jint epfd) {
-    int res;
-    RESTARTABLE(close(epfd), res);
-}
--- a/src/java.base/share/classes/java/lang/System.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/src/java.base/share/classes/java/lang/System.java	Mon Apr 17 08:37:15 2017 -0700
@@ -1764,6 +1764,7 @@
      * @since   1.1
      */
     @Deprecated(since="1.2", forRemoval=true)
+    @SuppressWarnings("removal")
     public static void runFinalizersOnExit(boolean value) {
         Runtime.runFinalizersOnExit(value);
     }
--- a/src/java.desktop/share/classes/sun/applet/AppletSecurity.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/src/java.desktop/share/classes/sun/applet/AppletSecurity.java	Mon Apr 17 08:37:15 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2017, 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
@@ -109,7 +109,8 @@
     /**
      * get the current (first) instance of an AppletClassLoader on the stack.
      */
-    @SuppressWarnings("deprecation")
+    @SuppressWarnings({"deprecation",
+                       "removal"}) // SecurityManager.currentClassLoader()
     private AppletClassLoader currentAppletClassLoader()
     {
         // try currentClassLoader first
@@ -298,7 +299,8 @@
      * @exception  SecurityException  if the caller does not have
      *             permission to access the AWT event queue.
      */
-    @SuppressWarnings("deprecation")
+    @SuppressWarnings({"deprecation",
+                       "removal"}) //  SecurityManager.checkAwtEventQueueAccess
     public void checkAwtEventQueueAccess() {
         AppContext appContext = AppContext.getAppContext();
         AppletClassLoader appletClassLoader = currentAppletClassLoader();
--- a/src/java.se.ee/share/classes/module-info.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/src/java.se.ee/share/classes/module-info.java	Mon Apr 17 08:37:15 2017 -0700
@@ -32,7 +32,8 @@
  * @moduleGraph
  * @since 9
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // java.corba and other modules
 module java.se.ee {
 
     requires transitive java.se;
--- a/src/jdk.internal.jvmstat/share/classes/module-info.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/src/jdk.internal.jvmstat/share/classes/module-info.java	Mon Apr 17 08:37:15 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -23,6 +23,12 @@
  * questions.
  */
 
+/**
+ * Defines an internal API for monitoring a HotSpot Java Virtual Machine using
+ * its shared memory instrumentation buffer
+ *
+ * @since 9
+ */
 module jdk.internal.jvmstat {
     exports sun.jvmstat.monitor to
         jdk.attach,
--- a/src/jdk.policytool/share/classes/sun/security/tools/policytool/PolicyTool.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/src/jdk.policytool/share/classes/sun/security/tools/policytool/PolicyTool.java	Mon Apr 17 08:37:15 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -71,6 +71,7 @@
  */
 
 @Deprecated(since="9", forRemoval=true)
+@SuppressWarnings("removal")
 public class PolicyTool {
 
     // for i18n
@@ -879,7 +880,8 @@
  * The Permission contains the (Type, Name, Action) triplet.
  *
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class PolicyEntry {
 
     private CodeSource codesource;
@@ -1019,7 +1021,8 @@
 /**
  * The main window for the PolicyTool
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class ToolWindow extends JFrame {
     // use serialVersionUID from JDK 1.2.2 for interoperability
     private static final long serialVersionUID = 5682568601210376777L;
@@ -1553,7 +1556,8 @@
 /**
  * General dialog window
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class ToolDialog extends JDialog {
     // use serialVersionUID from JDK 1.2.2 for interoperability
     private static final long serialVersionUID = -372244357011301190L;
@@ -2917,7 +2921,8 @@
 /**
  * Event handler for the PolicyTool window
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class ToolWindowListener implements WindowListener {
 
     private PolicyTool tool;
@@ -2962,7 +2967,8 @@
 /**
  * Event handler for the Policy List
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class PolicyListListener extends MouseAdapter implements ActionListener {
 
     private PolicyTool tool;
@@ -2992,7 +2998,8 @@
 /**
  * Event handler for the File Menu
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class FileMenuListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3091,7 +3098,8 @@
 /**
  * Event handler for the main window buttons and Edit Menu
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class MainWindowListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3167,7 +3175,8 @@
  *    if edit is FALSE, then we are ADDing a new PolicyEntry,
  *    so we only need to update the GUI listing.
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class AddEntryDoneButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3234,7 +3243,8 @@
 /**
  * Event handler for ChangeKeyStoreOKButton button
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class ChangeKeyStoreOKButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3281,7 +3291,8 @@
 /**
  * Event handler for AddPrinButton button
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class AddPrinButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3307,7 +3318,8 @@
 /**
  * Event handler for AddPermButton button
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class AddPermButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3333,7 +3345,8 @@
 /**
  * Event handler for AddPrinOKButton button
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class NewPolicyPrinOKButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3397,7 +3410,8 @@
 /**
  * Event handler for AddPermOKButton button
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class NewPolicyPermOKButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3461,7 +3475,8 @@
 /**
  * Event handler for RemovePrinButton button
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class RemovePrinButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3497,7 +3512,8 @@
 /**
  * Event handler for RemovePermButton button
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class RemovePermButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -3540,7 +3556,8 @@
  * GUI listing.  If the user is editing an existing PolicyEntry, we
  * update both the GUI listing and the actual PolicyEntry.
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class EditPrinButtonListener extends MouseAdapter implements ActionListener {
 
     private PolicyTool tool;
@@ -3587,7 +3604,8 @@
  * GUI listing.  If the user is editing an existing PolicyEntry, we
  * update both the GUI listing and the actual PolicyEntry.
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class EditPermButtonListener extends MouseAdapter implements ActionListener {
 
     private PolicyTool tool;
@@ -3628,7 +3646,8 @@
 /**
  * Event handler for Principal Popup Menu
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class PrincipalTypeMenuListener implements ItemListener {
 
     private ToolDialog td;
@@ -3680,7 +3699,8 @@
 /**
  * Event handler for Permission Popup Menu
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class PermissionMenuListener implements ItemListener {
 
     private ToolDialog td;
@@ -3755,7 +3775,8 @@
 /**
  * Event handler for Permission Name Popup Menu
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class PermissionNameMenuListener implements ItemListener {
 
     private ToolDialog td;
@@ -3909,7 +3930,8 @@
 /**
  * Event handler for UserSaveYes button
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class UserSaveYesButtonListener implements ActionListener {
 
     private ToolDialog us;
@@ -3964,7 +3986,8 @@
 /**
  * Event handler for UserSaveNoButton
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class UserSaveNoButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -4013,7 +4036,8 @@
 /**
  * Event handler for ConfirmRemovePolicyEntryOKButtonListener
  */
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class ConfirmRemovePolicyEntryOKButtonListener implements ActionListener {
 
     private PolicyTool tool;
@@ -4169,7 +4193,8 @@
     }
 }
 
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class AuthPerm extends Perm {
     AuthPerm() {
         super(javax.security.auth.AuthPermission.class,
@@ -4242,7 +4267,8 @@
     }
 }
 
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class URLPerm extends Perm {
     URLPerm() {
         super(java.net.URLPermission.class,
@@ -4407,7 +4433,8 @@
     }
 }
 
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class RuntimePerm extends Perm {
     RuntimePerm() {
         super(java.lang.RuntimePermission.class,
@@ -4448,7 +4475,8 @@
     }
 }
 
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation",
+                   "removal"}) // PolicyTool
 class SecurityPerm extends Perm {
     SecurityPerm() {
         super(java.security.SecurityPermission.class,
--- a/src/jdk.security.auth/share/classes/com/sun/security/auth/module/SolarisLoginModule.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/src/jdk.security.auth/share/classes/com/sun/security/auth/module/SolarisLoginModule.java	Mon Apr 17 08:37:15 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -66,6 +66,7 @@
     private boolean debug = true;
 
     // SolarisSystem to retrieve underlying system info
+    @SuppressWarnings("removal")
     private SolarisSystem ss;
 
     // the authentication status
@@ -73,9 +74,13 @@
     private boolean commitSucceeded = false;
 
     // Underlying system info
+    @SuppressWarnings("removal")
     private SolarisPrincipal userPrincipal;
+    @SuppressWarnings("removal")
     private SolarisNumericUserPrincipal UIDPrincipal;
+    @SuppressWarnings("removal")
     private SolarisNumericGroupPrincipal GIDPrincipal;
+    @SuppressWarnings("removal")
     private LinkedList<SolarisNumericGroupPrincipal> supplementaryGroups =
                 new LinkedList<>();
 
@@ -121,6 +126,7 @@
      * @return true in all cases (this {@code LoginModule}
      *          should not be ignored).
      */
+    @SuppressWarnings("removal")
     public boolean login() throws LoginException {
 
         long[] solarisGroups = null;
@@ -234,6 +240,7 @@
      * @return false if this LoginModule's own login and/or commit attempts
      *          failed, and true otherwise.
      */
+    @SuppressWarnings("removal")
     public boolean abort() throws LoginException {
         if (debug) {
             System.out.println("\t\t[SolarisLoginModule]: " +
@@ -271,6 +278,7 @@
      * @return true in all cases (this {@code LoginModule}
      *          should not be ignored).
      */
+    @SuppressWarnings("removal")
     public boolean logout() throws LoginException {
         if (debug) {
             System.out.println("\t\t[SolarisLoginModule]: " +
--- a/src/jdk.unsupported/share/classes/sun/reflect/Reflection.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/src/jdk.unsupported/share/classes/sun/reflect/Reflection.java	Mon Apr 17 08:37:15 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -35,6 +35,7 @@
      * with {@link StackWalker.StackFrame#getDeclaringClass} instead.
      */
     @Deprecated(forRemoval=true)
+    @SuppressWarnings("removal") // Reflection.getCallerClass
     public static Class<?> getCallerClass(int depth) {
         if (depth < 0)
             throw new InternalError("depth must be positive");
--- a/test/ProblemList.txt	Fri Apr 14 16:51:31 2017 +0300
+++ b/test/ProblemList.txt	Mon Apr 17 08:37:15 2017 -0700
@@ -124,6 +124,7 @@
 # jdk_lang
 
 java/lang/StringCoding/CheckEncodings.sh                        7008363 generic-all
+java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java    8178776 generic-all
 
 jdk/internal/misc/JavaLangAccess/NewUnsafeString.java           8176188 generic-all
 
@@ -255,8 +256,7 @@
 tools/jimage/JImageListTest.java                                8170120 generic-all
 tools/jimage/JImageVerifyTest.java                              8170120 generic-all
 
-
-tools/jlink/multireleasejar/JLinkMultiReleaseJarTest.java       8169971 windows-x64
+tools/jimage/VerifyJimage.java                                  8178776 generic-all
 
 ############################################################################
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/Base.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+import jdk.testlibrary.JDKToolFinder;
+
+import static jdk.testlibrary.ProcessTools.executeCommand;
+
+/*
+ * Base class for tests.
+ * The tests focuse on that LoggerFinder works well in jigsaw environment,
+ * i.e. make sure correct Logger can be retrieved,
+ * also verify that basic functionality of retrieved Logger's works well.
+ *
+ * Note: As the test will take long time, to avoid timeout,
+ * split it as several tests, this class is the base class for tests.
+ */
+public class Base {
+    protected static final String JAVA_HOME = System.getProperty("java.home");
+    protected static final Path JDK_IMAGE = Paths.get(JAVA_HOME);
+    protected static final Path JMODS = Paths.get(JAVA_HOME, "jmods");
+
+    protected static final String TEST_SRC = System.getProperty("test.src");
+
+    // logger client to get logger from java.base module, it should get a lazy logger
+    // which wraps the underlying real logger implementation
+    protected static final Path SRC_PATCHED_USAGE =
+            Paths.get(TEST_SRC, "patched_usage", "java.base");
+    protected static final Path DEST_PATCHED_USAGE = Paths.get("patched_usage", "java.base");
+    protected static final Path SRC_PATCHED_CLIENT = Paths.get(TEST_SRC, "patched_client");
+    protected static final Path DEST_PATCHED_CLIENT = Paths.get("patched_client");
+
+    // logger client to get logger from bootclasspath/a, it should get a lazy logger
+    // which wraps the underlying real logger implementation
+    protected static final Path SRC_BOOT_USAGE = Paths.get(TEST_SRC, "boot_usage");
+    protected static final Path DEST_BOOT_USAGE = Paths.get("boot_usage");
+    protected static final Path SRC_BOOT_CLIENT = Paths.get(TEST_SRC, "boot_client");
+    protected static final Path DEST_BOOT_CLIENT = Paths.get("boot_client");
+
+    // logger provider in named module m.l.a
+    protected static final Path SRC_NAMED_LOGGER = Paths.get(TEST_SRC, "named_logger");
+    protected static final Path DEST_NAMED_LOGGER = Paths.get("mods_named_logger");
+
+    // logger provider in unnamed module
+    protected static final Path SRC_UNNAMED_LOGGER = Paths.get(TEST_SRC, "unnamed_logger");
+    protected static final Path DEST_UNNAMED_LOGGER = Paths.get("cp_unnamed_logger");
+    protected static final Path SRC_UNNAMED_LOGGER_SERVICE_FILE =
+            SRC_UNNAMED_LOGGER.resolve("META-INF/services/java.lang.System$LoggerFinder");
+    protected static final Path DEST_UNNAMED_LOGGER_SERVICE_DIR =
+            DEST_UNNAMED_LOGGER.resolve("META-INF/services");
+    protected static final Path DEST_UNNAMED_LOGGER_SERVICE_FILE =
+            DEST_UNNAMED_LOGGER.resolve("META-INF/services/java.lang.System$LoggerFinder");
+
+    // logger client in named module m.t.a
+    protected static final Path SRC_NAMED_CLIENT = Paths.get(TEST_SRC, "named_client");
+    protected static final Path DEST_NAMED_CLIENT = Paths.get("mods_named_client");
+
+    // logger client in unnamed module
+    protected static final Path SRC_UNNAMED_CLIENT = Paths.get(TEST_SRC, "unnamed_client");
+    protected static final Path DEST_UNNAMED_CLIENT = Paths.get("cp_unnamed_client");
+
+    // customized image with only module java.base
+    protected static final Path IMAGE = Paths.get("image");
+    // customized image with java.base and logger provider module m.l.a
+    protected static final Path IMAGE_LOGGER = Paths.get("image_logger");
+    // customized image with module java.base and logger client module m.t.a
+    protected static final Path IMAGE_CLIENT = Paths.get("image_client");
+    // customized image with module java.base, logger provider module m.l.a
+    // and logger client module m.t.a
+    protected static final Path IMAGE_CLIENT_LOGGER = Paths.get("image_all");
+
+    // lazy logger class which wraps the underlying real logger implementation
+    protected static final String LAZY_LOGGER =
+            "jdk.internal.logger.LazyLoggers$JdkLazyLogger";
+    // JUL logger class which wraps java.util.logging.Logger
+    protected static final String JUL_LOGGER =
+            "sun.util.logging.internal.LoggingProviderImpl$JULWrapper";
+    // default simple logger class when no logger provider can be found
+    protected static final String SIMPLE_LOGGER =
+            "jdk.internal.logger.SimpleConsoleLogger";
+    // logger class in named module m.l.a
+    protected static final String LOGGER_A = "pkg.a.l.LoggerA";
+    // logger class in unnamed module m.l.b
+    protected static final String LOGGER_B = "pkg.b.l.LoggerB";
+
+    // logger client in named module
+    protected static final String CLIENT_A = "m.t.a/pkg.a.t.TestA";
+    // logger client in unnamed module
+    protected static final String CLIENT_B = "pkg.b.t.TestB";
+    // logger client which gets logger through boot class BootUsage
+    protected static final String BOOT_CLIENT = "BootClient";
+    // logger client which gets logger through patched class
+    // java.base/java.lang.PatchedUsage
+    protected static final String PATCHED_CLIENT = "PatchedClient";
+
+    protected void setupAllClient() throws Throwable {
+        // compiles logger client which will get logger through patched
+        // class java.base/java.lang.PatchedUsage
+        compile(SRC_BOOT_USAGE, DEST_BOOT_USAGE);
+        compile(SRC_BOOT_CLIENT, DEST_BOOT_CLIENT,
+                "--class-path", DEST_BOOT_USAGE.toString());
+
+        // compiles logger client which will get logger through boot
+        // class BootUsage
+        compile(SRC_PATCHED_USAGE, DEST_PATCHED_USAGE,
+                "--patch-module", "java.base=" + SRC_PATCHED_USAGE.toString());
+        compile(SRC_PATCHED_CLIENT, DEST_PATCHED_CLIENT,
+                "--patch-module", "java.base=" + DEST_PATCHED_USAGE.toString());
+
+        // compiles logger client in unnamed module
+        compile(SRC_UNNAMED_CLIENT, DEST_UNNAMED_CLIENT,
+                "--source-path", SRC_UNNAMED_CLIENT.toString());
+
+        // compiles logger client in named module m.t.a
+        compile(SRC_NAMED_CLIENT, DEST_NAMED_CLIENT,
+                "--module-source-path", SRC_NAMED_CLIENT.toString());
+    }
+
+    protected void setupNamedLogger() throws Throwable {
+        // compiles logger provider in named module m.l.a
+        compile(SRC_NAMED_LOGGER, DEST_NAMED_LOGGER,
+                "--module-source-path", SRC_NAMED_LOGGER.toString());
+    }
+
+    protected void setupUnnamedLogger() throws Throwable {
+        // compiles logger provider in unnamed module
+        compile(SRC_UNNAMED_LOGGER, DEST_UNNAMED_LOGGER,
+                "--source-path", SRC_UNNAMED_LOGGER.toString());
+        Files.createDirectories(DEST_UNNAMED_LOGGER_SERVICE_DIR);
+        Files.copy(SRC_UNNAMED_LOGGER_SERVICE_FILE, DEST_UNNAMED_LOGGER_SERVICE_FILE,
+                   StandardCopyOption.REPLACE_EXISTING);
+    }
+
+    protected boolean checkJMODS() throws Throwable {
+        // if $JAVA_HOME/jmods does not exist, skip below steps
+        // as there is no way to build customized images by jlink
+        if (Files.notExists(JMODS)) {
+            System.err.println("Skip tests which require image");
+            return false;
+        }
+        return true;
+    }
+
+    protected void setupJavaBaseImage() throws Throwable {
+        if (!checkJMODS()) {
+            return;
+        }
+
+        // build image with just java.base module
+        String mpath = JMODS.toString();
+        execTool("jlink",
+                "--module-path", mpath,
+                "--add-modules", "java.base",
+                "--output", IMAGE.toString());
+    }
+
+    protected void setupLoggerImage() throws Throwable {
+        if (!checkJMODS()) {
+            return;
+        }
+
+        // build image with java.base + m.l.a modules
+        String mpath = DEST_NAMED_LOGGER.toString() + File.pathSeparator + JMODS.toString();
+        execTool("jlink",
+                "--module-path", mpath,
+                "--add-modules", "m.l.a",
+                "--output", IMAGE_LOGGER.toString());
+    }
+
+    protected void setupClientImage() throws Throwable {
+        if (!checkJMODS()) {
+            return;
+        }
+
+        // build image with java.base + m.t.a modules
+        String mpath = DEST_NAMED_CLIENT.toString() + File.pathSeparator + JMODS.toString();
+        execTool("jlink",
+                "--module-path", mpath,
+                "--add-modules", "m.t.a",
+                "--output", IMAGE_CLIENT.toString());
+    }
+
+    protected void setupFullImage() throws Throwable {
+        if (!checkJMODS()) {
+            return;
+        }
+
+        // build image with java.base + m.l.a + m.t.a modules
+        String mpath = DEST_NAMED_LOGGER.toString() + File.pathSeparator
+                + DEST_NAMED_CLIENT.toString() + File.pathSeparator + JMODS.toString();
+        execTool("jlink",
+                "--module-path", mpath,
+                "--add-modules", "m.l.a,m.t.a",
+                "--output", IMAGE_CLIENT_LOGGER.toString());
+
+    }
+
+    protected static void assertTrue(boolean b) {
+        if (!b) {
+            throw new RuntimeException("expected true, but get false.");
+        }
+    }
+
+    /*
+     * run test with supplied java image which could be jdk image or customized image
+     */
+    protected void runTest(Path image, String... opts) throws Throwable {
+        String[] options = Stream.concat(Stream.of(getJava(image)), Stream.of(opts))
+                                 .toArray(String[]::new);
+
+        ProcessBuilder pb = new ProcessBuilder(options);
+        int exitValue = executeCommand(pb).outputTo(System.out)
+                                          .errorTo(System.err)
+                                          .getExitValue();
+        assertTrue(exitValue == 0);
+    }
+
+    private void compile(Path src, Path dest, String... params) throws Throwable {
+        assertTrue(CompilerUtils.compile(src, dest, params));
+    }
+
+    private String getJava(Path image) {
+        boolean isWindows = System.getProperty("os.name").startsWith("Windows");
+        Path java = image.resolve("bin").resolve(isWindows ? "java.exe" : "java");
+        if (Files.notExists(java))
+            throw new RuntimeException(java + " not found");
+        return java.toAbsolutePath().toString();
+    }
+
+    private void execTool(String tool, String... args) throws Throwable {
+        String path = JDKToolFinder.getJDKTool(tool);
+        List<String> commands = new ArrayList<>();
+        commands.add(path);
+        Stream.of(args).forEach(commands::add);
+        ProcessBuilder pb = new ProcessBuilder(commands);
+
+        int exitValue = executeCommand(pb).outputTo(System.out)
+                                          .errorTo(System.out)
+                                          .shouldNotContain("no module is recorded in hash")
+                                          .getExitValue();
+        assertTrue(exitValue == 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/JDKLoggerForImageTest.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+import jdk.testlibrary.JDKToolFinder;
+
+import static jdk.testlibrary.ProcessTools.executeCommand;
+
+/*
+ * @test
+ * @modules jdk.compiler
+ * @summary Test cases which run against customized image, check the situation where
+ *            1. logger provider is the default one supplied by java.base,
+ *            2. clients are in named/unnamed module,
+ *               patched system module, or Xbootclasspath
+ *          This test does not require existence of java.logging module,
+ *          but require jdk.compiler module
+ * @library /lib/testlibrary
+ * @build Base CompilerUtils jdk.testlibrary.*
+ * @run main/othervm JDKLoggerForImageTest
+ */
+
+public class JDKLoggerForImageTest extends Base {
+
+    public static void main(String args[]) throws Throwable {
+        JDKLoggerForImageTest t = new JDKLoggerForImageTest();
+        t.setup();
+        t.test();
+    }
+
+    private void setup() throws Throwable {
+        setupAllClient();
+
+        setupJavaBaseImage();
+    }
+
+    private void test() throws Throwable {
+        if (!checkJMODS()) {
+            return;
+        }
+
+        // logger client is in named module m.t.a
+        runTest(IMAGE,
+                "--module-path", DEST_NAMED_CLIENT.toString(),
+                "-m", CLIENT_A, "system", SIMPLE_LOGGER);
+        // logger client is in unnamed module
+        runTest(IMAGE,
+                "--class-path", DEST_UNNAMED_CLIENT.toString(),
+                CLIENT_B, "system", SIMPLE_LOGGER);
+        // logger client gets logger through boot class BootUsage
+        runTest(IMAGE,
+                "-Xbootclasspath/a:" + DEST_BOOT_USAGE.toString(),
+                "--class-path", DEST_BOOT_CLIENT.toString(),
+                BOOT_CLIENT, "system", SIMPLE_LOGGER);
+        // logger client gets logger through patched class
+        // java.base/java.lang.PatchedUsage
+        runTest(IMAGE,
+                "--patch-module", "java.base=" + DEST_PATCHED_USAGE.toString(),
+                "--class-path", DEST_PATCHED_CLIENT.toString(),
+                PATCHED_CLIENT, "system", SIMPLE_LOGGER);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/JDKLoggerForJDKTest.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+import jdk.testlibrary.JDKToolFinder;
+
+import static jdk.testlibrary.ProcessTools.executeCommand;
+
+/*
+ * @test
+ * @modules java.logging
+ * @modules jdk.compiler
+ * @summary Test cases which run against the JDK image, check the situation where
+ *            1. logger provider is the default one supplied by the JDK,
+ *            2. clients are in named/unnamed module,
+ *               patched system module, or Xbootclasspath
+ *          This test DOES require existence of java.logging module
+ * @library /lib/testlibrary
+ * @build Base CompilerUtils jdk.testlibrary.*
+ * @run main/othervm JDKLoggerForJDKTest
+ */
+
+public class JDKLoggerForJDKTest extends Base {
+
+    public static void main(String args[]) throws Throwable {
+        JDKLoggerForJDKTest t = new JDKLoggerForJDKTest();
+        t.setup();
+        t.test();
+    }
+
+    private void setup() throws Throwable {
+        setupAllClient();
+    }
+
+    private void test() throws Throwable {
+        // logger client is in named module m.t.a
+        runTest(JDK_IMAGE,
+                "--module-path", DEST_NAMED_CLIENT.toString(),
+                "-m", CLIENT_A, "system", JUL_LOGGER);
+        // logger client is in unnamed module
+        runTest(JDK_IMAGE,
+                "--class-path", DEST_UNNAMED_CLIENT.toString(),
+                CLIENT_B, "system", JUL_LOGGER);
+        // logger client gets logger through boot class BootUsage
+        runTest(JDK_IMAGE,
+                "-Xbootclasspath/a:" + DEST_BOOT_USAGE.toString(),
+                "--class-path", DEST_BOOT_CLIENT.toString(),
+                BOOT_CLIENT, "system", LAZY_LOGGER, JUL_LOGGER);
+        // logger client gets logger through patched class
+        // java.base/java.lang.PatchedUsage
+        runTest(JDK_IMAGE,
+                "--patch-module", "java.base=" + DEST_PATCHED_USAGE.toString(),
+                "--class-path", DEST_PATCHED_CLIENT.toString(),
+                PATCHED_CLIENT, "system", LAZY_LOGGER, JUL_LOGGER);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/LoggerInImageTest.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+import jdk.testlibrary.JDKToolFinder;
+
+import static jdk.testlibrary.ProcessTools.executeCommand;
+
+/*
+ * @test
+ * @modules jdk.compiler
+ * @summary Test cases which run against customized image, check the situation where
+ *            1. logger providers are in the customized image too,
+ *            2. clients are in named/unnamed module, image,
+ *               patched system module, or Xbootclasspath
+ *          This test does not require existence of java.logging module,
+ *          but require jdk.compiler module
+ * @library /lib/testlibrary
+ * @build Base CompilerUtils jdk.testlibrary.*
+ * @run main/othervm LoggerInImageTest
+ */
+
+public class LoggerInImageTest extends Base {
+
+    public static void main(String args[]) throws Throwable {
+        LoggerInImageTest t = new LoggerInImageTest();
+        t.setup();
+        t.test();
+    }
+
+    private void setup() throws Throwable {
+        setupAllClient();
+
+        setupNamedLogger();
+
+        setupLoggerImage();
+        setupFullImage();
+    }
+
+    private void test() throws Throwable {
+        if (!checkJMODS()) {
+            return;
+        }
+
+        // logger client is in named module m.t.a which is also in customized image
+        runTest(IMAGE_CLIENT_LOGGER,
+                "-m", CLIENT_A, "named", LOGGER_A);
+        // logger client in named module m.t.a
+        runTest(IMAGE_LOGGER,
+                "--module-path", DEST_NAMED_CLIENT.toString(),
+                "-m", CLIENT_A, "named", LOGGER_A);
+        // logger client is in unnamed module
+        runTest(IMAGE_LOGGER,
+                "--class-path", DEST_UNNAMED_CLIENT.toString(),
+                CLIENT_B, "named", LOGGER_A);
+        // logger client gets logger through boot class BootUsage
+        runTest(IMAGE_LOGGER,
+                "-Xbootclasspath/a:" + DEST_BOOT_USAGE.toString(),
+                "--class-path", DEST_BOOT_CLIENT.toString(),
+                BOOT_CLIENT, "system", LAZY_LOGGER, LOGGER_A);
+        // logger client gets logger through patched class
+        // java.base/java.lang.PatchedUsage
+        runTest(IMAGE_LOGGER,
+                "--patch-module", "java.base=" + DEST_PATCHED_USAGE.toString(),
+                "--class-path", DEST_PATCHED_CLIENT.toString(),
+                PATCHED_CLIENT, "system", LAZY_LOGGER, LOGGER_A);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/NamedLoggerForImageTest.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+import jdk.testlibrary.JDKToolFinder;
+
+import static jdk.testlibrary.ProcessTools.executeCommand;
+
+/*
+ * @test
+ * @modules jdk.compiler
+ * @summary Test cases which run against customized image, check the situation where
+ *            1. logger providers are in named module,
+ *            2. clients are in named/unnamed module, image,
+ *               patched system module, or Xbootclasspath
+ *          This test does not require existence of java.logging module,
+ *          but require jdk.compiler module
+ * @library /lib/testlibrary
+ * @build Base CompilerUtils jdk.testlibrary.*
+ * @run main/othervm NamedLoggerForImageTest
+ */
+
+public class NamedLoggerForImageTest extends Base {
+
+    public static void main(String args[]) throws Throwable {
+        NamedLoggerForImageTest t = new NamedLoggerForImageTest();
+        t.setup();
+        t.test();
+    }
+
+    private void setup() throws Throwable {
+        setupAllClient();
+
+        setupNamedLogger();
+
+        setupJavaBaseImage();
+        setupClientImage();
+    }
+
+    private void test() throws Throwable {
+        if (!checkJMODS()) {
+            return;
+        }
+
+        // logger client is in named module m.t.a
+        runTest(IMAGE,
+                "--module-path", DEST_NAMED_LOGGER.toString()
+                    + File.pathSeparator + DEST_NAMED_CLIENT.toString(),
+                "-m", CLIENT_A, "named", LOGGER_A);
+        // logger client is in unnamed module
+        runTest(IMAGE,
+                "--module-path", DEST_NAMED_LOGGER.toString(),
+                "--class-path", DEST_UNNAMED_CLIENT.toString(),
+                CLIENT_B, "named", LOGGER_A);
+        // logger client is in named module m.t.a which is in customized image
+        runTest(IMAGE_CLIENT,
+                "--module-path", DEST_NAMED_LOGGER.toString(),
+                "-m", CLIENT_A, "named", LOGGER_A);
+        // logger client gets logger through boot class BootUsage
+        runTest(IMAGE,
+                "--module-path", DEST_NAMED_LOGGER.toString(),
+                "-Xbootclasspath/a:" + DEST_BOOT_USAGE.toString(),
+                "--class-path", DEST_BOOT_CLIENT.toString(),
+                BOOT_CLIENT, "system", LAZY_LOGGER, LOGGER_A);
+        // logger client gets logger through patched class
+        // java.base/java.lang.PatchedUsage
+        runTest(IMAGE,
+                "--module-path", DEST_NAMED_LOGGER.toString(),
+                "--patch-module", "java.base=" + DEST_PATCHED_USAGE.toString(),
+                "--class-path", DEST_PATCHED_CLIENT.toString(),
+                PATCHED_CLIENT, "system", LAZY_LOGGER, LOGGER_A);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/NamedLoggerForJDKTest.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+import jdk.testlibrary.JDKToolFinder;
+
+import static jdk.testlibrary.ProcessTools.executeCommand;
+
+/*
+ * @test
+ * @modules jdk.compiler
+ * @summary Test cases which run against the JDK image, check the situation where
+ *            1. logger providers are in named module,
+ *            2. clients are in named/unnamed module,
+ *               patched system module, or Xbootclasspath
+ *          This test does not require existence of java.logging module,
+ *          but require jdk.compiler module
+ * @library /lib/testlibrary
+ * @build Base CompilerUtils jdk.testlibrary.*
+ * @run main/othervm NamedLoggerForJDKTest
+ */
+
+public class NamedLoggerForJDKTest extends Base {
+
+    public static void main(String args[]) throws Throwable {
+        NamedLoggerForJDKTest t = new NamedLoggerForJDKTest();
+        t.setup();
+        t.test();
+    }
+
+    private void setup() throws Throwable {
+        setupAllClient();
+
+        setupNamedLogger();
+    }
+
+    private void test() throws Throwable {
+        // logger client is in named module m.t.a
+        runTest(JDK_IMAGE,
+                "--module-path", DEST_NAMED_LOGGER.toString()
+                    + File.pathSeparator + DEST_NAMED_CLIENT.toString(),
+                "-m", CLIENT_A, "named", LOGGER_A);
+        // logger client is in unnamed module
+        runTest(JDK_IMAGE,
+                "--module-path", DEST_NAMED_LOGGER.toString(),
+                "--class-path", DEST_UNNAMED_CLIENT.toString(),
+                CLIENT_B, "named", LOGGER_A);
+        // logger client gets logger through boot class BootUsage
+        runTest(JDK_IMAGE,
+                "--module-path", DEST_NAMED_LOGGER.toString(),
+                "-Xbootclasspath/a:" + DEST_BOOT_USAGE.toString(),
+                "--class-path", DEST_BOOT_CLIENT.toString(),
+                BOOT_CLIENT, "system", LAZY_LOGGER, LOGGER_A);
+        // logger client gets logger through patched class
+        // java.base/java.lang.PatchedUsage
+        runTest(JDK_IMAGE,
+                "--module-path", DEST_NAMED_LOGGER.toString(),
+                "--patch-module", "java.base=" + DEST_PATCHED_USAGE.toString(),
+                "--class-path", DEST_PATCHED_CLIENT.toString(),
+                PATCHED_CLIENT, "system", LAZY_LOGGER, LOGGER_A);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/UnnamedLoggerForImageTest.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+import jdk.testlibrary.JDKToolFinder;
+
+import static jdk.testlibrary.ProcessTools.executeCommand;
+
+/*
+ * @test
+ * @modules jdk.compiler
+ * @summary Test cases which run against customized image, check the situation where
+ *            1. logger providers are in unnamed module,
+ *            2. clients are in named/unnamed module, image,
+ *               patched system module, or Xbootclasspath
+ *          This test does not require existence of java.logging module,
+ *          but require jdk.compiler module
+ * @library /lib/testlibrary
+ * @build Base CompilerUtils jdk.testlibrary.*
+ * @run main/othervm UnnamedLoggerForImageTest
+ */
+
+public class UnnamedLoggerForImageTest extends Base {
+
+    public static void main(String args[]) throws Throwable {
+        UnnamedLoggerForImageTest t = new UnnamedLoggerForImageTest();
+        t.setup();
+        t.test();
+    }
+
+    private void setup() throws Throwable {
+        setupAllClient();
+
+        setupUnnamedLogger();
+
+        setupJavaBaseImage();
+        setupClientImage();
+    }
+
+    private void test() throws Throwable {
+        if (!checkJMODS()) {
+            return;
+        }
+
+        // logger client is in unnamed module
+        runTest(IMAGE,
+                "--class-path", DEST_UNNAMED_LOGGER.toString()
+                    + File.pathSeparator + DEST_UNNAMED_CLIENT.toString(),
+                CLIENT_B, "unnamed", LOGGER_B);
+        // logger client is in named module m.t.a
+        runTest(IMAGE,
+                "--class-path", DEST_UNNAMED_LOGGER.toString(),
+                "--module-path", DEST_NAMED_CLIENT.toString(),
+                "-m", CLIENT_A, "unnamed", LOGGER_B);
+        // logger client is in named module m.t.a which is in customized image
+        runTest(IMAGE_CLIENT,
+                "--class-path", DEST_UNNAMED_LOGGER.toString(),
+                "-m", CLIENT_A, "unnamed", LOGGER_B);
+        // logger client gets logger through boot class BootUsage
+        runTest(IMAGE,
+                "--class-path", DEST_UNNAMED_LOGGER.toString()
+                    + File.pathSeparator + DEST_BOOT_CLIENT.toString(),
+                "-Xbootclasspath/a:" + DEST_BOOT_USAGE.toString(),
+                BOOT_CLIENT, "system", LAZY_LOGGER, LOGGER_B);
+        // logger client gets logger through patched class
+        // java.base/java.lang.PatchedUsage
+        runTest(IMAGE,
+                "--class-path", DEST_UNNAMED_LOGGER.toString()
+                    + File.pathSeparator + DEST_PATCHED_CLIENT.toString(),
+                "--patch-module", "java.base=" + DEST_PATCHED_USAGE.toString(),
+                PATCHED_CLIENT, "system", LAZY_LOGGER, LOGGER_B);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/UnnamedLoggerForJDKTest.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+import jdk.testlibrary.JDKToolFinder;
+
+import static jdk.testlibrary.ProcessTools.executeCommand;
+
+/*
+ * @test
+ * @modules jdk.compiler
+ * @summary Test cases which run against the JDK image, check the situation where
+ *            1. logger providers are in unnamed module,
+ *            2. clients are in named/unnamed module,
+ *               patched system module, or Xbootclasspath
+ *          This test does not require existence of java.logging module,
+ *          but require jdk.compiler module
+ * @library /lib/testlibrary
+ * @build Base CompilerUtils jdk.testlibrary.*
+ * @run main/othervm UnnamedLoggerForJDKTest
+ */
+
+public class UnnamedLoggerForJDKTest extends Base {
+
+    public static void main(String args[]) throws Throwable {
+        UnnamedLoggerForJDKTest t = new UnnamedLoggerForJDKTest();
+        t.setup();
+        t.test();
+    }
+
+    private void setup() throws Throwable {
+        setupAllClient();
+
+        setupUnnamedLogger();
+    }
+
+    private void test() throws Throwable {
+        // logger client is in named module m.t.a
+        runTest(JDK_IMAGE,
+                "--class-path", DEST_UNNAMED_LOGGER.toString(),
+                "--module-path", DEST_NAMED_CLIENT.toString(),
+                "-m", CLIENT_A, "unnamed", LOGGER_B);
+        // logger client is also in unnamed module
+        runTest(JDK_IMAGE,
+                "--class-path", DEST_UNNAMED_LOGGER.toString()
+                    + File.pathSeparator + DEST_UNNAMED_CLIENT.toString(),
+                CLIENT_B, "unnamed", LOGGER_B);
+        // logger client gets logger through boot class BootUsage
+        runTest(JDK_IMAGE,
+                "--class-path", DEST_UNNAMED_LOGGER.toString()
+                    + File.pathSeparator + DEST_BOOT_CLIENT.toString(),
+                "-Xbootclasspath/a:" + DEST_BOOT_USAGE.toString(),
+                BOOT_CLIENT, "system", LAZY_LOGGER, LOGGER_B);
+        // logger client gets logger through patched class
+        // java.base/java.lang.PatchedUsage
+        runTest(JDK_IMAGE,
+                "--class-path", DEST_UNNAMED_LOGGER.toString()
+                    + File.pathSeparator + DEST_PATCHED_CLIENT.toString(),
+                "--patch-module", "java.base=" + DEST_PATCHED_USAGE.toString(),
+                PATCHED_CLIENT, "system", LAZY_LOGGER, LOGGER_B);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/boot_client/BootClient.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.lang.reflect.Method;
+import java.lang.System.Logger;
+import java.util.ResourceBundle;
+import java.util.ListResourceBundle;
+
+/*
+ * Tests when logger client is in Xbootclasspath
+ */
+public final class BootClient {
+
+    public static void main(String[] args) throws Exception {
+        assertTrue(args.length >= 2);
+        String loggerMode = args[0];
+        String loggerClassName = args[1];
+        String underlyingLoggerClassName = args.length >= 3 ? args[2] : null;
+
+        testLogger(loggerMode, loggerClassName, underlyingLoggerClassName);
+        testLog(underlyingLoggerClassName);
+    }
+
+    /*
+     * Tests System.getLogger(String) get expected logger.
+     */
+    private static void testLogger(String loggerMode, String loggerClassName,
+                                   String underlyingLoggerClassName) {
+        String name = "test.boot";
+        Logger logger = getLogger(name);
+        printLogger(logger);
+
+        final Module lm = logger.getClass().getModule();
+        final ClassLoader loggerCL = lm.getClassLoader();
+        if (loggerMode.equals("system")) {
+            assertTrue(lm.isNamed());
+            assertTrue(loggerCL == null);
+        } else if(loggerMode.equals("unnamed")) {
+            assertTrue(!lm.isNamed());
+            assertTrue(loggerCL != null);
+        } else {
+            throw new RuntimeException("wrong parameter");
+        }
+
+        assertTrue(loggerClassName.equals(logger.getClass().getName()));
+        if (underlyingLoggerClassName != null) {
+            String loggerName = logger.getName();
+            if (underlyingLoggerClassName.equals(
+                    "sun.util.logging.internal.LoggingProviderImpl$JULWrapper")) {
+                assertTrue(loggerName.equals(name));
+            } else {
+                assertTrue(loggerName.equals(underlyingLoggerClassName));
+            }
+        }
+    }
+
+    /*
+     * Tests Logger retrieved by System.getLogger(String, ResourceBundle) and
+     * System.getLogger(String) works well.
+     */
+    private static void testLog(String underlyingLoggerClassName) throws Exception {
+        if (underlyingLoggerClassName == null) {
+            return;
+        }
+
+        if (underlyingLoggerClassName.equals("pkg.a.l.LoggerA")
+                || underlyingLoggerClassName.equals("pkg.b.l.LoggerB")) {
+
+            String name = "test.boot.logger";
+            String plainMsg = "this is test log message #1";
+            ResourceBundle rb = new MyResourcesBoot();
+            Throwable ex = new Throwable("this is an expected exception to be logged");
+            Class<?> clazz = Class.forName(underlyingLoggerClassName);
+            Method method = clazz.getMethod("checkLog", String.class,
+                                            System.Logger.Level.class,
+                                            ResourceBundle.class, String.class,
+                                            Throwable.class, Object[].class);
+
+            Logger logger = getLogger(name);
+            printLogger(logger);
+            assertTrue(logger.getClass().getName()
+                             .equals("jdk.internal.logger.LazyLoggers$JdkLazyLogger"));
+            assertTrue(logger.getName().equals(underlyingLoggerClassName));
+            logger.log(Logger.Level.WARNING, plainMsg);
+            boolean pass = (boolean)method.invoke(null, name, Logger.Level.WARNING,
+                                                  null, plainMsg, ex, (Object)null);
+            assertTrue(pass);
+            pass = (boolean)method.invoke(null, name, Logger.Level.INFO,
+                                          rb, MyResourcesBoot.VALUE, (Throwable)null,
+                                          (Object)null);
+            assertTrue(!pass);
+
+            logger = getLogger(name, rb);
+            printLogger(logger);
+            assertTrue(logger.getClass().getName()
+                             .equals("jdk.internal.logger.LocalizedLoggerWrapper"));
+            assertTrue(logger.getName().equals(underlyingLoggerClassName));
+            logger.log(Logger.Level.INFO, MyResourcesBoot.KEY);
+            pass = (boolean)method.invoke(null, name, Logger.Level.INFO,
+                                          rb, MyResourcesBoot.VALUE, (Throwable)null,
+                                          (Object)null);
+            assertTrue(pass);
+            pass = (boolean)method.invoke(null, name, Logger.Level.WARNING,
+                                          null, plainMsg, ex, (Object)null);
+            assertTrue(pass);
+        }
+    }
+
+    private static class MyResourcesBoot extends ListResourceBundle {
+        static final String KEY = "this is the key in MyResourcesBoot";
+        static final String VALUE = "THIS IS THE VALUE IN MyResourcesBoot";
+
+        @Override
+        protected Object[][] getContents() {
+            return new Object[][] {
+                {KEY, VALUE}
+            };
+        }
+    }
+
+    private static Logger getLogger(String name) {
+        return BootUsage.getLogger(name);
+    }
+
+    private static Logger getLogger(String name, ResourceBundle rb) {
+        return BootUsage.getLogger(name, rb);
+    }
+
+    private static void printLogger(Logger logger) {
+        System.err.println("logger name: " + logger.getName()
+                           + ", logger class: " + logger.getClass());
+    }
+
+    private static void assertTrue(boolean b) {
+        if (!b) {
+            throw new RuntimeException("expected true, but get false.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/boot_usage/BootUsage.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.lang.System.Logger;
+import java.util.ResourceBundle;
+
+/*
+ * BootUsage is put to Xbootclasspath, it will be used by
+ * BootClient to test when logger client is in boot classpath
+ */
+public final class BootUsage {
+
+    public static Logger getLogger(String name) {
+        check();
+        return System.getLogger(name);
+    }
+
+    public static Logger getLogger(String name, ResourceBundle rb) {
+        check();
+        return System.getLogger(name, rb);
+    }
+
+    private static void check() {
+        final Module m = BootUsage.class.getModule();
+        final ClassLoader moduleCL = m.getClassLoader();
+        assertTrue(!m.isNamed());
+        assertTrue(moduleCL == null);
+    }
+
+    private static void assertTrue(boolean b) {
+        if (!b) {
+            throw new RuntimeException("expected true, but get false.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/named_client/m.t.a/module-info.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+module m.t.a {
+    exports pkg.a.t;
+    uses System.LoggerFinder;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/named_client/m.t.a/pkg/a/t/TestA.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2017, 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 pkg.a.t;
+
+import java.lang.reflect.Method;
+import java.lang.System.Logger;
+import java.util.ResourceBundle;
+import java.util.ListResourceBundle;
+
+/*
+ * Tests when logger client is in named module m.l.a
+ */
+public class TestA {
+
+    public static void main(String[] args) throws Exception {
+        assertTrue(args.length == 2);
+        String loggerMode = args[0];
+        String loggerClassName = args[1];
+
+        testLogger(loggerMode, loggerClassName);
+        testLog(loggerClassName);
+    }
+
+    /*
+     * Tests System.getLogger(String) get expected logger.
+     */
+    private static void testLogger(String loggerMode, String loggerClassName) {
+        final Module m = TestA.class.getModule();
+        final ClassLoader moduleCL = m.getClassLoader();
+        assertTrue(m.isNamed());
+        assertTrue(moduleCL != null);
+
+        String name = "test.a";
+        Logger logger = getLogger(name);
+        printLogger(logger);
+
+        final Module lm = logger.getClass().getModule();
+        final ClassLoader loggerCL = lm.getClassLoader();
+        if (loggerMode.equals("system")) {
+            assertTrue(lm.isNamed());
+            assertTrue(loggerCL == null);
+        } else if(loggerMode.equals("named")) {
+            assertTrue(lm.isNamed());
+            assertTrue(loggerCL != null);
+        } else if(loggerMode.equals("unnamed")) {
+            assertTrue(!lm.isNamed());
+            assertTrue(loggerCL != null);
+        } else {
+            throw new RuntimeException("wrong parameter");
+        }
+
+        assertTrue(loggerClassName.equals(logger.getClass().getName()));
+        assertTrue(!loggerClassName.equals("jdk.internal.logger.LazyLoggers$JdkLazyLogger"));
+    }
+
+    /*
+     * Tests Logger retrieved by System.getLogger(String, ResourceBundle) and
+     * System.getLogger(String) works well.
+     */
+    private static void testLog(String loggerClassName) throws Exception {
+        if (loggerClassName.equals("pkg.a.l.LoggerA")
+                || loggerClassName.equals("pkg.b.l.LoggerB")) {
+
+            String name = "test.a.A";
+            String plainMsg = "this is test log message #1";
+            ResourceBundle rb = new MyResourcesA();
+            Throwable ex = new Throwable("this is an expected exception to be logged");
+            Class<?> clazz = Class.forName(loggerClassName);
+            Method method = clazz.getMethod("checkLog", String.class,
+                                            System.Logger.Level.class,
+                                            ResourceBundle.class, String.class,
+                                            Throwable.class, Object[].class);
+
+            Logger logger = getLogger(name);
+            printLogger(logger);
+            assertTrue(logger.getClass().getName().equals(loggerClassName));
+            assertTrue(logger.getName().equals(loggerClassName));
+            logger.log(Logger.Level.WARNING, plainMsg);
+            boolean pass = (boolean)method.invoke(null, name,
+                                                  Logger.Level.WARNING,
+                                                  null, plainMsg, ex, (Object)null);
+            assertTrue(pass);
+            pass = (boolean)method.invoke(null, name, Logger.Level.INFO,
+                                          rb, MyResourcesA.VALUE, (Throwable)null,
+                                          (Object)null);
+            assertTrue(!pass);
+
+            logger = getLogger(name, rb);
+            printLogger(logger);
+            assertTrue(logger.getClass().getName()
+                             .equals("jdk.internal.logger.LocalizedLoggerWrapper"));
+            assertTrue(logger.getName().equals(loggerClassName));
+            logger.log(Logger.Level.INFO, MyResourcesA.KEY);
+            pass = (boolean)method.invoke(null, name, Logger.Level.INFO,
+                                          rb, MyResourcesA.VALUE, (Throwable)null,
+                                          (Object)null);
+            assertTrue(pass);
+            pass = (boolean)method.invoke(null, name, Logger.Level.WARNING,
+                                          null, plainMsg, ex, (Object)null);
+            assertTrue(pass);
+        }
+    }
+
+    private static class MyResourcesA extends ListResourceBundle {
+        static final String KEY = "this is the key in MyResourcesA";
+        static final String VALUE = "THIS IS THE VALUE IN MyResourcesA";
+
+        @Override
+        protected Object[][] getContents() {
+            return new Object[][] {
+                {KEY, VALUE}
+            };
+        }
+    }
+
+    private static Logger getLogger(String name) {
+        return System.getLogger(name);
+    }
+
+    private static Logger getLogger(String name, ResourceBundle rb) {
+        return System.getLogger(name, rb);
+    }
+
+    private static void printLogger(Logger logger) {
+        System.err.println("logger name: " + logger.getName()
+                           + ", logger class: " + logger.getClass());
+    }
+
+    private static void assertTrue(boolean b) {
+        if (!b) {
+            throw new RuntimeException("expected true, but get false.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/named_logger/m.l.a/module-info.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+module m.l.a {
+    opens pkg.a.l;
+    provides java.lang.System.LoggerFinder with pkg.a.p.LoggerFinderA;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/named_logger/m.l.a/pkg/a/l/LoggerA.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2017, 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 pkg.a.l;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.ResourceBundle;
+
+public class LoggerA implements System.Logger {
+
+    // ---- test utility fields and methods ----
+
+    private static Map<String, LoggerA> map = new HashMap<>();
+
+    public static LoggerA getLogger(String name) {
+        return map.computeIfAbsent(name, (n) -> new LoggerA());
+    }
+
+    public static boolean checkLog(String name, Level level, ResourceBundle bundle,
+                                   String format, Throwable throwable, Object... params) {
+        LoggerA logger = map.get(name);
+        LogEvent event = new LogEvent(level, bundle, format, null, params);
+        for (LogEvent l : logger.queue) {
+            if (l.equals(event)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // ---- logger implementation ----
+
+    private Queue<LogEvent> queue = new LinkedList<>();
+
+    @Override
+    public String getName() {
+        return this.getClass().getName();
+    }
+
+    @Override
+    public boolean isLoggable(Level level) {
+        return true;
+    }
+
+    @Override
+    public void log(Level level, ResourceBundle bundle, String format, Object... params) {
+        String msg = bundle != null ? bundle.getString(format) : format;
+        log(new LogEvent(level, bundle, msg, null, params));
+    }
+
+    @Override
+    public void log(Level level, ResourceBundle bundle, String format, Throwable throwable) {
+        String msg = bundle != null ? bundle.getString(format) : format;
+        log(new LogEvent(level, bundle, msg, throwable, (Object)null));
+    }
+
+    void log(LogEvent l) {
+        print(l);
+        queue.add(l);
+    }
+
+    private void print(LogEvent l) {
+        System.err.println("LoggerA Message"+ l);
+    }
+
+    public Queue<LogEvent> getLogEvent() {
+        return queue;
+    }
+
+    public static class LogEvent {
+        public LogEvent(Level level, ResourceBundle bundle, String format,
+                        Throwable throwable, Object... params) {
+            this.level = level;
+            this.bundle = bundle;
+            this.format = format;
+            this.throwable = throwable;
+            this.params = params;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof LogEvent) {
+                LogEvent e = (LogEvent)o;
+                return level == e.level
+                    && bundle == e.bundle
+                    && format == e.format
+                    && params == e.params;
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("[level: %s, bundle: %s, format: %s, throwable: %s, object: %s]",
+                    level, bundle, format, throwable, params);
+        }
+
+        private Level level;
+        private ResourceBundle bundle;
+        private String format;
+        private Throwable throwable;
+        private Object[] params;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/named_logger/m.l.a/pkg/a/p/LoggerFinderA.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017, 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 pkg.a.p;
+
+import pkg.a.l.LoggerA;
+
+public class LoggerFinderA extends System.LoggerFinder {
+    @Override
+    public System.Logger getLogger(String name, Module module) {
+        return LoggerA.getLogger(name);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/patched_client/PatchedClient.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.lang.reflect.Method;
+import java.lang.System.Logger;
+import java.util.ResourceBundle;
+import java.util.ListResourceBundle;
+
+/*
+ * Tests when logger client is in patched module
+ */
+public class PatchedClient {
+
+    public static void main(String[] args) throws Exception {
+        assertTrue(args.length >= 2);
+        String loggerMode = args[0];
+        String loggerClassName = args[1];
+        String underlyingLoggerClassName = args.length >= 3 ? args[2] : null;
+
+        testLogger(loggerMode, loggerClassName, underlyingLoggerClassName);
+        testLog(underlyingLoggerClassName);
+    }
+
+    /*
+     * Tests System.getLogger(String) get expected logger.
+     */
+    private static void testLogger(String loggerMode, String loggerClassName,
+                                   String underlyingLoggerClassName) {
+        String name = "test.patched";
+        Logger logger = getLogger(name);
+        printLogger(logger);
+
+        final Module lm = logger.getClass().getModule();
+        final ClassLoader loggerCL = lm.getClassLoader();
+        if (loggerMode.equals("system")) {
+            assertTrue(lm.isNamed());
+            assertTrue(loggerCL == null);
+        } else if(loggerMode.equals("unnamed")) {
+            assertTrue(!lm.isNamed());
+            assertTrue(loggerCL != null);
+        } else {
+            throw new RuntimeException("wrong parameter");
+        }
+
+        assertTrue(loggerClassName.equals(logger.getClass().getName()));
+        if (underlyingLoggerClassName != null) {
+            String loggerName = logger.getName();
+            if (underlyingLoggerClassName.equals(
+                    "sun.util.logging.internal.LoggingProviderImpl$JULWrapper")) {
+                assertTrue(loggerName.equals(name));
+            } else {
+                assertTrue(loggerName.equals(underlyingLoggerClassName));
+            }
+        }
+    }
+
+    /*
+     * Tests Logger retrieved by System.getLogger(String, ResourceBundle) and
+     * System.getLogger(String) works well.
+     */
+    private static void testLog(String underlyingLoggerClassName) throws Exception {
+        if (underlyingLoggerClassName == null) {
+            return;
+        }
+
+        if (underlyingLoggerClassName.equals("pkg.a.l.LoggerA")
+                || underlyingLoggerClassName.equals("pkg.b.l.LoggerB")) {
+
+            String name = "test.patched.logger";
+            String plainMsg = "this is test log message #1";
+            ResourceBundle rb = new MyResourcesPatched();
+            Throwable ex = new Throwable("this is an expected exception to be logged");
+            Class<?> clazz = Class.forName(underlyingLoggerClassName);
+            Method method = clazz.getMethod("checkLog", String.class,
+                                            System.Logger.Level.class,
+                                            ResourceBundle.class, String.class,
+                                            Throwable.class, Object[].class);
+
+            Logger logger = getLogger(name);
+            printLogger(logger);
+            assertTrue(logger.getClass().getName()
+                             .equals("jdk.internal.logger.LazyLoggers$JdkLazyLogger"));
+            assertTrue(logger.getName().equals(underlyingLoggerClassName));
+            logger.log(Logger.Level.WARNING, plainMsg);
+            boolean pass = (boolean)method.invoke(null, name, Logger.Level.WARNING,
+                                                  null, plainMsg, ex, (Object)null);
+            assertTrue(pass);
+            pass = (boolean)method.invoke(null, name, Logger.Level.INFO,
+                                          rb, MyResourcesPatched.VALUE, (Throwable)null,
+                                          (Object)null);
+            assertTrue(!pass);
+
+            logger = getLogger(name, rb);
+            printLogger(logger);
+            assertTrue(logger.getClass().getName()
+                             .equals("jdk.internal.logger.LocalizedLoggerWrapper"));
+            assertTrue(logger.getName().equals(underlyingLoggerClassName));
+            logger.log(Logger.Level.INFO, MyResourcesPatched.KEY);
+            pass = (boolean)method.invoke(null, name, Logger.Level.INFO,
+                                          rb, MyResourcesPatched.VALUE, (Throwable)null,
+                                          (Object)null);
+            assertTrue(pass);
+            pass = (boolean)method.invoke(null, name, Logger.Level.WARNING,
+                                          null, plainMsg, ex, (Object)null);
+            assertTrue(pass);
+        }
+    }
+
+    private static class MyResourcesPatched extends ListResourceBundle {
+        static final String KEY = "this is the key in MyResourcesPatched";
+        static final String VALUE = "THIS IS THE VALUE IN MyResourcesPatched";
+
+        @Override
+        protected Object[][] getContents() {
+            return new Object[][] {
+                {KEY, VALUE}
+            };
+        }
+    }
+
+    private static Logger getLogger(String name) {
+        return PatchedUsage.getLogger(name);
+    }
+
+    private static Logger getLogger(String name, ResourceBundle rb) {
+        return PatchedUsage.getLogger(name, rb);
+    }
+
+    private static void printLogger(Logger logger) {
+        System.err.println("logger name: " + logger.getName()
+                           + ", logger class: " + logger.getClass());
+    }
+
+    private static void assertTrue(boolean b) {
+        if (!b) {
+            throw new RuntimeException("expected true, but get false.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/patched_usage/java.base/java/lang/PatchedUsage.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, 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;
+
+import java.lang.System.Logger;
+import java.util.ResourceBundle;
+
+/*
+ * PatchedUsage is patched into java.base, it will be used by
+ * PatchedClient to test when logger client is in patched module
+ */
+public class PatchedUsage {
+
+    public static Logger getLogger(String name) {
+        check();
+        return System.getLogger(name);
+    }
+
+    public static Logger getLogger(String name, ResourceBundle rb) {
+        check();
+        return System.getLogger(name, rb);
+    }
+
+    private static void check() {
+        final Module m = PatchedUsage.class.getModule();
+        final ClassLoader moduleCL = m.getClassLoader();
+        assertTrue(m.isNamed());
+        assertTrue(moduleCL == null);
+    }
+
+    private static void assertTrue(boolean b) {
+        if (!b) {
+            throw new RuntimeException("expected true, but get false.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/unnamed_client/pkg/b/t/TestB.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2017, 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 pkg.b.t;
+
+import java.lang.reflect.Method;
+import java.lang.System.Logger;
+import java.util.ResourceBundle;
+import java.util.ListResourceBundle;
+
+/*
+ * Tests when logger client is in unnamed module
+ */
+public class TestB {
+
+    public static void main(String[] args) throws Exception {
+        assertTrue(args.length == 2);
+        String loggerMode = args[0];
+        String loggerClassName = args[1];
+
+        testLogger(loggerMode, loggerClassName);
+        testLog(loggerClassName);
+    }
+
+    /*
+     * Tests System.getLogger(String) get expected logger.
+     */
+    private static void testLogger(String loggerMode, String loggerClassName) {
+        final Module m = TestB.class.getModule();
+        final ClassLoader moduleCL = m.getClassLoader();
+        assertTrue(!m.isNamed());
+        assertTrue(moduleCL != null);
+
+        String name = "test.b";
+        Logger logger = getLogger(name);
+        printLogger(logger);
+
+        final Module lm = logger.getClass().getModule();
+        final ClassLoader loggerCL = lm.getClassLoader();
+        if (loggerMode.equals("system")) {
+            assertTrue(lm.isNamed());
+            assertTrue(loggerCL == null);
+        } else if(loggerMode.equals("named")) {
+            assertTrue(lm.isNamed());
+            assertTrue(loggerCL != null);
+        } else if(loggerMode.equals("unnamed")) {
+            assertTrue(!lm.isNamed());
+            assertTrue(loggerCL != null);
+        } else {
+            throw new RuntimeException("wrong parameter");
+        }
+
+        assertTrue(loggerClassName.equals(logger.getClass().getName()));
+        assertTrue(!loggerClassName.equals("jdk.internal.logger.LazyLoggers$JdkLazyLogger"));
+    }
+
+    /*
+     * Tests Logger retrieved by System.getLogger(String, ResourceBundle) and
+     * System.getLogger(String) works well.
+     */
+    private static void testLog(String loggerClassName) throws Exception {
+        if (loggerClassName.equals("pkg.a.l.LoggerA")
+                || loggerClassName.equals("pkg.b.l.LoggerB")) {
+
+            String name = "test.b.B";
+            String plainMsg = "this is test log message #1";
+            ResourceBundle rb = new MyResourcesB();
+            Throwable ex = new Throwable("this is an expected exception to be logged");
+            Class<?> clazz = Class.forName(loggerClassName);
+            Method method = clazz.getMethod("checkLog", String.class,
+                                            System.Logger.Level.class,
+                                            ResourceBundle.class, String.class,
+                                            Throwable.class, Object[].class);
+
+            Logger logger = getLogger(name);
+            printLogger(logger);
+            assertTrue(logger.getClass().getName().equals(loggerClassName));
+            assertTrue(logger.getName().equals(loggerClassName));
+            logger.log(Logger.Level.WARNING, plainMsg);
+            boolean pass = (boolean)method.invoke(null, name, Logger.Level.WARNING,
+                                                  null, plainMsg, ex, (Object)null);
+            assertTrue(pass);
+            pass = (boolean)method.invoke(null, name, Logger.Level.INFO,
+                                          rb, MyResourcesB.VALUE, (Throwable)null,
+                                          (Object)null);
+            assertTrue(!pass);
+
+            logger = getLogger(name, rb);
+            printLogger(logger);
+            assertTrue(logger.getClass().getName()
+                             .equals("jdk.internal.logger.LocalizedLoggerWrapper"));
+            assertTrue(logger.getName().equals(loggerClassName));
+            logger.log(Logger.Level.INFO, MyResourcesB.KEY);
+            pass = (boolean)method.invoke(null, name, Logger.Level.INFO,
+                                          rb, MyResourcesB.VALUE, (Throwable)null,
+                                          (Object)null);
+            assertTrue(pass);
+            pass = (boolean)method.invoke(null, name, Logger.Level.WARNING,
+                                          null, plainMsg, ex, (Object)null);
+            assertTrue(pass);
+        }
+    }
+
+    private static class MyResourcesB extends ListResourceBundle {
+        static final String KEY = "this is the key in MyResourcesB";
+        static final String VALUE = "THIS IS THE VALUE IN MyResourcesB";
+
+        @Override
+        protected Object[][] getContents() {
+            return new Object[][] {
+                {KEY, VALUE}
+            };
+        }
+    }
+
+    private static Logger getLogger(String name) {
+        return System.getLogger(name);
+    }
+
+    private static Logger getLogger(String name, ResourceBundle rb) {
+        return System.getLogger(name, rb);
+    }
+
+    private static void printLogger(Logger logger) {
+        System.err.println("logger name: " + logger.getName()
+                           + ", logger class: " + logger.getClass());
+    }
+
+    private static void assertTrue(boolean b) {
+        if (!b) {
+            throw new RuntimeException("expected true, but get false.");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/unnamed_logger/META-INF/services/java.lang.System$LoggerFinder	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,1 @@
+pkg.b.p.LoggerFinderB
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/unnamed_logger/pkg/b/l/LoggerB.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2017, 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 pkg.b.l;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.ResourceBundle;
+
+public class LoggerB implements System.Logger {
+
+    // ---- test utility fields and methods ----
+
+    private static Map<String, LoggerB> map = new HashMap<>();
+
+    public static LoggerB getLogger(String name) {
+        return map.computeIfAbsent(name, (n) -> new LoggerB());
+    }
+
+    public static boolean checkLog(String name, Level level, ResourceBundle bundle,
+                                   String format, Throwable throwable, Object... params) {
+        LoggerB logger = map.get(name);
+        LogEvent event = new LogEvent(level, bundle, format, null, params);
+        for (LogEvent l : logger.queue) {
+            if (l.equals(event)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // ---- logger implementation ----
+
+    private Queue<LogEvent> queue = new LinkedList<>();
+
+    @Override
+    public String getName() {
+        return this.getClass().getName();
+    }
+
+    @Override
+    public boolean isLoggable(Level level) {
+        return true;
+    }
+
+    @Override
+    public void log(Level level, ResourceBundle bundle, String format, Object... params) {
+        String msg = bundle != null ? bundle.getString(format) : format;
+        log(new LogEvent(level, bundle, msg, null, params));
+    }
+
+    @Override
+    public void log(Level level, ResourceBundle bundle, String format, Throwable throwable) {
+        String msg = bundle != null ? bundle.getString(format) : format;
+        log(new LogEvent(level, bundle, msg, throwable, (Object)null));
+    }
+
+    void log(LogEvent l) {
+        print(l);
+        queue.add(l);
+    }
+
+    private void print(LogEvent l) {
+        System.err.println("LoggerB Message"+ l);
+    }
+
+    public Queue<LogEvent> getLogEvent() {
+        return queue;
+    }
+
+    public static class LogEvent {
+        public LogEvent(Level level, ResourceBundle bundle, String format,
+                        Throwable throwable, Object... params) {
+            this.level = level;
+            this.bundle = bundle;
+            this.format = format;
+            this.throwable = throwable;
+            this.params = params;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof LogEvent) {
+                LogEvent e = (LogEvent)o;
+                return level == e.level
+                    && bundle == e.bundle
+                    && format == e.format
+                    && params == e.params;
+            }
+            return false;
+        }
+
+        private Level level;
+        private ResourceBundle bundle;
+        private String format;
+        private Throwable throwable;
+        private Object[] params;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/System/LoggerFinder/modules/unnamed_logger/pkg/b/p/LoggerFinderB.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017, 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 pkg.b.p;
+
+import pkg.b.l.LoggerB;
+
+public class LoggerFinderB extends System.LoggerFinder {
+    @Override
+    public System.Logger getLogger(String name, Module module) {
+        return LoggerB.getLogger(name);
+    }
+}
--- a/test/java/net/Inet6Address/B6206527.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/test/java/net/Inet6Address/B6206527.java	Mon Apr 17 08:37:15 2017 -0700
@@ -25,10 +25,14 @@
  * @test 1.1 05/01/05
  * @bug 6206527
  * @summary "cannot assign address" when binding ServerSocket on Suse 9
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.NetworkConfiguration
+ * @run main B6206527
  */
 
 import java.net.*;
 import java.util.*;
+import jdk.testlibrary.NetworkConfiguration;
 
 public class B6206527 {
 
@@ -53,21 +57,12 @@
         ss.bind(new InetSocketAddress(addr, 0));
     }
 
-    public static Inet6Address getLocalAddr () throws Exception {
-        Enumeration e = NetworkInterface.getNetworkInterfaces();
-        while (e.hasMoreElements()) {
-            NetworkInterface ifc = (NetworkInterface) e.nextElement();
-            Enumeration addrs = ifc.getInetAddresses();
-            while (addrs.hasMoreElements()) {
-                InetAddress a = (InetAddress)addrs.nextElement();
-                if (a instanceof Inet6Address) {
-                    Inet6Address ia6 = (Inet6Address) a;
-                    if (ia6.isLinkLocalAddress()) {
-                        return ia6;
-                    }
-                }
-            }
-        }
-        return null;
+    public static Inet6Address getLocalAddr() throws Exception {
+        Optional<Inet6Address> oaddr = NetworkConfiguration.probe()
+                .ip6Addresses()
+                .filter(a -> a.isLinkLocalAddress())
+                .findFirst();
+
+        return oaddr.orElseGet(() -> null);
     }
 }
--- a/test/java/net/Inet6Address/B6558853.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/test/java/net/Inet6Address/B6558853.java	Mon Apr 17 08:37:15 2017 -0700
@@ -21,43 +21,42 @@
  * questions.
  */
 
-/**
+/*
  * @test
  * @bug 6558853
  * @summary  getHostAddress() on connections using IPv6 link-local addrs should have zone id
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.NetworkConfiguration
+ * @run main B6558853
  */
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.*;
-import java.util.Enumeration;
+import java.util.Optional;
+import jdk.testlibrary.NetworkConfiguration;
 
 public class B6558853 implements Runnable {
     private InetAddress addr = null;
     private int port = 0;
 
     public static void main(String[] args) throws Exception {
-        ServerSocket ss = new ServerSocket(0);
-        int port = ss.getLocalPort();
-        Enumeration<NetworkInterface> l = NetworkInterface.getNetworkInterfaces();
-        InetAddress dest = null;
-        while (l.hasMoreElements() && dest == null) {
-            NetworkInterface nif = l.nextElement();
-            if (!nif.isUp())
-                continue;
+        Optional<Inet6Address> oaddr = NetworkConfiguration.probe()
+                .ip6Addresses()
+                .filter(a -> a.isLinkLocalAddress())
+                .findFirst();
 
-            for (InterfaceAddress a : nif.getInterfaceAddresses()) {
-                if (a.getAddress() instanceof Inet6Address) {
-                    Inet6Address a6 = (Inet6Address) a.getAddress();
-                    if (a6.isLinkLocalAddress()) {
-                        dest = a6;
-                    }
-                    break;
-                }
-            }
+        if (!oaddr.isPresent()) {
+            System.out.println("No suitable interface found. Exiting.");
+            return;
         }
+
+        Inet6Address dest = oaddr.get();
         System.out.println("Using " + dest);
-        if (dest != null) {
+
+        try (ServerSocket ss = new ServerSocket(0)) {
+            int port = ss.getLocalPort();
             B6558853 test = new B6558853(dest, port);
             Thread thread = new Thread(test);
             thread.start();
--- a/test/java/net/InetAddress/CheckJNI.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/test/java/net/InetAddress/CheckJNI.java	Mon Apr 17 08:37:15 2017 -0700
@@ -24,11 +24,15 @@
 /* @test
    @bug 4889870 4890033
    @summary java -Xcheck:jni failing in net code on Solaris / [Datagram]Socket.getLocalAddress() failure
+   @library /lib/testlibrary
+   @build jdk.testlibrary.NetworkConfiguration
    @run main/othervm -Xcheck:jni CheckJNI
 */
 
 import java.net.*;
 import java.util.*;
+import java.util.stream.Collectors;
+import jdk.testlibrary.NetworkConfiguration;
 
 public class CheckJNI {
     static Socket s;
@@ -49,32 +53,23 @@
         dg2 = new DatagramSocket (0, InetAddress.getByName ("127.0.0.1"));
         testDatagrams (dg1, dg2);
 
-        /* Use NetworkInterface to find link local IPv6 addrs to test */
+        /* Find link local IPv6 addrs to test */
+        List<Inet6Address> addrs = NetworkConfiguration.probe()
+                .ip6Addresses()
+                .filter(Inet6Address::isLinkLocalAddress)
+                .collect(Collectors.toList());
 
-        Enumeration ifs = NetworkInterface.getNetworkInterfaces();
-        server = new ServerSocket (0);
+        server = new ServerSocket(0);
+        for (Inet6Address ia6 : addrs) {
+            System.out.println("Address:" + ia6);
+            System.out.println("Testing IPv6 Socket");
+            s = new Socket(ia6, server.getLocalPort());
+            s.close();
 
-        while (ifs.hasMoreElements()) {
-            NetworkInterface nif = (NetworkInterface)ifs.nextElement();
-            if (!nif.isUp())
-                continue;
-            Enumeration addrs = nif.getInetAddresses();
-            while (addrs.hasMoreElements()) {
-                InetAddress addr = (InetAddress) addrs.nextElement();
-                if (addr instanceof Inet6Address) {
-                    Inet6Address ia6 = (Inet6Address) addr;
-                    if (ia6.isLinkLocalAddress()) {
-                        System.out.println ("Testing IPv6 Socket");
-                        s = new Socket (ia6, server.getLocalPort());
-                        s.close();
-
-                        System.out.println ("Testing IPv6 DatagramSocket");
-                        dg1 = new DatagramSocket (0, ia6);
-                        dg2 = new DatagramSocket (0, ia6);
-                        testDatagrams (dg1, dg2);
-                    }
-                }
-            }
+            System.out.println("Testing IPv6 DatagramSocket");
+            dg1 = new DatagramSocket(0, ia6);
+            dg2 = new DatagramSocket(0, ia6);
+            testDatagrams(dg1, dg2);
         }
         server.close();
         System.out.println ("OK");
--- a/test/java/net/MulticastSocket/B6427403.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/test/java/net/MulticastSocket/B6427403.java	Mon Apr 17 08:37:15 2017 -0700
@@ -23,15 +23,12 @@
 
 /*
  * @test
- *
  * @bug 6427403
- *
  * @summary java.net.MulticastSocket.joinGroup() reports 'socket closed'
- *
  */
 import java.net.*;
 import java.io.*;
-import java.util.*;
+
 public class B6427403 {
     public static void main( String[] args ) throws IOException {
         InetAddress lh = InetAddress.getLocalHost();
@@ -39,4 +36,4 @@
         ms.joinGroup( InetAddress.getByName("224.80.80.80") );
         ms.close();
     }
-}
+}
\ No newline at end of file
--- a/test/java/net/MulticastSocket/JoinGroup.java	Fri Apr 14 16:51:31 2017 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 1998, 1999, 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 4091811 4148753
- * @summary Test java.net.MulticastSocket joinGroup and leaveGroup
- *
- */
-
-import java.io.*;
-import java.net.*;
-
-
-public class JoinGroup {
-
-    public static void main(String args[]) throws Exception  {
-        MulticastSocket soc = null;
-        InetAddress sin = null;
-
-        soc = new MulticastSocket();
-        sin = InetAddress.getByName("224.80.80.80");
-        soc.joinGroup(sin);
-        soc.leaveGroup(sin);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/net/MulticastSocket/JoinLeave.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1998, 1999, 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 4091811 4148753 4102731
+ * @summary Test java.net.MulticastSocket joinGroup and leaveGroup
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.NetworkConfiguration
+ * @run main JoinLeave
+ */
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.net.NetworkInterface;
+import jdk.testlibrary.NetworkConfiguration;
+
+public class JoinLeave {
+
+    public static void main(String args[]) throws IOException  {
+        InetAddress ip4Group = InetAddress.getByName("224.80.80.80");
+        InetAddress ip6Group = InetAddress.getByName("ff02::a");
+
+        NetworkConfiguration nc = NetworkConfiguration.probe();
+        nc.ip4MulticastInterfaces().forEach(nic -> joinLeave(ip4Group, nic));
+        nc.ip6MulticastInterfaces().forEach(nic -> joinLeave(ip6Group, nic));
+    }
+
+    static void joinLeave(InetAddress group, NetworkInterface nif)
+    {
+        System.out.println("Joining:" + group + " on " + nif);
+        try (MulticastSocket soc = new MulticastSocket()) {
+            soc.setNetworkInterface(nif);
+            soc.joinGroup(group);
+            soc.leaveGroup(group);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+}
--- a/test/java/net/MulticastSocket/Leave.java	Fri Apr 14 16:51:31 2017 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 1998, 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 4102731
- * @summary Test the java.net.multicastsocket.leave method
- *
- */
-
-import java.net.*;
-import java.io.*;
-
-public class Leave {
-
-    public static void main(String args[]) throws Exception {
-        MulticastSocket socket = null;
-        InetAddress mca = null;
-
-        mca = InetAddress.getByName("224.80.80.80");
-        socket = new MulticastSocket();
-        socket.joinGroup(mca);
-        socket.leaveGroup(mca);
-        socket.close();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/net/NetworkConfigurationProbe.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017, 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 NOT A TEST. Captures the network interface configuration.
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.NetworkConfiguration
+ * @run main NetworkConfigurationProbe
+ */
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.NetworkInterface;
+import jdk.testlibrary.NetworkConfiguration;
+import static java.util.stream.Collectors.joining;
+import static java.lang.System.out;
+
+/**
+ * Not a test. Captures the network interface configuration.
+ */
+public class NetworkConfigurationProbe {
+
+    public static void main(String... args) throws Exception {
+        NetworkConfiguration.printSystemConfiguration(out);
+
+        NetworkConfiguration nc = NetworkConfiguration.probe();
+        String list;
+        list = nc.ip4MulticastInterfaces()
+                  .map(NetworkInterface::getName)
+                  .collect(joining(" "));
+        out.println("ip4MulticastInterfaces: " +  list);
+
+        list = nc.ip4Addresses()
+                  .map(Inet4Address::toString)
+                  .collect(joining(" "));
+        out.println("ip4Addresses: " +  list);
+
+        list = nc.ip6MulticastInterfaces()
+                  .map(NetworkInterface::getName)
+                  .collect(joining(" "));
+        out.println("ip6MulticastInterfaces: " +  list);
+
+        list = nc.ip6Addresses()
+                  .map(Inet6Address::toString)
+                  .collect(joining(" "));
+        out.println("ip6Addresses: " +  list);
+    }
+}
--- a/test/java/net/Socket/LinkLocal.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/test/java/net/Socket/LinkLocal.java	Mon Apr 17 08:37:15 2017 -0700
@@ -26,9 +26,15 @@
  * @bug 4469866
  * @summary Connecting to a link-local IPv6 address should not
  *          causes a SocketException to be thrown.
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.NetworkConfiguration
+ * @run main LinkLocal
  */
+import jdk.testlibrary.NetworkConfiguration;
+
 import java.net.*;
-import java.util.Enumeration;
+import java.util.List;
+import java.util.stream.Collectors;
 
 public class LinkLocal {
 
@@ -134,22 +140,13 @@
          * IPv6 address.
          */
         if (args.length == 0) {
-            Enumeration nifs = NetworkInterface.getNetworkInterfaces();
-            while (nifs.hasMoreElements()) {
-                NetworkInterface ni = (NetworkInterface)nifs.nextElement();
-                if (!ni.isUp())
-                    continue;
+            List<Inet6Address> addrs = NetworkConfiguration.probe()
+                    .ip6Addresses()
+                    .filter(Inet6Address::isLinkLocalAddress)
+                    .collect(Collectors.toList());
 
-                Enumeration addrs = ni.getInetAddresses();
-                while (addrs.hasMoreElements()) {
-                    InetAddress addr = (InetAddress)addrs.nextElement();
-
-                    if (addr instanceof Inet6Address &&
-                        addr.isLinkLocalAddress()) {
-
-                        TestAddress(addr);
-                    }
-                }
+            for (Inet6Address addr : addrs) {
+                TestAddress(addr);
             }
         }
 
--- a/test/java/net/SocketPermission/SocketPermissionTest.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/test/java/net/SocketPermission/SocketPermissionTest.java	Mon Apr 17 08:37:15 2017 -0700
@@ -25,13 +25,17 @@
  * @test
  * @bug 8047031
  * @summary SocketPermission tests for legacy socket types
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.NetworkConfiguration
  * @run testng/othervm SocketPermissionTest
  */
+
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
 import java.net.MulticastSocket;
+import java.net.NetworkInterface;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.SocketPermission;
@@ -44,11 +48,14 @@
 import java.security.Policy;
 import java.security.PrivilegedExceptionAction;
 import java.security.ProtectionDomain;
+import java.util.Optional;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
+
 import static org.testng.Assert.*;
 
+import static jdk.testlibrary.NetworkConfiguration.probe;
 import static java.nio.charset.StandardCharsets.UTF_8;
 
 public class SocketPermissionTest {
@@ -210,12 +217,17 @@
                     new SocketPermission(addr, "listen,resolve"),
                     new SocketPermission("229.227.226.221", "connect,accept"));
 
-            // Positive
-            AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
-                s.joinGroup(group);
-                s.leaveGroup(group);
-                return null;
-            }, acc);
+            // Positive ( requires a functional network interface )
+            Optional<NetworkInterface> onif = probe().ip4MulticastInterfaces().findFirst();
+            if (!onif.isPresent()) {
+                s.setNetworkInterface(onif.get());
+
+                AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+                    s.joinGroup(group);
+                    s.leaveGroup(group);
+                    return null;
+                }, acc);
+            }
 
             // Negative
             try {
--- a/test/java/net/ipv6tests/B6521014.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/test/java/net/ipv6tests/B6521014.java	Mon Apr 17 08:37:15 2017 -0700
@@ -25,13 +25,15 @@
  * @test
  * @bug 6521014 6543428
  * @summary IOException thrown when Socket tries to bind to an local IPv6 address on SuSE Linux
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.NetworkConfiguration
+ * @run main B6521014
  */
 
-
 import java.net.*;
 import java.io.*;
 import java.util.*;
-
+import jdk.testlibrary.NetworkConfiguration;
 
 /*
  *
@@ -52,38 +54,26 @@
  */
 public class B6521014 {
 
-    static InetAddress sin;
-
-    static Inet6Address getLocalAddr () throws Exception {
-        Enumeration e = NetworkInterface.getNetworkInterfaces();
-        while (e.hasMoreElements()) {
-            NetworkInterface ifc = (NetworkInterface) e.nextElement();
-            if (!ifc.isUp())
-                continue;
-            Enumeration addrs = ifc.getInetAddresses();
-            while (addrs.hasMoreElements()) {
-                InetAddress a = (InetAddress)addrs.nextElement();
-                if (a instanceof Inet6Address) {
-                    Inet6Address ia6 = (Inet6Address) a;
-                    if (ia6.isLinkLocalAddress()) {
-                        // remove %scope suffix
-                        return (Inet6Address)InetAddress.getByAddress(ia6.getAddress());
-                    }
-                }
-            }
+    static Inet6Address removeScope(Inet6Address addr) {
+        try {
+            return (Inet6Address)InetAddress.getByAddress(addr.getAddress());
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
         }
-        return null;
     }
 
-    static void test1() throws Exception {
-        ServerSocket ssock;
-        Socket sock;
-        int port;
+    static Optional<Inet6Address> getLocalAddr() throws Exception {
+        return NetworkConfiguration.probe()
+                .ip6Addresses()
+                .filter(Inet6Address::isLinkLocalAddress)
+                .map(B6521014::removeScope)
+                .findFirst();
+    }
 
-        ssock = new ServerSocket(0);
-        port = ssock.getLocalPort();
-        sock = new Socket();
-        try {
+    static void test1(Inet6Address sin) throws Exception {
+        try (ServerSocket ssock = new ServerSocket(0);
+             Socket sock = new Socket()) {
+            int port = ssock.getLocalPort();
             sock.connect(new InetSocketAddress(sin, port), 100);
         } catch (SocketTimeoutException e) {
             // time out exception is okay
@@ -91,36 +81,29 @@
         }
     }
 
-    static void test2() throws Exception {
-        Socket sock;
-        ServerSocket ssock;
-        int port;
-
-        ssock = new ServerSocket(0);
-        ssock.setSoTimeout(100);
-        port = ssock.getLocalPort();
-        sock = new Socket();
-        sock.bind(new InetSocketAddress(sin, 0));
-        try {
+    static void test2(Inet6Address sin) throws Exception {
+        try (ServerSocket ssock = new ServerSocket(0);
+             Socket sock = new Socket()) {
+            int port = ssock.getLocalPort();
+            ssock.setSoTimeout(100);
+            sock.bind(new InetSocketAddress(sin, 0));
             sock.connect(new InetSocketAddress(sin, port), 100);
-        } catch (SocketTimeoutException e) {
+        } catch (SocketTimeoutException expected) {
             // time out exception is okay
             System.out.println("timed out when connecting.");
         }
     }
 
     public static void main(String[] args) throws Exception {
-        sin = getLocalAddr();
-        if (sin == null) {
+        Optional<Inet6Address> oaddr = getLocalAddr();
+        if (!oaddr.isPresent()) {
             System.out.println("Cannot find a link-local address.");
             return;
         }
 
-        try {
-            test1();
-            test2();
-        } catch (IOException e) {
-            throw new RuntimeException("Test failed: cannot create socket.", e);
-        }
+        Inet6Address addr = oaddr.get();
+        System.out.println("Using " + addr);
+        test1(addr);
+        test2(addr);
     }
 }
--- a/test/java/net/ipv6tests/Tests.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/test/java/net/ipv6tests/Tests.java	Mon Apr 17 08:37:15 2017 -0700
@@ -27,7 +27,10 @@
 
 public class Tests {
 
-    static boolean isWindows = System.getProperty("os.name").startsWith("Windows");
+    static final boolean isWindows =
+            System.getProperty("os.name").startsWith("Windows");
+    static final boolean isMacOS =
+            System.getProperty("os.name").contains("OS X");
 
     /**
      * performs a simple exchange of data between the two sockets
@@ -278,6 +281,8 @@
                         String dName = nic.getDisplayName();
                         if (dName != null && dName.contains("Teredo"))
                             continue;
+                    } else if (isMacOS && nic.getName().contains("awdl")) {
+                        continue;
                     }
                     try {
                         if (nic.isUp() && !nic.isLoopback())
--- a/test/java/security/SignedObject/Chain.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/test/java/security/SignedObject/Chain.java	Mon Apr 17 08:37:15 2017 -0700
@@ -33,7 +33,6 @@
 /*
  * @test
  * @bug 8050374
- * @key intermittent
  * @summary Verify a chain of signed objects
  */
 public class Chain {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/jdk/testlibrary/NetworkConfiguration.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+package jdk.testlibrary;
+
+import java.io.PrintStream;
+import java.io.UncheckedIOException;
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+import static java.net.NetworkInterface.getNetworkInterfaces;
+import static java.util.Collections.list;
+
+/**
+ * Helper class for retrieving network interfaces and local addresses
+ * suitable for testing.
+ */
+public class NetworkConfiguration {
+
+    static final boolean isWindows =
+            System.getProperty("os.name").startsWith("Windows");
+    static final boolean isMacOS =
+            System.getProperty("os.name").contains("OS X");
+
+    private Map<NetworkInterface,List<Inet4Address>> ip4Interfaces;
+    private Map<NetworkInterface,List<Inet6Address>> ip6Interfaces;
+
+    private NetworkConfiguration(Map<NetworkInterface,List<Inet4Address>> ip4Interfaces,
+                                 Map<NetworkInterface,List<Inet6Address>> ip6Interfaces)
+    {
+        this.ip4Interfaces = ip4Interfaces;
+        this.ip6Interfaces = ip6Interfaces;
+    }
+
+    /**
+     * Returns a stream of interfaces suitable for functional tests.
+     */
+    public Stream<NetworkInterface> interfaces() {
+        return Stream.concat(ip4Interfaces(), ip6Interfaces())
+                     .distinct();
+    }
+
+    /**
+     * Returns a stream of interfaces suitable for IPv4 functional tests.
+     */
+    public Stream<NetworkInterface> ip4Interfaces() {
+        return ip4Interfaces.keySet().stream()
+                .filter(NetworkConfiguration::isNotExcludedInterface)
+                .filter(hasIp4Addresses);
+    }
+
+    /**
+     * Returns a stream of interfaces suitable for IPv6 functional tests.
+     */
+    public Stream<NetworkInterface> ip6Interfaces() {
+        return ip6Interfaces.keySet().stream()
+                .filter(NetworkConfiguration::isNotExcludedInterface)
+                .filter(hasIp6Addresses);
+    }
+
+    private static boolean isNotExcludedInterface(NetworkInterface nif) {
+        if (isMacOS && nif.getName().contains("awdl"))
+            return false;
+        String dName = nif.getDisplayName();
+        if (isWindows && dName != null && dName.contains("Teredo"))
+            return false;
+        return true;
+    }
+
+    private final Predicate<NetworkInterface> hasIp4Addresses = nif -> {
+        Optional<?> addr = ip4Interfaces.get(nif).stream()
+                .filter(a -> !a.isAnyLocalAddress())
+                .findAny();
+
+        return addr.isPresent();
+    };
+
+    private final Predicate<NetworkInterface> hasIp6Addresses = nif -> {
+        Optional<?> addr = ip6Interfaces.get(nif).stream()
+                .filter(a -> !a.isAnyLocalAddress())
+                .findAny();
+
+        return addr.isPresent();
+    };
+
+
+    /**
+     * Returns a stream of interfaces suitable for IPv4 multicast tests.
+     */
+    public Stream<NetworkInterface> ip4MulticastInterfaces() {
+        return ip4Interfaces().filter(supportsIp4Multicast);
+    }
+
+    /**
+     * Returns a stream of interfaces suitable for IPv6 multicast tests.
+     */
+    public Stream<NetworkInterface> ip6MulticastInterfaces() {
+        return ip6Interfaces().filter(supportsIp6Multicast);
+    }
+
+    private final Predicate<NetworkInterface> supportsIp4Multicast = nif -> {
+        try {
+            if (!nif.supportsMulticast() || nif.isLoopback())
+                return false;
+
+            Optional<?> addr = ip4Interfaces.get(nif).stream()
+                    .filter(a -> !a.isAnyLocalAddress())
+                    .findAny();
+
+            return addr.isPresent();
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    };
+
+    private final Predicate<NetworkInterface> supportsIp6Multicast = nif -> {
+        try {
+            if (!nif.supportsMulticast() || nif.isLoopback())
+                return false;
+
+            Optional<?> addr = ip6Interfaces.get(nif).stream()
+                    .filter(a -> !a.isAnyLocalAddress())
+                    .findAny();
+
+            return addr.isPresent();
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    };
+
+    /**
+     * Returns all addresses on all "functional" interfaces.
+     */
+    public Stream<InetAddress> addresses(NetworkInterface nif) {
+        return Stream.concat(ip4Interfaces.get(nif).stream(),
+                             ip6Interfaces.get(nif).stream());
+    }
+
+    /**
+     * Returns all IPv4 addresses on all "functional" interfaces.
+     */
+    public Stream<Inet4Address> ip4Addresses() {
+        return ip4Interfaces().flatMap(nif -> ip4Addresses(nif));
+    }
+
+    /**
+     * Returns all IPv6 addresses on all "functional" interfaces.
+     */
+    public Stream<Inet6Address> ip6Addresses() {
+        return ip6Interfaces().flatMap(nif -> ip6Addresses(nif));
+    }
+
+    /**
+     * Returns all IPv4 addresses the given interface.
+     */
+    public Stream<Inet4Address> ip4Addresses(NetworkInterface nif) {
+        return ip4Interfaces.get(nif).stream();
+    }
+
+    /**
+     * Returns all IPv6 addresses for the given interface.
+     */
+    public Stream<Inet6Address> ip6Addresses(NetworkInterface nif) {
+        return ip6Interfaces.get(nif).stream();
+    }
+
+    /**
+     * Return a NetworkConfiguration instance.
+     */
+    public static NetworkConfiguration probe() throws IOException {
+        Map<NetworkInterface, List<Inet4Address>> ip4Interfaces = new HashMap<>();
+        Map<NetworkInterface, List<Inet6Address>> ip6Interfaces = new HashMap<>();
+
+        List<NetworkInterface> nifs = list(getNetworkInterfaces());
+        for (NetworkInterface nif : nifs) {
+            // ignore interfaces that are down
+            if (!nif.isUp() || nif.isPointToPoint())
+                continue;
+
+            List<Inet4Address> ip4Addresses = new LinkedList<>();
+            List<Inet6Address> ip6Addresses = new LinkedList<>();
+            ip4Interfaces.put(nif, ip4Addresses);
+            ip6Interfaces.put(nif, ip6Addresses);
+            for (InetAddress addr : list(nif.getInetAddresses())) {
+                if (addr instanceof Inet4Address)
+                    ip4Addresses.add((Inet4Address)addr);
+                else if (addr instanceof Inet6Address)
+                    ip6Addresses.add((Inet6Address)addr);
+            }
+        }
+        return new NetworkConfiguration(ip4Interfaces, ip6Interfaces);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        interfaces().forEach(nif -> sb.append(interfaceInformation(nif)));
+        return sb.toString();
+    }
+
+    /** Returns detailed information for the given interface. */
+    public static String interfaceInformation(NetworkInterface nif) {
+        StringBuilder sb = new StringBuilder();
+        try {
+            sb.append("Display name: " + nif.getDisplayName() + "\n");
+            sb.append("Name: " + nif.getName() + "\n");
+            for (InetAddress inetAddress : list(nif.getInetAddresses()))
+                sb.append("InetAddress: " + inetAddress + "\n");
+            sb.append("Up? " + nif.isUp() + "\n");
+            sb.append("Loopback? " + nif.isLoopback() + "\n");
+            sb.append("PointToPoint? " + nif.isPointToPoint() + "\n");
+            sb.append("Supports multicast? " + nif.supportsMulticast() + "\n");
+            sb.append("Virtual? " + nif.isVirtual() + "\n");
+            sb.append("Hardware address: " +
+                    Arrays.toString(nif.getHardwareAddress()) + "\n");
+            sb.append("MTU: " + nif.getMTU() + "\n");
+            sb.append("Index: " + nif.getIndex() + "\n");
+            sb.append("\n");
+            return sb.toString();
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    /** Prints all the system interface information to the give stream. */
+    public static void printSystemConfiguration(PrintStream out) {
+        try {
+            out.println("*** all system network interface configuration ***");
+            List<NetworkInterface> nifs = list(getNetworkInterfaces());
+            for (NetworkInterface nif : nifs)
+                out.print(interfaceInformation(nif));
+            out.println("*** end ***");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+}
--- a/test/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/test/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java	Mon Apr 17 08:37:15 2017 -0700
@@ -31,9 +31,9 @@
  * @bug 6216082
  * @summary  Redirect problem with HttpsURLConnection using a proxy
  * @modules java.base/sun.net.www
- * @library ..
+ * @library .. /lib/testlibrary
  * @build HttpCallback TestHttpsServer ClosedChannelList
- *        HttpTransaction TunnelProxy
+ *        HttpTransaction TunnelProxy jdk.testlibrary.NetworkConfiguration
  * @key intermittent
  * @run main/othervm B6216082
  */
@@ -43,6 +43,8 @@
 import javax.net.ssl.*;
 import java.util.*;
 
+import jdk.testlibrary.NetworkConfiguration;
+
 public class B6216082 {
     static SimpleHttpTransaction httpTrans;
     static TestHttpsServer server;
@@ -118,21 +120,17 @@
     }
 
     public static InetAddress getNonLoAddress() throws Exception {
-        NetworkInterface loNIC = NetworkInterface.getByInetAddress(InetAddress.getByName("localhost"));
-        Enumeration<NetworkInterface> nics = NetworkInterface.getNetworkInterfaces();
-        while (nics.hasMoreElements()) {
-            NetworkInterface nic = nics.nextElement();
-            if (!nic.getName().equalsIgnoreCase(loNIC.getName())) {
-                Enumeration<InetAddress> addrs = nic.getInetAddresses();
-                while (addrs.hasMoreElements()) {
-                    InetAddress addr = addrs.nextElement();
-                    if (!addr.isLoopbackAddress())
-                        return addr;
-                }
-            }
-        }
+        InetAddress lh = InetAddress.getByName("localhost");
+        NetworkInterface loNIC = NetworkInterface.getByInetAddress(lh);
 
-        return null;
+        NetworkConfiguration nc = NetworkConfiguration.probe();
+        Optional<InetAddress> oaddr = nc.interfaces()
+                .filter(nif -> !nif.getName().equalsIgnoreCase(loNIC.getName()))
+                .flatMap(nif -> nc.addresses(nif))
+                .filter(a -> !a.isLoopbackAddress())
+                .findFirst();
+
+        return oaddr.orElseGet(() -> null);
     }
 
     public static void startHttpServer() throws IOException {
--- a/test/sun/security/krb5/auto/Basic.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/test/sun/security/krb5/auto/Basic.java	Mon Apr 17 08:37:15 2017 -0700
@@ -23,50 +23,18 @@
 
 /*
  * @test
- * @bug 7152176 8164437
+ * @bug 7152176
  * @summary More krb5 tests
- * @library /test/lib
  * @compile -XDignore.symbol.file Basic.java
  * @run main/othervm Basic
  */
 
-import jdk.test.lib.process.ProcessTools;
 import sun.security.jgss.GSSUtil;
 
-import java.util.List;
-import java.util.stream.Stream;
-
+// The basic krb5 test skeleton you can copy from
 public class Basic {
 
-    public static void main(String[] args) throws Throwable {
-
-        if (args.length == 0) { // jtreg launched here
-
-            // With all modules
-            test("jdk.security.jgss");
-
-            // With limited modules
-            List<String> cmd = ProcessTools.createJavaProcessBuilder().command();
-            Stream.of(jdk.internal.misc.VM.getRuntimeArguments())
-                    .filter(arg -> arg.startsWith("--add-exports=") ||
-                            arg.startsWith("--add-opens="))
-                    .forEach(cmd::add);
-            cmd.addAll(List.of(
-                    "-Dtest.src=" + System.getProperty("test.src"),
-                    "--add-modules",
-                        "java.base,java.security.jgss,jdk.security.auth",
-                    "--limit-modules",
-                        "java.security.jgss,jdk.security.auth",
-                    "Basic",
-                    "launched-limited"));
-            ProcessTools.executeCommand(cmd.toArray(new String[cmd.size()]))
-                    .shouldHaveExitValue(0);
-        } else { // Launched by ProcessTools above, with limited modules.
-            test("java.security.jgss");
-        }
-    }
-
-    static void test(String expected) throws Exception {
+    public static void main(String[] args) throws Exception {
 
         new OneKDC(null).writeJAASConf();
 
@@ -92,12 +60,5 @@
         b.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
 
         Context.handshake(s2, b);
-
-        // Bonus test for 8164437.
-        String moduleName = c.x().getClass().getModule().getName();
-        if (!moduleName.equals(expected)) {
-            throw new Exception("Expected: " + expected
-                    + ". Actual: " + moduleName);
-        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/ModuleName.java	Mon Apr 17 08:37:15 2017 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017, 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 8164437
+ * @summary GSSContext type when jdk.security.jgss is not available
+ * @library /test/lib
+ * @compile -XDignore.symbol.file ModuleName.java
+ * @run main/othervm ModuleName
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import sun.security.jgss.GSSUtil;
+
+import java.util.List;
+import java.util.stream.Stream;
+
+public class ModuleName {
+
+    public static void main(String[] args) throws Throwable {
+
+        if (args.length == 0) { // jtreg launched here
+
+            // With all modules
+            test("jdk.security.jgss");
+
+            // With limited modules
+            List<String> cmd = ProcessTools.createJavaProcessBuilder().command();
+            Stream.of(jdk.internal.misc.VM.getRuntimeArguments())
+                    .filter(arg -> arg.startsWith("--add-exports=") ||
+                            arg.startsWith("--add-opens="))
+                    .forEach(cmd::add);
+            cmd.addAll(List.of(
+                    "-Dtest.src=" + System.getProperty("test.src"),
+                    "--add-modules",
+                        "java.base,java.security.jgss,jdk.security.auth",
+                    "--limit-modules",
+                        "java.security.jgss,jdk.security.auth",
+                    "ModuleName",
+                    "launched-limited"));
+            ProcessTools.executeCommand(cmd.toArray(new String[cmd.size()]))
+                    .shouldHaveExitValue(0);
+        } else { // Launched by ProcessTools above, with limited modules.
+            test("java.security.jgss");
+        }
+    }
+
+    static void test(String expected) throws Exception {
+
+        new OneKDC(null).writeJAASConf();
+
+        Context c = Context.fromJAAS("client");
+        c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+
+        String moduleName = c.x().getClass().getModule().getName();
+        if (!moduleName.equals(expected)) {
+            throw new Exception("Expected: " + expected
+                    + ". Actual: " + moduleName);
+        }
+    }
+}
--- a/test/tools/jlink/multireleasejar/JLinkMultiReleaseJarTest.java	Fri Apr 14 16:51:31 2017 +0300
+++ b/test/tools/jlink/multireleasejar/JLinkMultiReleaseJarTest.java	Mon Apr 17 08:37:15 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -26,16 +26,15 @@
  * @bug 8156499
  * @summary Test image creation from Multi-Release JAR
  * @author Steve Drach
- * @library /lib/testlibrary /test/lib
+ * @library /test/lib
  * @modules java.base/jdk.internal.jimage
  *          java.base/jdk.internal.module
- * @build jdk.testlibrary.FileUtils jdk.test.lib.process.*
+ * @build jdk.test.lib.process.*
  * @run testng JLinkMultiReleaseJarTest
 */
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
-import java.io.UncheckedIOException;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
@@ -54,10 +53,8 @@
 import jdk.internal.jimage.BasicImageReader;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.testlibrary.FileUtils;
 
 import org.testng.Assert;
-import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
@@ -138,23 +135,6 @@
         Assert.assertEquals(rc, 0);
     }
 
-    @AfterClass
-    public void close() throws IOException {
-        Files.walk(userdir, 1)
-                .filter(p -> !p.equals(userdir))
-                .forEach(p -> {
-                    try {
-                        if (Files.isDirectory(p)) {
-                            FileUtils.deleteFileTreeWithRetry(p);
-                        } else {
-                            FileUtils.deleteFileIfExistsWithRetry(p);
-                        }
-                    } catch (IOException x) {
-                        throw new UncheckedIOException(x);
-                    }
-                });
-    }
-
     @Test
     public void basicTest() throws Throwable {
         if (ignoreTest()) return;