src/share/classes/sun/corba/Bridge.java

Tue, 28 Dec 2010 15:52:36 -0800

author
ohair
date
Tue, 28 Dec 2010 15:52:36 -0800
changeset 240
f90b3e014e83
parent 173
032585ad970d
child 748
6845b95cba6b
permissions
-rw-r--r--

6962318: Update copyright year
Reviewed-by: xdono

     1 /*
     2  * Copyright (c) 2004, 2010, 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  */
    26 package sun.corba ;
    28 import java.lang.reflect.Field ;
    29 import java.lang.reflect.Method ;
    30 import java.lang.reflect.Constructor ;
    31 import java.lang.reflect.InvocationTargetException ;
    33 import java.io.ObjectInputStream ;
    35 import java.security.AccessController;
    36 import java.security.Permission;
    37 import java.security.PrivilegedAction;
    39 import sun.misc.Unsafe ;
    40 import sun.reflect.ReflectionFactory ;
    42 /** This class provides the methods for fundamental JVM operations
    43  * needed in the ORB that are not part of the public Java API.  This includes:
    44  * <ul>
    45  * <li>throwException, which can throw undeclared checked exceptions.
    46  * This is needed to handle throwing arbitrary exceptions across a standardized OMG interface that (incorrectly) does not specify appropriate exceptions.</li>
    47  * <li>putXXX/getXXX methods that allow unchecked access to fields of objects.
    48  * This is used for setting uninitialzed non-static final fields (which is
    49  * impossible with reflection) and for speed.</li>
    50  * <li>objectFieldOffset to obtain the field offsets for use in the putXXX/getXXX methods</li>
    51  * <li>newConstructorForSerialization to get the special constructor required for a
    52  * Serializable class</li>
    53  * <li>latestUserDefinedLoader to get the latest user defined class loader from
    54  * the call stack as required by the RMI-IIOP specification (really from the
    55  * JDK 1.1 days)</li>
    56  * </ul>
    57  * The code that calls Bridge.get() must have the following Permissions:
    58  * <ul>
    59  * <li>RuntimePermission "reflectionFactoryAccess"</li>
    60  * <li>BridgePermission "getBridge"</li>
    61  * <li>ReflectPermission "suppressAccessChecks"</li>
    62  * </ul>
    63  * <p>
    64  * All of these permissions are required to obtain and correctly initialize
    65  * the instance of Bridge.  No security checks are performed on calls
    66  * made to Bridge instance methods, so access to the Bridge instance
    67  * must be protected.
    68  * <p>
    69  * This class is a singleton (per ClassLoader of course).  Access to the
    70  * instance is obtained through the Bridge.get() method.
    71  */
    72 public final class Bridge
    73 {
    74     private static final Class[] NO_ARGS = new Class[] {};
    75     private static final Permission getBridgePermission =
    76         new BridgePermission( "getBridge" ) ;
    77     private static Bridge bridge = null ;
    79     // latestUserDefinedLoader() is a private static method
    80     // in ObjectInputStream in JDK 1.3 through 1.5.
    81     // We use reflection in a doPrivileged block to get a
    82     // Method reference and make it accessible.
    83     private final Method latestUserDefinedLoaderMethod ;
    84     private final Unsafe unsafe ;
    85     private final ReflectionFactory reflectionFactory ;
    87     private Method getLatestUserDefinedLoaderMethod()
    88     {
    89         return (Method) AccessController.doPrivileged(
    90             new PrivilegedAction()
    91             {
    92                 public Object run()
    93                 {
    94                     Method result = null;
    96                     try {
    97                         Class io = ObjectInputStream.class;
    98                         result = io.getDeclaredMethod(
    99                             "latestUserDefinedLoader", NO_ARGS);
   100                         result.setAccessible(true);
   101                     } catch (NoSuchMethodException nsme) {
   102                         Error err = new Error( "java.io.ObjectInputStream" +
   103                             " latestUserDefinedLoader " + nsme );
   104                         err.initCause(nsme) ;
   105                         throw err ;
   106                     }
   108                     return result;
   109                 }
   110             }
   111         );
   112     }
   114     private Unsafe getUnsafe() {
   115         Field fld = (Field)AccessController.doPrivileged(
   116             new PrivilegedAction()
   117             {
   118                 public Object run()
   119                 {
   120                     Field fld = null ;
   122                     try {
   123                         Class unsafeClass = sun.misc.Unsafe.class ;
   124                         fld = unsafeClass.getDeclaredField( "theUnsafe" ) ;
   125                         fld.setAccessible( true ) ;
   126                         return fld ;
   127                     } catch (NoSuchFieldException exc) {
   128                         Error err = new Error( "Could not access Unsafe" ) ;
   129                         err.initCause( exc ) ;
   130                         throw err ;
   131                     }
   132                 }
   133             }
   134         ) ;
   136         Unsafe unsafe = null;
   138         try {
   139             unsafe = (Unsafe)(fld.get( null )) ;
   140         } catch (Throwable t) {
   141             Error err = new Error( "Could not access Unsafe" ) ;
   142             err.initCause( t ) ;
   143             throw err ;
   144         }
   146         return unsafe ;
   147     }
   150     private Bridge()
   151     {
   152         latestUserDefinedLoaderMethod = getLatestUserDefinedLoaderMethod();
   153         unsafe = getUnsafe() ;
   154         reflectionFactory = (ReflectionFactory)AccessController.doPrivileged(
   155             new ReflectionFactory.GetReflectionFactoryAction());
   156     }
   158     /** Fetch the Bridge singleton.  This requires the following
   159      * permissions:
   160      * <ul>
   161      * <li>RuntimePermission "reflectionFactoryAccess"</li>
   162      * <li>BridgePermission "getBridge"</li>
   163      * <li>ReflectPermission "suppressAccessChecks"</li>
   164      * </ul>
   165      * @return The singleton instance of the Bridge class
   166      * @throws SecurityException if the caller does not have the
   167      * required permissions and the caller has a non-null security manager.
   168      */
   169     public static final synchronized Bridge get()
   170     {
   171         SecurityManager sman = System.getSecurityManager() ;
   172         if (sman != null)
   173             sman.checkPermission( getBridgePermission ) ;
   175         if (bridge == null) {
   176             bridge = new Bridge() ;
   177         }
   179         return bridge ;
   180     }
   182     /** Obtain the latest user defined ClassLoader from the call stack.
   183      * This is required by the RMI-IIOP specification.
   184      */
   185     public final ClassLoader getLatestUserDefinedLoader()
   186     {
   187         try {
   188             // Invoke the ObjectInputStream.latestUserDefinedLoader method
   189             return (ClassLoader)latestUserDefinedLoaderMethod.invoke(null,
   190                                                                      (Object[])NO_ARGS);
   191         } catch (InvocationTargetException ite) {
   192             Error err = new Error(
   193                 "sun.corba.Bridge.latestUserDefinedLoader: " + ite ) ;
   194             err.initCause( ite ) ;
   195             throw err ;
   196         } catch (IllegalAccessException iae) {
   197             Error err = new Error(
   198                 "sun.corba.Bridge.latestUserDefinedLoader: " + iae ) ;
   199             err.initCause( iae ) ;
   200             throw err ;
   201         }
   202     }
   204     /**
   205      * Fetches a field element within the given
   206      * object <code>o</code> at the given offset.
   207      * The result is undefined unless the offset was obtained from
   208      * {@link #objectFieldOffset} on the {@link java.lang.reflect.Field}
   209      * of some Java field and the object referred to by <code>o</code>
   210      * is of a class compatible with that field's class.
   211      * @param o Java heap object in which the field from which the offset
   212      * was obtained resides
   213      * @param offset indication of where the field resides in a Java heap
   214      *        object
   215      * @return the value fetched from the indicated Java field
   216      * @throws RuntimeException No defined exceptions are thrown, not even
   217      *         {@link NullPointerException}
   218      */
   219     public final int getInt(Object o, long offset)
   220     {
   221         return unsafe.getInt( o, offset ) ;
   222     }
   224     /**
   225      * Stores a value into a given Java field.
   226      * <p>
   227      * The first two parameters are interpreted exactly as with
   228      * {@link #getInt(Object, long)} to refer to a specific
   229      * Java field.  The given value is stored into that field.
   230      * <p>
   231      * The field must be of the same type as the method
   232      * parameter <code>x</code>.
   233      *
   234      * @param o Java heap object in which the field resides, if any, else
   235      *        null
   236      * @param offset indication of where the field resides in a Java heap
   237      *        object.
   238      * @param x the value to store into the indicated Java field
   239      * @throws RuntimeException No defined exceptions are thrown, not even
   240      *         {@link NullPointerException}
   241      */
   242     public final void putInt(Object o, long offset, int x)
   243     {
   244         unsafe.putInt( o, offset, x ) ;
   245     }
   247     /**
   248      * @see #getInt(Object, long)
   249      */
   250     public final Object getObject(Object o, long offset)
   251     {
   252         return unsafe.getObject( o, offset ) ;
   253     }
   255     /**
   256      * @see #putInt(Object, long, int)
   257      */
   258     public final void putObject(Object o, long offset, Object x)
   259     {
   260         unsafe.putObject( o, offset, x ) ;
   261     }
   263     /** @see #getInt(Object, long) */
   264     public final boolean getBoolean(Object o, long offset)
   265     {
   266         return unsafe.getBoolean( o, offset ) ;
   267     }
   268     /** @see #putInt(Object, long, int) */
   269     public final void    putBoolean(Object o, long offset, boolean x)
   270     {
   271         unsafe.putBoolean( o, offset, x ) ;
   272     }
   273     /** @see #getInt(Object, long) */
   274     public final byte    getByte(Object o, long offset)
   275     {
   276         return unsafe.getByte( o, offset ) ;
   277     }
   278     /** @see #putInt(Object, long, int) */
   279     public final void    putByte(Object o, long offset, byte x)
   280     {
   281         unsafe.putByte( o, offset, x ) ;
   282     }
   283     /** @see #getInt(Object, long) */
   284     public final short   getShort(Object o, long offset)
   285     {
   286         return unsafe.getShort( o, offset ) ;
   287     }
   288     /** @see #putInt(Object, long, int) */
   289     public final void    putShort(Object o, long offset, short x)
   290     {
   291         unsafe.putShort( o, offset, x ) ;
   292     }
   293     /** @see #getInt(Object, long) */
   294     public final char    getChar(Object o, long offset)
   295     {
   296         return unsafe.getChar( o, offset ) ;
   297     }
   298     /** @see #putInt(Object, long, int) */
   299     public final void    putChar(Object o, long offset, char x)
   300     {
   301         unsafe.putChar( o, offset, x ) ;
   302     }
   303     /** @see #getInt(Object, long) */
   304     public final long    getLong(Object o, long offset)
   305     {
   306         return unsafe.getLong( o, offset ) ;
   307     }
   308     /** @see #putInt(Object, long, int) */
   309     public final void    putLong(Object o, long offset, long x)
   310     {
   311         unsafe.putLong( o, offset, x ) ;
   312     }
   313     /** @see #getInt(Object, long) */
   314     public final float   getFloat(Object o, long offset)
   315     {
   316         return unsafe.getFloat( o, offset ) ;
   317     }
   318     /** @see #putInt(Object, long, int) */
   319     public final void    putFloat(Object o, long offset, float x)
   320     {
   321         unsafe.putFloat( o, offset, x ) ;
   322     }
   323     /** @see #getInt(Object, long) */
   324     public final double  getDouble(Object o, long offset)
   325     {
   326         return unsafe.getDouble( o, offset ) ;
   327     }
   328     /** @see #putInt(Object, long, int) */
   329     public final void    putDouble(Object o, long offset, double x)
   330     {
   331         unsafe.putDouble( o, offset, x ) ;
   332     }
   334     /**
   335      * This constant differs from all results that will ever be returned from
   336      * {@link #objectFieldOffset}.
   337      */
   338     public static final long INVALID_FIELD_OFFSET   = -1;
   340     /**
   341      * Returns the offset of a non-static field.
   342      */
   343     public final long objectFieldOffset(Field f)
   344     {
   345         return unsafe.objectFieldOffset( f ) ;
   346     }
   348     /** Throw the exception.
   349      * The exception may be an undeclared checked exception.
   350      */
   351     public final void throwException(Throwable ee)
   352     {
   353         unsafe.throwException( ee ) ;
   354     }
   356     /** Obtain a constructor for Class cl using constructor cons which
   357      * may be the constructor defined in a superclass of cl.  This is
   358      * used to create a constructor for Serializable classes that
   359      * constructs an instance of the Serializable class using the
   360      * no args constructor of the first non-Serializable superclass
   361      * of the Serializable class.
   362      */
   363     public final Constructor newConstructorForSerialization( Class cl,
   364         Constructor cons )
   365     {
   366         return reflectionFactory.newConstructorForSerialization( cl, cons ) ;
   367     }
   368 }

mercurial