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