< prev index next >

src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java

Print this page

 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package jdk.internal.reflect;
 27 
 28 import java.io.Externalizable;
 29 import java.io.ObjectInputStream;
 30 import java.io.ObjectOutputStream;
 31 import java.io.ObjectStreamClass;
 32 import java.io.ObjectStreamField;
 33 import java.io.OptionalDataException;
 34 import java.io.Serializable;
 35 import java.lang.classfile.ClassFile;
 36 import java.lang.invoke.MethodHandle;
 37 import java.lang.invoke.MethodHandles;
 38 import java.lang.reflect.*;
 39 import java.util.Set;
 40 
 41 import jdk.internal.access.JavaLangReflectAccess;
 42 import jdk.internal.access.SharedSecrets;
 43 import jdk.internal.misc.VM;
 44 import jdk.internal.vm.annotation.Stable;
 45 
 46 /** <P> The master factory for all reflective objects, both those in
 47     java.lang.reflect (Fields, Methods, Constructors) as well as their
 48     delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
 49     </P>
 50 
 51     <P> The methods in this class are extremely unsafe and can cause
 52     subversion of both the language and the verifier. For this reason,
 53     they are all instance methods, and access to the constructor of
 54     this factory is guarded by a security check, in similar style to
 55     {@link jdk.internal.misc.Unsafe}. </P>

182     public Class<?>[] getExecutableSharedParameterTypes(Executable ex) {
183         return langReflectAccess.getExecutableSharedParameterTypes(ex);
184     }
185 
186     public <T> T newInstance(Constructor<T> ctor, Object[] args, Class<?> caller)
187         throws IllegalAccessException, InstantiationException, InvocationTargetException
188     {
189         return langReflectAccess.newInstance(ctor, args, caller);
190     }
191 
192     //--------------------------------------------------------------------------
193     //
194     // Routines used by serialization
195     //
196     //
197 
198     public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
199         if (!Externalizable.class.isAssignableFrom(cl)) {
200             return null;
201         }



202         try {
203             Constructor<?> cons = cl.getConstructor();
204             cons.setAccessible(true);
205             return cons;
206         } catch (NoSuchMethodException ex) {
207             return null;
208         }
209     }
210 
211     public final Constructor<?> newConstructorForSerialization(Class<?> cl,
212                                                                Constructor<?> constructorToCall)
213     {
214         if (constructorToCall.getDeclaringClass() == cl) {
215             constructorToCall.setAccessible(true);
216             return constructorToCall;
217         }



218         return generateConstructor(cl, constructorToCall);
219     }
220 
221     /**
222      * Given a class, determines whether its superclass has
223      * any constructors that are accessible from the class.
224      * This is a special purpose method intended to do access
225      * checking for a serializable class and its superclasses
226      * up to, but not including, the first non-serializable
227      * superclass. This also implies that the superclass is
228      * always non-null, because a serializable class must be a
229      * class (not an interface) and Object is not serializable.
230      *
231      * @param cl the class from which access is checked
232      * @return whether the superclass has a constructor accessible from cl
233      */
234     private boolean superHasAccessibleConstructor(Class<?> cl) {
235         Class<?> superCl = cl.getSuperclass();
236         assert Serializable.class.isAssignableFrom(cl);
237         assert superCl != null;

257                     return true;
258                 }
259             }
260             return false;
261         }
262     }
263 
264     /**
265      * Returns a constructor that allocates an instance of cl and that then initializes
266      * the instance by calling the no-arg constructor of its first non-serializable
267      * superclass. This is specified in the Serialization Specification, section 3.1,
268      * in step 11 of the deserialization process. If cl is not serializable, returns
269      * cl's no-arg constructor. If no accessible constructor is found, or if the
270      * class hierarchy is somehow malformed (e.g., a serializable class has no
271      * superclass), null is returned.
272      *
273      * @param cl the class for which a constructor is to be found
274      * @return the generated constructor, or null if none is available
275      */
276     public final Constructor<?> newConstructorForSerialization(Class<?> cl) {




277         Class<?> initCl = cl;
278         while (Serializable.class.isAssignableFrom(initCl)) {
279             Class<?> prev = initCl;
280             if ((initCl = initCl.getSuperclass()) == null ||
281                 (!disableSerialConstructorChecks() && !superHasAccessibleConstructor(prev))) {
282                 return null;
283             }
284         }
285         Constructor<?> constructorToCall;
286         try {
287             constructorToCall = initCl.getDeclaredConstructor();
288             int mods = constructorToCall.getModifiers();
289             if ((mods & Modifier.PRIVATE) != 0 ||
290                     ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
291                             !packageEquals(cl, initCl))) {
292                 return null;
293             }
294         } catch (NoSuchMethodException ex) {
295             return null;
296         }

496             return null;
497         }
498 
499         try {
500             Field field = cl.getDeclaredField("serialPersistentFields");
501             int mods = field.getModifiers();
502             if (! (Modifier.isStatic(mods) && Modifier.isPrivate(mods) && Modifier.isFinal(mods))) {
503                 return null;
504             }
505             if (field.getType() != ObjectStreamField[].class) {
506                 return null;
507             }
508             field.setAccessible(true);
509             ObjectStreamField[] array = (ObjectStreamField[]) field.get(null);
510             return array != null && array.length > 0 ? array.clone() : array;
511         } catch (ReflectiveOperationException e) {
512             return null;
513         }
514     }
515 
516     public final Set<AccessFlag> parseAccessFlags(int mask, AccessFlag.Location location, Class<?> classFile) {
517         var cffv = classFileFormatVersion(classFile);
518         return cffv == null ?
519                 AccessFlag.maskToAccessFlags(mask, location) :
520                 AccessFlag.maskToAccessFlags(mask, location, cffv);
521     }
522 
523     private final ClassFileFormatVersion classFileFormatVersion(Class<?> cl) {
524         int raw = SharedSecrets.getJavaLangAccess().classFileVersion(cl);
525 
526         int major = raw & 0xFFFF;
527         int minor = raw >>> Character.SIZE;
528 
529         assert VM.isSupportedClassFileVersion(major, minor) : major + "." + minor;
530 
531         if (major >= ClassFile.JAVA_12_VERSION) {
532             if (minor == 0)
533                 return ClassFileFormatVersion.fromMajor(raw);
534             return null; // preview or old preview, fallback to default handling
535         } else if (major == ClassFile.JAVA_1_VERSION) {
536             return minor < 3 ? ClassFileFormatVersion.RELEASE_0 : ClassFileFormatVersion.RELEASE_1;
537         }
538         return ClassFileFormatVersion.fromMajor(major);
539     }
540 
541     //--------------------------------------------------------------------------
542     //
543     // Internals only below this point
544     //
545 
546     /*
547      * If -Djdk.reflect.useNativeAccessorOnly is set, use the native accessor only.
548      * For testing purpose only.
549      */
550     static boolean useNativeAccessorOnly() {
551         return config().useNativeAccessorOnly;
552     }
553 
554     private static boolean disableSerialConstructorChecks() {
555         return config().disableSerialConstructorChecks;
556     }
557 
558     /**
559      * The configuration is lazily initialized after the module system is initialized. The
560      * default config would be used before the proper config is loaded.

 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package jdk.internal.reflect;
 27 
 28 import java.io.Externalizable;
 29 import java.io.ObjectInputStream;
 30 import java.io.ObjectOutputStream;
 31 import java.io.ObjectStreamClass;
 32 import java.io.ObjectStreamField;
 33 import java.io.OptionalDataException;
 34 import java.io.Serializable;

 35 import java.lang.invoke.MethodHandle;
 36 import java.lang.invoke.MethodHandles;
 37 import java.lang.reflect.*;
 38 import java.util.Set;
 39 
 40 import jdk.internal.access.JavaLangReflectAccess;
 41 import jdk.internal.access.SharedSecrets;
 42 import jdk.internal.misc.VM;
 43 import jdk.internal.vm.annotation.Stable;
 44 
 45 /** <P> The master factory for all reflective objects, both those in
 46     java.lang.reflect (Fields, Methods, Constructors) as well as their
 47     delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
 48     </P>
 49 
 50     <P> The methods in this class are extremely unsafe and can cause
 51     subversion of both the language and the verifier. For this reason,
 52     they are all instance methods, and access to the constructor of
 53     this factory is guarded by a security check, in similar style to
 54     {@link jdk.internal.misc.Unsafe}. </P>

181     public Class<?>[] getExecutableSharedParameterTypes(Executable ex) {
182         return langReflectAccess.getExecutableSharedParameterTypes(ex);
183     }
184 
185     public <T> T newInstance(Constructor<T> ctor, Object[] args, Class<?> caller)
186         throws IllegalAccessException, InstantiationException, InvocationTargetException
187     {
188         return langReflectAccess.newInstance(ctor, args, caller);
189     }
190 
191     //--------------------------------------------------------------------------
192     //
193     // Routines used by serialization
194     //
195     //
196 
197     public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
198         if (!Externalizable.class.isAssignableFrom(cl)) {
199             return null;
200         }
201         if (cl.isValue()) {
202             throw new UnsupportedOperationException("newConstructorForExternalization does not support value classes");
203         }
204         try {
205             Constructor<?> cons = cl.getConstructor();
206             cons.setAccessible(true);
207             return cons;
208         } catch (NoSuchMethodException ex) {
209             return null;
210         }
211     }
212 
213     public final Constructor<?> newConstructorForSerialization(Class<?> cl,
214                                                                Constructor<?> constructorToCall)
215     {
216         if (constructorToCall.getDeclaringClass() == cl) {
217             constructorToCall.setAccessible(true);
218             return constructorToCall;
219         }
220         if (cl.isValue()) {
221             throw new UnsupportedOperationException("newConstructorForSerialization does not support value classes");
222         }
223         return generateConstructor(cl, constructorToCall);
224     }
225 
226     /**
227      * Given a class, determines whether its superclass has
228      * any constructors that are accessible from the class.
229      * This is a special purpose method intended to do access
230      * checking for a serializable class and its superclasses
231      * up to, but not including, the first non-serializable
232      * superclass. This also implies that the superclass is
233      * always non-null, because a serializable class must be a
234      * class (not an interface) and Object is not serializable.
235      *
236      * @param cl the class from which access is checked
237      * @return whether the superclass has a constructor accessible from cl
238      */
239     private boolean superHasAccessibleConstructor(Class<?> cl) {
240         Class<?> superCl = cl.getSuperclass();
241         assert Serializable.class.isAssignableFrom(cl);
242         assert superCl != null;

262                     return true;
263                 }
264             }
265             return false;
266         }
267     }
268 
269     /**
270      * Returns a constructor that allocates an instance of cl and that then initializes
271      * the instance by calling the no-arg constructor of its first non-serializable
272      * superclass. This is specified in the Serialization Specification, section 3.1,
273      * in step 11 of the deserialization process. If cl is not serializable, returns
274      * cl's no-arg constructor. If no accessible constructor is found, or if the
275      * class hierarchy is somehow malformed (e.g., a serializable class has no
276      * superclass), null is returned.
277      *
278      * @param cl the class for which a constructor is to be found
279      * @return the generated constructor, or null if none is available
280      */
281     public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
282         if (cl.isValue()) {
283             throw new UnsupportedOperationException("newConstructorForSerialization does not support value classes: " + cl);
284         }
285 
286         Class<?> initCl = cl;
287         while (Serializable.class.isAssignableFrom(initCl)) {
288             Class<?> prev = initCl;
289             if ((initCl = initCl.getSuperclass()) == null ||
290                 (!disableSerialConstructorChecks() && !superHasAccessibleConstructor(prev))) {
291                 return null;
292             }
293         }
294         Constructor<?> constructorToCall;
295         try {
296             constructorToCall = initCl.getDeclaredConstructor();
297             int mods = constructorToCall.getModifiers();
298             if ((mods & Modifier.PRIVATE) != 0 ||
299                     ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
300                             !packageEquals(cl, initCl))) {
301                 return null;
302             }
303         } catch (NoSuchMethodException ex) {
304             return null;
305         }

505             return null;
506         }
507 
508         try {
509             Field field = cl.getDeclaredField("serialPersistentFields");
510             int mods = field.getModifiers();
511             if (! (Modifier.isStatic(mods) && Modifier.isPrivate(mods) && Modifier.isFinal(mods))) {
512                 return null;
513             }
514             if (field.getType() != ObjectStreamField[].class) {
515                 return null;
516             }
517             field.setAccessible(true);
518             ObjectStreamField[] array = (ObjectStreamField[]) field.get(null);
519             return array != null && array.length > 0 ? array.clone() : array;
520         } catch (ReflectiveOperationException e) {
521             return null;
522         }
523     }
524 

























525     //--------------------------------------------------------------------------
526     //
527     // Internals only below this point
528     //
529 
530     /*
531      * If -Djdk.reflect.useNativeAccessorOnly is set, use the native accessor only.
532      * For testing purpose only.
533      */
534     static boolean useNativeAccessorOnly() {
535         return config().useNativeAccessorOnly;
536     }
537 
538     private static boolean disableSerialConstructorChecks() {
539         return config().disableSerialConstructorChecks;
540     }
541 
542     /**
543      * The configuration is lazily initialized after the module system is initialized. The
544      * default config would be used before the proper config is loaded.
< prev index next >