Tue, 28 Dec 2010 15:52:36 -0800
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 }