diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index 8333ab65042..7c5c998e2f1 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -84,6 +84,7 @@ import java.util.Set; import java.util.stream.Collectors; +import jdk.internal.access.SharedSecrets; import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.constant.ConstantUtils; import jdk.internal.javac.PreviewFeature; @@ -2469,7 +2470,7 @@ private Deconstructor[] getDeclaredDeconstructors0(Class[] params, int whi ByteBuffer assembled_rvta = getAnnotationContents(rvta != null, (BoundAttribute) rvta); for (int i = 0; i < parameterList.size(); i++) { - Class bindingClass = parameterList.get(i).resolveConstantDesc(MethodHandles.lookup()); + Class bindingClass = parameterList.get(i).resolveConstantDesc(MethodHandles.privateLookupIn(this, SharedSecrets.getJavaLangInvokeAccess().implLookup())); deconstructorBindings.add(new PatternBinding( currentDeconstructor, parameterNameList.get(i), diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java index e79c8463d30..235d7e37b79 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -1653,6 +1653,9 @@ public MethodHandle serializableConstructor(Class decl, Constructor ctorTo return IMPL_LOOKUP.serializableConstructor(decl, ctorToCall); } + @Override + public Lookup implLookup() { return IMPL_LOOKUP; } + }); } diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangInvokeAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangInvokeAccess.java index 563870381fe..69c3d46588f 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangInvokeAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangInvokeAccess.java @@ -170,4 +170,7 @@ public interface JavaLangInvokeAccess { * This method should only be used by ReflectionFactory::newConstructorForSerialization. */ MethodHandle serializableConstructor(Class decl, Constructor ctorToCall) throws IllegalAccessException; + + // TODO: extra check if needed + Lookup implLookup(); } diff --git a/test/jdk/java/lang/reflect/Deconstructor/SimpleDeconstructorsTest.java b/test/jdk/java/lang/reflect/Deconstructor/SimpleDeconstructorsTest.java index 00825d8fb94..e0ff73c5417 100644 --- a/test/jdk/java/lang/reflect/Deconstructor/SimpleDeconstructorsTest.java +++ b/test/jdk/java/lang/reflect/Deconstructor/SimpleDeconstructorsTest.java @@ -53,6 +53,7 @@ public static void main(String[] args) throws NoSuchPatternException, IllegalAcc testDeconstructorElementsAnnotations(); testDeconstructorAnnotations(); testGenericString(); + testGetDeclaredDeconstructors_bug1(); } public static void testGetMethods() { @@ -167,12 +168,30 @@ public static void testGenericString() throws NoSuchPatternException{ assertEquals(method.toGenericString(), "public pattern SimpleDeconstructorsTest$Person1(java.util.List)"); } + public static void testGetDeclaredDeconstructors_bug1() { + Deconstructor[] methods = B.class.getDeclaredDeconstructors(); + + assertEquals(methods.length, 1); + } + static void assertEquals(Object actual, Object expected) { if (!Objects.equals(expected, actual)) { throw new AssertionError("Expected: " + expected + ", but got: " + actual); } } + class A { + String s; + public A(String s) { this.s = s; } + public pattern A(String s) { match A(this.s); } + } + + class B { + A a; + public B(A a) { this.a = a; } + public pattern B(A a) { match B(this.a); } + } + public static class Person1 { private final String name; private final String username;