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

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

mercurial