public final class ReflectionUtils extends java.lang.Object
Reads the properties of a bean whose class is not public.
A class that is not public -- anonymous, local, or package-private -- cannot have its read
methods invoked from another package even when the methods themselves are public, so reflection
over such a bean needs help. Groovy 4 stamped ACC_PUBLIC on anonymous inner classes and
Groovy 5 does not, which is why beans of that shape reach the framework at all.
This compatibility handling is deliberately visible: warnOnNonPublicClass reports the class once so an application can be corrected, and so the handling can be withdrawn if the compiler stops producing non-public classes for this shape.
| Type Params | Return Type | Name and description |
|---|---|---|
|
public static void |
resetWarnedClasses()Forgets which classes have been reported. |
|
public static java.lang.reflect.Method |
resolveInvokableReadMethod(java.lang.reflect.Method readMethod, java.lang.Class<?> targetClass, java.lang.Object target)Resolves a read method that can actually be invoked on target. |
|
public static boolean |
tryMakeReadable(java.lang.reflect.Field field, java.lang.Object target)Makes an instance field readable, widening it only when it is not readable already. |
|
public static boolean |
warnOnNonPublicClass(java.lang.Class<?> clazz)Reports clazz if it is not public, at most once per class. |
| Methods inherited from class | Name |
|---|---|
class java.lang.Object |
java.lang.Object#equals(java.lang.Object), java.lang.Object#getClass(), java.lang.Object#hashCode(), java.lang.Object#notify(), java.lang.Object#notifyAll(), java.lang.Object#toString(), java.lang.Object#wait(), java.lang.Object#wait(long), java.lang.Object#wait(long, int) |
Forgets which classes have been reported. Intended for tests, which would otherwise depend on whether another test in the same JVM reported the same class first.
Resolves a read method that can actually be invoked on target.
Where an equivalent method is declared by a public type anywhere in the hierarchy -- an
interface or a superclass -- that one is returned: it is declared by an accessible type, and
virtual dispatch still reaches the override. Only where there is no such type does the method
need help, and then a private copy is widened, so that the accessibility flag cannot leak
into a Method instance shared through a descriptor cache.
readMethod - the property's read method, typically from a PropertyDescriptortargetClass - the class being read, used to resolve the publicly accessible methodtarget - the instance being read, or null for a static read methodtargetMakes an instance field readable, widening it only when it is not readable already.
The field is expected to have come from java.lang.Class#getDeclaredFields, which hands out a fresh copy on every call, so widening it is confined to the caller's own copy.
field - an instance fieldtarget - the instance being readfalse when the field cannot be read, in which case the caller should skip it
rather than fail the whole read Reports clazz if it is not public, at most once per class.
Synthetic classes and classes from the JDK, Groovy and Spring are not reported: they are not written by the application whose log this is, so nobody reading it can act on them.
The bookkeeping deliberately runs before the log level is consulted, so that "once" does not depend on how logging happens to be configured.