Issue 1736: Local stubs proposal (java2idl-rtf) Source: (, ) Nature: Uncategorized Issue Severity: Summary: Summary: There is currently no standard support for local RMI/IDL stubs. In contrast, the IDL/Java mapping specifies how support for local stubs is to be provided. The Java to IDL mapping should also specify standard APIs for local stubs which are compatible with the POA and the mechanisms used by IDL/Java local stubs. Resolution: closed, accepted Revised Text: dd the following methods to the javax.rmi.CORBA.Util class: public static RemoteException wrapException(Throwable obj) { ... } The wrapException method wraps an exception thrown by an implementation method. It returns the corresponding client-side exception. See section 28.4.8.1 for details. public static Object copyObject (Object obj, ORB orb) throws RemoteException { ... } public static Object[] copyObjects (Object[] obj, ORB orb) throws RemoteException { ... } The copyObject method is used by local stubs to copy an actual parameter, result object, or exception. The copyObjects method is used by local stubs to copy any number of actual parameters, preserving sharing across parameters as necessary to support RMI/IDL semantics. The actual parameter Object array holds the method parameter objects that need to be copied, and the result Object array holds the copied results. The stubs are required to call the above methods (or generate equivalent inline code) to handle Remote objects correctly. public static boolean isLocal(Stub s) throws java.rmi.RemoteException { ... }; This method has the same semantics as the ObjectImpl._is_local method, except that it can throw a java.rmi.RemoteException. Add the following new section after section 28.5.2.1: 28.5.2.2 Local Stubs The stub class may provide an optimized call path for local server implementation objects. For a method echo(int x) of a remote interface Aardvark, the optimized path does the following: 1. Find out if the servant is local by calling javax.rmi.CORBA.Util.isLocal() 2. If the servant is local, call this._servant_preinvoke("echo", Aardvark.class) 3. If _servant_preinvoke returned a non-null ServantObject so, call ((Aardvark)so.servant).echo(x) 4. If _servant_preinvoke returned a non-null ServantObject so, call this._servant_postinvoke(so) 5. If _servant_preinvoke returned null, repeat step 1. The call to Util.isLocal() will return false, causing the non-optimized path to be followed. The _servant_preinvoke method returns non-null if and only if an optimized local call may be used. It performs any security checking that may be necessary. Local stubs are responsible for performing all copying of method parameters, results and exceptions that is necessary to provide remote/local-transparent RMI/IDL semantics. The following is an example of a stub class that provides this optimized call path. public class Aardvark_Stub extends javax.rmi.CORBA.Stub implements Aardvark { public int echo(int x) throws java.rmi.RemoteException, Boomerang { if (!javax.rmi.CORBA.Util.isLocal(this)) { InputStream in = null; try { try { OutputStream out = _request("echo", true); out.write_long(x); in = _invoke(out); return in.read_long(); } catch (ApplicationException ex) { in = ex.getInputStream(); String id = in.read_string(); if (id.equals("IDL:BoomerangEx/1.0")) { throw (Boomerang) ((org.omg.CORBA_2_3.portable.InputStream)in). read_Value(); } else { throw new java.rmi.UnexpectedException(id); } } catch (RemarshalException ex) { return echo(x); } } catch (SystemException ex) { throw javax.rmi.CORBA.Util.mapSystemException(ex); } finally { _releaseReply(in); } } else { ServantObject so = _servant_preinvoke("echo", Aardvark.class); if (so == null) return echo(x); try { return ((Aardvark)so.servant).echo(x); } catch (Throwable ex) { Throwable ex2 = (Throwable)Util.copyObject(ex, _orb()); if (ex2 instanceof Boomerang) throw (Boomerang)ex2; else throw Util.wrapException(ex2); } finally { _servant_postinvoke(so); } } } } Actions taken: July 27, 1998: received issue June 4, 1999: closed issue Discussion: End of Annotations:===== Return-Path: Date: Mon, 27 Jul 1998 13:40:14 +0100 From: Simon Nash Reply-To: nash@hursley.ibm.com Organization: IBM To: java2idl-rtf@omg.org Cc: issues@omg.org Subject: Local stubs proposal There is currently no standard support for local RMI/IDL stubs. In contrast, the IDL/Java mapping specifies how support for local stubs is to be provided. The Java to IDL mapping should also specify standard APIs for local stubs which are compatible with the POA and the mechanisms used by IDL/Java local stubs. This proposal allows local stubs for RMI-IIOP implementations to be the same object as the RMI-IIOP tie, or a different object (for example, a subclass of the RMI-IIOP stub, similar to IDL/Java local stubs). The decision would be made by the generated code for ties and stubs. The places where an RMI-IIOP local stub is created are: a. PortableRemoteObject.toStub b. read_Object(clz) c. PortableRemoteObject.narrow We would like to define an API that creates a local stub and can be used by runtime code in all these places. The API to create a local stub is a method org.omg.CORBA.Object getStub(); on the javax.rmi.CORBA.Tie interface. For a non-POA tie for Foo that has local stub methods on the tie class (our current implementation), the implementation of this method is return this; For a POA tie for Foo, and local stubs as subclasses of remote stubs, the implementation of this method is localStub = new Foo_LocalStub(); localStub._set_delegate(_this_object()._get_delegate()); return localStub; Other combinations are possible, for example, no support for local stubs, in which case getStub returns a remote stub. The important point is that the Tie encapsulates the knowledge of how to create a local stub. Let's go through the three cases above to see how they work. a. toStub is passed the implementation object. It gets a tie from the implementation object using Util.getTie, then calls getStub on the tie. b. read_Object finds that the implementation object is local when it demarshals the IOR. It proceeds as in case a. c. narrow is passed a stub. It calls is_local to see if the implementation object is local. If it is, it needs some way to locate the implementation object so that it can proceed as in case a. We propose that it call servant_preinvoke on the stub, passing null as the operation name. The ORB runtime treats the null operation name parameter specially, and always returns the ServantObject in this case (unless it does not provide support for local stubs). The RMI local stub must use servant_preinvoke and servant_postinvoke, just as an IDL local stub does. Instead of passing the operations interface, it passes the RMI interface. This should be OK, since the RMI interface does not extend org.omg.CORBA.Object. Simon -- Simon C Nash, IBM Java Technology Centre, Hursley, UK MailPoint 146, x245156 Tel. 01962 815156 or +44-1962-815156 Internet: nash@hursley.ibm.com Notes mail: Simon Nash@ibmgb