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