1 /*
2 * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
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>
56 */
57
58 public class ReflectionFactory {
59
60 private static final ReflectionFactory soleInstance = new ReflectionFactory();
61
62
63 /* Method for static class initializer <clinit>, or null */
88 //
89 //
90
91 /*
92 * Note: this routine can cause the declaring class for the field
93 * be initialized and therefore must not be called until the
94 * first get/set of this field.
95 * @param field the field
96 * @param override true if caller has overridden accessibility
97 */
98 public FieldAccessor newFieldAccessor(Field field, boolean override) {
99 Field root = langReflectAccess.getRoot(field);
100 if (root != null) {
101 // FieldAccessor will use the root unless the modifiers have
102 // been overridden
103 if (root.getModifiers() == field.getModifiers() || !override) {
104 field = root;
105 }
106 }
107 boolean isFinal = Modifier.isFinal(field.getModifiers());
108 boolean isReadOnly = isFinal && (!override || langReflectAccess.isTrustedFinalField(field));
109 return MethodHandleAccessorFactory.newFieldAccessor(field, isReadOnly);
110 }
111
112 public MethodAccessor newMethodAccessor(Method method, boolean callerSensitive) {
113 // use the root Method that will not cache caller class
114 Method root = langReflectAccess.getRoot(method);
115 if (root != null) {
116 method = root;
117 }
118
119 return MethodHandleAccessorFactory.newMethodAccessor(method, callerSensitive);
120 }
121
122 public ConstructorAccessor newConstructorAccessor(Constructor<?> c) {
123 Class<?> declaringClass = c.getDeclaringClass();
124 if (Modifier.isAbstract(declaringClass.getModifiers())) {
125 return new InstantiationExceptionConstructorAccessorImpl(null);
126 }
127 if (declaringClass == Class.class) {
128 return new InstantiationExceptionConstructorAccessorImpl
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;
251 if ((superCl.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) {
252 return false;
253 }
254 // accessible if any constructor is protected or public
255 for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
256 if ((ctor.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) != 0) {
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 }
297 return generateConstructor(cl, constructorToCall);
298 }
299
300 private final Constructor<?> generateConstructor(Class<?> cl,
301 Constructor<?> constructorToCall) {
302 ConstructorAccessor acc = MethodHandleAccessorFactory
303 .newSerializableConstructorAccessor(cl, constructorToCall);
304 // Unlike other root constructors, this constructor is not copied for mutation
305 // but directly mutated, as it is not cached. To cache this constructor,
306 // setAccessible call must be done on a copy and return that copy instead.
307 Constructor<?> ctor = langReflectAccess.newConstructorWithAccessor(constructorToCall, acc);
308 ctor.setAccessible(true);
309 return ctor;
310 }
311
312 public final MethodHandle readObjectForSerialization(Class<?> cl) {
313 return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class);
314 }
315
316 public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
317 return findReadWriteObjectForSerialization(cl, "readObjectNoData", null);
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.
|
1 /*
2 * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
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.value.ValueClass;
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>
56 */
57
58 public class ReflectionFactory {
59
60 private static final ReflectionFactory soleInstance = new ReflectionFactory();
61
62
63 /* Method for static class initializer <clinit>, or null */
88 //
89 //
90
91 /*
92 * Note: this routine can cause the declaring class for the field
93 * be initialized and therefore must not be called until the
94 * first get/set of this field.
95 * @param field the field
96 * @param override true if caller has overridden accessibility
97 */
98 public FieldAccessor newFieldAccessor(Field field, boolean override) {
99 Field root = langReflectAccess.getRoot(field);
100 if (root != null) {
101 // FieldAccessor will use the root unless the modifiers have
102 // been overridden
103 if (root.getModifiers() == field.getModifiers() || !override) {
104 field = root;
105 }
106 }
107 boolean isFinal = Modifier.isFinal(field.getModifiers());
108 boolean isReadOnly = isFinal && (!override || langReflectAccess.isTrustedFinalField(field) || field.isStrictInit());
109 return MethodHandleAccessorFactory.newFieldAccessor(field, isReadOnly);
110 }
111
112 public MethodAccessor newMethodAccessor(Method method, boolean callerSensitive) {
113 // use the root Method that will not cache caller class
114 Method root = langReflectAccess.getRoot(method);
115 if (root != null) {
116 method = root;
117 }
118
119 return MethodHandleAccessorFactory.newMethodAccessor(method, callerSensitive);
120 }
121
122 public ConstructorAccessor newConstructorAccessor(Constructor<?> c) {
123 Class<?> declaringClass = c.getDeclaringClass();
124 if (Modifier.isAbstract(declaringClass.getModifiers())) {
125 return new InstantiationExceptionConstructorAccessorImpl(null);
126 }
127 if (declaringClass == Class.class) {
128 return new InstantiationExceptionConstructorAccessorImpl
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
222 return generateConstructor(cl, constructorToCall);
223 }
224
225 /**
226 * Given a class, determines whether its superclass has
227 * any constructors that are accessible from the class.
228 * This is a special purpose method intended to do access
229 * checking for a serializable class and its superclasses
230 * up to, but not including, the first non-serializable
231 * superclass. This also implies that the superclass is
232 * always non-null, because a serializable class must be a
233 * class (not an interface) and Object is not serializable.
234 *
235 * @param cl the class from which access is checked
236 * @return whether the superclass has a constructor accessible from cl
237 */
238 private boolean superHasAccessibleConstructor(Class<?> cl) {
239 Class<?> superCl = cl.getSuperclass();
240 assert Serializable.class.isAssignableFrom(cl);
241 assert superCl != null;
255 if ((superCl.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) {
256 return false;
257 }
258 // accessible if any constructor is protected or public
259 for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
260 if ((ctor.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) != 0) {
261 return true;
262 }
263 }
264 return false;
265 }
266 }
267
268 /**
269 * Returns a constructor that allocates an instance of cl and that then initializes
270 * the instance by calling the no-arg constructor of its first non-serializable
271 * superclass. This is specified in the Serialization Specification, section 3.1,
272 * in step 11 of the deserialization process. If cl is not serializable, returns
273 * cl's no-arg constructor. If no accessible constructor is found, or if the
274 * class hierarchy is somehow malformed (e.g., a serializable class has no
275 * superclass), or if this serializable class or a serializable superclass
276 * declares a strictly-initialized non-static field, 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 return null;
284 }
285
286 Class<?> initCl = cl;
287 while (Serializable.class.isAssignableFrom(initCl)) {
288 Class<?> prev = initCl;
289 if ((initCl = initCl.getSuperclass()) == null || ValueClass.hasStrictInstanceField(prev) ||
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 }
306
307 return newConstructorForSerialization(cl, constructorToCall);
308 }
309
310 private final Constructor<?> generateConstructor(Class<?> cl,
311 Constructor<?> constructorToCall) {
312 ConstructorAccessor acc = MethodHandleAccessorFactory
313 .newSerializableConstructorAccessor(cl, constructorToCall);
314 // Unlike other root constructors, this constructor is not copied for mutation
315 // but directly mutated, as it is not cached. To cache this constructor,
316 // setAccessible call must be done on a copy and return that copy instead.
317 Constructor<?> ctor = langReflectAccess.newConstructorWithAccessor(constructorToCall, acc);
318 ctor.setAccessible(true);
319 return ctor;
320 }
321
322 public final MethodHandle readObjectForSerialization(Class<?> cl) {
323 return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class);
324 }
325
326 public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
327 return findReadWriteObjectForSerialization(cl, "readObjectNoData", null);
506 return null;
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 //--------------------------------------------------------------------------
527 //
528 // Internals only below this point
529 //
530
531 /*
532 * If -Djdk.reflect.useNativeAccessorOnly is set, use the native accessor only.
533 * For testing purpose only.
534 */
535 static boolean useNativeAccessorOnly() {
536 return config().useNativeAccessorOnly;
537 }
538
539 private static boolean disableSerialConstructorChecks() {
540 return config().disableSerialConstructorChecks;
541 }
542
543 /**
544 * The configuration is lazily initialized after the module system is initialized. The
545 * default config would be used before the proper config is loaded.
|