| <!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> |