mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8336934: Clean up JavaLangReflectAccess
Reviewed-by: rriggs, darcy
This commit is contained in:
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;
|
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}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
|
|
|
@ -173,21 +173,6 @@ public final class Method extends Executable {
|
||||||
return res;
|
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 InaccessibleObjectException {@inheritDoc}
|
||||||
* @throws SecurityException {@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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -25,65 +25,15 @@
|
||||||
|
|
||||||
package java.lang.reflect;
|
package java.lang.reflect;
|
||||||
|
|
||||||
import jdk.internal.reflect.MethodAccessor;
|
import jdk.internal.access.JavaLangReflectAccess;
|
||||||
import jdk.internal.reflect.ConstructorAccessor;
|
import jdk.internal.reflect.ConstructorAccessor;
|
||||||
|
|
||||||
/** Package-private class implementing the
|
/** Package-private class implementing the
|
||||||
jdk.internal.access.JavaLangReflectAccess interface, allowing the java.lang
|
jdk.internal.access.JavaLangReflectAccess interface, allowing the java.lang
|
||||||
package to instantiate objects in this package. */
|
package to instantiate objects in this package. */
|
||||||
|
final class ReflectAccess implements JavaLangReflectAccess {
|
||||||
class ReflectAccess implements jdk.internal.access.JavaLangReflectAccess {
|
public <T> Constructor<T> newConstructorWithAccessor(Constructor<T> original, ConstructorAccessor accessor) {
|
||||||
public <T> Constructor<T> newConstructor(Class<T> declaringClass,
|
return original.newWithAccessor(accessor);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getExecutableTypeAnnotationBytes(Executable ex) {
|
public byte[] getExecutableTypeAnnotationBytes(Executable ex) {
|
||||||
|
@ -105,9 +55,6 @@ class ReflectAccess implements jdk.internal.access.JavaLangReflectAccess {
|
||||||
public Method copyMethod(Method arg) {
|
public Method copyMethod(Method arg) {
|
||||||
return arg.copy();
|
return arg.copy();
|
||||||
}
|
}
|
||||||
public Method leafCopyMethod(Method arg) {
|
|
||||||
return arg.leafCopy();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Field copyField(Field arg) {
|
public Field copyField(Field arg) {
|
||||||
return arg.copy();
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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.*;
|
import jdk.internal.reflect.*;
|
||||||
|
|
||||||
/** An interface which gives privileged packages Java-level access to
|
/** 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 {
|
public interface JavaLangReflectAccess {
|
||||||
/** Creates a new java.lang.reflect.Constructor. Access checks as
|
/**
|
||||||
per java.lang.reflect.AccessibleObject are not overridden. */
|
* Creates a new root constructor from the original one, with
|
||||||
public <T> Constructor<T> newConstructor(Class<T> declaringClass,
|
* a custom accessor. Used by serialization hooks.
|
||||||
Class<?>[] parameterTypes,
|
*/
|
||||||
Class<?>[] checkedExceptions,
|
<T> Constructor<T> newConstructorWithAccessor(Constructor<T> original, ConstructorAccessor accessor);
|
||||||
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);
|
|
||||||
|
|
||||||
/** Gets the byte[] that encodes TypeAnnotations on an Executable. */
|
/** Gets the byte[] that encodes TypeAnnotations on an Executable. */
|
||||||
public byte[] getExecutableTypeAnnotationBytes(Executable ex);
|
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. */
|
/** Gets the shared array of parameter types of an Executable. */
|
||||||
public Class<?>[] getExecutableSharedParameterTypes(Executable ex);
|
public Class<?>[] getExecutableSharedParameterTypes(Executable ex);
|
||||||
|
|
||||||
/** Gets the shared array of exception types of an Executable. */
|
/** Gets the shared array of exception types of an Executable. */
|
||||||
public Class<?>[] getExecutableSharedExceptionTypes(Executable ex);
|
public Class<?>[] getExecutableSharedExceptionTypes(Executable ex);
|
||||||
|
|
||||||
//
|
|
||||||
// Copying routines, needed to quickly fabricate new Field,
|
// Copying routines, needed to quickly fabricate new Field,
|
||||||
// Method, and Constructor objects from templates
|
// Method, and Constructor objects from templates
|
||||||
//
|
|
||||||
|
|
||||||
/** Makes a "child" copy of a Method */
|
/** Makes a "child" copy of a Method */
|
||||||
public Method copyMethod(Method arg);
|
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 */
|
/** Makes a "child" copy of a Field */
|
||||||
public Field copyField(Field arg);
|
public Field copyField(Field arg);
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,13 @@ import javax.security.auth.x500.X500Principal;
|
||||||
within that package; the object implementing that interface is
|
within that package; the object implementing that interface is
|
||||||
provided through a third package to which access is restricted.
|
provided through a third package to which access is restricted.
|
||||||
This framework avoids the primary disadvantage of using reflection
|
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 {
|
public class SharedSecrets {
|
||||||
private static JavaAWTAccess javaAWTAccess;
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
/** Makes a copy of the passed method. The returned method is a
|
||||||
"child" of the passed one; see the comments in Method.java for
|
"child" of the passed one; see the comments in Method.java for
|
||||||
details. */
|
details. */
|
||||||
|
@ -225,10 +190,10 @@ public class ReflectionFactory {
|
||||||
* a "child" but a "sibling" of the Method in arg. Should only be
|
* a "child" but a "sibling" of the Method in arg. Should only be
|
||||||
* used on non-root methods. */
|
* used on non-root methods. */
|
||||||
public Method leafCopyMethod(Method arg) {
|
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
|
/** Makes a copy of the passed field. The returned field is a
|
||||||
"child" of the passed one; see the comments in Field.java for
|
"child" of the passed one; see the comments in Field.java for
|
||||||
details. */
|
details. */
|
||||||
|
@ -369,15 +334,6 @@ public class ReflectionFactory {
|
||||||
|
|
||||||
private final Constructor<?> generateConstructor(Class<?> cl,
|
private final Constructor<?> generateConstructor(Class<?> cl,
|
||||||
Constructor<?> constructorToCall) {
|
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;
|
ConstructorAccessor acc;
|
||||||
if (useOldSerializableConstructor()) {
|
if (useOldSerializableConstructor()) {
|
||||||
acc = new SerializationConstructorAccessorGenerator().
|
acc = new SerializationConstructorAccessorGenerator().
|
||||||
|
@ -386,9 +342,12 @@ public class ReflectionFactory {
|
||||||
constructorToCall.getModifiers(),
|
constructorToCall.getModifiers(),
|
||||||
constructorToCall.getDeclaringClass());
|
constructorToCall.getDeclaringClass());
|
||||||
} else {
|
} 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);
|
ctor.setAccessible(true);
|
||||||
return ctor;
|
return ctor;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue