Skip to content

Commit

Permalink
8336934: Clean up JavaLangReflectAccess
Browse files Browse the repository at this point in the history
Reviewed-by: rriggs, darcy
  • Loading branch information
liach committed Aug 21, 2024
1 parent d728107 commit 88ccbb6
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 168 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,14 @@ Constructor<T> copy() {
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}
*
Expand Down
15 changes: 0 additions & 15 deletions src/java.base/share/classes/java/lang/reflect/Method.java
Original file line number Diff line number Diff line change
Expand Up @@ -173,21 +173,6 @@ Method copy() {
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}
Expand Down
63 changes: 5 additions & 58 deletions src/java.base/share/classes/java/lang/reflect/ReflectAccess.java
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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) {
Expand All @@ -105,9 +55,6 @@ public Class<?>[] getExecutableSharedExceptionTypes(Executable ex) {
public Method copyMethod(Method arg) {
return arg.copy();
}
public Method leafCopyMethod(Method arg) {
return arg.leafCopy();
}

public Field copyField(Field arg) {
return arg.copy();
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -29,67 +29,29 @@
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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,13 @@ interface and provides the ability to call package-private methods
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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -179,41 +179,6 @@ public ConstructorAccessor newConstructorAccessor(Constructor<?> c) {
//
//

/** 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. */
Expand All @@ -225,10 +190,10 @@ public Method copyMethod(Method arg) {
* 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. */
Expand Down Expand Up @@ -369,15 +334,6 @@ public final Constructor<?> newConstructorForSerialization(Class<?> cl) {

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().
Expand All @@ -386,9 +342,12 @@ private final Constructor<?> generateConstructor(Class<?> cl,
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;
}
Expand Down

0 comments on commit 88ccbb6

Please sign in to comment.