changeset 17758:1df761aac102

Merge
author prr
date Thu, 25 May 2017 09:15:55 -0700
parents 78765a0b65f2 b9409a7daa6c
children c7bdf294af3f
files src/java.base/share/classes/sun/security/ssl/RecordType.java test/lib/testlibrary/ModuleInfoMaker.java test/lib/testlibrary/jdk/testlibrary/LockFreeLogManager.java test/lib/testlibrary/jdk/testlibrary/management/ThreadMXBeanTool.java
diffstat 14 files changed, 128 insertions(+), 452 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon May 22 09:34:38 2017 -0700
+++ b/.hgtags	Thu May 25 09:15:55 2017 -0700
@@ -420,3 +420,5 @@
 e78da9db6299b3fcba49300d52e2359e82fdd218 jdk-9+168
 177436a54ca13730ffc725a6e5dbfcd9486f3da3 jdk-9+169
 ef9954f6896bb0b95ac62bf769f68b59a7a56ccd jdk-9+170
+cbd65760a005766610583949b3b5c9ace92e74b3 jdk-10+7
+f0adc10ed8316e6cf316e3208c5ecf6835d22bc4 jdk-10+8
--- a/src/java.base/share/classes/sun/security/ssl/RecordType.java	Mon May 22 09:34:38 2017 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-/*
- * enumation of record type
- */
-enum RecordType {
-
-    RECORD_CHANGE_CIPHER_SPEC   (Record.ct_change_cipher_spec,
-                                    HandshakeMessage.ht_not_applicable),
-    RECORD_ALERT                (Record.ct_alert,
-                                    HandshakeMessage.ht_not_applicable),
-    RECORD_HELLO_REQUEST        (Record.ct_handshake,
-                                    HandshakeMessage.ht_hello_request),
-    RECORD_CLIENT_HELLO         (Record.ct_handshake,
-                                    HandshakeMessage.ht_client_hello),
-    RECORD_SERVER_HELLO         (Record.ct_handshake,
-                                    HandshakeMessage.ht_server_hello),
-    RECORD_HELLO_VERIFY_REQUEST (Record.ct_handshake,
-                                    HandshakeMessage.ht_hello_verify_request),
-    RECORD_NEW_SESSION_TICKET   (Record.ct_handshake,
-                                    HandshakeMessage.ht_new_session_ticket),
-    RECORD_CERTIFICATE          (Record.ct_handshake,
-                                    HandshakeMessage.ht_certificate),
-    RECORD_SERVER_KEY_EXCHANGE  (Record.ct_handshake,
-                                    HandshakeMessage.ht_server_key_exchange),
-    RECORD_CERTIFICATE_REQUEST  (Record.ct_handshake,
-                                    HandshakeMessage.ht_certificate_request),
-    RECORD_SERVER_HELLO_DONE    (Record.ct_handshake,
-                                    HandshakeMessage.ht_server_hello_done),
-    RECORD_CERTIFICATE_VERIFY   (Record.ct_handshake,
-                                    HandshakeMessage.ht_certificate_verify),
-    RECORD_CLIENT_KEY_EXCHANGE  (Record.ct_handshake,
-                                    HandshakeMessage.ht_client_key_exchange),
-    RECORD_FINISHED             (Record.ct_handshake,
-                                    HandshakeMessage.ht_finished),
-    RECORD_CERTIFICATE_URL      (Record.ct_handshake,
-                                    HandshakeMessage.ht_certificate_url),
-    RECORD_CERTIFICATE_STATUS   (Record.ct_handshake,
-                                    HandshakeMessage.ht_certificate_status),
-    RECORD_SUPPLIEMENTAL_DATA   (Record.ct_handshake,
-                                    HandshakeMessage.ht_supplemental_data),
-    RECORD_APPLICATION_DATA     (Record.ct_application_data,
-                                    HandshakeMessage.ht_not_applicable);
-
-    byte            contentType;
-    byte            handshakeType;
-
-    private RecordType(byte contentType, byte handshakeType) {
-        this.contentType = contentType;
-        this.handshakeType = handshakeType;
-    }
-
-    static RecordType valueOf(byte contentType, byte handshakeType) {
-        if (contentType == Record.ct_change_cipher_spec) {
-            return RECORD_CHANGE_CIPHER_SPEC;
-        } else if (contentType == Record.ct_alert) {
-            return RECORD_ALERT;
-        } else if (contentType == Record.ct_application_data) {
-            return RECORD_APPLICATION_DATA;
-        } else if (handshakeType == HandshakeMessage.ht_hello_request) {
-            return RECORD_HELLO_REQUEST;
-        } else if (handshakeType == HandshakeMessage.ht_client_hello) {
-            return RECORD_CLIENT_HELLO;
-        } else if (handshakeType == HandshakeMessage.ht_server_hello) {
-            return RECORD_SERVER_HELLO;
-        } else if (handshakeType == HandshakeMessage.ht_hello_verify_request) {
-            return RECORD_HELLO_VERIFY_REQUEST;
-        } else if (handshakeType == HandshakeMessage.ht_new_session_ticket) {
-            return RECORD_NEW_SESSION_TICKET;
-        } else if (handshakeType == HandshakeMessage.ht_certificate) {
-            return RECORD_CERTIFICATE;
-        } else if (handshakeType == HandshakeMessage.ht_server_key_exchange) {
-            return RECORD_SERVER_KEY_EXCHANGE;
-        } else if (handshakeType == HandshakeMessage.ht_certificate_request) {
-            return RECORD_CERTIFICATE_REQUEST;
-        } else if (handshakeType == HandshakeMessage.ht_server_hello_done) {
-            return RECORD_SERVER_HELLO_DONE;
-        } else if (handshakeType == HandshakeMessage.ht_certificate_verify) {
-            return RECORD_CERTIFICATE_VERIFY;
-        } else if (handshakeType == HandshakeMessage.ht_client_key_exchange) {
-            return RECORD_CLIENT_KEY_EXCHANGE;
-        } else if (handshakeType == HandshakeMessage.ht_finished) {
-            return RECORD_FINISHED;
-        } else if (handshakeType == HandshakeMessage.ht_certificate_url) {
-            return RECORD_CERTIFICATE_URL;
-        } else if (handshakeType == HandshakeMessage.ht_certificate_status) {
-            return RECORD_CERTIFICATE_STATUS;
-        } else if (handshakeType == HandshakeMessage.ht_supplemental_data) {
-            return RECORD_SUPPLIEMENTAL_DATA;
-        }
-
-        // otherwise, invalid record type
-        throw new IllegalArgumentException(
-                "Invalid record type (ContentType:" + contentType +
-                ", HandshakeType:" + handshakeType + ")");
-    }
-}
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java	Mon May 22 09:34:38 2017 -0700
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java	Thu May 25 09:15:55 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -513,7 +513,7 @@
         if (entry != null) {
             // Get end-entity certificate and remove from system cert store
             X509Certificate[] certChain = entry.getCertificateChain();
-            if (certChain != null) {
+            if (certChain != null && certChain.length > 0) {
 
                 try {
 
@@ -629,7 +629,9 @@
 
         for (Map.Entry<String,KeyEntry> mapEntry : entries.entrySet()) {
             KeyEntry entry = mapEntry.getValue();
-            if (entry.certChain != null && entry.certChain[0].equals(cert)) {
+            if (entry.certChain != null &&
+                entry.certChain.length > 0 &&
+                entry.certChain[0].equals(cert)) {
                 return entry.getAlias();
             }
         }
--- a/test/java/lang/Thread/ThreadStateController.java	Mon May 22 09:34:38 2017 -0700
+++ b/test/java/lang/Thread/ThreadStateController.java	Thu May 25 09:15:55 2017 -0700
@@ -27,7 +27,7 @@
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.LockSupport;
 
-import jdk.testlibrary.LockFreeLogManager;
+import jdk.test.lib.LockFreeLogger;
 import jdk.testlibrary.Utils;
 
 /**
@@ -100,7 +100,7 @@
     private final AtomicInteger iterations = new AtomicInteger();
     private final AtomicInteger interrupted = new AtomicInteger();
 
-    private final LockFreeLogManager logManager = new LockFreeLogManager();
+    private final LockFreeLogger logger = new LockFreeLogger();
 
     @Override
     public void run() {
@@ -349,7 +349,7 @@
     }
 
     private void log(String msg, Object ... params) {
-        logManager.log(msg, params);
+        logger.log(msg, params);
     }
 
     /**
@@ -361,6 +361,6 @@
     public String getLog() throws InterruptedException {
         this.join();
 
-        return logManager.toString();
+        return logger.toString();
     }
 }
--- a/test/java/lang/Thread/ThreadStateTest.java	Mon May 22 09:34:38 2017 -0700
+++ b/test/java/lang/Thread/ThreadStateTest.java	Thu May 25 09:15:55 2017 -0700
@@ -31,6 +31,7 @@
  *
  * @author  Mandy Chung
  * @library /lib/testlibrary
+ * @library /test/lib
  * @build jdk.testlibrary.*
  * @build ThreadStateTest ThreadStateController
  * @run main/othervm -Xmixed ThreadStateTest
--- a/test/java/lang/management/ThreadMXBean/Locks.java	Mon May 22 09:34:38 2017 -0700
+++ b/test/java/lang/management/ThreadMXBean/Locks.java	Thu May 25 09:15:55 2017 -0700
@@ -29,17 +29,17 @@
  * @author  Mandy Chung
  * @author  Jaroslav Bachorik
  *
- * @library /lib/testlibrary
+ * @library /test/lib
  *
- * @build jdk.testlibrary.*
  * @run main/othervm Locks
  */
 import java.lang.management.*;
 import java.util.Arrays;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.concurrent.Phaser;
 import java.util.function.Predicate;
-import jdk.testlibrary.LockFreeLogManager;
+import jdk.test.lib.LockFreeLogger;
 
 public class Locks {
 
@@ -47,7 +47,7 @@
     private static final Object OBJB = new Object();
     private static final EnhancedWaiter OBJC = new EnhancedWaiter();
     private static final ThreadMXBean TM = ManagementFactory.getThreadMXBean();
-    private static final LockFreeLogManager LOGGER = new LockFreeLogManager();
+    private static final LockFreeLogger LOGGER = new LockFreeLogger();
 
     private static String getLockName(Object lock) {
         if (lock == null) return null;
@@ -60,12 +60,12 @@
         if (t == null) {
             return;
         }
-        Optional<ThreadInfo> result = Arrays.asList(
-                TM.getThreadInfo(TM.getAllThreadIds(), true, true)).
-                stream().
-                filter(tInfo -> (tInfo != null && tInfo.getLockOwnerName() != null)
-                        ? tInfo.getLockOwnerName().equals(t.getName()) : false).
-                findAny();
+        String name = t.getName();
+        Optional<ThreadInfo> result = Arrays.stream(
+                TM.getThreadInfo(TM.getAllThreadIds(), true, true))
+                                            .filter(Objects::nonNull)
+                                            .filter(i -> name.equals(i.getLockOwnerName()))
+                                            .findAny();
         if (result.isPresent()) {
             throw new RuntimeException("Thread " + t.getName() + " is not "
                     + "supposed to be hold any lock. Currently owning lock : "
--- a/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java	Mon May 22 09:34:38 2017 -0700
+++ b/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java	Thu May 25 09:15:55 2017 -0700
@@ -31,6 +31,7 @@
  *
  * @library ../../Thread
  * @library /lib/testlibrary
+ * @library /test/lib
  *
  * @build jdk.testlibrary.*
  * @build ThreadMXBeanStateTest ThreadStateController
--- a/test/lib/testlibrary/ModuleInfoMaker.java	Mon May 22 09:34:38 2017 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Stream;
-
-import static org.testng.Assert.assertTrue;
-
-/**
- * Utility class for creating test modules.
- */
-public class ModuleInfoMaker {
-    private static String MODULE_INFO_JAVA = "module-info.java";
-    private static Pattern MODULE_PATTERN =
-        Pattern.compile("module\\s+((?:\\w+\\.)*)");
-    private static Pattern PACKAGE_PATTERN =
-                       Pattern.compile("package\\s+(((?:\\w+\\.)*)(?:\\w+))");
-    private static Pattern CLASS_PATTERN =
-          Pattern.compile("(?:public\\s+)?(?:class|enum|interface)\\s+(\\w+)");
-
-    private final Path dir;
-    public ModuleInfoMaker(Path dir) {
-        this.dir = dir;
-    }
-
-    /**
-     * Create java source files of the given module
-     */
-    public void writeJavaFiles(String module, String moduleInfoJava, String... contents)
-        throws IOException
-    {
-        Path msrc = dir.resolve(module);
-        new JavaSource(moduleInfoJava).write(msrc);
-        for (String c : contents) {
-            new JavaSource(c).write(msrc);
-        }
-    }
-
-    /**
-     * Compile the module to the given destination.
-     */
-    public void compile(String module, Path dest, String... options)
-        throws IOException
-    {
-        Path msrc = dir.resolve(module);
-        Stream<String> args =
-            Stream.concat(Arrays.stream(options),
-                          Stream.of("--module-source-path",
-                                    dir.toString()));
-        assertTrue(CompilerUtils.compile(msrc, dest, args.toArray(String[]::new)),
-                   "Fail to compile " + module);
-    }
-
-    static class JavaSource {
-        final String source;
-        JavaSource(String source) {
-            this.source = source;
-        }
-
-        /**
-         * Writes the source code to a file in a specified directory.
-         * @param dir the directory
-         * @throws IOException if there is a problem writing the file
-         */
-        public void write(Path dir) throws IOException {
-            Path file = dir.resolve(getJavaFileNameFromSource(source));
-            Files.createDirectories(file.getParent());
-            try (BufferedWriter out = Files.newBufferedWriter(file)) {
-                out.write(source.replace("\n", System.lineSeparator()));
-            }
-        }
-
-        /**
-         * Extracts the Java file name from the class declaration.
-         * This method is intended for simple files and uses regular expressions,
-         * so comments matching the pattern can make the method fail.
-         */
-        static String getJavaFileNameFromSource(String source) {
-            String packageName = null;
-
-            Matcher matcher = MODULE_PATTERN.matcher(source);
-            if (matcher.find())
-                return MODULE_INFO_JAVA;
-
-            matcher = PACKAGE_PATTERN.matcher(source);
-            if (matcher.find())
-                packageName = matcher.group(1).replace(".", "/");
-
-            matcher = CLASS_PATTERN.matcher(source);
-            if (matcher.find()) {
-                String className = matcher.group(1) + ".java";
-                return (packageName == null) ? className : packageName + "/" + className;
-            } else if (packageName != null) {
-                return packageName + "/package-info.java";
-            } else {
-                throw new Error("Could not extract the java class " +
-                    "name from the provided source");
-            }
-        }
-    }
-}
--- a/test/lib/testlibrary/jdk/testlibrary/LockFreeLogManager.java	Mon May 22 09:34:38 2017 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2014, 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.util.Collection;
-import java.util.Formatter;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
-
-/**
- * A log manager designed specifically to allow collecting ordered log messages
- * in a multi-threaded environment without involving any kind of locking.
- * <p>
- * It is particularly useful in situations when one needs to assert various
- * details about the tested thread state or the locks it hold while also wanting
- * to produce diagnostic log messages.
- * <p>
- * The log manager does not provide any guarantees about the completness of the
- * logs written from different threads - it is up to the caller to make sure
- * {@code toString()} method is called only when all the activity has ceased
- * and the per-thread logs contain all the necessary data.
- *
- * @author Jaroslav Bachorik
- **/
-public class LockFreeLogManager {
-    private final AtomicInteger logCntr = new AtomicInteger(0);
-    private final Collection<Map<Integer, String>> allRecords = new ConcurrentLinkedQueue<>();
-    private final ThreadLocal<Map<Integer, String>> records = new ThreadLocal<Map<Integer, String>>() {
-        @Override
-        protected Map<Integer, String> initialValue() {
-            Map<Integer, String> m = new ConcurrentHashMap<>();
-            allRecords.add(m);
-            return m;
-        }
-
-    };
-
-    /**
-     * Log a message
-     * @param format Message format
-     * @param params Message parameters
-     */
-    public void log(String format, Object ... params) {
-        int id = logCntr.getAndIncrement();
-        try (Formatter formatter = new Formatter()) {
-            records.get().put(id, formatter.format(format, params).toString());
-        }
-    }
-
-    /**
-     * Will generate an aggregated log of chronologically ordered messages.
-     * <p>
-     * Make sure that you call this method only when all the related threads
-     * have finished; otherwise you might get incomplete data.
-     *
-     * @return An aggregated log of chronologically ordered messages
-     */
-    @Override
-    public String toString() {
-        return allRecords.stream()
-            .flatMap(m->m.entrySet().stream())
-            .sorted((l, r)->l.getKey().compareTo(r.getKey()))
-            .map(e->e.getValue())
-            .collect(Collectors.joining());
-    }
-}
--- a/test/lib/testlibrary/jdk/testlibrary/management/ThreadMXBeanTool.java	Mon May 22 09:34:38 2017 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.testlibrary.management;
-
-import java.lang.management.ManagementFactory;
-import java.lang.management.ThreadInfo;
-import java.lang.management.ThreadMXBean;
-import java.util.concurrent.TimeoutException;
-
-/**
- * A few utility methods to use ThreadMXBean.
- */
-public final class ThreadMXBeanTool {
-
-    /**
-     * Waits until {@link Thread} is in the certain {@link State}
-     * and blocking on {@code object}.
-     *
-     * @param state The thread state
-     * @param object The object to block on
-     */
-    public static void waitUntilBlockingOnObject(Thread thread, Thread.State state, Object object)
-        throws InterruptedException {
-        String want = object == null ? null : object.getClass().getName() + '@'
-                + Integer.toHexString(System.identityHashCode(object));
-        ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
-        while (thread.isAlive()) {
-            ThreadInfo ti = tmx.getThreadInfo(thread.getId());
-            if (ti.getThreadState() == state
-                    && (want == null || want.equals(ti.getLockName()))) {
-                return;
-            }
-            Thread.sleep(1);
-        }
-    }
-
-    /**
-     * Waits until {@link Thread} is in native.
-     */
-    public static void waitUntilInNative(Thread thread) throws InterruptedException {
-        ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
-        while (thread.isAlive()) {
-            ThreadInfo ti = tmx.getThreadInfo(thread.getId());
-            if (ti.isInNative()) {
-                return;
-            }
-            Thread.sleep(1);
-        }
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/mscapi/KeyStoreEmptyCertChain.java	Thu May 25 09:15:55 2017 -0700
@@ -0,0 +1,81 @@
+/*
+ * 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 8172244
+ * @summary Verify that no exception is thrown with empty cert chain
+ *    in MSCAPI.
+ * @requires os.family == "windows"
+ * @modules java.base/sun.security.tools.keytool java.base/sun.security.x509
+ * @run main/othervm --add-opens java.base/java.security=ALL-UNNAMED
+ *      KeyStoreEmptyCertChain
+ */
+
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import sun.security.x509.X500Name;
+import sun.security.tools.keytool.CertAndKeyGen;
+import java.security.KeyPairGenerator;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.KeyStoreSpi;
+import java.lang.reflect.*;
+
+public class KeyStoreEmptyCertChain {
+
+    public static void main(String[] args) {
+
+        try {
+
+            KeyStore keyStore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
+            keyStore.load(null, null);
+
+            // Generate a certificate to use for testing
+            CertAndKeyGen gen = new CertAndKeyGen("RSA", "SHA256withRSA");
+            gen.generate(2048);
+            Certificate cert =
+                gen.getSelfCertificate(new X500Name("CN=test"), 3600);
+            String alias = "JDK-8172244";
+            char[] password = "password".toCharArray();
+            KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+
+            // generate a private key for the certificate
+            kpg.initialize(2048);
+            KeyPair keyPair = kpg.generateKeyPair();
+            PrivateKey privKey = keyPair.getPrivate();
+            // need to bypass checks to store the private key without the cert
+            Field spiField = KeyStore.class.getDeclaredField("keyStoreSpi");
+            spiField.setAccessible(true);
+            KeyStoreSpi spi = (KeyStoreSpi) spiField.get(keyStore);
+            spi.engineSetKeyEntry(alias, privKey, password, new Certificate[0]);
+            keyStore.store(null, null);
+
+            keyStore.getCertificateAlias(cert);
+            keyStore.deleteEntry(alias);
+            // test passes if no exception is thrown
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+}
--- a/test/tools/jmod/hashes/HashesTest.java	Mon May 22 09:34:38 2017 -0700
+++ b/test/tools/jmod/hashes/HashesTest.java	Thu May 25 09:15:55 2017 -0700
@@ -25,13 +25,12 @@
  * @test
  * @bug 8160286
  * @summary Test the recording and checking of module hashes
- * @library /lib/testlibrary
+ * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.base/jdk.internal.module
  *          jdk.compiler
  *          jdk.jartool
  *          jdk.jlink
- * @build CompilerUtils ModuleInfoMaker
  * @run testng HashesTest
  */
 
@@ -62,6 +61,8 @@
 import jdk.internal.module.ModuleHashes;
 import jdk.internal.module.ModulePath;
 
+import jdk.test.lib.compiler.ModuleInfoMaker;
+
 import org.testng.annotations.Test;
 
 import static org.testng.Assert.*;
@@ -382,7 +383,7 @@
         makeModule(mn, null, deps);
     }
 
-    private void makeModule(String mn, ModuleDescriptor.Requires.Modifier mod,  String... deps)
+    private void makeModule(String mn, ModuleDescriptor.Requires.Modifier mod, String... deps)
         throws IOException
     {
         if (mod != null && mod != TRANSITIVE && mod != STATIC) {
@@ -390,23 +391,23 @@
         }
 
         StringBuilder sb = new StringBuilder();
-        sb.append("module " + mn + " {").append("\n");
-        Arrays.stream(deps).forEach(req -> {
-            sb.append("    requires ");
-            if (mod != null) {
-                sb.append(mod.toString().toLowerCase()).append(" ");
-            }
-            sb.append(req + ";\n");
-        });
+        sb.append("module ")
+          .append(mn)
+          .append(" {")
+          .append("\n");
+        Arrays.stream(deps)
+              .forEach(req -> {
+                  sb.append("    requires ");
+                  if (mod != null) {
+                      sb.append(mod.toString().toLowerCase())
+                        .append(" ");
+                  }
+                  sb.append(req)
+                    .append(";\n");
+              });
         sb.append("}\n");
         builder.writeJavaFiles(mn, sb.toString());
-
-        compileModule(mn, srcDir);
-    }
-
-    private void compileModule(String moduleName, Path src) throws IOException {
-        Path msrc = src.resolve(moduleName);
-        assertTrue(CompilerUtils.compile(msrc, mods, "--module-source-path", src.toString()));
+        builder.compile(mn, mods);
     }
 
     private void jmodHashModules(String moduleName, String hashModulesPattern) {
--- a/test/tools/launcher/modules/addexports/AddExportsTestWarningError.java	Mon May 22 09:34:38 2017 -0700
+++ b/test/tools/launcher/modules/addexports/AddExportsTestWarningError.java	Thu May 25 09:15:55 2017 -0700
@@ -25,9 +25,8 @@
  * @test
  * @bug 8168836
  * @summary Basic argument validation for --add-exports
- * @library /lib/testlibrary
+ * @library /lib/testlibrary /test/lib
  * @modules jdk.compiler
- * @build AddExportsTestWarningError CompilerUtils ModuleInfoMaker
  * @build jdk.testlibrary.*
  * @run testng AddExportsTestWarningError
  */
@@ -40,6 +39,7 @@
 import java.util.Arrays;
 import java.util.stream.Stream;
 
+import jdk.test.lib.compiler.ModuleInfoMaker;
 import jdk.testlibrary.OutputAnalyzer;
 import static jdk.testlibrary.ProcessTools.*;
 
@@ -48,7 +48,6 @@
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
 
-
 @Test
 public class AddExportsTestWarningError {
 
--- a/test/tools/launcher/modules/addreads/AddReadsTestWarningError.java	Mon May 22 09:34:38 2017 -0700
+++ b/test/tools/launcher/modules/addreads/AddReadsTestWarningError.java	Thu May 25 09:15:55 2017 -0700
@@ -25,9 +25,9 @@
  * @test
  * @bug 8168836
  * @summary  Basic argument validation for --add-reads
- * @library /lib/testlibrary
+ * @library /lib/testlibrary /test/lib
  * @modules jdk.compiler
- * @build AddReadsTestWarningError CompilerUtils ModuleInfoMaker
+ * @build AddReadsTestWarningError
  * @build jdk.testlibrary.*
  * @run testng AddReadsTestWarningError
  */
@@ -40,6 +40,7 @@
 import java.util.Arrays;
 import java.util.stream.Stream;
 
+import jdk.test.lib.compiler.ModuleInfoMaker;
 import jdk.testlibrary.OutputAnalyzer;
 import static jdk.testlibrary.ProcessTools.*;
 
@@ -48,7 +49,6 @@
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
 
-
 @Test
 public class AddReadsTestWarningError {