< prev index next >

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

Print this page

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         }

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() {

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         if (cl.isValue()) {
203             throw new UnsupportedOperationException("newConstructorForExternalization does not support value classes");
204         }
205         try {
206             Constructor<?> cons = cl.getConstructor();
207             cons.setAccessible(true);
208             return cons;
209         } catch (NoSuchMethodException ex) {
210             return null;
211         }
212     }
213 
214     public final Constructor<?> newConstructorForSerialization(Class<?> cl,
215                                                                Constructor<?> constructorToCall)
216     {
217         if (constructorToCall.getDeclaringClass() == cl) {
218             constructorToCall.setAccessible(true);
219             return constructorToCall;
220         }
221         if (cl.isValue()) {
222             throw new UnsupportedOperationException("newConstructorForSerialization does not support value classes");
223         }
224         return generateConstructor(cl, constructorToCall);
225     }
226 
227     /**
228      * Given a class, determines whether its superclass has
229      * any constructors that are accessible from the class.
230      * This is a special purpose method intended to do access
231      * checking for a serializable class and its superclasses
232      * up to, but not including, the first non-serializable
233      * superclass. This also implies that the superclass is
234      * always non-null, because a serializable class must be a
235      * class (not an interface) and Object is not serializable.
236      *
237      * @param cl the class from which access is checked
238      * @return whether the superclass has a constructor accessible from cl
239      */
240     private boolean superHasAccessibleConstructor(Class<?> cl) {
241         Class<?> superCl = cl.getSuperclass();
242         assert Serializable.class.isAssignableFrom(cl);
243         assert superCl != null;

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

507         }
508 
509         try {
510             Field field = cl.getDeclaredField("serialPersistentFields");
511             int mods = field.getModifiers();
512             if (! (Modifier.isStatic(mods) && Modifier.isPrivate(mods) && Modifier.isFinal(mods))) {
513                 return null;
514             }
515             if (field.getType() != ObjectStreamField[].class) {
516                 return null;
517             }
518             field.setAccessible(true);
519             ObjectStreamField[] array = (ObjectStreamField[]) field.get(null);
520             return array != null && array.length > 0 ? array.clone() : array;
521         } catch (ReflectiveOperationException e) {
522             return null;
523         }
524     }
525 
526     public final Set<AccessFlag> parseAccessFlags(int mask, AccessFlag.Location location, Class<?> classFile) {
527         return AccessFlag.maskToAccessFlags(mask, location, classFileFormatVersion(classFile));



528     }
529 
530     public final ClassFileFormatVersion classFileFormatVersion(Class<?> cl) {
531         if (cl.isArray() || cl.isPrimitive())
532             return ClassFileFormatVersion.CURRENT_PREVIEW_FEATURES;
533         int raw = SharedSecrets.getJavaLangAccess().classFileVersion(cl);
534 
535         int major = raw & 0xFFFF;
536         int minor = raw >>> Character.SIZE;
537 
538         assert VM.isSupportedClassFileVersion(major, minor) : major + "." + minor;
539 
540         if (major >= ClassFile.JAVA_12_VERSION) {
541             if (minor == 0)
542                 return ClassFileFormatVersion.fromMajor(raw);
543             return ClassFileFormatVersion.CURRENT_PREVIEW_FEATURES;
544         } else if (major == ClassFile.JAVA_1_VERSION) {
545             return minor < 3 ? ClassFileFormatVersion.RELEASE_0 : ClassFileFormatVersion.RELEASE_1;
546         }
547         return ClassFileFormatVersion.fromMajor(major);
548     }
549 
550     //--------------------------------------------------------------------------
551     //
552     // Internals only below this point
553     //
554 
555     /*
556      * If -Djdk.reflect.useNativeAccessorOnly is set, use the native accessor only.
557      * For testing purpose only.
558      */
559     static boolean useNativeAccessorOnly() {
560         return config().useNativeAccessorOnly;
561     }
562 
563     private static boolean disableSerialConstructorChecks() {
< prev index next >