Certain sophisticated clients of the Java Core Reflection API require a means to suppress default Java language access control checks when using reflected members and constructors. These checks--for public, default (package) access, protected, and private members--are performed when Fields, Methods or Constructors are used to set or get fields, to invoke methods, or to create new instances of classes, respectively.

Examples of such clients are the Java Object Serialization service, development tools such as object inspectors and debuggers, and other applications such as database persistence mechanisms.

SOLUTION

In Java 1.2, a Field, Method or Constructor object may be explicitly flagged as suppressing default Java language access control. When the reflective object is used, this flag--a new instance field--is consulted as part of access checking. If the flag is true, access checks are disabled and the requested operation proceeds; otherwise, normal access checks are performed as in Java 1.1. The flag is false by default in a reflected member or constructor.

The act of setting the flag is security-checked using the new Java 1.2 security mechanisms. A client's calling context must have sufficient privilege to perform this operation.

Thus, in Java 1.2 each concrete reflected class (Field, Method and Constructor) extends a new base class, AccessibleObject, defined below. This class provides the necessary state and methods to set and get an "accessible" flag for a reflected object. A new ReflectPermission class, also defined below, provides the ability to grant the necessary permission via the security policy file.

PROGRAMMING INTERFACE

package java.lang.reflect;
/**
 * The AccessibleObject class is the base class for Field, Method and
 * Constructor objects.  It provides the ability to flag a reflected
 * object as suppressing default Java language access control checks
 * when it is used.  The access checks--for public, default (package)
 * access, protected, and private members--are performed when Fields,
 * Methods or Constructors are used to set or get fields, to invoke
 * methods, or to create and initialize new instances of classes,
 * respectively.
 *
 * <p>Setting the <tt>accessible</tt> flag in a reflected object
 * permits sophisticated applications with sufficient privilege, such
 * as Java Object Serialization or other persistence mechanisms, to
 * manipulate objects in a manner that would normally be prohibited.
 *
 * @see Field
 * @see Method
 * @see Constructor
 * @see ReflectPermission
 *
 * @since JDK1.2
 */
public
class AccessibleObject {

    /**
     * Convenience method to set the <tt>accessible</tt> flag for an
     * array of objects with a single security check (for efficiency).
     *
     * @param array the array of AccessibleObjects
     * @param flag the new value for the <tt>accessible</tt> flag in each object
     * @throws SecurityException if the request is denied
     */
    public static void setAccessible(AccessibleObject[] array, boolean flag)
    throws SecurityException;

    /**
     * Set the <tt>accessible</tt> flag for this object to
     * the indicated boolean value.  A value of <tt>true</tt> indicates that
     * the reflected object should suppress Java language access
     * checking when it is used.  A value of <tt>false</tt> indicates 
     * that the reflected object should enforce Java language access checks.
     *
     * @param flag the new value for the <tt>accessible</tt> flag
     * @throws SecurityException if the request is denied
     */
    public void setAccessible(boolean flag) throws SecurityException;

    /**
     * Get the value of the <tt>accessible</tt> flag for this object.
     */
    public boolean isAccessible();

    /**
     * Constructor: only used by the Java Virtual Machine.
     */
    protected AccessibleObject();

}

package java.lang.reflect;

/**
 * The Permission class for reflective operations.  A
 * ReflectPermission is a <em>named permission</em> and has no
 * actions.  The only name currently defined is <tt>access</tt>,
 * which allows suppressing the standard Java language access checks
 * --for public, default (package) access, protected, and private
 * members--performed by reflected objects at their point of use.
 *
 * <p>An example of permitting the identity "Duke" to suppress the
 * language access checking for reflected members might be:
 * <code>
 *    grant signedBy "Duke" {
 *        java.lang.reflect.ReflectPermission "access";
 *    }
 * </code>
 *
 * @see java.security.Permission
 * @see java.security.BasicPermission
 * @see AccessibleObject
 * @see Field#get
 * @see Field#set
 * @see Method#invoke
 * @see Constructor#newInstance
 *
 * @since JDK1.2
 */
public final
class ReflectPermission extends java.security.BasicPermission {

    /**
     * Constructs a ReflectPermission with the specified name.
     *
     * @param name the name of the ReflectPermission
     */
    public ReflectPermission(String name);

    /**
     * Constructs a ReflectPermission with the specified name and actions.
     * The actions should be null; they are ignored.
     *
     * @param name the name of the ReflectPermission
     * @param actions should be null.
     */
    public ReflectPermission(String name, String actions);
}