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