# HG changeset patch # User wetmore # Date 1526080047 25200 # Node ID 2352538d2f6e5ac0a92a02ef9c38761140b547cb # Parent 56aaa6cb3693ed4652ea238dbf1ff30d86554995# Parent 05979f6ba5602b9e147bda3669988e78400e13b4 Merge diff -r 56aaa6cb3693 -r 2352538d2f6e make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java --- 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 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> 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> jreMeta = jreMetaMap.entrySet().stream() .filter(jm -> Arrays.deepEquals(data, jm.getKey())) @@ -1024,16 +1054,9 @@ } private static Stream zidMapEntry() { - Map 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 ? "" : diff -r 56aaa6cb3693 -r 2352538d2f6e src/hotspot/cpu/aarch64/assembler_aarch64.hpp --- 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); \ } diff -r 56aaa6cb3693 -r 2352538d2f6e src/hotspot/cpu/arm/compiledIC_arm.cpp --- 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; diff -r 56aaa6cb3693 -r 2352538d2f6e src/hotspot/cpu/arm/jvmciCodeInstaller_arm.cpp --- 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(); } diff -r 56aaa6cb3693 -r 2352538d2f6e src/java.base/share/classes/java/lang/reflect/AccessibleObject.java --- 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(); + } } diff -r 56aaa6cb3693 -r 2352538d2f6e src/java.base/share/classes/java/lang/reflect/Constructor.java --- 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 root; - /** - * Used by Excecutable for annotation sharing. - */ @Override - Executable getRoot() { + Constructor getRoot() { return root; } diff -r 56aaa6cb3693 -r 2352538d2f6e src/java.base/share/classes/java/lang/reflect/Executable.java --- 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 { diff -r 56aaa6cb3693 -r 2352538d2f6e src/java.base/share/classes/java/lang/reflect/Field.java --- 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 diff -r 56aaa6cb3693 -r 2352538d2f6e src/java.base/share/classes/java/lang/reflect/Method.java --- 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; } diff -r 56aaa6cb3693 -r 2352538d2f6e src/java.base/share/classes/java/lang/reflect/ReflectAccess.java --- 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 Constructor copyConstructor(Constructor arg) { return arg.copy(); } + + @SuppressWarnings("unchecked") + public T getRoot(T obj) { + return (T) obj.getRoot(); + } } diff -r 56aaa6cb3693 -r 2352538d2f6e src/java.base/share/classes/jdk/internal/reflect/LangReflectAccess.java --- 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 Constructor copyConstructor(Constructor arg); + + /** Gets the root of the given AccessibleObject object; null if arg is the root */ + public T getRoot(T obj); } diff -r 56aaa6cb3693 -r 2352538d2f6e src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java --- 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. diff -r 56aaa6cb3693 -r 2352538d2f6e src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java --- 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 diff -r 56aaa6cb3693 -r 2352538d2f6e src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties --- 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\ diff -r 56aaa6cb3693 -r 2352538d2f6e test/jdk/ProblemList.txt --- 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 diff -r 56aaa6cb3693 -r 2352538d2f6e test/jdk/TEST.groups --- 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 diff -r 56aaa6cb3693 -r 2352538d2f6e test/jdk/java/lang/reflect/callerCache/AccessTest.java --- /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 { + public Object call() throws Exception { + Constructor c = Members.class.getConstructor(); + return c.newInstance(); + } + } + + public static class PublicMethod extends Members implements Callable { + 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 { + 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 { + 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 { + 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 { + 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 { + 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 { + 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"); + } + } +} diff -r 56aaa6cb3693 -r 2352538d2f6e test/jdk/java/lang/reflect/callerCache/Members.java --- /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; +} diff -r 56aaa6cb3693 -r 2352538d2f6e test/jdk/java/lang/reflect/callerCache/ReflectionCallerCacheTest.java --- /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"); + } + } +} diff -r 56aaa6cb3693 -r 2352538d2f6e test/jdk/sun/util/resources/cldr/Bug8202764.java --- /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 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)); + } + }); + } +} diff -r 56aaa6cb3693 -r 2352538d2f6e test/jdk/tools/launcher/FXLauncherTest.java --- 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 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() {"); - 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 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 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); + } } + } diff -r 56aaa6cb3693 -r 2352538d2f6e test/jdk/tools/launcher/mockfx/src/javafx.graphics/com/sun/javafx/application/LauncherImpl.java --- /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"); + } + +} diff -r 56aaa6cb3693 -r 2352538d2f6e test/jdk/tools/launcher/mockfx/src/javafx.graphics/javafx/application/Application.java --- /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 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; +} diff -r 56aaa6cb3693 -r 2352538d2f6e test/jdk/tools/launcher/mockfx/src/javafx.graphics/javafx/stage/Stage.java --- /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() {} +} diff -r 56aaa6cb3693 -r 2352538d2f6e test/jdk/tools/launcher/mockfx/src/javafx.graphics/module-info.java --- /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; +} diff -r 56aaa6cb3693 -r 2352538d2f6e test/langtools/tools/javac/T8194998/BrokenErrorMessageTest.java --- /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() {} + } +} diff -r 56aaa6cb3693 -r 2352538d2f6e test/langtools/tools/javac/T8194998/BrokenErrorMessageTest.out --- /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 diff -r 56aaa6cb3693 -r 2352538d2f6e test/langtools/tools/javac/diags/examples/BadReference.java --- /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() {} + } +}