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