1. /*
  2. * @(#)PortableRemoteObject.java 1.13 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 com.sun.corba.se.impl.javax.rmi;
  16. import java.lang.reflect.Method ;
  17. import javax.rmi.CORBA.Tie;
  18. import javax.rmi.CORBA.Util;
  19. import java.rmi.RemoteException;
  20. import java.rmi.NoSuchObjectException;
  21. import java.rmi.Remote;
  22. import java.util.Properties;
  23. import org.omg.CORBA.ORB;
  24. import org.omg.CORBA.portable.Delegate;
  25. import org.omg.CORBA.SystemException;
  26. import java.rmi.server.UnicastRemoteObject;
  27. import java.rmi.server.RemoteStub;
  28. import java.rmi.server.ExportException;
  29. import java.net.URL;
  30. import com.sun.corba.se.impl.util.JDKBridge;
  31. import com.sun.corba.se.impl.util.Utility;
  32. import com.sun.corba.se.impl.util.RepositoryId;
  33. import com.sun.corba.se.spi.presentation.rmi.StubAdapter;
  34. import java.security.AccessController;
  35. import com.sun.corba.se.impl.orbutil.GetPropertyAction;
  36. /**
  37. * Server implementation objects may either inherit from
  38. * javax.rmi.PortableRemoteObject or they may implement a remote interface
  39. * and then use the exportObject method to register themselves as a server object.
  40. * The toStub method takes a server implementation and returns a stub that
  41. * can be used to access that server object.
  42. * The connect method makes a Remote object ready for remote communication.
  43. * The unexportObject method is used to deregister a server object, allowing it to become
  44. * available for garbage collection.
  45. * The narrow method takes an object reference or abstract interface type and
  46. * attempts to narrow it to conform to
  47. * the given interface. If the operation is successful the result will be an
  48. * object of the specified type, otherwise an exception will be thrown.
  49. */
  50. public class PortableRemoteObject
  51. implements javax.rmi.CORBA.PortableRemoteObjectDelegate {
  52. /**
  53. * Makes a server object ready to receive remote calls. Note
  54. * that subclasses of PortableRemoteObject do not need to call this
  55. * method, as it is called by the constructor.
  56. * @param obj the server object to export.
  57. * @exception RemoteException if export fails.
  58. */
  59. public void exportObject(Remote obj)
  60. throws RemoteException {
  61. if (obj == null) {
  62. throw new NullPointerException("invalid argument");
  63. }
  64. // Has this object already been exported to IIOP?
  65. if (Util.getTie(obj) != null) {
  66. // Yes, so this is an error...
  67. throw new ExportException (obj.getClass().getName() + " already exported");
  68. }
  69. // Can we load a Tie?
  70. Tie theTie = Utility.loadTie(obj);
  71. if (theTie != null) {
  72. // Yes, so export it to IIOP...
  73. Util.registerTarget(theTie,obj);
  74. } else {
  75. // No, so export to JRMP. If this is called twice for the
  76. // same object, it will throw an ExportException...
  77. UnicastRemoteObject.exportObject(obj);
  78. }
  79. }
  80. /**
  81. * Returns a stub for the given server object.
  82. * @param obj the server object for which a stub is required. Must either be a subclass
  83. * of PortableRemoteObject or have been previously the target of a call to
  84. * {@link #exportObject}.
  85. * @return the most derived stub for the object.
  86. * @exception NoSuchObjectException if a stub cannot be located for the given server object.
  87. */
  88. public Remote toStub (Remote obj)
  89. throws NoSuchObjectException
  90. {
  91. Remote result = null;
  92. if (obj == null) {
  93. throw new NullPointerException("invalid argument");
  94. }
  95. // If the class is already an IIOP stub then return it.
  96. if (StubAdapter.isStub( obj )) {
  97. return obj;
  98. }
  99. // If the class is already a JRMP stub then return it.
  100. if (obj instanceof java.rmi.server.RemoteStub) {
  101. return obj;
  102. }
  103. // Has it been exported to IIOP?
  104. Tie theTie = Util.getTie(obj);
  105. if (theTie != null) {
  106. result = Utility.loadStub(theTie,null,null,true);
  107. } else {
  108. if (Utility.loadTie(obj) == null) {
  109. result = java.rmi.server.RemoteObject.toStub(obj);
  110. }
  111. }
  112. if (result == null) {
  113. throw new NoSuchObjectException("object not exported");
  114. }
  115. return result;
  116. }
  117. /**
  118. * Deregisters a server object from the runtime, allowing the object to become
  119. * available for garbage collection.
  120. * @param obj the object to unexport.
  121. * @exception NoSuchObjectException if the remote object is not
  122. * currently exported.
  123. */
  124. public void unexportObject(Remote obj)
  125. throws NoSuchObjectException {
  126. if (obj == null) {
  127. throw new NullPointerException("invalid argument");
  128. }
  129. if (StubAdapter.isStub(obj) ||
  130. obj instanceof java.rmi.server.RemoteStub) {
  131. throw new NoSuchObjectException(
  132. "Can only unexport a server object.");
  133. }
  134. Tie theTie = Util.getTie(obj);
  135. if (theTie != null) {
  136. Util.unexportObject(obj);
  137. } else {
  138. if (Utility.loadTie(obj) == null) {
  139. UnicastRemoteObject.unexportObject(obj,true);
  140. } else {
  141. throw new NoSuchObjectException("Object not exported.");
  142. }
  143. }
  144. }
  145. /**
  146. * Checks to ensure that an object of a remote or abstract interface type
  147. * can be cast to a desired type.
  148. * @param narrowFrom the object to check.
  149. * @param narrowTo the desired type.
  150. * @return an object which can be cast to the desired type.
  151. * @throws ClassCastException if narrowFrom cannot be cast to narrowTo.
  152. */
  153. public java.lang.Object narrow ( java.lang.Object narrowFrom,
  154. java.lang.Class narrowTo) throws ClassCastException
  155. {
  156. java.lang.Object result = null;
  157. if (narrowFrom == null)
  158. return null;
  159. if (narrowTo == null)
  160. throw new NullPointerException("invalid argument");
  161. try {
  162. if (narrowTo.isAssignableFrom(narrowFrom.getClass()))
  163. return narrowFrom;
  164. // Is narrowTo an interface that might be
  165. // implemented by a servant running on iiop?
  166. if (narrowTo.isInterface() &&
  167. narrowTo != java.io.Serializable.class &&
  168. narrowTo != java.io.Externalizable.class) {
  169. org.omg.CORBA.Object narrowObj
  170. = (org.omg.CORBA.Object) narrowFrom;
  171. // Create an id from the narrowTo type...
  172. String id = RepositoryId.createForAnyType(narrowTo);
  173. if (narrowObj._is_a(id)) {
  174. return Utility.loadStub(narrowObj,narrowTo);
  175. } else {
  176. throw new ClassCastException( "Object is not of remote type " +
  177. narrowTo.getName() ) ;
  178. }
  179. } else {
  180. throw new ClassCastException( "Class " + narrowTo.getName() +
  181. " is not a valid remote interface" ) ;
  182. }
  183. } catch(Exception error) {
  184. ClassCastException cce = new ClassCastException() ;
  185. cce.initCause( error ) ;
  186. throw cce ;
  187. }
  188. }
  189. /**
  190. * Makes a Remote object ready for remote communication. This normally
  191. * happens implicitly when the object is sent or received as an argument
  192. * on a remote method call, but in some circumstances it is useful to
  193. * perform this action by making an explicit call. See the
  194. * {@link Stub#connect} method for more information.
  195. * @param target the object to connect.
  196. * @param source a previously connected object.
  197. * @throws RemoteException if <code>source</code> is not connected
  198. * or if <code>target</code> is already connected to a different ORB than
  199. * <code>source</code>.
  200. */
  201. public void connect (Remote target, Remote source)
  202. throws RemoteException
  203. {
  204. if (target == null || source == null) {
  205. throw new NullPointerException("invalid argument");
  206. }
  207. ORB orb = null;
  208. try {
  209. if (StubAdapter.isStub( source )) {
  210. orb = StubAdapter.getORB( source ) ;
  211. } else {
  212. // Is this a servant that was exported to iiop?
  213. Tie tie = Util.getTie(source);
  214. if (tie == null) {
  215. /* loadTie always succeeds for dynamic RMI-IIOP
  216. // No, can we get a tie for it? If not,
  217. // assume that source is a JRMP object...
  218. if (Utility.loadTie(source) != null) {
  219. // Yes, so it is an iiop object which
  220. // has not been exported...
  221. throw new RemoteException(
  222. "'source' object not exported");
  223. }
  224. */
  225. } else {
  226. orb = tie.orb();
  227. }
  228. }
  229. } catch (SystemException e) {
  230. throw new RemoteException("'source' object not connected", e );
  231. }
  232. boolean targetIsIIOP = false ;
  233. Tie targetTie = null;
  234. if (StubAdapter.isStub(target)) {
  235. targetIsIIOP = true;
  236. } else {
  237. targetTie = Util.getTie(target);
  238. if (targetTie != null) {
  239. targetIsIIOP = true;
  240. } else {
  241. /* loadTie always succeeds for dynamic RMI-IIOP
  242. if (Utility.loadTie(target) != null) {
  243. throw new RemoteException("'target' servant not exported");
  244. }
  245. */
  246. }
  247. }
  248. if (!targetIsIIOP) {
  249. // Yes. Do we have an ORB from the source object?
  250. // If not, we're done - there is nothing to do to
  251. // connect a JRMP object. If so, it is an error because
  252. // the caller mixed JRMP and IIOP...
  253. if (orb != null) {
  254. throw new RemoteException(
  255. "'source' object exported to IIOP, 'target' is JRMP");
  256. }
  257. } else {
  258. // The target object is IIOP. Make sure we have a
  259. // valid ORB from the source object...
  260. if (orb == null) {
  261. throw new RemoteException(
  262. "'source' object is JRMP, 'target' is IIOP");
  263. }
  264. // And, finally, connect it up...
  265. try {
  266. if (targetTie != null) {
  267. // Is the tie already connected?
  268. try {
  269. ORB existingOrb = targetTie.orb();
  270. // Yes. Is it the same orb?
  271. if (existingOrb == orb) {
  272. // Yes, so nothing to do...
  273. return;
  274. } else {
  275. // No, so this is an error...
  276. throw new RemoteException(
  277. "'target' object was already connected");
  278. }
  279. } catch (SystemException e) {}
  280. // No, so do it...
  281. targetTie.orb(orb);
  282. } else {
  283. StubAdapter.connect( target, orb ) ;
  284. }
  285. } catch (SystemException e) {
  286. // The stub or tie was already connected...
  287. throw new RemoteException(
  288. "'target' object was already connected", e );
  289. }
  290. }
  291. }
  292. }