-
Notifications
You must be signed in to change notification settings - Fork 0
/
ReflectionFactory.java
228 lines (211 loc) · 9.53 KB
/
ReflectionFactory.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/*
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.io.OptionalDataException;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
/**
* ReflectionFactory supports custom serialization.
* Its methods support the creation of uninitialized objects, invoking serialization
* private methods for readObject, writeObject, readResolve, and writeReplace.
* <p>
* ReflectionFactory access is restricted, if a security manager is active,
* unless the permission {@code RuntimePermission("reflectionFactoryAccess")}
* is granted.
*/
public class ReflectionFactory {
private static final ReflectionFactory soleInstance = new ReflectionFactory();
@SuppressWarnings("removal")
private static final jdk.internal.reflect.ReflectionFactory delegate = AccessController.doPrivileged(
new PrivilegedAction<jdk.internal.reflect.ReflectionFactory>() {
public jdk.internal.reflect.ReflectionFactory run() {
return jdk.internal.reflect.ReflectionFactory.getReflectionFactory();
}
});
private ReflectionFactory() {}
private static final Permission REFLECTION_FACTORY_ACCESS_PERM
= new RuntimePermission("reflectionFactoryAccess");
/**
* Provides the caller with the capability to instantiate reflective
* objects.
*
* <p> First, if there is a security manager, its {@code checkPermission}
* method is called with a {@link java.lang.RuntimePermission} with target
* {@code "reflectionFactoryAccess"}. This may result in a security
* exception.
*
* <p> The returned {@code ReflectionFactory} object should be carefully
* guarded by the caller, since it can be used to read and write private
* data and invoke private methods, as well as to load unverified bytecodes.
* It must never be passed to untrusted code.
*
* @return the ReflectionFactory
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method doesn't allow access to
* the RuntimePermission "reflectionFactoryAccess".
*/
public static ReflectionFactory getReflectionFactory() {
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(REFLECTION_FACTORY_ACCESS_PERM);
}
return soleInstance;
}
/**
* Returns an accessible constructor capable of creating instances
* of the given class, initialized by the given constructor.
*
* @param cl the class to instantiate
* @param constructorToCall the constructor to call
* @return an accessible constructor
*/
public Constructor<?> newConstructorForSerialization(Class<?> cl,
Constructor<?> constructorToCall)
{
return delegate.newConstructorForSerialization(cl,
constructorToCall);
}
/**
* Returns an accessible no-arg constructor for a class.
* The no-arg constructor is found searching the class and its supertypes.
*
* @param cl the class to instantiate
* @return a no-arg constructor for the class or {@code null} if
* the class or supertypes do not have a suitable no-arg constructor
*/
public final Constructor<?> newConstructorForSerialization(Class<?> cl)
{
return delegate.newConstructorForSerialization(cl);
}
/**
* Returns an accessible no-arg constructor for an externalizable class to be
* initialized using a public no-argument constructor.
*
* @param cl the class to instantiate
* @return A no-arg constructor for the class; returns {@code null} if
* the class does not implement {@link java.io.Externalizable}
*/
public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
return delegate.newConstructorForExternalization(cl);
}
/**
* Returns a direct MethodHandle for the {@code readObject} method on
* a Serializable class.
* The first argument of {@link MethodHandle#invoke} is the serializable
* object and the second argument is the {@code ObjectInputStream} passed to
* {@code readObject}.
*
* @param cl a Serializable class
* @return a direct MethodHandle for the {@code readObject} method of the class or
* {@code null} if the class does not have a {@code readObject} method
*/
public final MethodHandle readObjectForSerialization(Class<?> cl) {
return delegate.readObjectForSerialization(cl);
}
/**
* Returns a direct MethodHandle for the {@code readObjectNoData} method on
* a Serializable class.
* The first argument of {@link MethodHandle#invoke} is the serializable
* object and the second argument is the {@code ObjectInputStream} passed to
* {@code readObjectNoData}.
*
* @param cl a Serializable class
* @return a direct MethodHandle for the {@code readObjectNoData} method
* of the class or {@code null} if the class does not have a
* {@code readObjectNoData} method
*/
public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
return delegate.readObjectNoDataForSerialization(cl);
}
/**
* Returns a direct MethodHandle for the {@code writeObject} method on
* a Serializable class.
* The first argument of {@link MethodHandle#invoke} is the serializable
* object and the second argument is the {@code ObjectOutputStream} passed to
* {@code writeObject}.
*
* @param cl a Serializable class
* @return a direct MethodHandle for the {@code writeObject} method of the class or
* {@code null} if the class does not have a {@code writeObject} method
*/
public final MethodHandle writeObjectForSerialization(Class<?> cl) {
return delegate.writeObjectForSerialization(cl);
}
/**
* Returns a direct MethodHandle for the {@code readResolve} method on
* a serializable class.
* The single argument of {@link MethodHandle#invoke} is the serializable
* object.
*
* @param cl the Serializable class
* @return a direct MethodHandle for the {@code readResolve} method of the class or
* {@code null} if the class does not have a {@code readResolve} method
*/
public final MethodHandle readResolveForSerialization(Class<?> cl) {
return delegate.readResolveForSerialization(cl);
}
/**
* Returns a direct MethodHandle for the {@code writeReplace} method on
* a serializable class.
* The single argument of {@link MethodHandle#invoke} is the serializable
* object.
*
* @param cl the Serializable class
* @return a direct MethodHandle for the {@code writeReplace} method of the class or
* {@code null} if the class does not have a {@code writeReplace} method
*/
public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
return delegate.writeReplaceForSerialization(cl);
}
/**
* Returns true if the class has a static initializer.
* The presence of a static initializer is used to compute the serialVersionUID.
* @param cl a serializable class
* @return {@code true} if the class has a static initializer,
* otherwise {@code false}
*/
public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
return delegate.hasStaticInitializerForSerialization(cl);
}
/**
* Returns a new OptionalDataException with {@code eof} set to {@code true}
* or {@code false}.
* @param bool the value of {@code eof} in the created OptionalDataException
* @return a new OptionalDataException
*/
public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) {
Constructor<OptionalDataException> cons = delegate.newOptionalDataExceptionForSerialization();
try {
return cons.newInstance(bool);
} catch (InstantiationException|IllegalAccessException|InvocationTargetException ex) {
throw new InternalError("unable to create OptionalDataException", ex);
}
}
}