sun.reflect |
Licensee impact of JDK 1.4 reflection changes
Sun's JDK 1.4 contains a new implementation of java.lang.reflect which
offers substantially higher performance than previous JDKs' native
code. Licensees can at their discretion port these changes. There are
no public API or documentation changes associated with the new
reflection implementation aside from a few minor clarifications in the
specifications of Method.invoke(), Constructor.newInstance(), and a
few methods in java.lang.reflect.Field.
The bulk of the new implementation is Java programming language code
which generates bytecodes, and is therefore portable. If licensees
desire to port it, the following JVM changes are required:
- The following four new JVM entry points must be added:
- JVM_GetClassDeclaredConstructors
- JVM_GetClassDeclaredFields
- JVM_GetClassDeclaredMethods
- JVM_GetClassAccessFlags
The first three return the declared constructors, fields, and methods
for a given class, with an option to return only the public ones. They
are similar in functionality to the earlier GetClassConstructors,
GetClassFields, and GetClassMethods. JVM_GetClassDeclaredFields and
JVM_GetClassDeclaredMethods must intern the Strings for the names of
the Field and Method objects returned. The fouth returns the access
flags for a given class as marked in the class file, as opposed to in
the InnerClasses attribute if the class is an inner class, and
therefore differs from JVM_GetClassModifiers for inner classes (most
importantly, protected inner classes; see 4471811.)
- The JVM's link resolver must be modified to allow all field and
method references from subclasses of sun.reflect.MagicAccessorImpl to
any other class (even to private members of other classes) to
succeed. This allows setAccessible() and its associated checks to be
implemented in Java.
- The code which calls the verifier must skip verification for all
subclasses of sun.reflect.MagicAccessorImpl. (It was originally
intended that only a subset of the stub classes used for serialization
would not pass the verifier, specifically, those subclassing
SerializationConstructorAccessorImpl; see 4486457 for a case where
this does not work.)
- The stack walker for security checks must be modified to skip not
only all Method.invoke() frames, but also any frames for which the
class is a subclass of sun.reflect.MethodAccessorImpl.
- The JVM entry points JVM_InvokeMethod and
JVM_NewInstanceFromConstructor are currently still used because the
first invocation of the bytecode-based reflection is currently slower
than the original native code. The security checks they perform can,
however, be disabled, as they are now performed by Java programming
language code.
The following changes were discovered to be necessary for backward
compatibility with certain applications (see bug 4474172):
- The existing JVM entry point JVM_LatestUserDefinedLoader
(typically used in applications which rely on the 1.1 security
framework) must skip reflection-related frames in its stack walk:
specifically all frames associated with subclasses of
sun.reflect.MethodAccessorImpl and
sun.reflect.ConstructorAccessorImpl.
- The new reflection implementation can cause class loading to
occur in previously-unexpected places (namely during reflective
calls). This can cause class loaders which contain subtle bugs to
break. In general it is not possible to guarantee complete backward
bug compatibility, but one kind of bug has been observed more than
once: the inability of a user-defined loader to handle delegation to
it for a class it has already loaded. The new reflection
implementation is predicated on delegation working properly, as it
loads stub classes into newly-fabricated class loaders of type
sun.reflect.DelegatingClassLoader, one stub class per loader, to allow
unloading of the stub classes to occur more quickly. To handle this
kind of bug, the JVM's internal class lookup mechanism must be
slightly modified to check for instances of
sun.reflect.DelegatingClassLoader as the incoming class loader and
silently traverse the "parent" field once for such loaders before
entering the bulk of the resolution code. This avoids an upcall to
Java programming language code which certain loaders can not handle.
The following JVM entry points may be deleted:
- JVM_GetClassFields
- JVM_GetClassMethods
- JVM_GetClassConstructors
- JVM_GetClassField
- JVM_GetClassMethod
- JVM_GetClassConstructor
- JVM_NewInstance
- JVM_GetField
- JVM_GetPrimitiveField
- JVM_SetField
- JVM_SetPrimitiveField
To keep using the previous reflection implementation, licensees should
not take changes from Sun's JDK 1.4 relating specifically to the
implementation of reflection in the following classes/methods and
any associated native code:
- java.lang.Class.newInstance0
- java.lang.Class.getClassLoader0
- java.lang.Class.getFields
- java.lang.Class.getMethods
- java.lang.Class.getDeclaredFields
- java.lang.Class.getDeclaredMethods
- java.lang.Class.getFields0
- java.lang.Class.getMethods0
- java.lang.Class.getConstructors0
- java.lang.Class.getField0
- java.lang.Class.getMethod0
- java.lang.Class.getConstructor0
- java.lang.ClassLoader.getCallerClassLoader
- java.lang.System.getCallerClass
- java.lang.reflect.AccessibleObject
- java.lang.reflect.Constructor
- java.lang.reflect.Field
- java.lang.reflect.Method
- java.lang.reflect.Modifier
- sun.misc.ClassReflector
|
Java Source File Name | Type | Comment |
AccessorGenerator.java | Class | |
BootstrapConstructorAccessorImpl.java | Class | Uses Unsafe.allocateObject() to instantiate classes; only used for
bootstrapping. |
ByteVector.java | Interface | A growable array of bytes. |
ByteVectorFactory.java | Class | |
ByteVectorImpl.java | Class | |
ClassDefiner.java | Class | Utility class which assists in calling Unsafe.defineClass() by
creating a new class loader which delegates to the one needed in
order for proper resolution of the given bytecodes to occur. |
ClassFileAssembler.java | Class | |
ClassFileConstants.java | Interface | Minimal set of class file constants for assembly of field and
method accessors. |
ConstantPool.java | Class | Provides reflective access to the constant pools of classes.
Currently this is needed to provide reflective access to annotations
but may be used by other internal subsystems in the future. |
ConstructorAccessor.java | Interface | This interface provides the declaration for
java.lang.reflect.Constructor.invoke(). |
ConstructorAccessorImpl.java | Class | Package-private implementation of the ConstructorAccessor
interface which has access to all classes and all fields,
regardless of language restrictions. |
DelegatingConstructorAccessorImpl.java | Class | Delegates its invocation to another ConstructorAccessorImpl and can
change its delegate at run time. |
DelegatingMethodAccessorImpl.java | Class | Delegates its invocation to another MethodAccessorImpl and can
change its delegate at run time. |
FieldAccessor.java | Interface | This interface provides the declarations for the accessor methods
of java.lang.reflect.Field. |
FieldAccessorImpl.java | Class | Package-private implementation of the FieldAccessor interface
which has access to all classes and all fields, regardless of
language restrictions. |
FieldInfo.java | Class | |
InstantiationExceptionConstructorAccessorImpl.java | Class | |
Label.java | Class | Allows forward references in bytecode streams emitted by
ClassFileAssembler. |
LangReflectAccess.java | Interface | An interface which gives privileged packages Java-level access to
internals of java.lang.reflect. |
MagicAccessorImpl.java | Class | MagicAccessorImpl (named for parity with FieldAccessorImpl and
others, not because it actually implements an interface) is a
marker class in the hierarchy. |
MethodAccessor.java | Interface | This interface provides the declaration for
java.lang.reflect.Method.invoke(). |
MethodAccessorGenerator.java | Class | Generator for sun.reflect.MethodAccessor and
sun.reflect.ConstructorAccessor objects using bytecodes to
implement reflection. |
MethodAccessorImpl.java | Class | Package-private implementation of the MethodAccessor interface
which has access to all classes and all fields, regardless of
language restrictions. |
NativeConstructorAccessorImpl.java | Class | |
NativeMethodAccessorImpl.java | Class | |
Reflection.java | Class | |
ReflectionFactory.java | Class | The master factory for all reflective objects, both those in
java.lang.reflect (Fields, Methods, Constructors) as well as their
delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
The methods in this class are extremely unsafe and can cause
subversion of both the language and the verifier. |
SerializationConstructorAccessorImpl.java | Class | Java serialization (in java.io) expects to be able to
instantiate a class and invoke a no-arg constructor of that
class's first non-Serializable superclass. |
SignatureIterator.java | Class | |
UnsafeBooleanFieldAccessorImpl.java | Class | |
UnsafeByteFieldAccessorImpl.java | Class | |
UnsafeCharacterFieldAccessorImpl.java | Class | |
UnsafeDoubleFieldAccessorImpl.java | Class | |
UnsafeFieldAccessorFactory.java | Class | |
UnsafeFieldAccessorImpl.java | Class | Base class for sun.misc.Unsafe-based FieldAccessors. |
UnsafeFloatFieldAccessorImpl.java | Class | |
UnsafeIntegerFieldAccessorImpl.java | Class | |
UnsafeLongFieldAccessorImpl.java | Class | |
UnsafeObjectFieldAccessorImpl.java | Class | |
UnsafeQualifiedBooleanFieldAccessorImpl.java | Class | |
UnsafeQualifiedByteFieldAccessorImpl.java | Class | |
UnsafeQualifiedCharacterFieldAccessorImpl.java | Class | |
UnsafeQualifiedDoubleFieldAccessorImpl.java | Class | |
UnsafeQualifiedFieldAccessorImpl.java | Class | Base class for sun.misc.Unsafe-based FieldAccessors for fields with
final or volatile qualifiers. |
UnsafeQualifiedFloatFieldAccessorImpl.java | Class | |
UnsafeQualifiedIntegerFieldAccessorImpl.java | Class | |
UnsafeQualifiedLongFieldAccessorImpl.java | Class | |
UnsafeQualifiedObjectFieldAccessorImpl.java | Class | |
UnsafeQualifiedShortFieldAccessorImpl.java | Class | |
UnsafeQualifiedStaticBooleanFieldAccessorImpl.java | Class | |
UnsafeQualifiedStaticByteFieldAccessorImpl.java | Class | |
UnsafeQualifiedStaticCharacterFieldAccessorImpl.java | Class | |
UnsafeQualifiedStaticDoubleFieldAccessorImpl.java | Class | |
UnsafeQualifiedStaticFieldAccessorImpl.java | Class | Base class for sun.misc.Unsafe-based FieldAccessors for final or
volatile static fields. |
UnsafeQualifiedStaticFloatFieldAccessorImpl.java | Class | |
UnsafeQualifiedStaticIntegerFieldAccessorImpl.java | Class | |
UnsafeQualifiedStaticLongFieldAccessorImpl.java | Class | |
UnsafeQualifiedStaticObjectFieldAccessorImpl.java | Class | |
UnsafeQualifiedStaticShortFieldAccessorImpl.java | Class | |
UnsafeShortFieldAccessorImpl.java | Class | |
UnsafeStaticBooleanFieldAccessorImpl.java | Class | |
UnsafeStaticByteFieldAccessorImpl.java | Class | |
UnsafeStaticCharacterFieldAccessorImpl.java | Class | |
UnsafeStaticDoubleFieldAccessorImpl.java | Class | |
UnsafeStaticFieldAccessorImpl.java | Class | Base class for sun.misc.Unsafe-based FieldAccessors for static
fields. |
UnsafeStaticFloatFieldAccessorImpl.java | Class | |
UnsafeStaticIntegerFieldAccessorImpl.java | Class | |
UnsafeStaticLongFieldAccessorImpl.java | Class | |
UnsafeStaticObjectFieldAccessorImpl.java | Class | |
UnsafeStaticShortFieldAccessorImpl.java | Class | |
UTF8.java | Class | It is necessary to use a "bootstrap" UTF-8 encoder for encoding
constant pool entries because the character set converters rely on
Class.newInstance(). |