Merge JDK-8200758-branch
authorherrick
Fri, 12 Oct 2018 18:58:40 -0400
branchJDK-8200758-branch
changeset 56962 a769ad2d40d6
parent 56959 973e113ced9a (current diff)
parent 52112 76c87b213fa0 (diff)
child 56963 eaca4369b068
Merge
test/jdk/lib/testlibrary/ModuleTargetHelper.java
test/jdk/lib/testlibrary/ModuleUtils.java
--- a/make/lib/Lib-jdk.hotspot.agent.gmk	Thu Oct 11 20:58:37 2018 -0400
+++ b/make/lib/Lib-jdk.hotspot.agent.gmk	Fri Oct 12 18:58:40 2018 -0400
@@ -44,7 +44,12 @@
   ifeq ($(OPENJDK_TARGET_CPU), x86_64)
     SA_CXXFLAGS := -DWIN64
   else
-    SA_CXXFLAGS := -RTC1
+    # Only add /RTC1 flag for debug builds as it's
+    # incompatible with release type builds. See
+    # https://msdn.microsoft.com/en-us/library/8wtf2dfz.aspx
+    ifeq ($(DEBUG_LEVEL),slowdebug)
+      SA_CXXFLAGS := -RTC1
+    endif
   endif
 endif
 
--- a/src/hotspot/cpu/sparc/nativeInst_sparc.cpp	Thu Oct 11 20:58:37 2018 -0400
+++ b/src/hotspot/cpu/sparc/nativeInst_sparc.cpp	Fri Oct 12 18:58:40 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -205,9 +205,9 @@
   uint idx;
   int offsets[] = {
     0x0,
-    0xfffffff0,
-    0x7ffffff0,
-    0x80000000,
+    (int)0xfffffff0,
+    (int)0x7ffffff0,
+    (int)0x80000000,
     0x20,
     0x4000,
   };
@@ -361,9 +361,9 @@
   uint idx;
   int offsets[] = {
     0x0,
-    0x7fffffff,
-    0x80000000,
-    0xffffffff,
+    (int)0x7fffffff,
+    (int)0x80000000,
+    (int)0xffffffff,
     0x20,
     4096,
     4097,
@@ -534,9 +534,9 @@
   uint idx;
   int offsets[] = {
     0x0,
-    0x7fffffff,
-    0x80000000,
-    0xffffffff,
+    (int)0x7fffffff,
+    (int)0x80000000,
+    (int)0xffffffff,
     0x20,
     4096,
     4097,
@@ -630,9 +630,9 @@
   uint idx1;
   int offsets[] = {
     0x0,
-    0xffffffff,
-    0x7fffffff,
-    0x80000000,
+    (int)0xffffffff,
+    (int)0x7fffffff,
+    (int)0x80000000,
     4096,
     4097,
     0x20,
@@ -751,9 +751,9 @@
   uint idx;
   int offsets[] = {
     0x0,
-    0xffffffff,
-    0x7fffffff,
-    0x80000000,
+    (int)0xffffffff,
+    (int)0x7fffffff,
+    (int)0x80000000,
     4096,
     4097,
     0x20,
--- a/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp	Thu Oct 11 20:58:37 2018 -0400
+++ b/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp	Fri Oct 12 18:58:40 2018 -0400
@@ -35,9 +35,6 @@
 
 #define BUFFER_SIZE 30*wordSize
 
-// Instead of issuing lfence for LoadLoad barrier, we create data dependency
-// between loads, which is more efficient than lfence.
-
 // Common register usage:
 // rax/xmm0: result
 // c_rarg0:    jni env
@@ -77,12 +74,6 @@
   __ mov   (robj, c_rarg1);
   __ testb (rcounter, 1);
   __ jcc (Assembler::notZero, slow);
-
-  __ xorptr(robj, rcounter);
-  __ xorptr(robj, rcounter);  // obj, since
-                              // robj ^ rcounter ^ rcounter == robj
-                              // robj is data dependent on rcounter.
-
   __ mov   (roffset, c_rarg2);
   __ shrptr(roffset, 2);                         // offset
 
@@ -103,12 +94,7 @@
     default:        ShouldNotReachHere();
   }
 
-  // create data dependency on rax
-  __ lea(rcounter_addr, counter);
-  __ xorptr(rcounter_addr, rax);
-  __ xorptr(rcounter_addr, rax);
-  __ cmpl (rcounter, Address(rcounter_addr, 0));
-
+  __ cmp32 (rcounter, counter);
   __ jcc (Assembler::notEqual, slow);
 
   __ ret (0);
@@ -178,11 +164,6 @@
   __ testb (rcounter, 1);
   __ jcc (Assembler::notZero, slow);
 
-  __ xorptr(robj, rcounter);
-  __ xorptr(robj, rcounter);  // obj, since
-                              // robj ^ rcounter ^ rcounter == robj
-                              // robj is data dependent on rcounter.
-
   // Both robj and rtmp are clobbered by try_resolve_jobject_in_native.
   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
   bs->try_resolve_jobject_in_native(masm, /* jni_env */ c_rarg0, robj, rtmp, slow);
@@ -198,13 +179,7 @@
     case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break;
     default:        ShouldNotReachHere();
   }
-
-  __ lea(rcounter_addr, counter);
-  __ movdq (rax, xmm0);
-  // counter address is data dependent on xmm0.
-  __ xorptr(rcounter_addr, rax);
-  __ xorptr(rcounter_addr, rax);
-  __ cmpl (rcounter, Address(rcounter_addr, 0));
+  __ cmp32 (rcounter, counter);
   __ jcc (Assembler::notEqual, slow);
 
   __ ret (0);
--- a/src/hotspot/os/aix/os_aix.cpp	Thu Oct 11 20:58:37 2018 -0400
+++ b/src/hotspot/os/aix/os_aix.cpp	Fri Oct 12 18:58:40 2018 -0400
@@ -4259,7 +4259,7 @@
 // or -1 on failure (e.g. can't fork a new process).
 // Unlike system(), this function can be called from signal handler. It
 // doesn't block SIGINT et al.
-int os::fork_and_exec(char* cmd) {
+int os::fork_and_exec(char* cmd, bool use_vfork_if_available) {
   char * argv[4] = {"sh", "-c", cmd, NULL};
 
   pid_t pid = fork();
--- a/src/hotspot/os/bsd/os_bsd.cpp	Thu Oct 11 20:58:37 2018 -0400
+++ b/src/hotspot/os/bsd/os_bsd.cpp	Fri Oct 12 18:58:40 2018 -0400
@@ -3785,7 +3785,7 @@
 // or -1 on failure (e.g. can't fork a new process).
 // Unlike system(), this function can be called from signal handler. It
 // doesn't block SIGINT et al.
-int os::fork_and_exec(char* cmd) {
+int os::fork_and_exec(char* cmd, bool use_vfork_if_available) {
   const char * argv[4] = {"sh", "-c", cmd, NULL};
 
   // fork() in BsdThreads/NPTL is not async-safe. It needs to run
--- a/src/hotspot/os/linux/os_linux.cpp	Thu Oct 11 20:58:37 2018 -0400
+++ b/src/hotspot/os/linux/os_linux.cpp	Fri Oct 12 18:58:40 2018 -0400
@@ -5676,10 +5676,16 @@
 // or -1 on failure (e.g. can't fork a new process).
 // Unlike system(), this function can be called from signal handler. It
 // doesn't block SIGINT et al.
-int os::fork_and_exec(char* cmd) {
+int os::fork_and_exec(char* cmd, bool use_vfork_if_available) {
   const char * argv[4] = {"sh", "-c", cmd, NULL};
 
-  pid_t pid = fork();
+  pid_t pid ;
+
+  if (use_vfork_if_available) {
+    pid = vfork();
+  } else {
+    pid = fork();
+  }
 
   if (pid < 0) {
     // fork failed
--- a/src/hotspot/os/solaris/os_solaris.cpp	Thu Oct 11 20:58:37 2018 -0400
+++ b/src/hotspot/os/solaris/os_solaris.cpp	Fri Oct 12 18:58:40 2018 -0400
@@ -1567,11 +1567,11 @@
   }
 
   typedef struct {
-    Elf32_Half  code;         // Actual value as defined in elf.h
-    Elf32_Half  compat_class; // Compatibility of archs at VM's sense
-    char        elf_class;    // 32 or 64 bit
-    char        endianess;    // MSB or LSB
-    char*       name;         // String representation
+    Elf32_Half    code;         // Actual value as defined in elf.h
+    Elf32_Half    compat_class; // Compatibility of archs at VM's sense
+    unsigned char elf_class;    // 32 or 64 bit
+    unsigned char endianess;    // MSB or LSB
+    char*         name;         // String representation
   } arch_t;
 
   static const arch_t arch_array[]={
@@ -5252,7 +5252,7 @@
 // or -1 on failure (e.g. can't fork a new process).
 // Unlike system(), this function can be called from signal handler. It
 // doesn't block SIGINT et al.
-int os::fork_and_exec(char* cmd) {
+int os::fork_and_exec(char* cmd, bool use_vfork_if_available) {
   char * argv[4];
   argv[0] = (char *)"sh";
   argv[1] = (char *)"-c";
--- a/src/hotspot/os/windows/os_windows.cpp	Thu Oct 11 20:58:37 2018 -0400
+++ b/src/hotspot/os/windows/os_windows.cpp	Fri Oct 12 18:58:40 2018 -0400
@@ -5254,7 +5254,7 @@
 
 // Run the specified command in a separate process. Return its exit value,
 // or -1 on failure (e.g. can't create a new process).
-int os::fork_and_exec(char* cmd) {
+int os::fork_and_exec(char* cmd, bool use_vfork_if_available) {
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
   DWORD exit_code;
--- a/src/hotspot/share/oops/compressedOops.inline.hpp	Thu Oct 11 20:58:37 2018 -0400
+++ b/src/hotspot/share/oops/compressedOops.inline.hpp	Fri Oct 12 18:58:40 2018 -0400
@@ -66,7 +66,7 @@
     assert(OopEncodingHeapMax > pd, "change encoding max if new encoding");
     uint64_t result = pd >> shift;
     assert((result & CONST64(0xffffffff00000000)) == 0, "narrow oop overflow");
-    assert(decode(result) == v, "reversibility");
+    assert(oopDesc::equals_raw(decode(result), v), "reversibility");
     return (narrowOop)result;
   }
 
--- a/src/hotspot/share/runtime/os.hpp	Thu Oct 11 20:58:37 2018 -0400
+++ b/src/hotspot/share/runtime/os.hpp	Fri Oct 12 18:58:40 2018 -0400
@@ -543,7 +543,7 @@
   static char* do_you_want_to_debug(const char* message);
 
   // run cmd in a separate process and return its exit code; or -1 on failures
-  static int fork_and_exec(char *cmd);
+  static int fork_and_exec(char *cmd, bool use_vfork_if_available = false);
 
   // Call ::exit() on all platforms but Windows
   static void exit(int num);
--- a/src/hotspot/share/runtime/vframe.cpp	Thu Oct 11 20:58:37 2018 -0400
+++ b/src/hotspot/share/runtime/vframe.cpp	Fri Oct 12 18:58:40 2018 -0400
@@ -134,7 +134,7 @@
     //
     // Skip the monitor that the thread is blocked to enter or waiting on
     //
-    if (!found_first_monitor && (obj == pending_obj || obj == waiting_obj)) {
+    if (!found_first_monitor && (oopDesc::equals(obj, pending_obj) || oopDesc::equals(obj, waiting_obj))) {
       continue;
     }
     found_first_monitor = true;
--- a/src/hotspot/share/utilities/vmError.cpp	Thu Oct 11 20:58:37 2018 -0400
+++ b/src/hotspot/share/utilities/vmError.cpp	Fri Oct 12 18:58:40 2018 -0400
@@ -1565,7 +1565,7 @@
 #endif
     tty->print_cr("\"%s\"...", cmd);
 
-    if (os::fork_and_exec(cmd) < 0) {
+    if (os::fork_and_exec(cmd, true) < 0) {
       tty->print_cr("os::fork_and_exec failed: %s (%s=%d)",
                      os::strerror(errno), os::errno_name(errno), errno);
     }
--- a/src/java.base/share/classes/java/net/SocketInputStream.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/src/java.base/share/classes/java/net/SocketInputStream.java	Fri Oct 12 18:58:40 2018 -0400
@@ -232,7 +232,11 @@
      * @return the number of immediately available bytes
      */
     public int available() throws IOException {
-        return impl.available();
+        if (eof) {
+            return 0;
+        } else {
+            return impl.available();
+        }
     }
 
     /**
--- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java	Fri Oct 12 18:58:40 2018 -0400
@@ -133,9 +133,7 @@
         // A case insensitive TreeSet of strings.
         TreeSet<String> treeSet = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
         treeSet.addAll(Set.of("connection", "content-length",
-                "date", "expect", "from", "host", "origin",
-                "referer", "upgrade",
-                "via", "warning"));
+                "date", "expect", "from", "host", "upgrade", "via", "warning"));
         DISALLOWED_HEADERS_SET = Collections.unmodifiableSet(treeSet);
     }
 
--- a/test/hotspot/jtreg/runtime/jni/terminatedThread/TestTerminatedThread.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/hotspot/jtreg/runtime/jni/terminatedThread/TestTerminatedThread.java	Fri Oct 12 18:58:40 2018 -0400
@@ -85,10 +85,14 @@
             System.out.println("Calling getThreadCpuTime ...");
             long t1 = mbean.getThreadCpuTime(t.getId());
             if (t1 != -1) {
-                throw new RuntimeException("Invalid ThreadCpuTime returned = " +
-                                           t1 + " expected = -1");
+                // At least on PPC, we know threads can still be around a short
+                // instant. In some stress scenarios we seem to grab times of
+                // new threads started with the same thread id. In these cases
+                // we get here.
+                System.out.println("Unexpected: thread still reports CPU time: " + t1);
+            } else {
+                System.out.println("Okay: getThreadCpuTime() reported -1 as expected");
             }
-            System.out.println("Okay: getThreadCpuTime() reported -1 as expected");
         } else {
             System.out.println("Skipping Thread CPU time test as it's not supported");
         }
@@ -96,10 +100,14 @@
         System.out.println("Calling getThreadUserTime ...");
         long t1 = mbean.getThreadUserTime(t.getId());
         if (t1 != -1) {
-            throw new RuntimeException("Invalid ThreadUserTime returned = " +
-                                       t1 + " expected = -1");
+            // At least on PPC, we know threads can still be around a short
+            // instant. In some stress scenarios we seem to grab times of
+            // new threads started with the same thread id. In these cases
+            // we get here.
+            System.out.println("Unexpected: thread still reports User time: " + t1);
+        } else {
+            System.out.println("Okay: getThreadUserTime() reported -1 as expected");
         }
-        System.out.println("Okay: getThreadUserTime() reported -1 as expected");
 
         System.out.println("Calling getThreadInfo ...");
         ThreadInfo info = mbean.getThreadInfo(t.getId());
--- a/test/jdk/ProblemList.txt	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/ProblemList.txt	Fri Oct 12 18:58:40 2018 -0400
@@ -835,8 +835,6 @@
 
 # jdk_jdi
 
-com/sun/jdi/BasicJDWPConnectionTest.java                        8195703 generic-all
-
 com/sun/jdi/RepStep.java                                        8043571 generic-all
 
 com/sun/jdi/sde/SourceDebugExtensionTest.java                   8158066 windows-all
--- a/test/jdk/com/sun/jdi/BasicJDWPConnectionTest.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/com/sun/jdi/BasicJDWPConnectionTest.java	Fri Oct 12 18:58:40 2018 -0400
@@ -29,17 +29,15 @@
  */
 
 import java.io.IOException;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
 
 import java.net.Socket;
 import java.net.SocketException;
 
 import jdk.test.lib.apps.LingeredApp;
-import jdk.test.lib.Utils;
 
 import java.util.ArrayList;
-import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 
 public class BasicJDWPConnectionTest {
@@ -64,25 +62,37 @@
         return res;
     }
 
-    public static ArrayList<String> prepareCmd(int port, String allowOpt) {
-         String address = "*:" + String.valueOf(port);
+    public static ArrayList<String> prepareCmd(String allowOpt) {
          ArrayList<String> cmd = new ArrayList<>();
 
          String jdwpArgs = "-agentlib:jdwp=transport=dt_socket,server=y," +
-                           "suspend=n,address=" + address + allowOpt;
+                           "suspend=n,address=*:0" + allowOpt;
          cmd.add(jdwpArgs);
          return cmd;
     }
 
+    private static Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(\\d+)\\b");
+    private static int detectPort(String s) {
+        Matcher m = listenRegexp.matcher(s);
+        if (!m.find()) {
+            throw new RuntimeException("Could not detect port from '" + s + "'");
+        }
+        // m.group(1) is transport, m.group(2) is port
+        return Integer.parseInt(m.group(2));
+    }
+
     public static void positiveTest(String testName, String allowOpt)
         throws InterruptedException, IOException {
         System.err.println("\nStarting " + testName);
-        int port = Utils.getFreePort();
-        ArrayList<String> cmd = prepareCmd(port, allowOpt);
+        ArrayList<String> cmd = prepareCmd(allowOpt);
 
         LingeredApp a = LingeredApp.startApp(cmd);
-        int res = handshake(port);
-        a.stopApp();
+        int res;
+        try {
+            res = handshake(detectPort(a.getProcessStdout()));
+        } finally {
+            a.stopApp();
+        }
         if (res < 0) {
             throw new RuntimeException(testName + " FAILED");
         }
@@ -92,12 +102,15 @@
     public static void negativeTest(String testName, String allowOpt)
         throws InterruptedException, IOException {
         System.err.println("\nStarting " + testName);
-        int port = Utils.getFreePort();
-        ArrayList<String> cmd = prepareCmd(port, allowOpt);
+        ArrayList<String> cmd = prepareCmd(allowOpt);
 
         LingeredApp a = LingeredApp.startApp(cmd);
-        int res = handshake(port);
-        a.stopApp();
+        int res;
+        try {
+            res = handshake(detectPort(a.getProcessStdout()));
+        } finally {
+            a.stopApp();
+        }
         if (res > 0) {
             System.err.println(testName + ": res=" + res);
             throw new RuntimeException(testName + " FAILED");
@@ -109,16 +122,18 @@
     public static void badAllowOptionTest(String testName, String allowOpt)
         throws InterruptedException, IOException {
         System.err.println("\nStarting " + testName);
-        int port = Utils.getFreePort();
-        ArrayList<String> cmd = prepareCmd(port, allowOpt);
+        ArrayList<String> cmd = prepareCmd(allowOpt);
 
+        LingeredApp a;
         try {
-            LingeredApp a = LingeredApp.startApp(cmd);
+            a = LingeredApp.startApp(cmd);
         } catch (IOException ex) {
             System.err.println(testName + ": caught expected IOException");
             System.err.println(testName + " PASSED");
             return;
         }
+        // LingeredApp.startApp is expected to fail, but if not, terminate the app
+        a.stopApp();
         throw new RuntimeException(testName + " FAILED");
     }
 
@@ -174,26 +189,16 @@
         badAllowOptionTest("ExplicitMultiDefault2Test", allowOpt);
     }
 
-    public static void main(String[] args) {
-        try {
-            DefaultTest();
-            ExplicitDefaultTest();
-            AllowTest();
-            MultiAllowTest();
-            DenyTest();
-            MultiDenyTest();
-            EmptyAllowOptionTest();
-            ExplicitMultiDefault1Test();
-            ExplicitMultiDefault2Test();
-            System.err.println("\nTest PASSED");
-        } catch (InterruptedException ex) {
-            System.err.println("\nTest ERROR, getFreePort");
-            ex.printStackTrace();
-            System.exit(3);
-        } catch (IOException ex) {
-            System.err.println("\nTest ERROR");
-            ex.printStackTrace();
-            System.exit(3);
-        }
+    public static void main(String[] args) throws Exception {
+        DefaultTest();
+        ExplicitDefaultTest();
+        AllowTest();
+        MultiAllowTest();
+        DenyTest();
+        MultiDenyTest();
+        EmptyAllowOptionTest();
+        ExplicitMultiDefault1Test();
+        ExplicitMultiDefault2Test();
+        System.err.println("\nTest PASSED");
     }
 }
--- a/test/jdk/com/sun/jdi/DoubleAgentTest.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/com/sun/jdi/DoubleAgentTest.java	Fri Oct 12 18:58:40 2018 -0400
@@ -41,10 +41,8 @@
             "test.classes", ".");
 
     public static void main(String[] args) throws Throwable {
-        int port = Utils.getFreePort();
-
         String jdwpOption = "-agentlib:jdwp=transport=dt_socket"
-                         + ",server=y" + ",suspend=n" + ",address=*:" + String.valueOf(port);
+                         + ",server=y" + ",suspend=n" + ",address=*:0";
 
         OutputAnalyzer output = ProcessTools.executeTestJvm("-classpath",
                 TEST_CLASSES,
--- a/test/jdk/java/lang/ModuleLayer/BasicLayerTest.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/java/lang/ModuleLayer/BasicLayerTest.java	Fri Oct 12 18:58:40 2018 -0400
@@ -23,9 +23,10 @@
 
 /**
  * @test
- * @library /lib/testlibrary
+ * @library /test/lib
  * @modules java.base/jdk.internal.misc
- * @build BasicLayerTest ModuleUtils
+ * @build BasicLayerTest
+ *        jdk.test.lib.util.ModuleUtils
  * @compile layertest/Test.java
  * @run testng BasicLayerTest
  * @summary Basic tests for java.lang.ModuleLayer
@@ -41,6 +42,8 @@
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import jdk.test.lib.util.ModuleUtils;
+
 import jdk.internal.misc.SharedSecrets;
 
 import org.testng.annotations.DataProvider;
--- a/test/jdk/java/lang/ModuleLayer/LayerAndLoadersTest.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/java/lang/ModuleLayer/LayerAndLoadersTest.java	Fri Oct 12 18:58:40 2018 -0400
@@ -23,9 +23,11 @@
 
 /**
  * @test
- * @library /lib/testlibrary /test/lib
+ * @library /test/lib
  * @modules jdk.compiler
- * @build LayerAndLoadersTest jdk.test.lib.compiler.CompilerUtils ModuleUtils
+ * @build LayerAndLoadersTest
+ *        jdk.test.lib.compiler.CompilerUtils
+ *        jdk.test.lib.util.ModuleUtils
  * @run testng LayerAndLoadersTest
  * @summary Tests for java.lang.ModuleLayer@defineModulesWithXXX methods
  */
@@ -54,6 +56,7 @@
 import java.util.stream.Collectors;
 
 import jdk.test.lib.compiler.CompilerUtils;
+import jdk.test.lib.util.ModuleUtils;
 
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
--- a/test/jdk/java/lang/ModuleLayer/LayerControllerTest.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/java/lang/ModuleLayer/LayerControllerTest.java	Fri Oct 12 18:58:40 2018 -0400
@@ -23,8 +23,9 @@
 
 /**
  * @test
- * @library /lib/testlibrary
- * @build LayerControllerTest ModuleUtils
+ * @library /test/lib
+ * @build LayerControllerTest
+ *        jdk.test.lib.util.ModuleUtils
  * @run testng LayerControllerTest
  * @summary Basic tests for java.lang.ModuleLayer.Controller
  */
@@ -35,6 +36,8 @@
 import java.util.List;
 import java.util.Set;
 
+import jdk.test.lib.util.ModuleUtils;
+
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
 
--- a/test/jdk/java/lang/module/AutomaticModulesTest.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/java/lang/module/AutomaticModulesTest.java	Fri Oct 12 18:58:40 2018 -0400
@@ -23,9 +23,10 @@
 
 /**
  * @test
- * @library /lib/testlibrary /test/lib
- * @build AutomaticModulesTest ModuleUtils
+ * @library /test/lib
+ * @build AutomaticModulesTest
  *        jdk.test.lib.util.JarUtils
+ *        jdk.test.lib.util.ModuleUtils
  * @run testng AutomaticModulesTest
  * @summary Basic tests for automatic modules
  */
@@ -50,6 +51,7 @@
 import java.util.stream.Stream;
 
 import jdk.test.lib.util.JarUtils;
+import jdk.test.lib.util.ModuleUtils;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
--- a/test/jdk/java/lang/module/ConfigurationTest.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/java/lang/module/ConfigurationTest.java	Fri Oct 12 18:58:40 2018 -0400
@@ -23,10 +23,11 @@
 
 /**
  * @test
- * @library /lib/testlibrary
+ * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.base/jdk.internal.module
- * @build ConfigurationTest ModuleUtils
+ * @build ConfigurationTest
+ *        jdk.test.lib.util.ModuleUtils
  * @run testng ConfigurationTest
  * @summary Basic tests for java.lang.module.Configuration
  */
@@ -47,6 +48,8 @@
 import java.util.Optional;
 import java.util.Set;
 
+import jdk.test.lib.util.ModuleUtils;
+
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.module.ModuleInfoWriter;
 import jdk.internal.module.ModuleTarget;
--- a/test/jdk/java/net/Socket/CloseAvailable.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/java/net/Socket/CloseAvailable.java	Fri Oct 12 18:58:40 2018 -0400
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 4091859
+ * @bug 4091859 8189366
  * @summary Test Socket.available()
  * @run main CloseAvailable
  * @run main/othervm -Djava.net.preferIPv4Stack=true CloseAvailable
@@ -33,18 +33,32 @@
 import java.io.*;
 
 
-public class CloseAvailable implements Runnable {
-    static ServerSocket ss;
-    static InetAddress addr;
-    static int port;
+public class CloseAvailable {
 
     public static void main(String[] args) throws Exception {
+        testClose();
+
+        testEOF(true);
+        testEOF(false);
+    }
+
+    static void testClose() throws IOException {
         boolean error = true;
-        addr = InetAddress.getLocalHost();
-        ss = new ServerSocket(0);
-        port = ss.getLocalPort();
+        InetAddress addr = InetAddress.getLocalHost();
+        ServerSocket ss = new ServerSocket(0);
+        int port = ss.getLocalPort();
 
-        Thread t = new Thread(new CloseAvailable());
+        Thread t = new Thread(new Thread("Close-Available-1") {
+            public void run() {
+                try {
+                    Socket s = new Socket(addr, port);
+                    s.close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+
         t.start();
 
         Socket  soc = ss.accept();
@@ -63,13 +77,42 @@
             throw new RuntimeException("Available() can be called after stream closed.");
     }
 
-    public void run() {
-        try {
-            Socket s = new Socket(addr, port);
-            s.close();
-        } catch (Exception e) {
-            e.printStackTrace();
+    // Verifies consistency of `available` behaviour when EOF reached, both
+    // explicitly and implicitly.
+    static void testEOF(boolean readUntilEOF) throws IOException {
+        System.out.println("testEOF, readUntilEOF: " + readUntilEOF);
+        InetAddress addr = InetAddress.getLoopbackAddress();
+        ServerSocket ss = new ServerSocket();
+        ss.bind(new InetSocketAddress(addr, 0), 0);
+        int port = ss.getLocalPort();
+
+        try (Socket s = new Socket(addr, port)) {
+            s.getOutputStream().write(0x42);
+            s.shutdownOutput();
+
+            try (Socket soc = ss.accept()) {
+                ss.close();
+
+                InputStream is = soc.getInputStream();
+                int b = is.read();
+                assert b == 0x42;
+                assert !s.isClosed();
+                if (readUntilEOF) {
+                    b = is.read();
+                    assert b == -1;
+                }
+
+                int a;
+                for (int i = 0; i < 100; i++) {
+                    a = is.available();
+                    System.out.print(a + ", ");
+                    if (a != 0)
+                        throw new RuntimeException("Unexpected non-zero available: " + a);
+                }
+                assert !s.isClosed();
+                assert is.read() == -1;
+            }
         }
+        System.out.println("\ncomplete");
     }
-
 }
--- a/test/jdk/java/net/httpclient/RequestBuilderTest.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/java/net/httpclient/RequestBuilderTest.java	Fri Oct 12 18:58:40 2018 -0400
@@ -337,15 +337,31 @@
         }
     }
 
+    // headers that are allowed now, but weren't before
+    private static final Set<String> FORMERLY_RESTRICTED = Set.of("referer", "origin",
+            "OriGin", "Referer");
+
+    @Test
+    public void testFormerlyRestricted()  throws URISyntaxException {
+        URI uri = new URI("http://localhost:80/test/");
+        URI otherURI = new URI("http://www.foo.com/test/");
+        for (String header : FORMERLY_RESTRICTED) {
+            HttpRequest req = HttpRequest.newBuilder(uri)
+                .header(header, otherURI.toString())
+                .GET()
+                .build();
+        }
+    }
+
     private static final Set<String> RESTRICTED = Set.of("connection", "content-length",
-            "date", "expect", "from", "host", "origin",
-            "referer", "upgrade", "via", "warning",
+            "date", "expect", "from", "host",
+            "upgrade", "via", "warning",
             "Connection", "Content-Length",
-            "DATE", "eXpect", "frOm", "hosT", "origIN",
-            "ReFerer", "upgradE", "vIa", "Warning",
+            "DATE", "eXpect", "frOm", "hosT",
+            "upgradE", "vIa", "Warning",
             "CONNection", "CONTENT-LENGTH",
-            "Date", "EXPECT", "From", "Host", "Origin",
-            "Referer", "Upgrade", "Via", "WARNING");
+            "Date", "EXPECT", "From", "Host",
+            "Upgrade", "Via", "WARNING");
 
     interface WithHeader {
         HttpRequest.Builder withHeader(HttpRequest.Builder builder, String name, String value);
--- a/test/jdk/java/net/httpclient/SpecialHeadersTest.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/java/net/httpclient/SpecialHeadersTest.java	Fri Oct 12 18:58:40 2018 -0400
@@ -57,21 +57,25 @@
 import java.net.InetSocketAddress;
 import java.net.URI;
 import java.net.http.HttpClient;
+import java.net.http.HttpHeaders;
 import java.net.http.HttpRequest;
 import java.net.http.HttpResponse;
 import java.net.http.HttpResponse.BodyHandlers;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Optional;
 
 import static java.lang.System.err;
 import static java.lang.System.out;
 import static java.net.http.HttpClient.Builder.NO_PROXY;
 import static java.nio.charset.StandardCharsets.US_ASCII;
+import org.testng.Assert;
 import static org.testng.Assert.assertEquals;
 
 public class SpecialHeadersTest implements HttpServerAdapters {
@@ -91,6 +95,13 @@
             {"User-Agent: camel-cased"},
             {"user-agent: all-lower-case"},
             {"user-Agent: mixed"},
+            // headers which were restricted before and are now allowable
+            {"referer: lower"},
+            {"Referer: normal"},
+            {"REFERER: upper"},
+            {"origin: lower"},
+            {"Origin: normal"},
+            {"ORIGIN: upper"},
     };
 
     @DataProvider(name = "variants")
@@ -169,6 +180,50 @@
     }
 
     @Test(dataProvider = "variants")
+    void testHomeMadeIllegalHeader(String uriString, String headerNameAndValue, boolean sameClient) throws Exception {
+        out.println("\n--- Starting ");
+        final URI uri = URI.create(uriString);
+
+        HttpClient client = HttpClient.newBuilder()
+                .proxy(NO_PROXY)
+                .sslContext(sslContext)
+                .build();
+
+        // Test a request which contains an illegal header created
+        HttpRequest req = new HttpRequest() {
+            @Override public Optional<BodyPublisher> bodyPublisher() {
+                return Optional.of(BodyPublishers.noBody());
+            }
+            @Override public String method() {
+                return "GET";
+            }
+            @Override public Optional<Duration> timeout() {
+                return Optional.empty();
+            }
+            @Override public boolean expectContinue() {
+                return false;
+            }
+            @Override public URI uri() {
+                return uri;
+            }
+            @Override public Optional<HttpClient.Version> version() {
+                return Optional.empty();
+            }
+            @Override public HttpHeaders headers() {
+                Map<String, List<String>> map = Map.of("via", List.of("http://foo.com"));
+                return HttpHeaders.of(map, (x, y) -> true);
+            }
+        };
+
+        try {
+            HttpResponse<String> response = client.send(req, BodyHandlers.ofString());
+            Assert.fail("Unexpected reply: " + response);
+        } catch (IllegalArgumentException ee) {
+            out.println("Got IAE as expected");
+        }
+    }
+
+    @Test(dataProvider = "variants")
     void testAsync(String uriString, String headerNameAndValue, boolean sameClient) {
         out.println("\n--- Starting ");
         int index = headerNameAndValue.indexOf(":");
@@ -259,7 +314,10 @@
         https2TestServer.stop();
     }
 
-    /** A handler that returns, as its body, the exact received request URI. */
+    /** A handler that returns, as its body, the exact received request URI.
+     *  The header whose name is in the URI query and is set in the request is
+     *  returned in the response with its name prefixed by X-
+     */
     static class HttpUriStringHandler implements HttpTestHandler {
         @Override
         public void handle(HttpTestExchange t) throws IOException {
--- a/test/jdk/lib/testlibrary/ModuleTargetHelper.java	Thu Oct 11 20:58:37 2018 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * 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.
- */
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.lang.module.ModuleReader;
-import java.lang.module.ModuleReference;
-import java.net.URI;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import jdk.internal.module.ModuleInfo;
-import jdk.internal.module.ModuleInfo.Attributes;
-
-public class ModuleTargetHelper {
-    private ModuleTargetHelper() {}
-
-    public static final class ModuleTarget {
-        private String targetPlatform;
-
-        public ModuleTarget(String targetPlatform) {
-            this.targetPlatform = targetPlatform;
-        }
-
-        public String targetPlatform() {
-            return targetPlatform;
-        }
-    }
-
-    public static ModuleTarget getJavaBaseTarget() throws IOException {
-        Path p = Paths.get(URI.create("jrt:/modules/java.base/module-info.class"));
-        try (InputStream in = Files.newInputStream(p)) {
-            return read(in);
-        }
-    }
-
-    public static ModuleTarget read(InputStream in) throws IOException {
-        ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
-        if (attrs.target() != null) {
-            return new ModuleTarget(attrs.target().targetPlatform());
-        } else {
-            return null;
-        }
-    }
-
-    public static ModuleTarget read(ModuleReference modRef) throws IOException {
-        ModuleReader reader = modRef.open();
-        try (InputStream in = reader.open("module-info.class").get()) {
-            return read(in);
-        } finally {
-            reader.close();
-        }
-    }
-}
--- a/test/jdk/lib/testlibrary/ModuleUtils.java	Thu Oct 11 20:58:37 2018 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +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.
- */
-
-import java.lang.module.ModuleDescriptor;
-import java.lang.module.ModuleFinder;
-import java.lang.module.ModuleReader;
-import java.lang.module.ModuleReference;
-import java.net.URI;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-
-
-/**
- * This class consists exclusively of static utility methods that are useful
- * for creating tests for modules.
- */
-
-public final class ModuleUtils {
-    private ModuleUtils() { }
-
-
-    /**
-     * Returns a ModuleFinder that finds modules with the given module
-     * descriptors.
-     */
-    static ModuleFinder finderOf(ModuleDescriptor... descriptors) {
-
-        // Create a ModuleReference for each module
-        Map<String, ModuleReference> namesToReference = new HashMap<>();
-
-        for (ModuleDescriptor descriptor : descriptors) {
-            String name = descriptor.name();
-
-            URI uri = URI.create("module:/" + name);
-
-            ModuleReference mref = new ModuleReference(descriptor, uri) {
-                @Override
-                public ModuleReader open() {
-                    throw new UnsupportedOperationException();
-                }
-            };
-
-            namesToReference.put(name, mref);
-        }
-
-        return new ModuleFinder() {
-            @Override
-            public Optional<ModuleReference> find(String name) {
-                Objects.requireNonNull(name);
-                return Optional.ofNullable(namesToReference.get(name));
-            }
-            @Override
-            public Set<ModuleReference> findAll() {
-                return new HashSet<>(namesToReference.values());
-            }
-        };
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/ModuleTargetHelper.java	Fri Oct 12 18:58:40 2018 -0400
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.lang.module.ModuleReader;
+import java.lang.module.ModuleReference;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import jdk.internal.module.ModuleInfo;
+import jdk.internal.module.ModuleInfo.Attributes;
+
+public class ModuleTargetHelper {
+    private ModuleTargetHelper() {}
+
+    public static final class ModuleTarget {
+        private String targetPlatform;
+
+        public ModuleTarget(String targetPlatform) {
+            this.targetPlatform = targetPlatform;
+        }
+
+        public String targetPlatform() {
+            return targetPlatform;
+        }
+    }
+
+    public static ModuleTarget getJavaBaseTarget() throws IOException {
+        Path p = Paths.get(URI.create("jrt:/modules/java.base/module-info.class"));
+        try (InputStream in = Files.newInputStream(p)) {
+            return read(in);
+        }
+    }
+
+    public static ModuleTarget read(InputStream in) throws IOException {
+        ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
+        if (attrs.target() != null) {
+            return new ModuleTarget(attrs.target().targetPlatform());
+        } else {
+            return null;
+        }
+    }
+
+    public static ModuleTarget read(ModuleReference modRef) throws IOException {
+        ModuleReader reader = modRef.open();
+        try (InputStream in = reader.open("module-info.class").get()) {
+            return read(in);
+        } finally {
+            reader.close();
+        }
+    }
+}
--- a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/SystemModulesTest.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/SystemModulesTest.java	Fri Oct 12 18:58:40 2018 -0400
@@ -42,7 +42,6 @@
 /**
  * @test
  * @bug 8142968 8173381
- * @library /lib/testlibrary
  * @modules java.base/jdk.internal.misc
  * @modules java.base/jdk.internal.module
  * @modules java.base/jdk.internal.org.objectweb.asm
--- a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java	Fri Oct 12 18:58:40 2018 -0400
@@ -44,7 +44,7 @@
 /**
  * @test
  * @bug 8142968 8173381 8174740
- * @library /lib/testlibrary /test/lib
+ * @library /test/lib
  * @modules jdk.compiler jdk.jlink
  * @modules java.base/jdk.internal.module
  * @modules java.base/jdk.internal.org.objectweb.asm
--- a/test/jdk/tools/jmod/hashes/HashesTest.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/tools/jmod/hashes/HashesTest.java	Fri Oct 12 18:58:40 2018 -0400
@@ -237,6 +237,28 @@
               .forEach(mn -> assertTrue(ht.hashes(mn) == null));
     }
 
+    @Test
+    public static void upgradeableModule() throws IOException {
+        Path mpath = Paths.get(System.getProperty("java.home"), "jmods");
+        if (!Files.exists(mpath)) {
+            return;
+        }
+
+        Path dest = Paths.get("test4");
+        HashesTest ht = new HashesTest(dest);
+        ht.makeModule("m1");
+        ht.makeModule("java.compiler", "m1");
+        ht.makeModule("m2", "java.compiler");
+
+        ht.makeJmod("m1");
+        ht.makeJmod("m2");
+        ht.makeJmod("java.compiler",
+                    "--module-path",
+                    ht.lib.toString() + File.pathSeparator + mpath,
+                    "--hash-modules", "java\\.(?!se)|^m.*");
+
+        ht.checkHashes("java.compiler",  "m2");
+    }
 
     @Test
     public static void testImageJmods() throws IOException {
--- a/test/jdk/tools/launcher/modules/addexports/AddExportsTest.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/jdk/tools/launcher/modules/addexports/AddExportsTest.java	Fri Oct 12 18:58:40 2018 -0400
@@ -24,7 +24,8 @@
 /**
  * @test
  * @library /test/lib
- * @modules jdk.compiler
+ * @modules java.compiler
+ *          jdk.compiler
  * @build AddExportsTest jdk.test.lib.compiler.CompilerUtils
  * @run testng AddExportsTest
  * @summary Basic tests for java --add-exports
@@ -51,12 +52,15 @@
 
     private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
     private static final Path MODS_DIR = Paths.get("mods");
+    private static final Path UPGRADE_MODS_DIRS = Paths.get("upgrademods");
 
     // test module m1 that uses Unsafe
     private static final String TEST1_MODULE = "m1";
     private static final String TEST1_MAIN_CLASS = "jdk.test1.Main";
 
-
+    // test module m2 uses java.compiler internals
+    private static final String TEST2_MODULE = "m2";
+    private static final String TEST2_MAIN_CLASS = "jdk.test2.Main";
 
     // test module m3 uses m4 internals
     private static final String TEST3_MODULE = "m3";
@@ -74,7 +78,19 @@
                 "--add-exports", "java.base/jdk.internal.misc=m1");
         assertTrue(compiled, "module " + TEST1_MODULE + " did not compile");
 
+        // javac -d upgrademods/java.compiler src/java.compiler/**
+        compiled = CompilerUtils.compile(
+                SRC_DIR.resolve("java.compiler"),
+                UPGRADE_MODS_DIRS.resolve("java.compiler"));
+        assertTrue(compiled, "module java.compiler did not compile");
 
+        // javac --upgrade-module-path upgrademods -d mods/m2 src/m2/**
+        compiled = CompilerUtils.compile(
+                SRC_DIR.resolve(TEST2_MODULE),
+                MODS_DIR.resolve(TEST2_MODULE),
+                "--upgrade-module-path", UPGRADE_MODS_DIRS.toString(),
+                "--add-exports", "java.compiler/javax.tools.internal=m2");
+        assertTrue(compiled, "module " + TEST2_MODULE + " did not compile");
 
         // javac -d mods/m3 src/m3/**
         compiled = CompilerUtils.compile(
@@ -146,7 +162,25 @@
         assertTrue(exitValue == 0);
     }
 
+    /**
+     * Test --add-exports with upgraded module
+     */
+    public void testWithUpgradedModule() throws Exception {
 
+        // java --add-exports java.compiler/javax.tools.internal=m2
+        //      --upgrade-module-path upgrademods --module-path mods -m ...
+        String mid = TEST2_MODULE + "/" + TEST2_MAIN_CLASS;
+        int exitValue = executeTestJava(
+                "--add-exports", "java.compiler/javax.tools.internal=m2",
+                "--upgrade-module-path", UPGRADE_MODS_DIRS.toString(),
+                "--module-path", MODS_DIR.toString(),
+                "-m", mid)
+                .outputTo(System.out)
+                .errorTo(System.out)
+                .getExitValue();
+
+        assertTrue(exitValue == 0);
+    }
 
     /**
      * Test --add-exports with module that is added to the set of root modules
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/annotation/processing/Generated.java	Fri Oct 12 18:58:40 2018 -0400
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, 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 javax.annotation.processing;
+
+public interface Generated {
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/tools/ToolsHelper.java	Fri Oct 12 18:58:40 2018 -0400
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018, 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 javax.tools;
+
+public class ToolsHelper {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/tools/internal/Helper.java	Fri Oct 12 18:58:40 2018 -0400
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018, 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 javax.tools.internal;
+
+public class Helper {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/modules/addexports/src/java.compiler/module-info.java	Fri Oct 12 18:58:40 2018 -0400
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018, 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.
+ */
+
+module java.compiler {
+    exports javax.tools;
+    exports javax.annotation.processing;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/modules/addexports/src/m2/jdk/test2/Main.java	Fri Oct 12 18:58:40 2018 -0400
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2015, 2018, 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.test2;
+
+import javax.tools.internal.Helper;
+
+public class Main {
+    public static void main(String[] args) {
+        Helper h = new Helper();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/modules/addexports/src/m2/module-info.java	Fri Oct 12 18:58:40 2018 -0400
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015, 2018, 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.
+ */
+
+module m2 {
+    requires java.compiler;
+}
--- a/test/lib/jdk/test/lib/apps/LingeredApp.java	Thu Oct 11 20:58:37 2018 -0400
+++ b/test/lib/jdk/test/lib/apps/LingeredApp.java	Fri Oct 12 18:58:40 2018 -0400
@@ -26,9 +26,6 @@
 import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
 import java.io.StringReader;
 import java.nio.file.Files;
 import java.nio.file.NoSuchFileException;
@@ -43,7 +40,6 @@
 import java.util.stream.Collectors;
 import java.util.UUID;
 import jdk.test.lib.process.OutputBuffer;
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.StreamPumper;
 
 /**
@@ -137,6 +133,14 @@
     }
 
     /**
+     * @return the LingeredApp's output.
+     * Can be called after the app is run.
+     */
+    public String getProcessStdout() {
+        return stdoutBuffer.toString();
+    }
+
+    /**
      *
      * @return OutputBuffer object for the LingeredApp's output. Can only be called
      * after LingeredApp has exited.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/jdk/test/lib/util/ModuleUtils.java	Fri Oct 12 18:58:40 2018 -0400
@@ -0,0 +1,85 @@
+/*
+ * 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.test.lib.util;
+
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReader;
+import java.lang.module.ModuleReference;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
+
+/**
+ * This class consists exclusively of static utility methods that are useful
+ * for creating tests for modules.
+ */
+
+public final class ModuleUtils {
+    private ModuleUtils() { }
+
+
+    /**
+     * Returns a ModuleFinder that finds modules with the given module
+     * descriptors.
+     */
+    public static ModuleFinder finderOf(ModuleDescriptor... descriptors) {
+
+        // Create a ModuleReference for each module
+        Map<String, ModuleReference> namesToReference = new HashMap<>();
+
+        for (ModuleDescriptor descriptor : descriptors) {
+            String name = descriptor.name();
+
+            URI uri = URI.create("module:/" + name);
+
+            ModuleReference mref = new ModuleReference(descriptor, uri) {
+                @Override
+                public ModuleReader open() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+
+            namesToReference.put(name, mref);
+        }
+
+        return new ModuleFinder() {
+            @Override
+            public Optional<ModuleReference> find(String name) {
+                Objects.requireNonNull(name);
+                return Optional.ofNullable(namesToReference.get(name));
+            }
+            @Override
+            public Set<ModuleReference> findAll() {
+                return new HashSet<>(namesToReference.values());
+            }
+        };
+    }
+
+}