diff --git a/.hgtags b/.hgtags index 060dcb4aae25f9aeb46d45e16167ee3d6d5d2677..503a024506f4b049abb82a7672cf99243679278e 100644 --- a/.hgtags +++ b/.hgtags @@ -313,3 +313,5 @@ dfb9f24d56b51e5a2ca26e77fc69a2464d51a4d3 jdk8u20-b24 dfb9f24d56b51e5a2ca26e77fc69a2464d51a4d3 jdk8u20-b25 dd229c5f57bff4e75a70908294a13072b9a48385 jdk8u20-b26 e6ed015afbbf3459ba3297e270b4f3170e989c80 jdk8u40-b00 +6e223d48080ef40f4ec11ecbcd19b4a20813b9eb jdk8u40-b01 +4797cd0713b44b009525f1276d571ade7e24f3f5 jdk8u40-b02 diff --git a/src/share/classes/java/lang/reflect/Constructor.java b/src/share/classes/java/lang/reflect/Constructor.java index d852fcd174180acc1249e8cf83b8b754b0f234e0..7a85545752fda0e7e445e6cfb5974d13b894b67f 100644 --- a/src/share/classes/java/lang/reflect/Constructor.java +++ b/src/share/classes/java/lang/reflect/Constructor.java @@ -543,15 +543,33 @@ public final class Constructor extends Executable { */ @Override public AnnotatedType getAnnotatedReceiverType() { - if (getDeclaringClass().getEnclosingClass() == null) - return super.getAnnotatedReceiverType(); + Class thisDeclClass = getDeclaringClass(); + Class enclosingClass = thisDeclClass.getEnclosingClass(); + if (enclosingClass == null) { + // A Constructor for a top-level class + return null; + } + + Class outerDeclaringClass = thisDeclClass.getDeclaringClass(); + if (outerDeclaringClass == null) { + // A constructor for a local or anonymous class + return null; + } + + // Either static nested or inner class + if (Modifier.isStatic(thisDeclClass.getModifiers())) { + // static nested + return null; + } + + // A Constructor for an inner class return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(), sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), + getConstantPool(thisDeclClass), this, - getDeclaringClass(), - getDeclaringClass().getEnclosingClass(), + thisDeclClass, + enclosingClass, TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER); } } diff --git a/src/share/classes/java/lang/reflect/Executable.java b/src/share/classes/java/lang/reflect/Executable.java index bf9c9b89b722afbd555f12749288c31fc7de066b..b4e88748cb6baf7c287e394e6ea59c99bc50413b 100644 --- a/src/share/classes/java/lang/reflect/Executable.java +++ b/src/share/classes/java/lang/reflect/Executable.java @@ -592,21 +592,24 @@ public abstract class Executable extends AccessibleObject /** * Returns an {@code AnnotatedType} object that represents the use of a * type to specify the receiver type of the method/constructor represented - * by this Executable object. The receiver type of a method/constructor is - * available only if the method/constructor has a receiver - * parameter (JLS 8.4.1). + * by this {@code Executable} object. * - * If this {@code Executable} object represents a constructor or instance - * method that does not have a receiver parameter, or has a receiver - * parameter with no annotations on its type, then the return value is an - * {@code AnnotatedType} object representing an element with no + * The receiver type of a method/constructor is available only if the + * method/constructor has a receiver parameter (JLS 8.4.1). If this {@code + * Executable} object represents an instance method or represents a + * constructor of an inner member class, and the + * method/constructor either has no receiver parameter or has a + * receiver parameter with no annotations on its type, then the return + * value is an {@code AnnotatedType} object representing an element with no * annotations. * - * If this {@code Executable} object represents a static method, then the - * return value is null. + * If this {@code Executable} object represents a static method or + * represents a constructor of a top level, static member, local, or + * anoymous class, then the return value is null. * * @return an object representing the receiver type of the method or - * constructor represented by this {@code Executable} + * constructor represented by this {@code Executable} or {@code null} if + * this {@code Executable} can not have a receiver parameter * * @since 1.8 */ diff --git a/src/share/classes/sun/awt/ComponentFactory.java b/src/share/classes/sun/awt/ComponentFactory.java index e1d616f1d93e3091e8aaed7e32d4e859596247e8..4d167804722a65471da5da094b7d70b02a1ee5e2 100644 --- a/src/share/classes/sun/awt/ComponentFactory.java +++ b/src/share/classes/sun/awt/ComponentFactory.java @@ -25,6 +25,8 @@ package sun.awt; +import sun.awt.datatransfer.DataTransferer; + import java.awt.*; import java.awt.dnd.*; import java.awt.dnd.peer.DragSourceContextPeer; @@ -93,4 +95,6 @@ public interface ComponentFactory { RobotPeer createRobot(Robot target, GraphicsDevice screen) throws AWTException, HeadlessException; + DataTransferer getDataTransferer(); + } diff --git a/src/share/classes/sun/awt/HeadlessToolkit.java b/src/share/classes/sun/awt/HeadlessToolkit.java index 9d68bd48b1ea28d3428ff15addfe57e87d292d26..c0757be829ca9a7a1f4aa41c2bd7bf60b76c1c20 100644 --- a/src/share/classes/sun/awt/HeadlessToolkit.java +++ b/src/share/classes/sun/awt/HeadlessToolkit.java @@ -25,6 +25,8 @@ package sun.awt; +import sun.awt.datatransfer.DataTransferer; + import java.awt.*; import java.awt.dnd.*; import java.awt.dnd.peer.DragSourceContextPeer; @@ -401,6 +403,11 @@ public class HeadlessToolkit extends Toolkit return null; } + @Override + public DataTransferer getDataTransferer() { + return null; + } + @SuppressWarnings("deprecation") public FontMetrics getFontMetrics(Font font) { return tk.getFontMetrics(font); diff --git a/src/share/classes/sun/awt/SunToolkit.java b/src/share/classes/sun/awt/SunToolkit.java index 3ce7b80b6a707da6e02f47a660bc4cfae7a75cf3..ccde34ac55ff4760c81abc49c0f2226a031b1015 100644 --- a/src/share/classes/sun/awt/SunToolkit.java +++ b/src/share/classes/sun/awt/SunToolkit.java @@ -205,8 +205,6 @@ public abstract class SunToolkit extends Toolkit public abstract boolean isTraySupported(); - public abstract DataTransferer getDataTransferer(); - @SuppressWarnings("deprecation") public abstract FontPeer getFontPeer(String name, int style); diff --git a/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/src/share/classes/sun/awt/datatransfer/DataTransferer.java index 2c4b75fcaac08d216794d67da234fecb35e9a938..c5a7f59197d573edaaf23ce617cddadb0ac34586 100644 --- a/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -86,6 +86,7 @@ import java.util.Stack; import java.util.TreeMap; import java.util.TreeSet; +import sun.awt.ComponentFactory; import sun.util.logging.PlatformLogger; import sun.awt.AppContext; @@ -272,7 +273,7 @@ public abstract class DataTransferer { * instead, null will be returned. */ public static synchronized DataTransferer getInstance() { - return ((SunToolkit) Toolkit.getDefaultToolkit()).getDataTransferer(); + return ((ComponentFactory) Toolkit.getDefaultToolkit()).getDataTransferer(); } /** diff --git a/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c b/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c index 55233d06cfc6ae4ad85aad02ee025b40c38afae8..c06efaf59117f52342092b2be2309192ea9fa866 100644 --- a/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c +++ b/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c @@ -315,7 +315,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_dup(JNIEnv* env, jclass this, jint fd) { int res = -1; RESTARTABLE(dup((int)fd), res); - if (fd == -1) { + if (res == -1) { throwUnixException(env, errno); } return (jint)res; @@ -343,13 +343,14 @@ Java_sun_nio_fs_UnixNativeDispatcher_fopen0(JNIEnv* env, jclass this, JNIEXPORT void JNICALL Java_sun_nio_fs_UnixNativeDispatcher_fclose(JNIEnv* env, jclass this, jlong stream) { - int res; FILE* fp = jlong_to_ptr(stream); - do { - res = fclose(fp); - } while (res == EOF && errno == EINTR); - if (res == EOF) { + /* NOTE: fclose() wrapper is only used with read-only streams. + * If it ever is used with write streams, it might be better to add + * RESTARTABLE(fflush(fp)) before closing, to make sure the stream + * is completely written even if fclose() failed. + */ + if (fclose(fp) == EOF && errno != EINTR) { throwUnixException(env, errno); } } @@ -657,11 +658,9 @@ Java_sun_nio_fs_UnixNativeDispatcher_fdopendir(JNIEnv* env, jclass this, int dfd JNIEXPORT void JNICALL Java_sun_nio_fs_UnixNativeDispatcher_closedir(JNIEnv* env, jclass this, jlong dir) { - int err; DIR* dirp = jlong_to_ptr(dir); - RESTARTABLE(closedir(dirp), err); - if (errno == -1) { + if (closedir(dirp) == -1 && errno != EINTR) { throwUnixException(env, errno); } } diff --git a/test/java/lang/annotation/typeAnnotations/ConstructorReceiverTest.java b/test/java/lang/annotation/typeAnnotations/ConstructorReceiverTest.java index d4a75daaaebadda3da2018f9e559d5b12c04c3d4..fb314502765c8d001922feea46bad74629b519af 100644 --- a/test/java/lang/annotation/typeAnnotations/ConstructorReceiverTest.java +++ b/test/java/lang/annotation/typeAnnotations/ConstructorReceiverTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8023651 + * @bug 8023651 8044629 * @summary Test that the receiver annotations and the return annotations of * constructors behave correctly. * @run testng ConstructorReceiverTest @@ -38,11 +38,16 @@ import org.testng.annotations.Test; import static org.testng.Assert.*; public class ConstructorReceiverTest { + public static final Integer EMPTY_ANNOTATED_TYPE = Integer.valueOf(-1); + // Format is { // { Class to get ctor for, // ctor param class, // value of anno of return type, - // value of anno for receiver or null if there should be no receiver anno + // value of anno for receiver, + // or null if there should be no receiver, + // or EMPTY_ANNOTATED_TYPE of there should be a receiver but + // no annotation // }, // ... // } @@ -51,13 +56,15 @@ public class ConstructorReceiverTest { { ConstructorReceiverTest.Middle.class, ConstructorReceiverTest.class, Integer.valueOf(10), Integer.valueOf(15) }, { ConstructorReceiverTest.Middle.Inner.class, ConstructorReceiverTest.Middle.class, Integer.valueOf(100), Integer.valueOf(150) }, { ConstructorReceiverTest.Middle.Inner.Innermost.class, ConstructorReceiverTest.Middle.Inner.class, Integer.valueOf(1000), Integer.valueOf(1500) }, - { ConstructorReceiverTest.Middle.InnerNoReceiver.class, ConstructorReceiverTest.Middle.class, Integer.valueOf(300), null }, + { ConstructorReceiverTest.Middle.InnerNoReceiver.class, ConstructorReceiverTest.Middle.class, Integer.valueOf(300), EMPTY_ANNOTATED_TYPE }, { ConstructorReceiverTest.Nested.class, null, Integer.valueOf(20), null }, { ConstructorReceiverTest.Nested.NestedMiddle.class, ConstructorReceiverTest.Nested.class, Integer.valueOf(200), Integer.valueOf(250)}, { ConstructorReceiverTest.Nested.NestedMiddle.NestedInner.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(2000), Integer.valueOf(2500)}, - { ConstructorReceiverTest.Nested.NestedMiddle.NestedInnerNoReceiver.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(4000), null}, + { ConstructorReceiverTest.Nested.NestedMiddle.NestedInnerNoReceiver.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(4000), EMPTY_ANNOTATED_TYPE}, + { ConstructorReceiverTest.Nested.NestedMiddle.SecondNestedInnerNoReceiver.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(5000), EMPTY_ANNOTATED_TYPE}, }; + @DataProvider public Object[][] data() { return TESTS; } @@ -71,14 +78,27 @@ public class ConstructorReceiverTest { c = toTest.getDeclaredConstructor(ctorParamType); AnnotatedType annotatedReceiverType = c.getAnnotatedReceiverType(); - Annotation[] receiverAnnotations = annotatedReceiverType.getAnnotations(); + // Some Constructors doesn't conceptually have a receiver, they should return null if (receiverVal == null) { - assertEquals(receiverAnnotations.length, 0, Arrays.asList(receiverAnnotations).toString() + - " should be empty. Looking at 'length': "); + assertNull(annotatedReceiverType, "getAnnotatedReciverType should return null for Constructor: " + c); return; } + // check that getType() matches the receiver + assertEquals(annotatedReceiverType.getType(), + ctorParamType, + "getType() doesn't match receiver type: " + ctorParamType); + + Annotation[] receiverAnnotations = annotatedReceiverType.getAnnotations(); + + // Some Constructors have no annotations on but in theory can have a receiver + if (receiverVal.equals(EMPTY_ANNOTATED_TYPE)) { + assertEquals(receiverAnnotations.length, 0, "expecting an empty annotated type for: " + c); + return; + } + + // The rest should have annotations assertEquals(receiverAnnotations.length, 1, "expecting a 1 element array. Looking at 'length': "); assertEquals(((Annot)receiverAnnotations[0]).value(), receiverVal.intValue(), " wrong annotation found. Found " + receiverAnnotations[0] + @@ -136,6 +156,10 @@ public class ConstructorReceiverTest { class NestedInnerNoReceiver { @Annot(4000) public NestedInnerNoReceiver() {} } + + class SecondNestedInnerNoReceiver { + @Annot(5000) public SecondNestedInnerNoReceiver(NestedMiddle NestedMiddle.this) {} + } } } diff --git a/test/java/lang/annotation/typeAnnotations/GetAnnotatedReceiverType.java b/test/java/lang/annotation/typeAnnotations/GetAnnotatedReceiverType.java index e3dd64612c8b5c0090d82a86afa65f41be857a7b..e9608089763a113db1d1fe77224766f73827a715 100644 --- a/test/java/lang/annotation/typeAnnotations/GetAnnotatedReceiverType.java +++ b/test/java/lang/annotation/typeAnnotations/GetAnnotatedReceiverType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -23,10 +23,11 @@ /* * @test - * @bug 8024915 + * @bug 8024915 8044629 */ import java.lang.reflect.AnnotatedType; +import java.lang.reflect.Executable; import java.util.Arrays; public class GetAnnotatedReceiverType { @@ -42,41 +43,115 @@ public class GetAnnotatedReceiverType { public Inner1(GetAnnotatedReceiverType GetAnnotatedReceiverType.this) {} } + public static class Nested { + public Nested() {} + + public class NestedInner { + public NestedInner() { } + + public Class getLocalClass () { + class NestedInnerLocal { public NestedInnerLocal() {} } + return NestedInnerLocal.class; + } + + public Class getAnonymousClass() { + return new Object() {}.getClass(); + } + } + } + + public class Inner2 { + public Inner2() { } + + public class Inner3 { + public Inner3() { } + + public Class getLocalClass () { + class InnerLocal { public InnerLocal() {} } + return InnerLocal.class; + } + + public Class getAnonymousClass() { + return new Object() {}.getClass(); + } + } + + public Class getLocalClass () { + class InnerLocal { public InnerLocal() {} } + return InnerLocal.class; + } + + public Class getAnonymousClass() { + return new Object() {}.getClass(); + } + } + private static int failures = 0; private static int tests = 0; public static void main(String[] args) throws NoSuchMethodException { - checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method").getAnnotatedReceiverType(), + checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method"), "getAnnotatedReceiverType for \"method\" should return an empty AnnotatedType"); - checkEmptyAT(Inner0.class.getConstructor(GetAnnotatedReceiverType.class).getAnnotatedReceiverType(), + checkEmptyAT(Inner0.class.getConstructor(GetAnnotatedReceiverType.class), "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType"); - checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method0").getAnnotatedReceiverType(), + checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method0"), "getAnnotatedReceiverType for \"method0\" should return an empty AnnotatedType"); - checkEmptyAT(Inner1.class.getConstructor(GetAnnotatedReceiverType.class).getAnnotatedReceiverType(), + checkEmptyAT(Inner1.class.getConstructor(GetAnnotatedReceiverType.class), "getAnnotatedReceiverType for a ctor with a \"this\" should return an empty AnnotatedType"); - checkNull(GetAnnotatedReceiverType.class.getMethod("method4").getAnnotatedReceiverType(), + checkNull(GetAnnotatedReceiverType.class.getMethod("method4"), "getAnnotatedReceiverType() on a static method should return null"); + // More nested, inner, local and anonymous classes + Nested nested = new Nested(); + Nested.NestedInner instance = nested.new NestedInner(); + checkNull(nested.getClass().getConstructors()[0], + "getAnnotatedReceiverType() on a constructor for a static class should return null"); + checkEmptyAT(instance.getClass().getConstructors()[0], + "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType"); + checkNull(instance.getLocalClass().getConstructors()[0], + "getAnnotatedReceiverType() on a constructor for a local class should return null"); + checkNull(instance.getAnonymousClass().getDeclaredConstructors()[0], + "getAnnotatedReceiverType() on a constructor for an anonymous class should return null"); + + GetAnnotatedReceiverType outer = new GetAnnotatedReceiverType(); + Inner2 instance2 = outer.new Inner2(); + checkEmptyAT(instance2.getClass().getConstructors()[0], + "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType"); + checkNull(instance2.getLocalClass().getConstructors()[0], + "getAnnotatedReceiverType() on a constructor for a local class should return null"); + checkNull(instance2.getAnonymousClass().getDeclaredConstructors()[0], + "getAnnotatedReceiverType() on a constructor for an anonymous class should return null"); + + Inner2.Inner3 instance3 = instance2.new Inner3(); + checkEmptyAT(instance3.getClass().getConstructors()[0], + "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType"); + checkNull(instance3.getLocalClass().getConstructors()[0], + "getAnnotatedReceiverType() on a constructor for a local class should return null"); + checkNull(instance3.getAnonymousClass().getDeclaredConstructors()[0], + "getAnnotatedReceiverType() on a constructor for an anonymous class should return null"); + if (failures != 0) throw new RuntimeException("Test failed, see log for details"); - else if (tests != 5) + else if (tests != 15) throw new RuntimeException("Not all cases ran, failing"); } - private static void checkNull(Object o, String msg) { - if (o != null) { + private static void checkNull(Executable e, String msg) { + AnnotatedType a = e.getAnnotatedReceiverType(); + if (a != null) { failures++; - System.err.println(msg); + System.err.println(msg + ": " + e); } tests++; } - private static void checkEmptyAT(AnnotatedType a, String msg) { + private static void checkEmptyAT(Executable e, String msg) { + AnnotatedType a = e.getAnnotatedReceiverType(); if (a.getAnnotations().length != 0) { failures++; - System.err.print(msg); + System.err.print(msg + ": " + e); } tests++; } diff --git a/test/java/lang/annotation/typeAnnotations/TestExecutableGetAnnotatedType.java b/test/java/lang/annotation/typeAnnotations/TestExecutableGetAnnotatedType.java index ad8a87a13d391dc134418aa919ed1d16bbf6e3bc..6735f46cec0d542a038210d09a47bde7595fadfe 100644 --- a/test/java/lang/annotation/typeAnnotations/TestExecutableGetAnnotatedType.java +++ b/test/java/lang/annotation/typeAnnotations/TestExecutableGetAnnotatedType.java @@ -73,13 +73,11 @@ public class TestExecutableGetAnnotatedType { testParameters(e.getParameters()); } - // should test constructors as well, see JDK-8044629 @Test(dataProvider = "genericMethodData") public void testGenericReceiverType(Executable e) throws Exception { testReceiverType0(e); } - // should test constructors as well, see JDK-8044629 @Test(dataProvider = "methodData") public void testReceiverType(Executable e) throws Exception { testReceiverType0(e);