8336934: Clean up JavaLangReflectAccess

Reviewed-by: rriggs, darcy
This commit is contained in:
Chen Liang 2024-08-21 01:05:41 +00:00
parent d72810794b
commit 88ccbb6091
6 changed files with 35 additions and 168 deletions

@ -165,6 +165,14 @@ public final class Constructor<T> extends Executable {
return res;
}
// Creates a new root constructor with a custom accessor for serialization hooks.
Constructor<T> newWithAccessor(ConstructorAccessor accessor) {
var res = new Constructor<>(clazz, parameterTypes, exceptionTypes, modifiers, slot,
signature, annotations, parameterAnnotations);
res.constructorAccessor = accessor;
return res;
}
/**
* {@inheritDoc}
*

@ -173,21 +173,6 @@ public final class Method extends Executable {
return res;
}
/**
* Make a copy of a leaf method.
*/
Method leafCopy() {
if (this.root == null)
throw new IllegalArgumentException("Can only leafCopy a non-root Method");
Method res = new Method(clazz, name, parameterTypes, returnType,
exceptionTypes, modifiers, slot, signature,
annotations, parameterAnnotations, annotationDefault);
res.root = root;
res.methodAccessor = methodAccessor;
return res;
}
/**
* @throws InaccessibleObjectException {@inheritDoc}
* @throws SecurityException {@inheritDoc}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2024, 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
@ -25,65 +25,15 @@
package java.lang.reflect;
import jdk.internal.reflect.MethodAccessor;
import jdk.internal.access.JavaLangReflectAccess;
import jdk.internal.reflect.ConstructorAccessor;
/** Package-private class implementing the
jdk.internal.access.JavaLangReflectAccess interface, allowing the java.lang
package to instantiate objects in this package. */
class ReflectAccess implements jdk.internal.access.JavaLangReflectAccess {
public <T> Constructor<T> newConstructor(Class<T> declaringClass,
Class<?>[] parameterTypes,
Class<?>[] checkedExceptions,
int modifiers,
int slot,
String signature,
byte[] annotations,
byte[] parameterAnnotations)
{
return new Constructor<>(declaringClass,
parameterTypes,
checkedExceptions,
modifiers,
slot,
signature,
annotations,
parameterAnnotations);
}
public MethodAccessor getMethodAccessor(Method m) {
return m.getMethodAccessor();
}
public void setMethodAccessor(Method m, MethodAccessor accessor) {
m.setMethodAccessor(accessor);
}
public ConstructorAccessor getConstructorAccessor(Constructor<?> c) {
return c.getConstructorAccessor();
}
public void setConstructorAccessor(Constructor<?> c,
ConstructorAccessor accessor)
{
c.setConstructorAccessor(accessor);
}
public int getConstructorSlot(Constructor<?> c) {
return c.getSlot();
}
public String getConstructorSignature(Constructor<?> c) {
return c.getSignature();
}
public byte[] getConstructorAnnotations(Constructor<?> c) {
return c.getRawAnnotations();
}
public byte[] getConstructorParameterAnnotations(Constructor<?> c) {
return c.getRawParameterAnnotations();
final class ReflectAccess implements JavaLangReflectAccess {
public <T> Constructor<T> newConstructorWithAccessor(Constructor<T> original, ConstructorAccessor accessor) {
return original.newWithAccessor(accessor);
}
public byte[] getExecutableTypeAnnotationBytes(Executable ex) {
@ -105,9 +55,6 @@ class ReflectAccess implements jdk.internal.access.JavaLangReflectAccess {
public Method copyMethod(Method arg) {
return arg.copy();
}
public Method leafCopyMethod(Method arg) {
return arg.leafCopy();
}
public Field copyField(Field arg) {
return arg.copy();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2024, 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
@ -29,67 +29,29 @@ import java.lang.reflect.*;
import jdk.internal.reflect.*;
/** An interface which gives privileged packages Java-level access to
internals of java.lang.reflect. */
internals of java.lang.reflect. Use as a last resort! */
public interface JavaLangReflectAccess {
/** Creates a new java.lang.reflect.Constructor. Access checks as
per java.lang.reflect.AccessibleObject are not overridden. */
public <T> Constructor<T> newConstructor(Class<T> declaringClass,
Class<?>[] parameterTypes,
Class<?>[] checkedExceptions,
int modifiers,
int slot,
String signature,
byte[] annotations,
byte[] parameterAnnotations);
/** Gets the MethodAccessor object for a java.lang.reflect.Method */
public MethodAccessor getMethodAccessor(Method m);
/** Sets the MethodAccessor object for a java.lang.reflect.Method */
public void setMethodAccessor(Method m, MethodAccessor accessor);
/** Gets the ConstructorAccessor object for a
java.lang.reflect.Constructor */
public ConstructorAccessor getConstructorAccessor(Constructor<?> c);
/** Sets the ConstructorAccessor object for a
java.lang.reflect.Constructor */
public void setConstructorAccessor(Constructor<?> c,
ConstructorAccessor accessor);
/**
* Creates a new root constructor from the original one, with
* a custom accessor. Used by serialization hooks.
*/
<T> Constructor<T> newConstructorWithAccessor(Constructor<T> original, ConstructorAccessor accessor);
/** Gets the byte[] that encodes TypeAnnotations on an Executable. */
public byte[] getExecutableTypeAnnotationBytes(Executable ex);
/** Gets the "slot" field from a Constructor (used for serialization) */
public int getConstructorSlot(Constructor<?> c);
/** Gets the "signature" field from a Constructor (used for serialization) */
public String getConstructorSignature(Constructor<?> c);
/** Gets the "annotations" field from a Constructor (used for serialization) */
public byte[] getConstructorAnnotations(Constructor<?> c);
/** Gets the "parameterAnnotations" field from a Constructor (used for serialization) */
public byte[] getConstructorParameterAnnotations(Constructor<?> c);
/** Gets the shared array of parameter types of an Executable. */
public Class<?>[] getExecutableSharedParameterTypes(Executable ex);
/** Gets the shared array of exception types of an Executable. */
public Class<?>[] getExecutableSharedExceptionTypes(Executable ex);
//
// Copying routines, needed to quickly fabricate new Field,
// Method, and Constructor objects from templates
//
/** Makes a "child" copy of a Method */
public Method copyMethod(Method arg);
/** Makes a copy of this non-root a Method */
public Method leafCopyMethod(Method arg);
/** Makes a "child" copy of a Field */
public Field copyField(Field arg);

@ -53,7 +53,13 @@ import javax.security.auth.x500.X500Principal;
within that package; the object implementing that interface is
provided through a third package to which access is restricted.
This framework avoids the primary disadvantage of using reflection
for this purpose, namely the loss of compile-time checking. */
for this purpose, namely the loss of compile-time checking.
* <p><strong>
* Usage of these APIs often means bad encapsulation designs,
* increased complexity and lack of sustainability.
* Use this only as a last resort!
* </strong>
*/
public class SharedSecrets {
private static JavaAWTAccess javaAWTAccess;

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2024, 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
@ -179,41 +179,6 @@ public class ReflectionFactory {
//
//
/** Creates a new java.lang.reflect.Constructor. Access checks as
per java.lang.reflect.AccessibleObject are not overridden. */
public Constructor<?> newConstructor(Class<?> declaringClass,
Class<?>[] parameterTypes,
Class<?>[] checkedExceptions,
int modifiers,
int slot,
String signature,
byte[] annotations,
byte[] parameterAnnotations)
{
return langReflectAccess.newConstructor(declaringClass,
parameterTypes,
checkedExceptions,
modifiers,
slot,
signature,
annotations,
parameterAnnotations);
}
/** Gets the ConstructorAccessor object for a
java.lang.reflect.Constructor */
public ConstructorAccessor getConstructorAccessor(Constructor<?> c) {
return langReflectAccess.getConstructorAccessor(c);
}
/** Sets the ConstructorAccessor object for a
java.lang.reflect.Constructor */
public void setConstructorAccessor(Constructor<?> c,
ConstructorAccessor accessor)
{
langReflectAccess.setConstructorAccessor(c, accessor);
}
/** Makes a copy of the passed method. The returned method is a
"child" of the passed one; see the comments in Method.java for
details. */
@ -225,10 +190,10 @@ public class ReflectionFactory {
* a "child" but a "sibling" of the Method in arg. Should only be
* used on non-root methods. */
public Method leafCopyMethod(Method arg) {
return langReflectAccess.leafCopyMethod(arg);
Method root = langReflectAccess.getRoot(arg);
return langReflectAccess.copyMethod(root);
}
/** Makes a copy of the passed field. The returned field is a
"child" of the passed one; see the comments in Field.java for
details. */
@ -369,15 +334,6 @@ public class ReflectionFactory {
private final Constructor<?> generateConstructor(Class<?> cl,
Constructor<?> constructorToCall) {
Constructor<?> ctor = newConstructor(constructorToCall.getDeclaringClass(),
constructorToCall.getParameterTypes(),
constructorToCall.getExceptionTypes(),
constructorToCall.getModifiers(),
langReflectAccess.getConstructorSlot(constructorToCall),
langReflectAccess.getConstructorSignature(constructorToCall),
langReflectAccess.getConstructorAnnotations(constructorToCall),
langReflectAccess.getConstructorParameterAnnotations(constructorToCall));
ConstructorAccessor acc;
if (useOldSerializableConstructor()) {
acc = new SerializationConstructorAccessorGenerator().
@ -386,9 +342,12 @@ public class ReflectionFactory {
constructorToCall.getModifiers(),
constructorToCall.getDeclaringClass());
} else {
acc = MethodHandleAccessorFactory.newSerializableConstructorAccessor(cl, ctor);
acc = MethodHandleAccessorFactory.newSerializableConstructorAccessor(cl, constructorToCall);
}
setConstructorAccessor(ctor, acc);
// Unlike other root constructors, this constructor is not copied for mutation
// but directly mutated, as it is not cached. To cache this constructor,
// setAccessible call must be done on a copy and return that copy instead.
Constructor<?> ctor = langReflectAccess.newConstructorWithAccessor(constructorToCall, acc);
ctor.setAccessible(true);
return ctor;
}