1/* 2 * Copyright (c) 2001, 2016, 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 26package sun.reflect; 27 28import java.io.OptionalDataException; 29import java.lang.invoke.MethodHandle; 30import java.lang.reflect.Constructor; 31import java.lang.reflect.InvocationTargetException; 32import java.security.AccessController; 33import java.security.Permission; 34import java.security.PrivilegedAction; 35 36/** 37 * ReflectionFactory supports custom serialization. 38 * Its methods support the creation of uninitialized objects, invoking serialization 39 * private methods for readObject, writeObject, readResolve, and writeReplace. 40 * <p> 41 * ReflectionFactory access is restricted, if a security manager is active, 42 * unless the permission {@code RuntimePermission("reflectionFactoryAccess")} 43 * is granted. 44 */ 45public class ReflectionFactory { 46 47 private static final ReflectionFactory soleInstance = new ReflectionFactory(); 48 private static final jdk.internal.reflect.ReflectionFactory delegate = AccessController.doPrivileged( 49 new PrivilegedAction<jdk.internal.reflect.ReflectionFactory>() { 50 public jdk.internal.reflect.ReflectionFactory run() { 51 return jdk.internal.reflect.ReflectionFactory.getReflectionFactory(); 52 } 53 }); 54 55 private ReflectionFactory() {} 56 57 private static final Permission REFLECTION_FACTORY_ACCESS_PERM 58 = new RuntimePermission("reflectionFactoryAccess"); 59 60 /** 61 * Provides the caller with the capability to instantiate reflective 62 * objects. 63 * 64 * <p> First, if there is a security manager, its {@code checkPermission} 65 * method is called with a {@link java.lang.RuntimePermission} with target 66 * {@code "reflectionFactoryAccess"}. This may result in a security 67 * exception. 68 * 69 * <p> The returned {@code ReflectionFactory} object should be carefully 70 * guarded by the caller, since it can be used to read and write private 71 * data and invoke private methods, as well as to load unverified bytecodes. 72 * It must never be passed to untrusted code. 73 * 74 * @return the ReflectionFactory 75 * @throws SecurityException if a security manager exists and its 76 * {@code checkPermission} method doesn't allow access to 77 * the RuntimePermission "reflectionFactoryAccess". 78 */ 79 public static ReflectionFactory getReflectionFactory() { 80 SecurityManager security = System.getSecurityManager(); 81 if (security != null) { 82 security.checkPermission(REFLECTION_FACTORY_ACCESS_PERM); 83 } 84 return soleInstance; 85 } 86 87 /** 88 * Returns an accessible constructor capable of creating instances 89 * of the given class, initialized by the given constructor. 90 * 91 * @param cl the class to instantiate 92 * @param constructorToCall the constructor to call 93 * @return an accessible constructor 94 */ 95 public Constructor<?> newConstructorForSerialization(Class<?> cl, 96 Constructor<?> constructorToCall) 97 { 98 return delegate.newConstructorForSerialization(cl, 99 constructorToCall); 100 } 101 102 /** 103 * Returns an accessible no-arg constructor for a class. 104 * The no-arg constructor is found searching the class and its supertypes. 105 * 106 * @param cl the class to instantiate 107 * @return a no-arg constructor for the class or {@code null} if 108 * the class or supertypes do not have a suitable no-arg constructor 109 */ 110 public final Constructor<?> newConstructorForSerialization(Class<?> cl) 111 { 112 return delegate.newConstructorForSerialization(cl); 113 } 114 115 /** 116 * Returns an accessible no-arg constructor for an externalizable class to be 117 * initialized using a public no-argument constructor. 118 * 119 * @param cl the class to instantiate 120 * @return A no-arg constructor for the class; returns {@code null} if 121 * the class does not implement {@link java.io.Externalizable} 122 */ 123 public final Constructor<?> newConstructorForExternalization(Class<?> cl) { 124 return delegate.newConstructorForExternalization(cl); 125 } 126 127 /** 128 * Returns a direct MethodHandle for the {@code readObject} method on 129 * a Serializable class. 130 * The first argument of {@link MethodHandle#invoke} is the serializable 131 * object and the second argument is the {@code ObjectInputStream} passed to 132 * {@code readObject}. 133 * 134 * @param cl a Serializable class 135 * @return a direct MethodHandle for the {@code readObject} method of the class or 136 * {@code null} if the class does not have a {@code readObject} method 137 */ 138 public final MethodHandle readObjectForSerialization(Class<?> cl) { 139 return delegate.readObjectForSerialization(cl); 140 } 141 142 /** 143 * Returns a direct MethodHandle for the {@code readObjectNoData} method on 144 * a Serializable class. 145 * The first argument of {@link MethodHandle#invoke} is the serializable 146 * object and the second argument is the {@code ObjectInputStream} passed to 147 * {@code readObjectNoData}. 148 * 149 * @param cl a Serializable class 150 * @return a direct MethodHandle for the {@code readObjectNoData} method 151 * of the class or {@code null} if the class does not have a 152 * {@code readObjectNoData} method 153 */ 154 public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) { 155 return delegate.readObjectNoDataForSerialization(cl); 156 } 157 158 /** 159 * Returns a direct MethodHandle for the {@code writeObject} method on 160 * a Serializable class. 161 * The first argument of {@link MethodHandle#invoke} is the serializable 162 * object and the second argument is the {@code ObjectOutputStream} passed to 163 * {@code writeObject}. 164 * 165 * @param cl a Serializable class 166 * @return a direct MethodHandle for the {@code writeObject} method of the class or 167 * {@code null} if the class does not have a {@code writeObject} method 168 */ 169 public final MethodHandle writeObjectForSerialization(Class<?> cl) { 170 return delegate.writeObjectForSerialization(cl); 171 } 172 173 /** 174 * Returns a direct MethodHandle for the {@code readResolve} method on 175 * a serializable class. 176 * The single argument of {@link MethodHandle#invoke} is the serializable 177 * object. 178 * 179 * @param cl the Serializable class 180 * @return a direct MethodHandle for the {@code readResolve} method of the class or 181 * {@code null} if the class does not have a {@code readResolve} method 182 */ 183 public final MethodHandle readResolveForSerialization(Class<?> cl) { 184 return delegate.readResolveForSerialization(cl); 185 } 186 187 /** 188 * Returns a direct MethodHandle for the {@code writeReplace} method on 189 * a serializable class. 190 * The single argument of {@link MethodHandle#invoke} is the serializable 191 * object. 192 * 193 * @param cl the Serializable class 194 * @return a direct MethodHandle for the {@code writeReplace} method of the class or 195 * {@code null} if the class does not have a {@code writeReplace} method 196 */ 197 public final MethodHandle writeReplaceForSerialization(Class<?> cl) { 198 return delegate.writeReplaceForSerialization(cl); 199 } 200 201 /** 202 * Returns true if the class has a static initializer. 203 * The presence of a static initializer is used to compute the serialVersionUID. 204 * @param cl a serializable class 205 * @return {@code true} if the class has a static initializer, 206 * otherwise {@code false} 207 */ 208 public final boolean hasStaticInitializerForSerialization(Class<?> cl) { 209 return delegate.hasStaticInitializerForSerialization(cl); 210 } 211 212 /** 213 * Returns a new OptionalDataException with {@code eof} set to {@code true} 214 * or {@code false}. 215 * @param bool the value of {@code eof} in the created OptionalDataException 216 * @return a new OptionalDataException 217 */ 218 public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) { 219 Constructor<OptionalDataException> cons = delegate.newOptionalDataExceptionForSerialization(); 220 try { 221 return cons.newInstance(bool); 222 } catch (InstantiationException|IllegalAccessException|InvocationTargetException ex) { 223 throw new InternalError("unable to create OptionalDataException", ex); 224 } 225 } 226} 227 228