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 26 package sun.reflect; 27 28 import java.io.OptionalDataException; 29 import java.lang.invoke.MethodHandle; 30 import java.lang.reflect.Constructor; 31 import java.lang.reflect.InvocationTargetException; 32 import java.security.AccessController; 33 import java.security.Permission; 34 import 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 */ 45 public 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 no-arg constructor for a class. 89 * The no-arg constructor is found searching the class and its supertypes. 90 * 91 * @param cl the class to instantiate 92 * @return a no-arg constructor for the class or {@code null} if 93 * the class or supertypes do not have a suitable no-arg constructor 94 */ 95 public final Constructor<?> newConstructorForSerialization(Class<?> cl) 96 { 97 return delegate.newConstructorForSerialization(cl); 98 } 99 100 /** 101 * Returns an accessible no-arg constructor for an externalizable class to be 102 * initialized using a public no-argument constructor. 103 * 104 * @param cl the class to instantiate 105 * @return A no-arg constructor for the class; returns {@code null} if 106 * the class does not implement {@link java.io.Externalizable} 107 */ 108 public final Constructor<?> newConstructorForExternalization(Class<?> cl) { 109 return delegate.newConstructorForExternalization(cl); 110 } 111 112 /** 113 * Returns a direct MethodHandle for the {@code readObject} method on 114 * a Serializable class. 115 * The first argument of {@link MethodHandle#invoke} is the serializable 116 * object and the second argument is the {@code ObjectInputStream} passed to 117 * {@code readObject}. 118 * 119 * @param cl a Serializable class 120 * @return a direct MethodHandle for the {@code readObject} method of the class or 121 * {@code null} if the class does not have a {@code readObject} method 122 */ 123 public final MethodHandle readObjectForSerialization(Class<?> cl) { 124 return delegate.readObjectForSerialization(cl); 125 } 126 127 /** 128 * Returns a direct MethodHandle for the {@code readObjectNoData} 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 readObjectNoData}. 133 * 134 * @param cl a Serializable class 135 * @return a direct MethodHandle for the {@code readObjectNoData} method 136 * of the class or {@code null} if the class does not have a 137 * {@code readObjectNoData} method 138 */ 139 public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) { 140 return delegate.readObjectNoDataForSerialization(cl); 141 } 142 143 /** 144 * Returns a direct MethodHandle for the {@code writeObject} method on 145 * a Serializable class. 146 * The first argument of {@link MethodHandle#invoke} is the serializable 147 * object and the second argument is the {@code ObjectOutputStream} passed to 148 * {@code writeObject}. 149 * 150 * @param cl a Serializable class 151 * @return a direct MethodHandle for the {@code writeObject} method of the class or 152 * {@code null} if the class does not have a {@code writeObject} method 153 */ 154 public final MethodHandle writeObjectForSerialization(Class<?> cl) { 155 return delegate.writeObjectForSerialization(cl); 156 } 157 158 /** 159 * Returns a direct MethodHandle for the {@code readResolve} method on 160 * a serializable class. 161 * The single argument of {@link MethodHandle#invoke} is the serializable 162 * object. 163 * 164 * @param cl the Serializable class 165 * @return a direct MethodHandle for the {@code readResolve} method of the class or 166 * {@code null} if the class does not have a {@code readResolve} method 167 */ 168 public final MethodHandle readResolveForSerialization(Class<?> cl) { 169 return delegate.readResolveForSerialization(cl); 170 } 171 172 /** 173 * Returns a direct MethodHandle for the {@code writeReplace} method on 174 * a serializable class. 175 * The single argument of {@link MethodHandle#invoke} is the serializable 176 * object. 177 * 178 * @param cl the Serializable class 179 * @return a direct MethodHandle for the {@code writeReplace} method of the class or 180 * {@code null} if the class does not have a {@code writeReplace} method 181 */ 182 public final MethodHandle writeReplaceForSerialization(Class<?> cl) { 183 return delegate.writeReplaceForSerialization(cl); 184 } 185 186 /** 187 * Returns true if the class has a static initializer. 188 * The presence of a static initializer is used to compute the serialVersionUID. 189 * @param cl a serializable class 190 * @return {@code true} if the class has a static initializer, 191 * otherwise {@code false} 192 */ 193 public final boolean hasStaticInitializerForSerialization(Class<?> cl) { 194 return delegate.hasStaticInitializerForSerialization(cl); 195 } 196 197 /** 198 * Returns a new OptionalDataException with {@code eof} set to {@code true} 199 * or {@code false}. 200 * @param bool the value of {@code eof} in the created OptionalDataException 201 * @return a new OptionalDataException 202 */ 203 public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) { 204 Constructor<OptionalDataException> cons = delegate.newOptionalDataExceptionForSerialization(); 205 try { 206 return cons.newInstance(bool); 207 } catch (InstantiationException|IllegalAccessException|InvocationTargetException ex) { 208 throw new InternalError("unable to create OptionalDataException", ex); 209 } 210 } 211 } 212