/*
 * Copyright (c) 2001, 2016, 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.lang.reflect.UndeclaredThrowableException;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.Permission;
import java.security.ProtectionDomain;
import java.security.PrivilegedAction;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaSecurityAccess;

ReflectionFactory supports custom serialization. Its methods support the creation of uninitialized objects, invoking serialization private methods for readObject, writeObject, readResolve, and writeReplace.

ReflectionFactory access is restricted, if a security manager is active, unless the permission RuntimePermission("reflectionFactoryAccess") is granted.

/** * 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(); 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.

First, if there is a security manager, its checkPermission method is called with a RuntimePermission with target "reflectionFactoryAccess". This may result in a security exception.

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

Throws:
  • SecurityException – if a security manager exists and its checkPermission method doesn't allow access to the RuntimePermission "reflectionFactoryAccess".
Returns:the ReflectionFactory
/** * 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() { 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.
Params:
  • cl – the class to instantiate
  • constructorToCall – the constructor to call
Returns:an accessible constructor
/** * 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.
Params:
  • cl – the class to instantiate
Returns:a no-arg constructor for the class or null if the class or supertypes do not have a suitable no-arg constructor
/** * 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.
Params:
  • cl – the class to instantiate
Returns:A no-arg constructor for the class; returns null if the class does not implement Externalizable
/** * 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 readObject method on a Serializable class. The first argument of MethodHandle.invoke is the serializable object and the second argument is the ObjectInputStream passed to readObject.
Params:
  • cl – a Serializable class
Returns: a direct MethodHandle for the readObject method of the class or null if the class does not have a readObject method
/** * 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); }
Invokes the supplied constructor, adding the provided protection domains to the invocation stack before invoking Constructor::newInstance. If no security manager is present, or no domains are provided, then this method simply calls cons.newInstance(). Otherwise, it invokes the provided constructor with privileges at the intersection of the current context and the provided protection domains.
Params:
  • cons – A constructor obtained from newConstructorForSerialization or newConstructorForExternalization.
  • domains – An array of protection domains that limit the privileges with which the constructor is invoked. Can be null or empty, in which case privileges are only limited by the current context.
Throws:
Returns:A new object built from the provided constructor.
/** * Invokes the supplied constructor, adding the provided protection domains * to the invocation stack before invoking {@code Constructor::newInstance}. * If no {@linkplain System#getSecurityManager() security manager} is present, * or no domains are provided, then this method simply calls * {@code cons.newInstance()}. Otherwise, it invokes the provided constructor * with privileges at the intersection of the current context and the provided * protection domains. * * @param cons A constructor obtained from {@code * newConstructorForSerialization} or {@code * newConstructorForExternalization}. * @param domains An array of protection domains that limit the privileges * with which the constructor is invoked. Can be {@code null} * or empty, in which case privileges are only limited by the * {@linkplain AccessController#getContext() current context}. * * @return A new object built from the provided constructor. * * @throws NullPointerException if {@code cons} is {@code null}. * @throws InstantiationException if thrown by {@code cons.newInstance()}. * @throws InvocationTargetException if thrown by {@code cons.newInstance()}. * @throws IllegalAccessException if thrown by {@code cons.newInstance()}. */
public final Object newInstanceForSerialization(Constructor<?> cons, ProtectionDomain[] domains) throws InstantiationException, InvocationTargetException, IllegalAccessException { SecurityManager sm = System.getSecurityManager(); if (sm == null || domains == null || domains.length == 0) { return cons.newInstance(); } else { JavaSecurityAccess jsa = SharedSecrets.getJavaSecurityAccess(); PrivilegedAction<?> pea = () -> { try { return cons.newInstance(); } catch (InstantiationException | InvocationTargetException | IllegalAccessException x) { throw new UndeclaredThrowableException(x); } }; // Can't use PrivilegedExceptionAction with jsa try { return jsa.doIntersectionPrivilege(pea, AccessController.getContext(), new AccessControlContext(domains)); } catch (UndeclaredThrowableException x) { Throwable cause = x.getCause(); if (cause instanceof InstantiationException) throw (InstantiationException) cause; if (cause instanceof InvocationTargetException) throw (InvocationTargetException) cause; if (cause instanceof IllegalAccessException) throw (IllegalAccessException) cause; // not supposed to happen throw x; } } }
Returns a direct MethodHandle for the readObjectNoData method on a Serializable class. The first argument of MethodHandle.invoke is the serializable object and the second argument is the ObjectInputStream passed to readObjectNoData.
Params:
  • cl – a Serializable class
Returns: a direct MethodHandle for the readObjectNoData method of the class or null if the class does not have a readObjectNoData method
/** * 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 writeObject method on a Serializable class. The first argument of MethodHandle.invoke is the serializable object and the second argument is the ObjectOutputStream passed to writeObject.
Params:
  • cl – a Serializable class
Returns: a direct MethodHandle for the writeObject method of the class or null if the class does not have a writeObject method
/** * 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 readResolve method on a serializable class. The single argument of MethodHandle.invoke is the serializable object.
Params:
  • cl – the Serializable class
Returns: a direct MethodHandle for the readResolve method of the class or null if the class does not have a readResolve method
/** * 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 writeReplace method on a serializable class. The single argument of MethodHandle.invoke is the serializable object.
Params:
  • cl – the Serializable class
Returns: a direct MethodHandle for the writeReplace method of the class or null if the class does not have a writeReplace method
/** * 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.
Params:
  • cl – a serializable class
Returns:true if the class has a static initializer, otherwise false
/** * 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 eof set to true or false.
Params:
  • bool – the value of eof in the created OptionalDataException
Returns: a new OptionalDataException
/** * 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); } } }