Merge JDK-8145252-TLS13-branch
authorwetmore
Fri, 11 May 2018 16:07:27 -0700
branchJDK-8145252-TLS13-branch
changeset 56543 2352538d2f6e
parent 56542 56aaa6cb3693 (current diff)
parent 50091 05979f6ba560 (diff)
child 56544 ad120e0dfcfb
child 56548 208b4e9365cd
Merge
--- a/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java	Fri May 11 15:53:12 2018 -0700
+++ b/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java	Fri May 11 16:07:27 2018 -0700
@@ -109,6 +109,7 @@
     private static final String[] AVAILABLE_TZIDS = TimeZone.getAvailableIDs();
     private static String zoneNameTempFile;
     private static String tzDataDir;
+    private static final Map<String, String> canonicalTZMap = new HashMap<>();
 
     static enum DraftType {
         UNCONFIRMED,
@@ -439,6 +440,15 @@
         // Parse timezone
         handlerTimeZone = new TimeZoneParseHandler();
         parseLDMLFile(new File(TIMEZONE_SOURCE_FILE), handlerTimeZone);
+
+        // canonical tz name map
+        // alias -> primary
+        handlerTimeZone.getData().forEach((k, v) -> {
+            String[] ids = ((String)v).split("\\s");
+            for (int i = 1; i < ids.length; i++) {
+                canonicalTZMap.put(ids[i], ids[0]);
+            }
+        });
     }
 
     private static void parseLDMLFile(File srcfile, AbstractLDMLHandler handler) throws Exception {
@@ -658,7 +668,27 @@
                     handlerMetaZones.get(tzid) == null ||
                     handlerMetaZones.get(tzid) != null &&
                     map.get(METAZONE_ID_PREFIX + handlerMetaZones.get(tzid)) == null) {
-                    // First, check the CLDR meta key
+
+                    // First, check the alias
+                    String canonID = canonicalTZMap.get(tzid);
+                    if (canonID != null && !tzid.equals(canonID)) {
+                        Object value = map.get(TIMEZONE_ID_PREFIX + canonID);
+                        if (value != null) {
+                            names.put(tzid, value);
+                            return;
+                        } else {
+                            String meta = handlerMetaZones.get(canonID);
+                            if (meta != null) {
+                                value = map.get(METAZONE_ID_PREFIX + meta);
+                                if (value != null) {
+                                    names.put(tzid, meta);
+                                    return;
+                                }
+                            }
+                        }
+                    }
+
+                    // Check the CLDR meta key
                     Optional<Map.Entry<String, String>> cldrMeta =
                         handlerMetaZones.getData().entrySet().stream()
                             .filter(me ->
@@ -666,7 +696,7 @@
                                     (String[])map.get(METAZONE_ID_PREFIX + me.getValue())))
                             .findAny();
                     cldrMeta.ifPresentOrElse(meta -> names.put(tzid, meta.getValue()), () -> {
-                        // check the JRE meta key, add if there is not.
+                        // Check the JRE meta key, add if there is not.
                         Optional<Map.Entry<String[], String>> jreMeta =
                             jreMetaMap.entrySet().stream()
                                 .filter(jm -> Arrays.deepEquals(data, jm.getKey()))
@@ -1024,16 +1054,9 @@
     }
 
     private static Stream<String> zidMapEntry() {
-        Map<String, String> canonMap = new HashMap<>();
-        handlerTimeZone.getData().entrySet().stream()
-            .forEach(e -> {
-                String[] ids = ((String)e.getValue()).split("\\s");
-                for (int i = 1; i < ids.length; i++) {
-                    canonMap.put(ids[i], ids[0]);
-                }});
         return ZoneId.getAvailableZoneIds().stream()
                 .map(id -> {
-                    String canonId = canonMap.getOrDefault(id, id);
+                    String canonId = canonicalTZMap.getOrDefault(id, id);
                     String meta = handlerMetaZones.get(canonId);
                     String zone001 = handlerMetaZones.zidMap().get(meta);
                     return zone001 == null ? "" :
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Fri May 11 15:53:12 2018 -0700
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Fri May 11 16:07:27 2018 -0700
@@ -2410,7 +2410,8 @@
 #define INSN(NAME, opcode)                                              \
   void NAME(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn, FloatRegister Vm) { \
     starti;                                                             \
-    f(0, 31), f(0b001110, 29, 24), f(0, 21), f(0b001110, 15, 10);       \
+    f(0, 31), f(0b001110, 29, 24), f(0, 21), f(0, 15);                  \
+    f(opcode, 14, 12), f(0b10, 11, 10);                                 \
     rf(Vm, 16), rf(Vn, 5), rf(Vd, 0);                                   \
     f(T & 1, 30), f(T >> 1, 23, 22);                                    \
   }
--- a/src/hotspot/cpu/arm/compiledIC_arm.cpp	Fri May 11 15:53:12 2018 -0700
+++ b/src/hotspot/cpu/arm/compiledIC_arm.cpp	Fri May 11 16:07:27 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, 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
@@ -91,6 +91,11 @@
 }
 #endif // COMPILER2_OR_JVMCI
 
+int CompiledStaticCall::to_trampoline_stub_size() {
+  // ARM doesn't use trampolines.
+  return 0;
+}
+
 // size of C2 call stub, compiled java to interpretor
 int CompiledStaticCall::to_interp_stub_size() {
   return 8 * NativeInstruction::instruction_size;
--- a/src/hotspot/cpu/arm/jvmciCodeInstaller_arm.cpp	Fri May 11 15:53:12 2018 -0700
+++ b/src/hotspot/cpu/arm/jvmciCodeInstaller_arm.cpp	Fri May 11 16:07:27 2018 -0700
@@ -52,7 +52,7 @@
   Unimplemented();
 }
 
-void CodeInstaller::pd_relocate_JavaMethod(Handle hotspot_method, jint pc_offset, TRAPS) {
+void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &cbuf, Handle hotspot_method, jint pc_offset, TRAPS) {
   Unimplemented();
 }
 
--- a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java	Fri May 11 15:53:12 2018 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java	Fri May 11 16:07:27 2018 -0700
@@ -564,7 +564,6 @@
         throw new AssertionError("All subclasses should override this method");
     }
 
-
     // Shared access checking logic.
 
     // For non-public members or members in package-private classes,
@@ -674,4 +673,13 @@
         }
         return printStackWhenAccessFails;
     }
+
+    /**
+     * Returns the root AccessibleObject; or null if this object is the root.
+     *
+     * All subclasses override this method.
+     */
+    AccessibleObject getRoot() {
+        throw new InternalError();
+    }
 }
--- a/src/java.base/share/classes/java/lang/reflect/Constructor.java	Fri May 11 15:53:12 2018 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/Constructor.java	Fri May 11 16:07:27 2018 -0700
@@ -103,11 +103,8 @@
     // occur in annotation code.
     private Constructor<T>      root;
 
-    /**
-     * Used by Excecutable for annotation sharing.
-     */
     @Override
-    Executable getRoot() {
+    Constructor<T> getRoot() {
         return root;
     }
 
--- a/src/java.base/share/classes/java/lang/reflect/Executable.java	Fri May 11 15:53:12 2018 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/Executable.java	Fri May 11 16:07:27 2018 -0700
@@ -56,11 +56,6 @@
     abstract byte[] getAnnotationBytes();
 
     /**
-     * Accessor method to allow code sharing
-     */
-    abstract Executable getRoot();
-
-    /**
      * Does the Executable have generic information.
      */
     abstract boolean hasGenericInformation();
@@ -602,7 +597,7 @@
         if ((declAnnos = declaredAnnotations) == null) {
             synchronized (this) {
                 if ((declAnnos = declaredAnnotations) == null) {
-                    Executable root = getRoot();
+                    Executable root = (Executable)getRoot();
                     if (root != null) {
                         declAnnos = root.declaredAnnotations();
                     } else {
--- a/src/java.base/share/classes/java/lang/reflect/Field.java	Fri May 11 15:53:12 2018 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/Field.java	Fri May 11 16:07:27 2018 -0700
@@ -1128,6 +1128,11 @@
         }
     }
 
+    @Override
+    Field getRoot() {
+        return root;
+    }
+
     /**
      * @throws NullPointerException {@inheritDoc}
      * @since 1.5
--- a/src/java.base/share/classes/java/lang/reflect/Method.java	Fri May 11 15:53:12 2018 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/Method.java	Fri May 11 16:07:27 2018 -0700
@@ -198,11 +198,8 @@
         checkCanSetAccessible(caller, clazz);
     }
 
-    /**
-     * Used by Excecutable for annotation sharing.
-     */
     @Override
-    Executable getRoot() {
+    Method getRoot() {
         return root;
     }
 
--- a/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java	Fri May 11 15:53:12 2018 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java	Fri May 11 16:07:27 2018 -0700
@@ -154,4 +154,9 @@
     public <T> Constructor<T> copyConstructor(Constructor<T> arg) {
         return arg.copy();
     }
+
+    @SuppressWarnings("unchecked")
+    public <T extends AccessibleObject> T getRoot(T obj) {
+        return (T) obj.getRoot();
+    }
 }
--- a/src/java.base/share/classes/jdk/internal/reflect/LangReflectAccess.java	Fri May 11 15:53:12 2018 -0700
+++ b/src/java.base/share/classes/jdk/internal/reflect/LangReflectAccess.java	Fri May 11 16:07:27 2018 -0700
@@ -115,4 +115,7 @@
 
     /** Makes a "child" copy of a Constructor */
     public <T> Constructor<T> copyConstructor(Constructor<T> arg);
+
+    /** Gets the root of the given AccessibleObject object; null if arg is the root */
+    public <T extends AccessibleObject> T getRoot(T obj);
 }
--- a/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java	Fri May 11 15:53:12 2018 -0700
+++ b/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java	Fri May 11 16:07:27 2018 -0700
@@ -39,7 +39,6 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Modifier;
-import java.security.Permission;
 import java.security.PrivilegedAction;
 import java.util.Objects;
 import java.util.Properties;
@@ -172,6 +171,15 @@
      */
     public FieldAccessor newFieldAccessor(Field field, boolean override) {
         checkInitted();
+
+        Field root = langReflectAccess.getRoot(field);
+        if (root != null) {
+            // FieldAccessor will use the root unless the modifiers have
+            // been overrridden
+            if (root.getModifiers() == field.getModifiers() || !override) {
+                field = root;
+            }
+        }
         return UnsafeFieldAccessorFactory.newFieldAccessor(field, override);
     }
 
@@ -185,6 +193,12 @@
             }
         }
 
+        // use the root Method that will not cache caller class
+        Method root = langReflectAccess.getRoot(method);
+        if (root != null) {
+            method = root;
+        }
+
         if (noInflation && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {
             return new MethodAccessorGenerator().
                 generateMethod(method.getDeclaringClass(),
@@ -214,6 +228,13 @@
             return new InstantiationExceptionConstructorAccessorImpl
                 ("Can not instantiate java.lang.Class");
         }
+
+        // use the root Constructor that will not cache caller class
+        Constructor<?> root = langReflectAccess.getRoot(c);
+        if (root != null) {
+            c = root;
+        }
+
         // Bootstrapping issue: since we use Class.newInstance() in
         // the ConstructorAccessor generation process, we have to
         // break the cycle here.
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Fri May 11 15:53:12 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Fri May 11 16:07:27 2018 -0700
@@ -3035,14 +3035,14 @@
                         targetError = false;
                 }
 
-                JCDiagnostic detailsDiag = ((Resolve.ResolveError)refSym.baseSymbol()).getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT,
+                JCDiagnostic detailsDiag = ((Resolve.ResolveError)refSym.baseSymbol())
+                        .getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT,
                                 that, exprType.tsym, exprType, that.name, argtypes, typeargtypes);
 
-                JCDiagnostic.DiagnosticType diagKind = targetError ?
-                        JCDiagnostic.DiagnosticType.FRAGMENT : JCDiagnostic.DiagnosticType.ERROR;
-
-                JCDiagnostic diag = diags.create(diagKind, log.currentSource(), that,
-                        "invalid.mref", Kinds.kindName(that.getMode()), detailsDiag);
+                JCDiagnostic diag = diags.create(log.currentSource(), that,
+                        targetError ?
+                            Fragments.InvalidMref(Kinds.kindName(that.getMode()), detailsDiag) :
+                            Errors.InvalidMref(Kinds.kindName(that.getMode()), detailsDiag));
 
                 if (targetError && currentTarget == Type.recoveryType) {
                     //a target error doesn't make sense during recovery stage
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri May 11 15:53:12 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri May 11 16:07:27 2018 -0700
@@ -278,7 +278,7 @@
     invalid {0} reference\n\
     {1}
 
-# 0: symbol kind, 1: message segment
+# 0: kind name, 1: message segment
 compiler.misc.invalid.mref=\
     invalid {0} reference\n\
     {1}
@@ -2469,6 +2469,11 @@
     cannot find symbol\n\
     symbol: {0} {1}({3})
 
+# 0: kind name, 1: name, 2: unused, 3: list of type
+compiler.misc.cant.resolve.args=\
+    cannot find symbol\n\
+    symbol: {0} {1}({3})
+
 # 0: kind name, 1: name, 2: list of type, 3: list of type
 compiler.err.cant.resolve.args.params=\
     cannot find symbol\n\
--- a/test/jdk/ProblemList.txt	Fri May 11 15:53:12 2018 -0700
+++ b/test/jdk/ProblemList.txt	Fri May 11 16:07:27 2018 -0700
@@ -731,8 +731,6 @@
 
 tools/pack200/CommandLineTests.java                             8059906 generic-all
 
-tools/launcher/FXLauncherTest.java                              8068049 linux-all,macosx-all
-
 tools/jimage/JImageExtractTest.java                             8198405,8198819 generic-all
 tools/jimage/JImageListTest.java                                8198405 windows-all
 
--- a/test/jdk/TEST.groups	Fri May 11 15:53:12 2018 -0700
+++ b/test/jdk/TEST.groups	Fri May 11 16:07:27 2018 -0700
@@ -25,23 +25,33 @@
 # Tiered testing definitions
 #
 
+# When adding tests to tier1, make sure they end up in one of the tier1_partX groups
 tier1 = \
-    :jdk_lang \
+    :tier1_part1 \
+    :tier1_part2 \
+    :tier1_part3
+    
+tier1_part1 = \
+    :jdk_lang
+
+tier1_part2 = \
     :jdk_util \
-    :jdk_svc_sanity \
+    -java/util/Arrays/TimSortStackSize2.java
+
+tier1_part3 = \
     :build_sanity \
-    sun/nio/cs/ISO8859x.java \
+    :jdk_math \
+    :jdk_svc_sanity \
     java/nio/Buffer \
     com/sun/crypto/provider/Cipher \
-    :jdk_math \
-    tools/pack200 \
-    -java/util/Arrays/TimSortStackSize2.java
+    sun/nio/cs/ISO8859x.java \
+    tools/pack200
 
+# When adding tests to tier2, make sure they end up in one of the tier2_partX groups
 tier2 = \
     :tier2_part1 \
     :tier2_part2 \
-    :tier2_part3 \
-    java/util/Arrays/TimSortStackSize2.java
+    :tier2_part3
 
 # com/sun/crypto/provider/Cipher is in tier1 because of JDK-8132855
 tier2_part1 = \
@@ -58,7 +68,9 @@
     -sun/nio/cs/ISO8859x.java \
     :jdk_other \
     :jdk_text \
-    :jdk_time
+    :jdk_time \
+    java/util/Arrays/TimSortStackSize2.java
+
 
 tier2_part3 = \
     :jdk_net
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/reflect/callerCache/AccessTest.java	Fri May 11 16:07:27 2018 -0700
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.concurrent.Callable;
+
+/**
+ * Each nested class tests a member of a specific access.
+ *
+ * Caller class is cached when setAccessible is not used to suppress the access
+ * check and only access allowed.  If not accessible, caller class is not cached.
+ */
+public class AccessTest {
+    public static class PublicConstructor implements Callable<Object> {
+        public Object call() throws Exception {
+            Constructor c = Members.class.getConstructor();
+            return c.newInstance();
+        }
+    }
+
+    public static class PublicMethod extends Members implements Callable<Void> {
+        public Void call() throws Exception {
+            Method m = Members.class.getDeclaredMethod("publicMethod");
+            m.invoke(new PublicMethod());
+            return null;
+        }
+    }
+
+    public static class ProtectedMethod extends Members implements Callable<Void> {
+        public Void call() throws Exception {
+            Method m = Members.class.getDeclaredMethod("protectedMethod");
+            m.invoke(new ProtectedMethod());
+            return null;
+        }
+    }
+
+    /*
+     * private field is not accessible.  So caller class is not cached.
+     */
+    public static class PrivateMethod extends Members implements Callable<Void> {
+        public Void call() throws Exception {
+            Method m = Members.class.getDeclaredMethod("privateMethod");
+            try {
+                m.invoke(new ProtectedMethod());
+            } catch (IllegalAccessException e) {
+            }
+            return null;
+        }
+    }
+
+    public static class PublicField extends Members implements Callable<Void> {
+        public Void call() throws Exception {
+            Field f = Members.class.getDeclaredField("publicField");
+            f.get(new PublicField());
+            return null;
+        }
+    }
+
+    public static class ProtectedField extends Members implements Callable<Void> {
+        public Void call() throws Exception {
+            Field f = Members.class.getDeclaredField("protectedField");
+            f.get(new ProtectedField());
+            return null;
+        }
+    }
+
+    /*
+     * private field is not accessible.  So caller class is not cached.
+     */
+    public static class PrivateField implements Callable<Void> {
+        public Void call() throws Exception {
+            Field f = Members.class.getDeclaredField("privateField");
+            try {
+                f.get(new Members());
+            } catch (IllegalAccessException e) {
+            }
+            return null;
+        }
+    }
+
+    /*
+     * Validate final field
+     */
+    public static class FinalField implements Callable<Void> {
+        final Field f;
+        final boolean isStatic;
+        public FinalField(String name) throws Exception {
+            this.f = Members.class.getDeclaredField(name);
+            this.isStatic = Modifier.isStatic(f.getModifiers());
+            if (!Modifier.isFinal(f.getModifiers())) {
+                throw new RuntimeException("not a final field");
+            }
+            makeFinalNonFinal(f);
+        }
+        public Void call() throws Exception {
+            Members obj = isStatic ? null : new Members();
+            try {
+                f.set(obj, 20);
+                checkValue(obj, 20);
+            } catch (IllegalAccessException e) {
+                throw e;
+            }
+            return null;
+        }
+
+        void checkValue(Object obj, int expected) throws Exception {
+            int value = (int) f.get(obj);
+            if (value != expected) {
+                throw new RuntimeException("unexpectd value: " + value);
+            }
+        }
+    }
+
+    public static class PublicFinalField extends FinalField {
+        public PublicFinalField() throws Exception {
+            super("publicFinalField");
+        }
+    }
+
+    public static class PrivateFinalField extends FinalField {
+        public PrivateFinalField() throws Exception {
+            super("privateFinalField");
+        }
+    }
+
+    public static class PublicStaticFinalField extends FinalField {
+        public PublicStaticFinalField() throws Exception {
+            super("publicStaticFinalField");
+        }
+    }
+
+    public static class PrivateStaticFinalField extends FinalField {
+        public PrivateStaticFinalField() throws Exception {
+            super("privateStaticFinalField");
+        }
+    }
+
+    private static void makeFinalNonFinal(Field f) throws ReflectiveOperationException {
+        Field modifiers = Field.class.getDeclaredField("modifiers");
+        modifiers.setAccessible(true);
+        modifiers.set(f, modifiers.getInt(f) & ~Modifier.FINAL);
+        f.setAccessible(true);
+
+        if (Modifier.isFinal(f.getModifiers())) {
+            throw new RuntimeException("should be a non-final field");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/reflect/callerCache/Members.java	Fri May 11 16:07:27 2018 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+public class Members {
+    public Members() {}
+    protected Members(boolean b) {}
+    private Members(int i) {}
+
+    public void publicMethod() {}
+    protected void protectedMethod() {}
+    private void privateMethod() {}
+
+    public Object publicField = new Object();
+    protected Object protectedField = new Object();
+    private Object privateField = new Object();
+
+    public final int publicFinalField = 10;
+    private final int privateFinalField = 10;
+    public static final int publicStaticFinalField = 10;
+    private static final int privateStaticFinalField = 10;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/reflect/callerCache/ReflectionCallerCacheTest.java	Fri May 11 16:07:27 2018 -0700
@@ -0,0 +1,175 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8202113
+ * @summary Test the caller class loader is not kept strongly reachable
+  *         by reflection API
+ * @library /test/lib/
+ * @build ReflectionCallerCacheTest Members jdk.test.lib.compiler.CompilerUtils
+ * @run testng/othervm ReflectionCallerCacheTest
+ */
+
+import java.io.IOException;
+import java.lang.ref.Cleaner;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BooleanSupplier;
+
+import jdk.test.lib.compiler.CompilerUtils;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class ReflectionCallerCacheTest {
+    private static final Path CLASSES = Paths.get("classes");
+    private static final ReflectionCallerCacheTest TEST = new ReflectionCallerCacheTest();
+
+    @BeforeTest
+    public void setup() throws IOException {
+        String src = System.getProperty("test.src", ".");
+        String classpath = System.getProperty("test.classes", ".");
+        boolean rc = CompilerUtils.compile(Paths.get(src, "AccessTest.java"), CLASSES, "-cp", classpath);
+        if (!rc) {
+            throw new RuntimeException("fail compilation");
+        }
+    }
+    @DataProvider(name = "memberAccess")
+    public Object[][] memberAccess() {
+        return new Object[][] {
+            { "AccessTest$PublicConstructor" },
+            { "AccessTest$PublicMethod" },
+            { "AccessTest$PublicField" },
+            { "AccessTest$ProtectedMethod" },
+            { "AccessTest$ProtectedField" },
+            { "AccessTest$PrivateMethod" },
+            { "AccessTest$PrivateField"},
+            { "AccessTest$PublicFinalField"},
+            { "AccessTest$PrivateFinalField"},
+            { "AccessTest$PublicStaticFinalField"},
+            { "AccessTest$PrivateStaticFinalField"}
+        };
+    }
+
+    // Keep the root of the reflective objects strongly reachable
+    private final Constructor<?> publicConstructor;
+    private final Method publicMethod;
+    private final Method protectedMethod;
+    private final Method privateMethod;
+    private final Field publicField;
+    private final Field protectedField;
+    private final Field privateField;
+
+    ReflectionCallerCacheTest() {
+        try {
+            this.publicConstructor = Members.class.getConstructor();
+            this.publicMethod = Members.class.getDeclaredMethod("publicMethod");
+            this.publicField = Members.class.getDeclaredField("publicField");
+            this.protectedMethod = Members.class.getDeclaredMethod("protectedMethod");
+            this.protectedField = Members.class.getDeclaredField("protectedField");
+            this.privateMethod = Members.class.getDeclaredMethod("privateMethod");
+            this.privateField = Members.class.getDeclaredField("privateField");
+        } catch (ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Test(dataProvider = "memberAccess")
+    private void load(String classname) throws Exception {
+        WeakReference<?> weakLoader = loadAndRunClass(classname);
+
+        // Force garbage collection to trigger unloading of class loader
+        new ForceGC().await(() -> weakLoader.get() == null);
+
+        if (weakLoader.get() != null) {
+            throw new RuntimeException("Class " + classname + " not unloaded!");
+        }
+    }
+
+    private WeakReference<?> loadAndRunClass(String classname) throws Exception {
+        try (TestLoader loader = new TestLoader()) {
+            // Load member access class with custom class loader
+            Class<?> c = Class.forName(classname, true, loader);
+            // access the reflective member
+            Callable callable = (Callable) c.newInstance();
+            callable.call();
+            return new WeakReference<>(loader);
+        }
+    }
+
+    static class TestLoader extends URLClassLoader {
+        static URL[] toURLs() {
+            try {
+                return new URL[] { CLASSES.toUri().toURL() };
+            } catch (MalformedURLException e) {
+                throw new Error(e);
+            }
+        }
+
+        TestLoader() {
+            super("testloader", toURLs(), ClassLoader.getSystemClassLoader());
+        }
+    }
+
+    /**
+     * Utility class to invoke System.gc()
+     */
+    static class ForceGC {
+        private  final CountDownLatch cleanerInvoked = new CountDownLatch(1);
+        private  final Cleaner cleaner = Cleaner.create();
+
+        ForceGC() {
+            cleaner.register(new Object(), () -> cleanerInvoked.countDown());
+        }
+
+        void doit() {
+            try {
+                for (int i = 0; i < 10; i++) {
+                    System.gc();
+                    if (cleanerInvoked.await(1L, TimeUnit.SECONDS)) {
+                        return;
+                    }
+                }
+            } catch (InterruptedException unexpected) {
+                throw new AssertionError("unexpected InterruptedException");
+            }
+        }
+
+        void await(BooleanSupplier s) {
+            for (int i = 0; i < 10; i++) {
+                if (s.getAsBoolean()) return;
+                doit();
+            }
+            throw new AssertionError("failed to satisfy condition");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/util/resources/cldr/Bug8202764.java	Fri May 11 16:07:27 2018 -0700
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+ /*
+ * @test
+ * @bug 8202764
+ * @modules jdk.localedata
+ * @summary Checks time zone names are consistent with aliased ids,
+ *      between DateFormatSymbols.getZoneStrings() and getDisplayName()
+ *      of TimeZone/ZoneId classes
+ * @run testng/othervm Bug8202764
+ */
+
+import static org.testng.Assert.assertEquals;
+
+import java.time.ZoneId;
+import java.time.format.TextStyle;
+import java.text.DateFormatSymbols;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Set;
+import java.util.TimeZone;
+
+import org.testng.annotations.Test;
+
+public class Bug8202764 {
+
+    @Test
+    public void testAliasedTZs() {
+        Set<String> zoneIds = ZoneId.getAvailableZoneIds();
+        Arrays.stream(DateFormatSymbols.getInstance(Locale.US).getZoneStrings())
+            .forEach(zone -> {
+                System.out.println(zone[0]);
+                TimeZone tz = TimeZone.getTimeZone(zone[0]);
+                assertEquals(zone[1], tz.getDisplayName(false, TimeZone.LONG, Locale.US));
+                assertEquals(zone[2], tz.getDisplayName(false, TimeZone.SHORT, Locale.US));
+                assertEquals(zone[3], tz.getDisplayName(true, TimeZone.LONG, Locale.US));
+                assertEquals(zone[4], tz.getDisplayName(true, TimeZone.SHORT, Locale.US));
+                if (zoneIds.contains(zone[0])) {
+                    // Some of the ids, e.g. three-letter ids are not supported in ZoneId
+                    ZoneId zi = tz.toZoneId();
+                    assertEquals(zone[5], zi.getDisplayName(TextStyle.FULL, Locale.US));
+                    assertEquals(zone[6], zi.getDisplayName(TextStyle.SHORT, Locale.US));
+                }
+            });
+    }
+}
--- a/test/jdk/tools/launcher/FXLauncherTest.java	Fri May 11 15:53:12 2018 -0700
+++ b/test/jdk/tools/launcher/FXLauncherTest.java	Fri May 11 16:07:27 2018 -0700
@@ -23,19 +23,28 @@
 
 /*
  * @test
- * @bug 8001533 8004547 8035782
+ * @library /test/lib
+ * @build FXLauncherTest jdk.test.lib.compiler.CompilerUtils
+ * @bug 8001533 8004547 8035782 8202553
  * @summary Test launching FX application with java -jar
- * Test uses main method and blank main method, a jfx app class and an incorrest
+ * Test uses main method and blank main method, a jfx app class and an incorrect
  * jfx app class, a main-class for the manifest, a bogus one and none.
+ * Now that FX is no longer bundled with the JDK, this test uses a
+ * "mock" javafx.graphics module to test the FX launcher. It also verifies
+ * that FX is, in fact, not included with the JDK.
  * All should execute except the incorrect fx app class entries.
  * @run main/othervm FXLauncherTest
- * @key intermittent headful
  */
 import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
+import jdk.test.lib.compiler.CompilerUtils;
+
 public class FXLauncherTest extends TestHelper {
     private static final String FX_MARKER_CLASS = "javafx.application.Application";
     private static void line() {
@@ -46,12 +55,21 @@
     private static final File ManifestFile = new File("manifest.txt");
     private static final File ScratchDir = new File(".");
 
+    private static final Path SRC_DIR =
+        TEST_SOURCES_DIR.toPath().resolve("mockfx/src");
+    private static final Path MODS_DIR = Paths.get("mods");
+    private static final String MODULE_DIR = MODS_DIR.toString();
+
     /* standard main class can be used as java main for fx app class */
     static final String StdMainClass = "helloworld.HelloWorld";
     static final String ExtMainClass = "helloworld.ExtHello";
     static final String NonFXMainClass = "helloworld.HelloJava";
     static int testcount = 0;
 
+    static final String LAUNCH_MODE_CLASS = "LM_CLASS";
+    static final String LAUNCH_MODE_JAR = "LM_JAR";
+    static final String LAUNCH_MODE_MODULE = "LM_MODULE";
+
     /* a main method and a blank. */
     static final String[] MAIN_METHODS = {
         "public static void main(String[] args) { launch(args); }",
@@ -68,41 +86,19 @@
             List<String> contents = new ArrayList<>();
             contents.add("package helloworld;");
             contents.add("import javafx.application.Application;");
-            contents.add("import javafx.event.ActionEvent;");
-            contents.add("import javafx.event.EventHandler;");
-            contents.add("import javafx.scene.Scene;");
-            contents.add("import javafx.scene.control.Button;");
-            contents.add("import javafx.scene.layout.StackPane;");
             contents.add("import javafx.stage.Stage;");
             contents.add("public class HelloWorld extends Application {");
             contents.add(mainmethod);
             contents.add("@Override");
             contents.add("public void start(Stage primaryStage) {");
-            contents.add("    primaryStage.setTitle(\"Hello World!\");");
-            contents.add("    Button btn = new Button();");
-            contents.add("    btn.setText(\"Say 'Hello World'\");");
-            contents.add("    btn.setOnAction(new EventHandler<ActionEvent>() {");
-            contents.add("        @Override");
-            contents.add("        public void handle(ActionEvent event) {");
-            contents.add("            System.out.println(\"Hello World!\");");
-            contents.add("        }");
-            contents.add("    });");
-            contents.add("    StackPane root = new StackPane();");
-            contents.add("    root.getChildren().add(btn);");
-            contents.add("    primaryStage.setScene(new Scene(root, 300, 250));");
-            contents.add("//    primaryStage.show(); no GUI for auto tests. ");
-            contents.add("    System.out.println(\"HelloWorld.primaryStage.show();\");");
-            contents.add("    System.out.println(\"Parameters:\");" );
-            contents.add("    for(String p : getParameters().getUnnamed())");
-            contents.add("        System.out.println(\"parameter: \" + p );" );
-            contents.add("    System.exit(0);");
+            contents.add("    throw new InternalError(\"should never get here\");");
             contents.add("}");
             contents.add("}");
 
             // Create and compile java source.
             MainJavaFile = new File(mainClass + JAVA_FILE_EXT);
             createFile(MainJavaFile, contents);
-            compile("-d", ".", mainClass + JAVA_FILE_EXT);
+            doFxCompile("-d", ".", mainClass + JAVA_FILE_EXT);
         } catch (java.io.IOException ioe) {
             ioe.printStackTrace();
             throw new RuntimeException("Failed creating HelloWorld.");
@@ -123,7 +119,7 @@
             // Create and compile java source.
             MainJavaFile = new File(mainClass + JAVA_FILE_EXT);
             createFile(MainJavaFile, contents);
-            compile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT);
+            doFxCompile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT);
         } catch (java.io.IOException ioe) {
             ioe.printStackTrace();
             throw new RuntimeException("Failed creating ExtHello.");
@@ -148,7 +144,7 @@
             // Create and compile java source.
             MainJavaFile = new File(mainClass + JAVA_FILE_EXT);
             createFile(MainJavaFile, contents);
-            compile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT);
+            doFxCompile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT);
         } catch (java.io.IOException ioe) {
             ioe.printStackTrace();
             throw new RuntimeException("Failed creating HelloJava.");
@@ -206,6 +202,41 @@
         }
     }
 
+    public static void compileFXModule() {
+        final String JAVAFX_GRAPHICS_MODULE = "javafx.graphics";
+
+        try {
+            // Compile mockfx/src/javafx.graphics/** into mods/javafx.graphics
+            boolean compiled
+                = CompilerUtils.compile(SRC_DIR.resolve(JAVAFX_GRAPHICS_MODULE),
+                                        MODS_DIR.resolve(JAVAFX_GRAPHICS_MODULE));
+
+            if (!compiled) {
+                throw new RuntimeException("Error compiling mock javafx.graphics module");
+            }
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+    }
+
+    static void doFxCompile(String...compilerArgs) {
+        compileFXModule();
+
+        List<String> fxCompilerArgs = new ArrayList<>();
+        fxCompilerArgs.add("--module-path=" + MODULE_DIR);
+        fxCompilerArgs.add("--add-modules=javafx.graphics");
+        fxCompilerArgs.addAll(Arrays.asList(compilerArgs));
+        compile(fxCompilerArgs.toArray(new String[fxCompilerArgs.size()]));
+    }
+
+    static TestResult doFxExec(String...cmds) {
+        List<String> fxCmds = new ArrayList<>();
+        fxCmds.addAll(Arrays.asList(cmds));
+        fxCmds.add(1, "--module-path=" + MODULE_DIR);
+        fxCmds.add(2, "--add-modules=javafx.graphics");
+        return doExec(fxCmds.toArray(new String[fxCmds.size()]));
+    }
+
     /*
      * Set Main-Class and iterate main_methods.
      * Try launching with both -jar and -cp methods, with and without FX main
@@ -240,14 +271,21 @@
             createFile(ManifestFile, createManifestContents(StdMainClass, fxMC));
             createJar(FXtestJar, ManifestFile);
             String sTestJar = FXtestJar.getAbsolutePath();
+            String launchMode;
             final TestResult tr;
             if (useCP) {
-                tr = doExec(javaCmd, "-cp", sTestJar, StdMainClass, APP_PARMS[0], APP_PARMS[1]);
+                tr = doFxExec(javaCmd, "-cp", sTestJar, StdMainClass, APP_PARMS[0], APP_PARMS[1]);
+                launchMode = LAUNCH_MODE_CLASS;
             } else {
-                tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
+                tr = doFxExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
+                launchMode = LAUNCH_MODE_JAR;
             }
             tr.checkPositive();
-            if (tr.testStatus && tr.contains("HelloWorld.primaryStage.show()")) {
+            if (tr.testStatus) {
+                if (!tr.contains(launchMode)) {
+                    System.err.println("ERROR: Did not find "
+                            + launchMode + " in output!");
+                }
                 for (String p : APP_PARMS) {
                     if (!tr.contains(p)) {
                         System.err.println("ERROR: Did not find "
@@ -291,14 +329,21 @@
             createFile(ManifestFile, createManifestContents(ExtMainClass, fxMC));
             createJar(FXtestJar, ManifestFile);
             String sTestJar = FXtestJar.getAbsolutePath();
+            String launchMode;
             final TestResult tr;
             if (useCP) {
-                tr = doExec(javaCmd, "-cp", sTestJar, ExtMainClass, APP_PARMS[0], APP_PARMS[1]);
+                tr = doFxExec(javaCmd, "-cp", sTestJar, ExtMainClass, APP_PARMS[0], APP_PARMS[1]);
+                launchMode = LAUNCH_MODE_CLASS;
             } else {
-                tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
+                tr = doFxExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
+                launchMode = LAUNCH_MODE_JAR;
             }
             tr.checkPositive();
-            if (tr.testStatus && tr.contains("HelloWorld.primaryStage.show()")) {
+            if (tr.testStatus) {
+                if (!tr.contains(launchMode)) {
+                    System.err.println("ERROR: Did not find "
+                            + launchMode + " in output!");
+                }
                 for (String p : APP_PARMS) {
                     if (!tr.contains(p)) {
                         System.err.println("ERROR: Did not find "
@@ -323,7 +368,7 @@
         createFile(ManifestFile, createManifestContents(null, StdMainClass)); // No MC, but supply JAC
         createJar(FXtestJar, ManifestFile);
         String sTestJar = FXtestJar.getAbsolutePath();
-        TestResult tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
+        TestResult tr = doFxExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
         tr.checkNegative(); // should abort if no Main-Class
         if (tr.testStatus) {
             if (!tr.contains("no main manifest attribute")) {
@@ -363,9 +408,9 @@
         final TestResult tr;
 
         if (useCP) {
-            tr = doExec(javaCmd, "-verbose:class", "-cp", sTestJar, NonFXMainClass, APP_PARMS[0], APP_PARMS[1]);
+            tr = doFxExec(javaCmd, "-verbose:class", "-cp", sTestJar, NonFXMainClass, APP_PARMS[0], APP_PARMS[1]);
         } else {
-            tr = doExec(javaCmd, "-verbose:class", "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
+            tr = doFxExec(javaCmd, "-verbose:class", "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
         }
         tr.checkPositive();
         if (tr.testStatus) {
@@ -390,7 +435,8 @@
     }
 
     public static void main(String... args) throws Exception {
-        //check if fx is part of jdk
+
+        // Ensure that FX is not part of jdk
         Class<?> fxClass = null;
         try {
             fxClass = Class.forName(FX_MARKER_CLASS);
@@ -398,20 +444,20 @@
             // do nothing
         }
         if (fxClass != null) {
-            FXLauncherTest fxt = new FXLauncherTest();
-            fxt.run(args);
-            if (testExitValue > 0) {
-                System.out.println("Total of " + testExitValue
-                        + " failed. Test cases covered: "
-                        + FXLauncherTest.testcount);
-                System.exit(1);
-            } else {
-                System.out.println("All tests pass. Test cases covered: "
-                        + FXLauncherTest.testcount);
-            }
+            throw new RuntimeException("JavaFX modules erroneously included in the JDK");
+        }
+
+        FXLauncherTest fxt = new FXLauncherTest();
+        fxt.run(args);
+        if (testExitValue > 0) {
+            System.out.println("Total of " + testExitValue
+                    + " failed. Test cases covered: "
+                    + FXLauncherTest.testcount);
+            System.exit(1);
         } else {
-            System.err.println("Warning: JavaFX components missing or not supported");
-            System.err.println("         test passes vacuously.");
-         }
+            System.out.println("All tests pass. Test cases covered: "
+                    + FXLauncherTest.testcount);
+        }
     }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/mockfx/src/javafx.graphics/com/sun/javafx/application/LauncherImpl.java	Fri May 11 16:07:27 2018 -0700
@@ -0,0 +1,56 @@
+/*
+ * 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 com.sun.javafx.application;
+
+/**
+ * Mock JavaFX LauncherImpl class, used by FXLauncherTest.
+ */
+public class LauncherImpl {
+    /**
+     * This method is called by the Java launcher.
+     *
+     * @param launchName The path to a jar file, the application class name to launch,
+     * or the module and optional class name to launch
+     * @param launchMode The method of launching the application, one of LM_JAR,
+     * LM_CLASS, or LM_MODULE
+     * @param args Application arguments from the command line
+     */
+    public static void launchApplication(final String launchName,
+                                         final String launchMode,
+                                         final String[] args) {
+
+        System.out.println("LaunchName: " + launchName);
+        System.out.println("LaunchMode: " + launchMode);
+        System.out.println("Parameters:");
+        for (String arg : args) {
+            System.out.println("parameter: " + arg);
+        }
+        System.exit(0);
+    }
+
+    private LauncherImpl() {
+        throw new InternalError("should not get here");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/mockfx/src/javafx.graphics/javafx/application/Application.java	Fri May 11 16:07:27 2018 -0700
@@ -0,0 +1,43 @@
+/*
+ * 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 javafx.application;
+
+import javafx.stage.Stage;
+
+/**
+ * Mock JavaFX Application class, used by FXLauncherTest.
+ */
+public abstract class Application {
+    public static void launch(Class<? extends Application> appClass, String... args) {
+        throw new InternalError("should not get here");
+    }
+
+    public static void launch(String... args) {
+        throw new InternalError("should not get here");
+    }
+
+    public Application() {}
+
+    public abstract void start(Stage primaryStage) throws Exception;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/mockfx/src/javafx.graphics/javafx/stage/Stage.java	Fri May 11 16:07:27 2018 -0700
@@ -0,0 +1,32 @@
+/*
+ * 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 javafx.stage;
+
+/**
+ * Mock JavaFX Stage class, used by FXLauncherTest.
+ */
+public class Stage {
+
+    public Stage() {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/mockfx/src/javafx.graphics/module-info.java	Fri May 11 16:07:27 2018 -0700
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * Mock javafx.graphics module with just those packages / classes needed
+ * to test the FX launcher.
+ */
+module javafx.graphics {
+    exports javafx.application;
+    exports javafx.stage;
+    exports com.sun.javafx.application to
+        java.base;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/T8194998/BrokenErrorMessageTest.java	Fri May 11 16:07:27 2018 -0700
@@ -0,0 +1,19 @@
+/*
+ * @test  /nodynamiccopyright/
+ * @bug 8194998
+ * @summary broken error message for subclass of interface with private method
+ * @compile/fail/ref=BrokenErrorMessageTest.out -XDrawDiagnostics BrokenErrorMessageTest.java
+ */
+
+class BrokenErrorMessageTest {
+    void foo() {
+        // there is no error in this case but it is an interesting test, ::test is a member of I so this is acceptable
+        Runnable test1 = ((I)(new I() {}))::test;
+        // ::test is not a member of any subclass of I as it is private
+        Runnable test2 = ((new I() {}))::test;
+    }
+
+    interface I {
+        private void test() {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/T8194998/BrokenErrorMessageTest.out	Fri May 11 16:07:27 2018 -0700
@@ -0,0 +1,2 @@
+BrokenErrorMessageTest.java:13:26: compiler.err.invalid.mref: kindname.method, (compiler.misc.cant.resolve.args: kindname.method, test, , )
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/BadReference.java	Fri May 11 16:07:27 2018 -0700
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.mref
+// key: compiler.misc.cant.resolve.args
+
+class BadReference {
+    void foo() {
+        // ::test is not a member of any subclass of I as it is private
+        Runnable test2 = ((new I() {}))::test;
+    }
+
+    interface I {
+        private void test() {}
+    }
+}