Mercurial > hg > icedtea7-forest-aarch64 > jdk
changeset 7973:fc87b55d62fc jdk7u66-b01
Merge
author | asaha |
---|---|
date | Tue, 15 Apr 2014 14:06:19 -0700 |
parents | 9e752d44a42b (current diff) d5353f8e1e02 (diff) |
children | 19a67abea24c |
files | |
diffstat | 20 files changed, 700 insertions(+), 119 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/awt/Component.java Sat Mar 08 01:40:14 2014 +0400 +++ b/src/share/classes/java/awt/Component.java Tue Apr 15 14:06:19 2014 -0700 @@ -7922,7 +7922,7 @@ res = toFocus.requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_BACKWARD); } } - if (!res) { + if (clearOnFailure && !res) { if (focusLog.isLoggable(PlatformLogger.FINER)) { focusLog.finer("clear global focus owner"); }
--- a/src/share/classes/java/awt/KeyboardFocusManager.java Sat Mar 08 01:40:14 2014 +0400 +++ b/src/share/classes/java/awt/KeyboardFocusManager.java Tue Apr 15 14:06:19 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2368,7 +2368,8 @@ focusLog.finest("Request {0}", String.valueOf(hwFocusRequest)); } if (hwFocusRequest == null && - heavyweight == nativeFocusOwner) + heavyweight == nativeFocusOwner && + heavyweight.getContainingWindow() == nativeFocusedWindow) { if (descendant == currentFocusOwner) { // Redundant request.
--- a/src/share/classes/java/lang/invoke/DirectMethodHandle.java Sat Mar 08 01:40:14 2014 +0400 +++ b/src/share/classes/java/lang/invoke/DirectMethodHandle.java Tue Apr 15 14:06:19 2014 -0700 @@ -243,12 +243,12 @@ assert(names.length == nameCursor); if (doesAlloc) { // names = { argx,y,z,... new C, init method } - names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]); - names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]); + names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]); } else if (needsInit) { - names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]); } else { - names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]); } Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class); assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args! @@ -596,18 +596,18 @@ final int RESULT = nameCursor-1; // either the call or the cast Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); if (needsInit) - names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]); + names[INIT_BAR] = new Name(Lazy.NF_ensureInitialized, names[DMH_THIS]); if (needsCast && !isGetter) - names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]); + names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]); Object[] outArgs = new Object[1 + linkerType.parameterCount()]; assert(outArgs.length == (isGetter ? 3 : 4)); outArgs[0] = UNSAFE; if (isStatic) { - outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]); - outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]); + outArgs[1] = names[F_HOLDER] = new Name(Lazy.NF_staticBase, names[DMH_THIS]); + outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_staticOffset, names[DMH_THIS]); } else { - outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]); - outArgs[2] = names[F_OFFSET] = new Name(NF_fieldOffset, names[DMH_THIS]); + outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]); + outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]); } if (!isGetter) { outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]); @@ -615,7 +615,7 @@ for (Object a : outArgs) assert(a != null); names[LINKER_CALL] = new Name(linker, outArgs); if (needsCast && isGetter) - names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); + names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); for (Name n : names) assert(n != null); String fieldOrStatic = (isStatic ? "Static" : "Field"); String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging @@ -624,48 +624,54 @@ return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT); } - private static final NamedFunction - NF_internalMemberName, - NF_internalMemberNameEnsureInit, - NF_ensureInitialized, - NF_fieldOffset, - NF_checkBase, - NF_staticBase, - NF_staticOffset, - NF_checkCast, - NF_allocateInstance, - NF_constructorMethod; - static { - try { - NamedFunction nfs[] = { - NF_internalMemberName = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("internalMemberName", Object.class)), - NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)), - NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("ensureInitialized", Object.class)), - NF_fieldOffset = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("fieldOffset", Object.class)), - NF_checkBase = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("checkBase", Object.class)), - NF_staticBase = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("staticBase", Object.class)), - NF_staticOffset = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("staticOffset", Object.class)), - NF_checkCast = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("checkCast", Object.class, Object.class)), - NF_allocateInstance = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("allocateInstance", Object.class)), - NF_constructorMethod = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("constructorMethod", Object.class)) - }; - for (NamedFunction nf : nfs) { - // Each nf must be statically invocable or we get tied up in our bootstraps. - assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf; - nf.resolve(); + /** + * Pre-initialized NamedFunctions for bootstrapping purposes. + * Factored in an inner class to delay initialization until first usage. + */ + private static class Lazy { + static final NamedFunction + NF_internalMemberName, + NF_internalMemberNameEnsureInit, + NF_ensureInitialized, + NF_fieldOffset, + NF_checkBase, + NF_staticBase, + NF_staticOffset, + NF_checkCast, + NF_allocateInstance, + NF_constructorMethod; + static { + try { + NamedFunction nfs[] = { + NF_internalMemberName = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("internalMemberName", Object.class)), + NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)), + NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("ensureInitialized", Object.class)), + NF_fieldOffset = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("fieldOffset", Object.class)), + NF_checkBase = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("checkBase", Object.class)), + NF_staticBase = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("staticBase", Object.class)), + NF_staticOffset = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("staticOffset", Object.class)), + NF_checkCast = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("checkCast", Object.class, Object.class)), + NF_allocateInstance = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("allocateInstance", Object.class)), + NF_constructorMethod = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("constructorMethod", Object.class)) + }; + for (NamedFunction nf : nfs) { + // Each nf must be statically invocable or we get tied up in our bootstraps. + assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf; + nf.resolve(); + } + } catch (ReflectiveOperationException ex) { + throw newInternalError(ex); } - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); } } }
--- a/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Sat Mar 08 01:40:14 2014 +0400 +++ b/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Tue Apr 15 14:06:19 2014 -0700 @@ -613,6 +613,12 @@ return false; // inner class of some sort if (cls.getClassLoader() != MethodHandle.class.getClassLoader()) return false; // not on BCP + MethodType mtype = member.getMethodOrFieldType(); + if (!isStaticallyNameable(mtype.returnType())) + return false; + for (Class<?> ptype : mtype.parameterArray()) + if (!isStaticallyNameable(ptype)) + return false; if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls)) return true; // in java.lang.invoke package if (member.isPublic() && isStaticallyNameable(cls))
--- a/src/share/classes/java/lang/invoke/MethodHandle.java Sat Mar 08 01:40:14 2014 +0400 +++ b/src/share/classes/java/lang/invoke/MethodHandle.java Tue Apr 15 14:06:19 2014 -0700 @@ -753,6 +753,10 @@ * to the target method handle. * (The array may also be null when zero elements are required.) * <p> + * If, when the adapter is called, the supplied array argument does + * not have the correct number of elements, the adapter will throw + * an {@link IllegalArgumentException} instead of invoking the target. + * <p> * Here are some simple examples of array-spreading method handles: * <blockquote><pre> MethodHandle equals = publicLookup() @@ -763,6 +767,12 @@ MethodHandle eq2 = equals.asSpreader(Object[].class, 2); assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" })); assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" })); +// try to spread from anything but a 2-array: +for (int n = 0; n <= 10; n++) { + Object[] badArityArgs = (n == 2 ? null : new Object[n]); + try { assert((boolean) eq2.invokeExact(badArityArgs) && false); } + catch (IllegalArgumentException ex) { } // OK +} // spread both arguments from a String array: MethodHandle eq2s = equals.asSpreader(String[].class, 2); assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
--- a/src/share/classes/java/lang/invoke/MethodHandleImpl.java Sat Mar 08 01:40:14 2014 +0400 +++ b/src/share/classes/java/lang/invoke/MethodHandleImpl.java Tue Apr 15 14:06:19 2014 -0700 @@ -430,7 +430,7 @@ // Spread the array. MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType); Name array = names[argIndex]; - names[nameCursor++] = new Name(NF_checkSpreadArgument, array, spreadArgCount); + names[nameCursor++] = new Name(Lazy.NF_checkSpreadArgument, array, spreadArgCount); for (int j = 0; j < spreadArgCount; i++, j++) { indexes[i] = nameCursor; names[nameCursor++] = new Name(aload, array, j); @@ -454,14 +454,8 @@ } static void checkSpreadArgument(Object av, int n) { - // FIXME: regression test for bug 7141637 erroneously expects an NPE, and other tests may expect IAE - // but the actual exception raised by an arity mismatch should be WMTE - final boolean RAISE_RANDOM_EXCEPTIONS = true; // FIXME: delete in JSR 292 M1 if (av == null) { if (n == 0) return; - int len; - if (RAISE_RANDOM_EXCEPTIONS) - len = ((Object[])av).length; // throw NPE; but delete this after tests are fixed } else if (av instanceof Object[]) { int len = ((Object[])av).length; if (len == n) return; @@ -470,19 +464,23 @@ if (len == n) return; } // fall through to error: - if (RAISE_RANDOM_EXCEPTIONS) - throw newIllegalArgumentException("Array is not of length "+n); - throw new WrongMethodTypeException("Array is not of length "+n); + throw newIllegalArgumentException("array is not of length "+n); } - private static final NamedFunction NF_checkSpreadArgument; - static { - try { - NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class - .getDeclaredMethod("checkSpreadArgument", Object.class, int.class)); - NF_checkSpreadArgument.resolve(); - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); + /** + * Pre-initialized NamedFunctions for bootstrapping purposes. + * Factored in an inner class to delay initialization until first usage. + */ + private static class Lazy { + static final NamedFunction NF_checkSpreadArgument; + static { + try { + NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class + .getDeclaredMethod("checkSpreadArgument", Object.class, int.class)); + NF_checkSpreadArgument.resolve(); + } catch (ReflectiveOperationException ex) { + throw newInternalError(ex); + } } }
--- a/src/share/classes/java/lang/invoke/MethodHandles.java Sat Mar 08 01:40:14 2014 +0400 +++ b/src/share/classes/java/lang/invoke/MethodHandles.java Tue Apr 15 14:06:19 2014 -0700 @@ -248,6 +248,9 @@ * In general, the conditions under which a method handle may be * looked up for a method {@code M} are exactly equivalent to the conditions * under which the lookup class could have compiled and resolved a call to {@code M}. + * Where the JVM would raise exceptions like {@code NoSuchMethodError}, + * a method handle lookup will generally raise a corresponding + * checked exception, such as {@code NoSuchMethodException}. * And the effect of invoking the method handle resulting from the lookup * is exactly equivalent to executing the compiled and resolved call to {@code M}. * The same point is true of fields and constructors. @@ -264,6 +267,12 @@ * (which will necessarily be a superclass of the lookup class) * to the lookup class itself. * <p> + * The JVM represents constructors and static initializer blocks as internal methods + * with special names ({@code "<init>"} and {@code "<clinit>"}). + * The internal syntax of invocation instructions allows them to refer to such internal + * methods as if they were normal methods, but the JVM verifier rejects them. + * A lookup of such an internal method will produce a {@code NoSuchMethodException}. + * <p> * In some cases, access between nested classes is obtained by the Java compiler by creating * an wrapper method to access a private method of another class * in the same top-level declaration. @@ -578,6 +587,15 @@ * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. + * <b>Example:</b> + * <p><blockquote><pre>{@code +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; +... +MethodHandle MH_asList = publicLookup().findStatic(Arrays.class, + "asList", methodType(List.class, Object[].class)); +assertEquals("[x, y]", MH_asList.invoke("x", "y").toString()); + * }</pre></blockquote> * @param refc the class from which the method is accessed * @param name the name of the method * @param type the type of the method @@ -628,6 +646,34 @@ * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker} * with the same {@code type} argument. * + * <b>Example:</b> + * <p><blockquote><pre>{@code +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; +... +MethodHandle MH_concat = publicLookup().findVirtual(String.class, + "concat", methodType(String.class, String.class)); +MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class, + "hashCode", methodType(int.class)); +MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class, + "hashCode", methodType(int.class)); +assertEquals("xy", (String) MH_concat.invokeExact("x", "y")); +assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy")); +assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy")); +// interface method: +MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class, + "subSequence", methodType(CharSequence.class, int.class, int.class)); +assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString()); +// constructor "internal method" must be accessed differently: +MethodType MT_newString = methodType(void.class); //()V for new String() +try { assertEquals("impossible", lookup() + .findVirtual(String.class, "<init>", MT_newString)); + } catch (NoSuchMethodException ex) { } // OK +MethodHandle MH_newString = publicLookup() + .findConstructor(String.class, MT_newString); +assertEquals("", (String) MH_newString.invokeExact()); + * }</pre></blockquote> + * * @param refc the class or interface from which the method is accessed * @param name the name of the method * @param type the type of the method, with the receiver argument omitted @@ -669,12 +715,30 @@ * If the constructor's class has not yet been initialized, that is done * immediately, before the method handle is returned. * <p> - * Note: The requested type must have a return type of {@code void}. - * This is consistent with the JVM's treatment of constructor type descriptors. + * <em>(Note: The requested type must have a return type of {@code void}. + * This is consistent with the JVM's treatment of constructor type descriptors.)</em> * <p> * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the constructor's variable arity modifier bit ({@code 0x0080}) is set. + * <b>Example:</b> + * <p><blockquote><pre>{@code +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; +... +MethodHandle MH_newArrayList = publicLookup().findConstructor( + ArrayList.class, methodType(void.class, Collection.class)); +Collection orig = Arrays.asList("x", "y"); +Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig); +assert(orig != copy); +assertEquals(orig, copy); +// a variable-arity constructor: +MethodHandle MH_newProcessBuilder = publicLookup().findConstructor( + ProcessBuilder.class, methodType(void.class, String[].class)); +ProcessBuilder pb = (ProcessBuilder) + MH_newProcessBuilder.invoke("x", "y", "z"); +assertEquals("[x, y, z]", pb.command().toString()); + * }</pre></blockquote> * @param refc the class or interface from which the method is accessed * @param type the type of the method, with the receiver argument omitted, and a void return type * @return the desired method handle @@ -714,6 +778,45 @@ * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. + * <p> + * <em>(Note: JVM internal methods named {@code <init>} not visible to this API, + * even though the {@code invokespecial} instruction can refer to them + * in special circumstances. Use {@link #findConstructor findConstructor} + * to access instance initialization methods in a safe manner.)</em> + * <b>Example:</b> + * <p><blockquote><pre>{@code +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; +... +static class Listie extends ArrayList { + public String toString() { return "[wee Listie]"; } + static Lookup lookup() { return MethodHandles.lookup(); } +} +... +// no access to constructor via invokeSpecial: +MethodHandle MH_newListie = Listie.lookup() + .findConstructor(Listie.class, methodType(void.class)); +Listie l = (Listie) MH_newListie.invokeExact(); +try { assertEquals("impossible", Listie.lookup().findSpecial( + Listie.class, "<init>", methodType(void.class), Listie.class)); + } catch (NoSuchMethodException ex) { } // OK +// access to super and self methods via invokeSpecial: +MethodHandle MH_super = Listie.lookup().findSpecial( + ArrayList.class, "toString" , methodType(String.class), Listie.class); +MethodHandle MH_this = Listie.lookup().findSpecial( + Listie.class, "toString" , methodType(String.class), Listie.class); +MethodHandle MH_duper = Listie.lookup().findSpecial( + Object.class, "toString" , methodType(String.class), Listie.class); +assertEquals("[]", (String) MH_super.invokeExact(l)); +assertEquals(""+l, (String) MH_this.invokeExact(l)); +assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method +try { assertEquals("inaccessible", Listie.lookup().findSpecial( + String.class, "toString", methodType(String.class), Listie.class)); + } catch (IllegalAccessException ex) { } // OK +Listie subl = new Listie() { public String toString() { return "[subclass]"; } }; +assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method + * }</pre></blockquote> + * * @param refc the class or interface from which the method is accessed * @param name the name of the method (which must not be "<init>") * @param type the type of the method, with the receiver argument omitted @@ -1017,15 +1120,16 @@ /// Helper methods, all package-private. MemberName resolveOrFail(byte refKind, Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException { + name.getClass(); type.getClass(); // NPE checkSymbolicClass(refc); // do this before attempting to resolve - name.getClass(); type.getClass(); // NPE return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), NoSuchFieldException.class); } MemberName resolveOrFail(byte refKind, Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { + type.getClass(); // NPE checkSymbolicClass(refc); // do this before attempting to resolve - name.getClass(); type.getClass(); // NPE + checkMethodName(refKind, name); return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), NoSuchMethodException.class); } @@ -1036,6 +1140,12 @@ throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this); } + void checkMethodName(byte refKind, String name) throws NoSuchMethodException { + if (name.startsWith("<") && refKind != REF_newInvokeSpecial) + throw new NoSuchMethodException("illegal method name: "+name); + } + + /** * Find my trustable caller class if m is a caller sensitive method. * If this lookup object has private access, then the caller class is the lookupClass. @@ -1406,6 +1516,9 @@ * <p> * Before invoking its target, the invoker will spread the final array, apply * reference casts as necessary, and unbox and widen primitive arguments. + * If, when the invoker is called, the supplied array argument does + * not have the correct number of elements, the invoker will throw + * an {@link IllegalArgumentException} instead of invoking the target. * <p> * This method is equivalent to the following code (though it may be more efficient): * <p><blockquote><pre>
--- a/src/share/classes/sun/awt/FontConfiguration.java Sat Mar 08 01:40:14 2014 +0400 +++ b/src/share/classes/sun/awt/FontConfiguration.java Tue Apr 15 14:06:19 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -867,7 +867,7 @@ return descriptors; } - private FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) { + protected FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) { String fontName = fontNames[fontIndex]; String styleName = styleNames[styleIndex];
--- a/src/share/classes/sun/invoke/util/VerifyAccess.java Sat Mar 08 01:40:14 2014 +0400 +++ b/src/share/classes/sun/invoke/util/VerifyAccess.java Tue Apr 15 14:06:19 2014 -0700 @@ -117,7 +117,7 @@ isSamePackage(defc, lookupClass)) return true; if ((allowedModes & PROTECTED) != 0 && - isPublicSuperClass(defc, lookupClass)) + isSuperClass(defc, lookupClass)) return true; return false; case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access. @@ -139,8 +139,8 @@ lookupClass.isAssignableFrom(refc)); } - static boolean isPublicSuperClass(Class<?> defc, Class<?> lookupClass) { - return isPublic(defc.getModifiers()) && defc.isAssignableFrom(lookupClass); + static boolean isSuperClass(Class<?> defc, Class<?> lookupClass) { + return defc.isAssignableFrom(lookupClass); } /**
--- a/src/solaris/classes/sun/font/FcFontConfiguration.java Sat Mar 08 01:40:14 2014 +0400 +++ b/src/solaris/classes/sun/font/FcFontConfiguration.java Tue Apr 15 14:06:19 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.HashMap; import java.util.HashSet; @@ -173,8 +174,16 @@ } @Override - public FontDescriptor[] getFontDescriptors(String fontName, int style) { - return new FontDescriptor[0]; + protected FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) { + CompositeFontDescriptor[] cfi = get2DCompositeFontInfo(); + int idx = fontIndex * NUM_STYLES + styleIndex; + String[] componentFaceNames = cfi[idx].getComponentFaceNames(); + FontDescriptor[] ret = new FontDescriptor[componentFaceNames.length]; + for (int i = 0; i < componentFaceNames.length; i++) { + ret[i] = new FontDescriptor(componentFaceNames[i], StandardCharsets.UTF_8.newEncoder(), new int[0]); + } + + return ret; } @Override @@ -250,10 +259,12 @@ } String[] fileNames = new String[numFonts]; + String[] faceNames = new String[numFonts]; int index; for (index = 0; index < fcFonts.length; index++) { fileNames[index] = fcFonts[index].fontFile; + faceNames[index] = fcFonts[index].familyName; } if (installedFallbackFontFiles != null) { @@ -266,7 +277,7 @@ = new CompositeFontDescriptor( faceName, 1, - null, + faceNames, fileNames, null, null); }
--- a/src/windows/native/sun/windows/awt_Component.cpp Sat Mar 08 01:40:14 2014 +0400 +++ b/src/windows/native/sun/windows/awt_Component.cpp Tue Apr 15 14:06:19 2014 -0700 @@ -1719,9 +1719,11 @@ case WM_IME_SETCONTEXT: // lParam is passed as pointer and it can be modified. mr = WmImeSetContext(static_cast<BOOL>(wParam), &lParam); + CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); break; case WM_IME_NOTIFY: mr = WmImeNotify(wParam, lParam); + CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); break; case WM_IME_STARTCOMPOSITION: mr = WmImeStartComposition(); @@ -4066,7 +4068,7 @@ { if (mr != mrConsume) { HWND proxy = GetProxyFocusOwner(); - if (proxy != NULL) { + if (proxy != NULL && ::IsWindowEnabled(proxy)) { retVal = ComCtl32Util::GetInstance().DefWindowProc(NULL, proxy, message, wParam, lParam); mr = mrConsume; }
--- a/src/windows/native/sun/windows/awt_Frame.cpp Sat Mar 08 01:40:14 2014 +0400 +++ b/src/windows/native/sun/windows/awt_Frame.cpp Tue Apr 15 14:06:19 2014 -0700 @@ -319,6 +319,8 @@ case WM_IME_STARTCOMPOSITION: case WM_IME_ENDCOMPOSITION: case WM_IME_COMPOSITION: + case WM_IME_SETCONTEXT: + case WM_IME_NOTIFY: case WM_IME_CONTROL: case WM_IME_COMPOSITIONFULL: case WM_IME_SELECT:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Focus/8013611/JDK8013611.java Tue Apr 15 14:06:19 2014 -0700 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 8013611 + @summary Tests showing a modal dialog with requesting focus in frame. + @author Anton.Tarasov: area=awt.focus + @library ../../regtesthelpers + @build Util + @run main JDK8013611 +*/ + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import test.java.awt.regtesthelpers.Util; + +import java.awt.*; + +public class JDK8013611 extends JFrame { + static JTextField textField = new JTextField("text"); + static JButton button1 = new JButton("button1"); + static JButton button2 = new JButton("button2"); + static Robot robot; + + static JDialog dialog; + static JButton button3 = new JButton("button3"); + + public static void main(String[] args) { + robot = Util.createRobot(); + + JDK8013611 frame = new JDK8013611(); + frame.setLayout(new FlowLayout()); + frame.add(textField); + frame.add(button1); + frame.add(button2); + frame.pack(); + + dialog = new JDialog(frame, true); + dialog.add(button3); + dialog.pack(); + + textField.addFocusListener(new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + dialog.setVisible(true); + } + }); + + button1.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + button2.requestFocusInWindow(); + } + }); + + frame.setVisible(true); + + frame.test(); + } + + public void test() { + if (!testFocused(textField)) { + Util.clickOnComp(textField, robot); + if (!testFocused(textField)) { + throw new RuntimeException("Error: couldn't focus " + textField); + } + } + + robot.keyPress(KeyEvent.VK_TAB); + robot.delay(50); + robot.keyRelease(KeyEvent.VK_TAB); + + if (!testFocused(button3)) { + throw new RuntimeException("Test failed: dialog didn't get focus!"); + } + + System.out.println("Test passed."); + } + + boolean testFocused(Component c) { + for (int i=0; i<10; i++) { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == c) { + return true; + } + Util.waitForIdle(robot); + } + return false; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Focus/DialogTraversFocusBackTest/DialogTraversFocusBackTest.java Tue Apr 15 14:06:19 2014 -0700 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 8031075 + @summary Regression: focus disappears with shift+tab on dialogue having a focus component + @author mcherkas + @run main DialogTraversFocusBackTest +*/ + +import sun.awt.SunToolkit; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.KeyEvent; + +public class DialogTraversFocusBackTest { + + private static Robot robot; + private volatile static JButton button; + private static Component currentFocusOwner; + + public static void main(String[] args) throws Exception { + initUI(); + sync(); + initRobot(); + runScript(); + sync(); + validate(); + } + + public static void sync() { + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(); + } + + private static void validate() throws Exception { + currentFocusOwner = FocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); + if(currentFocusOwner + != button) { + throw new Exception("Test failed! Wrong focus owner: " + + String.valueOf(currentFocusOwner) + "\n but must be: " + + button); + } + } + + private static void runScript() { + robot.keyPress(KeyEvent.VK_SHIFT); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_SHIFT); + + } + + private static void initRobot() throws AWTException { + robot = new Robot(); + robot.setAutoDelay(100); + + } + + private static void initUI() throws Exception { + SwingUtilities.invokeAndWait( new Runnable() { + @Override + public void run() { + JDialog dialog = new JDialog((Frame)null, "Test Dialog"); + button = new JButton("Button 1"); + dialog.add(button); + dialog.pack(); + dialog.setVisible(true); + } + }); + + } +}
--- a/test/java/awt/Frame/7024749/bug7024749.java Sat Mar 08 01:40:14 2014 +0400 +++ b/test/java/awt/Frame/7024749/bug7024749.java Tue Apr 15 14:06:19 2014 -0700 @@ -23,7 +23,7 @@ /* * @test - * @bug 7024749 7184326 + * @bug 7024749 7184326 8019990 * @summary JDK7 b131---a crash in: Java_sun_awt_windows_ThemeReader_isGetThemeTransitionDurationDefined+0x75 * @library ../../regtesthelpers * @build Util
--- a/test/java/lang/invoke/JavaDocExamplesTest.java Sat Mar 08 01:40:14 2014 +0400 +++ b/test/java/lang/invoke/JavaDocExamplesTest.java Tue Apr 15 14:06:19 2014 -0700 @@ -64,7 +64,11 @@ new JavaDocExamplesTest().run(); } public void run() throws Throwable { + testMisc(); + testFindStatic(); + testFindConstructor(); testFindVirtual(); + testFindSpecial(); testPermuteArguments(); testDropArguments(); testFilterArguments(); @@ -110,7 +114,8 @@ {} - @Test public void testFindVirtual() throws Throwable { + @Test public void testMisc() throws Throwable { +// Extra tests, not from javadoc: {} MethodHandle CONCAT_3 = LOOKUP.findVirtual(String.class, "concat", methodType(String.class, String.class)); @@ -125,6 +130,92 @@ {} } + @Test public void testFindStatic() throws Throwable { +{} +MethodHandle MH_asList = publicLookup().findStatic(Arrays.class, + "asList", methodType(List.class, Object[].class)); +assertEquals("[x, y]", MH_asList.invoke("x", "y").toString()); +{} + } + + @Test public void testFindVirtual() throws Throwable { +{} +MethodHandle MH_concat = publicLookup().findVirtual(String.class, + "concat", methodType(String.class, String.class)); +MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class, + "hashCode", methodType(int.class)); +MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class, + "hashCode", methodType(int.class)); +assertEquals("xy", (String) MH_concat.invokeExact("x", "y")); +assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy")); +assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy")); +// interface method: +MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class, + "subSequence", methodType(CharSequence.class, int.class, int.class)); +assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString()); +// constructor "internal method" must be accessed differently: +MethodType MT_newString = methodType(void.class); //()V for new String() +try { assertEquals("impossible", lookup() + .findVirtual(String.class, "<init>", MT_newString)); + } catch (NoSuchMethodException ex) { } // OK +MethodHandle MH_newString = publicLookup() + .findConstructor(String.class, MT_newString); +assertEquals("", (String) MH_newString.invokeExact()); +{} + } + + @Test public void testFindConstructor() throws Throwable { +{} +MethodHandle MH_newArrayList = publicLookup().findConstructor( + ArrayList.class, methodType(void.class, Collection.class)); +Collection orig = Arrays.asList("x", "y"); +Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig); +assert(orig != copy); +assertEquals(orig, copy); +// a variable-arity constructor: +MethodHandle MH_newProcessBuilder = publicLookup().findConstructor( + ProcessBuilder.class, methodType(void.class, String[].class)); +ProcessBuilder pb = (ProcessBuilder) + MH_newProcessBuilder.invoke("x", "y", "z"); +assertEquals("[x, y, z]", pb.command().toString()); +{} + } + +// for testFindSpecial +{} +static class Listie extends ArrayList { + public String toString() { return "[wee Listie]"; } + static Lookup lookup() { return MethodHandles.lookup(); } +} +{} + + @Test public void testFindSpecial() throws Throwable { +{} +// no access to constructor via invokeSpecial: +MethodHandle MH_newListie = Listie.lookup() + .findConstructor(Listie.class, methodType(void.class)); +Listie l = (Listie) MH_newListie.invokeExact(); +try { assertEquals("impossible", Listie.lookup().findSpecial( + Listie.class, "<init>", methodType(void.class), Listie.class)); + } catch (NoSuchMethodException ex) { } // OK +// access to super and self methods via invokeSpecial: +MethodHandle MH_super = Listie.lookup().findSpecial( + ArrayList.class, "toString" , methodType(String.class), Listie.class); +MethodHandle MH_this = Listie.lookup().findSpecial( + Listie.class, "toString" , methodType(String.class), Listie.class); +MethodHandle MH_duper = Listie.lookup().findSpecial( + Object.class, "toString" , methodType(String.class), Listie.class); +assertEquals("[]", (String) MH_super.invokeExact(l)); +assertEquals(""+l, (String) MH_this.invokeExact(l)); +assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method +try { assertEquals("inaccessible", Listie.lookup().findSpecial( + String.class, "toString", methodType(String.class), Listie.class)); + } catch (IllegalAccessException ex) { } // OK +Listie subl = new Listie() { public String toString() { return "[subclass]"; } }; +assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method +{} + } + @Test public void testPermuteArguments() throws Throwable { {{ {} /// JAVADOC @@ -275,6 +366,12 @@ MethodHandle eq2 = equals.asSpreader(Object[].class, 2); assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" })); assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" })); +// try to spread from anything but a 2-array: +for (int n = 0; n <= 10; n++) { + Object[] badArityArgs = (n == 2 ? null : new Object[n]); + try { assert((boolean) eq2.invokeExact(badArityArgs) && false); } + catch (IllegalArgumentException ex) { } // OK +} // spread both arguments from a String array: MethodHandle eq2s = equals.asSpreader(String[].class, 2); assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
--- a/test/java/lang/invoke/MethodHandlesTest.java Sat Mar 08 01:40:14 2014 +0400 +++ b/test/java/lang/invoke/MethodHandlesTest.java Tue Apr 15 14:06:19 2014 -0700 @@ -363,6 +363,7 @@ protected Example(String name) { this.name = name; } @SuppressWarnings("LeakingThisInConstructor") protected Example(int x) { this(); called("protected <init>", this, x); } + //Example(Void x) { does not exist; lookup elicts NoSuchMethodException } @Override public String toString() { return name; } public void v0() { called("v0", this); } @@ -463,6 +464,9 @@ return lookup.in(defc); } + /** Is findVirtual (etc.) of "<init>" supposed to elicit a NoSuchMethodException? */ + final static boolean INIT_REF_CAUSES_NSME = true; + @Test public void testFindStatic() throws Throwable { if (CAN_SKIP_WORKING) return; @@ -483,6 +487,8 @@ testFindStatic(Example.class, Object.class, "s7", float.class, double.class); testFindStatic(false, PRIVATE, Example.class, void.class, "bogus"); + testFindStatic(false, PRIVATE, Example.class, void.class, "<init>", int.class); + testFindStatic(false, PRIVATE, Example.class, void.class, "<init>", Void.class); testFindStatic(false, PRIVATE, Example.class, void.class, "v0"); } @@ -505,11 +511,12 @@ target = maybeMoveIn(lookup, defc).findStatic(defc, methodName, type); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("<init>")) + ? NoSuchMethodException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("findStatic "+lookup+": "+defc.getName()+"."+name+"/"+type+" => "+target @@ -527,6 +534,13 @@ System.out.print(':'); } + static void assertExceptionClass(Class<? extends Throwable> expected, + Throwable actual) { + if (expected.isInstance(actual)) return; + actual.printStackTrace(); + assertEquals(expected, actual.getClass()); + } + static final boolean DEBUG_METHOD_HANDLE_NAMES = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES"); // rough check of name string @@ -556,6 +570,8 @@ testFindVirtual(PubExample.class, void.class, "Pub/pro_v0"); testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "bogus"); + testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "<init>", int.class); + testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "<init>", Void.class); testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "s0"); // test dispatch @@ -591,11 +607,12 @@ target = maybeMoveIn(lookup, defc).findVirtual(defc, methodName, type); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("<init>")) + ? NoSuchMethodException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("findVirtual "+lookup+": "+defc.getName()+"."+name+"/"+type+" => "+target @@ -632,11 +649,11 @@ testFindSpecial(SubExample.class, Example.class, void.class, "pkg_v0"); testFindSpecial(RemoteExample.class, PubExample.class, void.class, "Pub/pro_v0"); // Do some negative testing: - testFindSpecial(false, EXAMPLE, SubExample.class, Example.class, void.class, "bogus"); - testFindSpecial(false, PRIVATE, SubExample.class, Example.class, void.class, "bogus"); for (Lookup lookup : new Lookup[]{ PRIVATE, EXAMPLE, PACKAGE, PUBLIC }) { testFindSpecial(false, lookup, Object.class, Example.class, void.class, "v0"); + testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "bogus"); testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "<init>", int.class); + testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "<init>", Void.class); testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "s0"); } } @@ -662,19 +679,25 @@ countTest(positive); String methodName = name.substring(1 + name.indexOf('/')); // foo/bar => foo MethodType type = MethodType.methodType(ret, params); + Lookup specialLookup = maybeMoveIn(lookup, specialCaller); + boolean specialAccessOK = (specialLookup.lookupClass() == specialCaller && + (specialLookup.lookupModes() & Lookup.PRIVATE) != 0); MethodHandle target = null; Exception noAccess = null; try { if (verbosity >= 4) System.out.println("lookup via "+lookup+" of "+defc+" "+name+type); - if (verbosity >= 5) System.out.println(" lookup => "+maybeMoveIn(lookup, specialCaller)); - target = maybeMoveIn(lookup, specialCaller).findSpecial(defc, methodName, type, specialCaller); + if (verbosity >= 5) System.out.println(" lookup => "+specialLookup); + target = specialLookup.findSpecial(defc, methodName, type, specialCaller); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + (!specialAccessOK) // this check should happen first + ? IllegalAccessException.class + : (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("<init>")) + ? NoSuchMethodException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("findSpecial from "+specialCaller.getName()+" to "+defc.getName()+"."+name+"/"+type+" => "+target @@ -719,7 +742,7 @@ target = lookup.findConstructor(defc, type); } catch (ReflectiveOperationException ex) { noAccess = ex; - assertTrue(noAccess instanceof IllegalAccessException); + assertTrue(noAccess.getClass().getName(), noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("findConstructor "+defc.getName()+".<init>/"+type+" => "+target @@ -750,6 +773,8 @@ testBind(Example.class, Object.class, "v2", int.class, Object.class); testBind(Example.class, Object.class, "v2", int.class, int.class); testBind(false, PRIVATE, Example.class, void.class, "bogus"); + testBind(false, PRIVATE, Example.class, void.class, "<init>", int.class); + testBind(false, PRIVATE, Example.class, void.class, "<init>", Void.class); testBind(SubExample.class, void.class, "Sub/v0"); testBind(SubExample.class, void.class, "Sub/pkg_v0"); testBind(IntExample.Impl.class, void.class, "Int/v0"); @@ -773,11 +798,12 @@ target = maybeMoveIn(lookup, defc).bind(receiver, methodName, type); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("<init>")) + ? NoSuchMethodException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("bind "+receiver+"."+name+"/"+type+" => "+target @@ -840,6 +866,10 @@ countTest(positive); String methodName = name.substring(1 + name.indexOf('/')); // foo/bar => foo MethodType type = MethodType.methodType(ret, params); + Lookup specialLookup = (specialCaller != null ? maybeMoveIn(lookup, specialCaller) : null); + boolean specialAccessOK = (specialCaller != null && + specialLookup.lookupClass() == specialCaller && + (specialLookup.lookupModes() & Lookup.PRIVATE) != 0); Method rmethod = defc.getDeclaredMethod(methodName, params); MethodHandle target = null; Exception noAccess = null; @@ -848,16 +878,15 @@ try { if (verbosity >= 4) System.out.println("lookup via "+lookup+" of "+defc+" "+name+type); if (isSpecial) - target = maybeMoveIn(lookup, specialCaller).unreflectSpecial(rmethod, specialCaller); + target = specialLookup.unreflectSpecial(rmethod, specialCaller); else target = maybeMoveIn(lookup, defc).unreflect(rmethod); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + IllegalAccessException.class, // NSME is impossible, since it was already reflected + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("unreflect"+(isSpecial?"Special":"")+" "+defc.getName()+"."+name+"/"+type @@ -1091,11 +1120,12 @@ } catch (ReflectiveOperationException ex) { mh = null; noAccess = ex; + assertExceptionClass( + (fname.contains("bogus")) + ? NoSuchFieldException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (fname.contains("bogus")) - assertTrue(noAccess instanceof NoSuchFieldException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/ProtectedMemberDifferentPackage/Test.java Tue Apr 15 14:06:19 2014 -0700 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 8032585 + * @summary JSR292: IllegalAccessError when attempting to invoke protected method from different package + * + * @compile p1/T2.java p2/T3.java + * @run main/othervm p2.T3 + */ +public class Test {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/ProtectedMemberDifferentPackage/p1/T2.java Tue Apr 15 14:06:19 2014 -0700 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package p1; + +class T1 { + protected void m() { System.out.println("T1.m");} +} + +public class T2 extends T1 {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/ProtectedMemberDifferentPackage/p2/T3.java Tue Apr 15 14:06:19 2014 -0700 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package p2; + +import p1.T2; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +public class T3 extends T2 { + public static void main(String[] args) throws Throwable { + MethodHandles.lookup().findVirtual(T3.class, "m", MethodType.methodType(void.class)); + System.out.println("TEST PASSED"); + } +}