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