187 lines · 6.8 KB · HTML
RawDownload
<!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 whichoffers substantially higher performance than previous JDKs' nativecode. Licensees can at their discretion port these changes. There areno public API or documentation changes associated with the newreflection implementation aside from a few minor clarifications in thespecifications of Method.invoke(), Constructor.newInstance(), and afew methods in java.lang.reflect.Field. </P><P> The bulk of the new implementation is Java programming language codewhich generates bytecodes, and is therefore portable. If licenseesdesire 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 methodsfor a given class, with an option to return only the public ones. Theyare similar in functionality to the earlier GetClassConstructors,GetClassFields, and GetClassMethods.  JVM_GetClassDeclaredFields andJVM_GetClassDeclaredMethods must intern the Strings for the names ofthe Field and Method objects returned. The fouth returns the accessflags for a given class as marked in the class file, as opposed to inthe InnerClasses attribute if the class is an inner class, andtherefore differs from JVM_GetClassModifiers for inner classes (mostimportantly, protected inner classes; see 4471811.) <LI> The JVM's link resolver must be modified to allow all field andmethod references from subclasses of sun.reflect.MagicAccessorImpl toany other class (even to private members of other classes) tosucceed. This allows setAccessible() and its associated checks to beimplemented in Java. <LI> The code which calls the verifier must skip verification for allsubclasses of sun.reflect.MagicAccessorImpl. (It was originallyintended that only a subset of the stub classes used for serializationwould not pass the verifier, specifically, those subclassingSerializationConstructorAccessorImpl; see 4486457 for a case wherethis does not work.) <LI> The stack walker for security checks must be modified to skip notonly all Method.invoke() frames, but also any frames for which theclass is a subclass of sun.reflect.MethodAccessorImpl. <LI> The JVM entry points JVM_InvokeMethod andJVM_NewInstanceFromConstructor are currently still used because thefirst invocation of the bytecode-based reflection is currently slowerthan the original native code. The security checks they perform can,however, be disabled, as they are now performed by Java programminglanguage code. </OL> </P><P> The following changes were discovered to be necessary for backwardcompatibility 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 securityframework) must skip reflection-related frames in its stack walk:specifically all frames associated with subclasses ofsun.reflect.MethodAccessorImpl andsun.reflect.ConstructorAccessorImpl. <LI> The new reflection implementation can cause class loading tooccur in previously-unexpected places (namely during reflectivecalls).  This can cause class loaders which contain subtle bugs tobreak.  In general it is not possible to guarantee complete backwardbug compatibility, but one kind of bug has been observed more thanonce: the inability of a user-defined loader to handle delegation toit for a class it has already loaded. The new reflectionimplementation is predicated on delegation working properly, as itloads stub classes into newly-fabricated class loaders of typesun.reflect.DelegatingClassLoader, one stub class per loader, to allowunloading of the stub classes to occur more quickly. To handle thiskind of bug, the JVM's internal class lookup mechanism must beslightly modified to check for instances ofsun.reflect.DelegatingClassLoader as the incoming class loader andsilently traverse the "parent" field once for such loaders beforeentering the bulk of the resolution code. This avoids an upcall toJava 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 shouldnot take changes from Sun's JDK 1.4 relating specifically to theimplementation of reflection in the following classes/methods andany 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>