| <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> | |
| <HTML> | |
| <HEAD> | |
| <!-- | |
| Copyright (c) 2001, 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 | |
| under the terms of the GNU General Public License version 2 only, as | |
| published by the Free Software Foundation. Oracle designates this | |
| particular file as subject to the "Classpath" exception as provided | |
| by Oracle in the LICENSE file that accompanied this code. | |
| This code is distributed in the hope that it will be useful, but WITHOUT | |
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| version 2 for more details (a copy is included in the LICENSE file that | |
| accompanied this code). | |
| You should have received a copy of the GNU General Public License version | |
| 2 along with this work; if not, write to the Free Software Foundation, | |
| Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| or visit www.oracle.com if you need additional information or have any | |
| questions. | |
| --> | |
| </HEAD> | |
| <BODY BGCOLOR="white"> | |
| <P> | |
| <B> Licensee impact of JDK 1.4 reflection changes </B> | |
| </P> | |
| <P> | |
| 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. | |
| </P> | |
| <P> | |
| 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: | |
| <OL> | |
| <LI> The following four new JVM entry points must be added: | |
| <UL> | |
| <LI> JVM_GetClassDeclaredConstructors | |
| <LI> JVM_GetClassDeclaredFields | |
| <LI> JVM_GetClassDeclaredMethods | |
| <LI> JVM_GetClassAccessFlags | |
| </UL> | |
| 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.) | |
| <LI> 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. | |
| <LI> 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.) | |
| <LI> 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. | |
| <LI> 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. | |
| </OL> | |
| </P> | |
| <P> | |
| The following changes were discovered to be necessary for backward | |
| compatibility with certain applications (see bug 4474172): | |
| <OL> | |
| <LI> 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. | |
| <LI> 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. | |
| </OL> | |
| </P> | |
| <P> | |
| The following JVM entry points may be deleted: | |
| <UL> | |
| <LI> JVM_GetClassFields | |
| <LI> JVM_GetClassMethods | |
| <LI> JVM_GetClassConstructors | |
| <LI> JVM_GetClassField | |
| <LI> JVM_GetClassMethod | |
| <LI> JVM_GetClassConstructor | |
| <LI> JVM_NewInstance | |
| <LI> JVM_GetField | |
| <LI> JVM_GetPrimitiveField | |
| <LI> JVM_SetField | |
| <LI> JVM_SetPrimitiveField | |
| </UL> | |
| </P> | |
| <P> | |
| 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: | |
| <UL> | |
| <LI> java.lang.Class.newInstance0 | |
| <LI> java.lang.Class.getClassLoader0 | |
| <LI> java.lang.Class.getFields | |
| <LI> java.lang.Class.getMethods | |
| <LI> java.lang.Class.getDeclaredFields | |
| <LI> java.lang.Class.getDeclaredMethods | |
| <LI> java.lang.Class.getFields0 | |
| <LI> java.lang.Class.getMethods0 | |
| <LI> java.lang.Class.getConstructors0 | |
| <LI> java.lang.Class.getField0 | |
| <LI> java.lang.Class.getMethod0 | |
| <LI> java.lang.Class.getConstructor0 | |
| <LI> java.lang.ClassLoader.getCallerClassLoader | |
| <LI> java.lang.System.getCallerClass | |
| <LI> java.lang.reflect.AccessibleObject | |
| <LI> java.lang.reflect.Constructor | |
| <LI> java.lang.reflect.Field | |
| <LI> java.lang.reflect.Method | |
| <LI> java.lang.reflect.Modifier | |
| <LI> sun.misc.ClassReflector | |
| </UL> | |
| </P> | |
| </HTML> |