Tue, 26 May 2015 10:00:55 -0700
Merge
duke@1 | 1 | /* |
ssides@553 | 2 | * Copyright (c) 1998, 2013, 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 | * Licensed Materials - Property of IBM |
duke@1 | 27 | * RMI-IIOP v1.0 |
duke@1 | 28 | * Copyright IBM Corp. 1998 1999 All Rights Reserved |
duke@1 | 29 | * |
duke@1 | 30 | */ |
duke@1 | 31 | |
duke@1 | 32 | package javax.rmi; |
duke@1 | 33 | |
duke@1 | 34 | import java.lang.reflect.Method ; |
duke@1 | 35 | |
duke@1 | 36 | import org.omg.CORBA.INITIALIZE; |
duke@1 | 37 | import javax.rmi.CORBA.Util; |
duke@1 | 38 | |
duke@1 | 39 | import java.rmi.RemoteException; |
duke@1 | 40 | import java.rmi.NoSuchObjectException; |
duke@1 | 41 | import java.rmi.Remote; |
duke@1 | 42 | import java.io.File; |
duke@1 | 43 | import java.io.FileInputStream; |
duke@1 | 44 | import java.util.Properties; |
duke@1 | 45 | import java.net.MalformedURLException ; |
duke@1 | 46 | import java.security.AccessController; |
duke@1 | 47 | import java.security.PrivilegedAction; |
duke@1 | 48 | import java.rmi.server.RMIClassLoader; |
duke@1 | 49 | |
duke@1 | 50 | import com.sun.corba.se.impl.orbutil.GetPropertyAction; |
duke@1 | 51 | |
duke@1 | 52 | /** |
duke@1 | 53 | * Server implementation objects may either inherit from |
duke@1 | 54 | * javax.rmi.PortableRemoteObject or they may implement a remote interface |
duke@1 | 55 | * and then use the exportObject method to register themselves as a server object. |
duke@1 | 56 | * The toStub method takes a server implementation and returns a stub that |
duke@1 | 57 | * can be used to access that server object. |
duke@1 | 58 | * The connect method makes a Remote object ready for remote communication. |
duke@1 | 59 | * The unexportObject method is used to deregister a server object, allowing it to become |
duke@1 | 60 | * available for garbage collection. |
duke@1 | 61 | * The narrow method takes an object reference or abstract interface type and |
duke@1 | 62 | * attempts to narrow it to conform to |
duke@1 | 63 | * the given interface. If the operation is successful the result will be an |
duke@1 | 64 | * object of the specified type, otherwise an exception will be thrown. |
duke@1 | 65 | */ |
duke@1 | 66 | public class PortableRemoteObject { |
duke@1 | 67 | |
alanb@533 | 68 | private static final javax.rmi.CORBA.PortableRemoteObjectDelegate proDelegate; |
duke@1 | 69 | |
duke@1 | 70 | private static final String PortableRemoteObjectClassKey = |
duke@1 | 71 | "javax.rmi.CORBA.PortableRemoteObjectClass"; |
duke@1 | 72 | |
duke@1 | 73 | static { |
duke@1 | 74 | proDelegate = (javax.rmi.CORBA.PortableRemoteObjectDelegate) |
alanb@533 | 75 | createDelegate(PortableRemoteObjectClassKey); |
duke@1 | 76 | } |
duke@1 | 77 | |
duke@1 | 78 | /** |
duke@1 | 79 | * Initializes the object by calling <code>exportObject(this)</code>. |
duke@1 | 80 | * @exception RemoteException if export fails. |
duke@1 | 81 | */ |
duke@1 | 82 | protected PortableRemoteObject() throws RemoteException { |
duke@1 | 83 | if (proDelegate != null) { |
duke@1 | 84 | PortableRemoteObject.exportObject((Remote)this); |
duke@1 | 85 | } |
duke@1 | 86 | } |
duke@1 | 87 | |
duke@1 | 88 | /** |
duke@1 | 89 | * Makes a server object ready to receive remote calls. Note |
duke@1 | 90 | * that subclasses of PortableRemoteObject do not need to call this |
duke@1 | 91 | * method, as it is called by the constructor. |
duke@1 | 92 | * @param obj the server object to export. |
duke@1 | 93 | * @exception RemoteException if export fails. |
duke@1 | 94 | */ |
duke@1 | 95 | public static void exportObject(Remote obj) |
duke@1 | 96 | throws RemoteException { |
duke@1 | 97 | |
duke@1 | 98 | // Let the delegate do everything, including error handling. |
duke@1 | 99 | if (proDelegate != null) { |
duke@1 | 100 | proDelegate.exportObject(obj); |
duke@1 | 101 | } |
duke@1 | 102 | } |
duke@1 | 103 | |
duke@1 | 104 | /** |
duke@1 | 105 | * Returns a stub for the given server object. |
duke@1 | 106 | * @param obj the server object for which a stub is required. Must either be a subclass |
duke@1 | 107 | * of PortableRemoteObject or have been previously the target of a call to |
duke@1 | 108 | * {@link #exportObject}. |
duke@1 | 109 | * @return the most derived stub for the object. |
duke@1 | 110 | * @exception NoSuchObjectException if a stub cannot be located for the given server object. |
duke@1 | 111 | */ |
duke@1 | 112 | public static Remote toStub (Remote obj) |
duke@1 | 113 | throws NoSuchObjectException { |
duke@1 | 114 | |
duke@1 | 115 | if (proDelegate != null) { |
duke@1 | 116 | return proDelegate.toStub(obj); |
duke@1 | 117 | } |
duke@1 | 118 | return null; |
duke@1 | 119 | } |
duke@1 | 120 | |
duke@1 | 121 | /** |
duke@1 | 122 | * Deregisters a server object from the runtime, allowing the object to become |
duke@1 | 123 | * available for garbage collection. |
duke@1 | 124 | * @param obj the object to unexport. |
duke@1 | 125 | * @exception NoSuchObjectException if the remote object is not |
duke@1 | 126 | * currently exported. |
duke@1 | 127 | */ |
duke@1 | 128 | public static void unexportObject(Remote obj) |
duke@1 | 129 | throws NoSuchObjectException { |
duke@1 | 130 | |
duke@1 | 131 | if (proDelegate != null) { |
duke@1 | 132 | proDelegate.unexportObject(obj); |
duke@1 | 133 | } |
duke@1 | 134 | |
duke@1 | 135 | } |
duke@1 | 136 | |
duke@1 | 137 | /** |
duke@1 | 138 | * Checks to ensure that an object of a remote or abstract interface type |
duke@1 | 139 | * can be cast to a desired type. |
duke@1 | 140 | * @param narrowFrom the object to check. |
duke@1 | 141 | * @param narrowTo the desired type. |
duke@1 | 142 | * @return an object which can be cast to the desired type. |
duke@1 | 143 | * @throws ClassCastException if narrowFrom cannot be cast to narrowTo. |
duke@1 | 144 | */ |
duke@1 | 145 | public static java.lang.Object narrow ( java.lang.Object narrowFrom, |
duke@1 | 146 | java.lang.Class narrowTo) |
duke@1 | 147 | throws ClassCastException { |
duke@1 | 148 | |
duke@1 | 149 | if (proDelegate != null) { |
duke@1 | 150 | return proDelegate.narrow(narrowFrom, narrowTo); |
duke@1 | 151 | } |
duke@1 | 152 | return null; |
duke@1 | 153 | |
duke@1 | 154 | } |
duke@1 | 155 | |
duke@1 | 156 | /** |
duke@1 | 157 | * Makes a Remote object ready for remote communication. This normally |
duke@1 | 158 | * happens implicitly when the object is sent or received as an argument |
duke@1 | 159 | * on a remote method call, but in some circumstances it is useful to |
duke@1 | 160 | * perform this action by making an explicit call. See the |
andrew@135 | 161 | * {@link javax.rmi.CORBA.Stub#connect} method for more information. |
duke@1 | 162 | * @param target the object to connect. |
duke@1 | 163 | * @param source a previously connected object. |
duke@1 | 164 | * @throws RemoteException if <code>source</code> is not connected |
duke@1 | 165 | * or if <code>target</code> is already connected to a different ORB than |
duke@1 | 166 | * <code>source</code>. |
duke@1 | 167 | */ |
duke@1 | 168 | public static void connect (Remote target, Remote source) |
duke@1 | 169 | throws RemoteException { |
duke@1 | 170 | |
duke@1 | 171 | if (proDelegate != null) { |
duke@1 | 172 | proDelegate.connect(target, source); |
duke@1 | 173 | } |
duke@1 | 174 | |
duke@1 | 175 | } |
duke@1 | 176 | |
duke@1 | 177 | // Same code as in javax.rmi.CORBA.Util. Can not be shared because they |
duke@1 | 178 | // are in different packages and the visibility needs to be package for |
duke@1 | 179 | // security reasons. If you know a better solution how to share this code |
duke@1 | 180 | // then remove it from here. |
alanb@533 | 181 | private static Object createDelegate(String classKey) { |
duke@1 | 182 | String className = (String) |
duke@1 | 183 | AccessController.doPrivileged(new GetPropertyAction(classKey)); |
duke@1 | 184 | if (className == null) { |
duke@1 | 185 | Properties props = getORBPropertiesFile(); |
duke@1 | 186 | if (props != null) { |
duke@1 | 187 | className = props.getProperty(classKey); |
duke@1 | 188 | } |
duke@1 | 189 | } |
duke@1 | 190 | if (className == null) { |
alanb@533 | 191 | return new com.sun.corba.se.impl.javax.rmi.PortableRemoteObject(); |
duke@1 | 192 | } |
duke@1 | 193 | |
duke@1 | 194 | try { |
duke@1 | 195 | return (Object) loadDelegateClass(className).newInstance(); |
duke@1 | 196 | } catch (ClassNotFoundException ex) { |
duke@1 | 197 | INITIALIZE exc = new INITIALIZE( "Cannot instantiate " + className); |
duke@1 | 198 | exc.initCause( ex ) ; |
duke@1 | 199 | throw exc ; |
duke@1 | 200 | } catch (Exception ex) { |
duke@1 | 201 | INITIALIZE exc = new INITIALIZE( "Error while instantiating" + className); |
duke@1 | 202 | exc.initCause( ex ) ; |
duke@1 | 203 | throw exc ; |
duke@1 | 204 | } |
duke@1 | 205 | |
duke@1 | 206 | } |
duke@1 | 207 | |
duke@1 | 208 | private static Class loadDelegateClass( String className ) throws ClassNotFoundException |
duke@1 | 209 | { |
duke@1 | 210 | try { |
duke@1 | 211 | ClassLoader loader = Thread.currentThread().getContextClassLoader(); |
duke@1 | 212 | return Class.forName(className, false, loader); |
duke@1 | 213 | } catch (ClassNotFoundException e) { |
duke@1 | 214 | // ignore, then try RMIClassLoader |
duke@1 | 215 | } |
duke@1 | 216 | |
duke@1 | 217 | try { |
duke@1 | 218 | return RMIClassLoader.loadClass(className); |
duke@1 | 219 | } catch (MalformedURLException e) { |
duke@1 | 220 | String msg = "Could not load " + className + ": " + e.toString(); |
duke@1 | 221 | ClassNotFoundException exc = new ClassNotFoundException( msg ) ; |
duke@1 | 222 | throw exc ; |
duke@1 | 223 | } |
duke@1 | 224 | } |
duke@1 | 225 | |
duke@1 | 226 | /** |
duke@1 | 227 | * Load the orb.properties file. |
duke@1 | 228 | */ |
duke@1 | 229 | private static Properties getORBPropertiesFile () { |
duke@1 | 230 | return (Properties) AccessController.doPrivileged(new GetORBPropertiesFileAction()); |
duke@1 | 231 | } |
duke@1 | 232 | } |
duke@1 | 233 | |
duke@1 | 234 | class GetORBPropertiesFileAction implements PrivilegedAction { |
duke@1 | 235 | private boolean debug = false ; |
duke@1 | 236 | |
duke@1 | 237 | public GetORBPropertiesFileAction () { |
duke@1 | 238 | } |
duke@1 | 239 | |
duke@1 | 240 | private String getSystemProperty(final String name) { |
duke@1 | 241 | // This will not throw a SecurityException because this |
duke@1 | 242 | // class was loaded from rt.jar using the bootstrap classloader. |
duke@1 | 243 | String propValue = (String) AccessController.doPrivileged( |
duke@1 | 244 | new PrivilegedAction() { |
duke@1 | 245 | public java.lang.Object run() { |
duke@1 | 246 | return System.getProperty(name); |
duke@1 | 247 | } |
duke@1 | 248 | } |
duke@1 | 249 | ); |
duke@1 | 250 | |
duke@1 | 251 | return propValue; |
duke@1 | 252 | } |
duke@1 | 253 | |
duke@1 | 254 | private void getPropertiesFromFile( Properties props, String fileName ) |
duke@1 | 255 | { |
duke@1 | 256 | try { |
duke@1 | 257 | File file = new File( fileName ) ; |
duke@1 | 258 | if (!file.exists()) |
duke@1 | 259 | return ; |
duke@1 | 260 | |
duke@1 | 261 | FileInputStream in = new FileInputStream( file ) ; |
duke@1 | 262 | |
duke@1 | 263 | try { |
duke@1 | 264 | props.load( in ) ; |
duke@1 | 265 | } finally { |
duke@1 | 266 | in.close() ; |
duke@1 | 267 | } |
duke@1 | 268 | } catch (Exception exc) { |
duke@1 | 269 | if (debug) |
duke@1 | 270 | System.out.println( "ORB properties file " + fileName + |
duke@1 | 271 | " not found: " + exc) ; |
duke@1 | 272 | } |
duke@1 | 273 | } |
duke@1 | 274 | |
duke@1 | 275 | public Object run() |
duke@1 | 276 | { |
duke@1 | 277 | Properties defaults = new Properties() ; |
duke@1 | 278 | |
duke@1 | 279 | String javaHome = getSystemProperty( "java.home" ) ; |
duke@1 | 280 | String fileName = javaHome + File.separator + "lib" + File.separator + |
duke@1 | 281 | "orb.properties" ; |
duke@1 | 282 | |
duke@1 | 283 | getPropertiesFromFile( defaults, fileName ) ; |
duke@1 | 284 | |
duke@1 | 285 | Properties results = new Properties( defaults ) ; |
duke@1 | 286 | |
duke@1 | 287 | String userHome = getSystemProperty( "user.home" ) ; |
duke@1 | 288 | fileName = userHome + File.separator + "orb.properties" ; |
duke@1 | 289 | |
duke@1 | 290 | getPropertiesFromFile( results, fileName ) ; |
duke@1 | 291 | return results ; |
duke@1 | 292 | } |
duke@1 | 293 | } |