java - Expose as reference return value of service proxied by RmiServiceExporter (or alternative to RMI) -


if export service via rmi rmiserviceexporter, return values of service calls serialized , sent on wire client. unless have simple service returns data, not useful.

i want able call methods on return value well, , have them run on server, not on client. essentially, want proxy return value created on client. there way rmiserviceexporter (or remoting option supported spring)?


i tried implement auto wrapping of return values, , came with:

on server side:

class rmireturnvaluestubbingexporter extends rmiserviceexporter {      /* can't use spring implementation of rmiinvocationhandler      * because it's package protected */     private class rmireturnvalueinvocationwrapper implements rmiinvocationhandler {         private final object wrappedobject;          private rmireturnvalueinvocationwrapper(class interf, object wrappedobject) {             this.wrappedobject = createproxyfor(interf, wrappedobject);         }          @override         public string gettargetinterfacename() throws remoteexception {             return null;         }          @override         public object invoke(remoteinvocation invocation) throws                 remoteexception, nosuchmethodexception, illegalaccessexception,                 invocationtargetexception {             return rmireturnvaluestubbingexporter.this.invoke(                     invocation, this.wrappedobject);         }     }      @override     protected object invoke(remoteinvocation invocation, object targetobject)             throws nosuchmethodexception, illegalaccessexception, invocationtargetexception {         object ret = maybewrap(super.invoke(invocation, targetobject));          if (ret instanceof remote) {             try {                 unicastremoteobject.exportobject((remote) ret, 0);             } catch (remoteexception e) {                 throw new invocationtargetexception(e);             }         }          return ret;     }      private object maybewrap(object supervalue) {         if (supervalue instanceof ontologyterm) {             return new rmireturnvalueinvocationwrapper(                     ontologyterm.class, supervalue);         } else if (supervalue instanceof list) {             return new rmireturnvalueinvocationwrapper(                     list.class, supervalue);         } else {             return supervalue;         }     }      private object createproxyfor(class interf, object object) {         proxyfactory proxyfactory = new proxyfactory();         proxyfactory.addinterface(interf);         proxyfactory.addadvice(new remoteinvocationtraceinterceptor(getexportername()));          proxyfactory.settarget(object);         // don't make opaque, on client need know interfaces implemented         return proxyfactory.getproxy(getbeanclassloader());     } } 

and on client side:

class rmistubreturnvalueproxyfactorybean extends rmiproxyfactorybean {      @override     protected object doinvoke(methodinvocation methodinvocation,                               rmiinvocationhandler invocationhandler) {          def supervalue = super.doinvoke(methodinvocation, invocationhandler)          if (supervalue instanceof java.lang.reflect.proxy &&                 java.lang.reflect.proxy.getinvocationhandler(supervalue)                 instanceof remoteobjectinvocationhandler) {             rmiinvocationhandler rih = supervalue              def proxiedinterfaces = rih.invoke(                     new remoteinvocation('getproxiedinterfaces',                             [] class[], [] object[]))              def clientproxy = new proxyfactory(proxiedinterfaces)              clientproxy.addadvice({ methodinvocation invoc ->                 doinvoke(invoc, rih)             } methodinterceptor)              clientproxy.getproxy beanclassloader         } else {             supervalue         }     } } 

this seems work fine 2 levels of wrapping; in case service returning list<ontologyterm>. suspect has quite problems, first of call unicastremoteobject.exportobject without ever reclaiming anything. things that's maybe missing here handling passing of these stubs clients gets arguments services. because arguments proxy objects created on client (wrapping rmi stub), guess @ least server have load classes client, i'd avoid.

my question if there's implemented (not rmi), can specify types returned value , serialized , types of return values should stubbed.

this ancient problem originated technologies corba, jini , first versions of ejb. idea abandoned not scale well.

a remote object cannot treated transparently local object due network overhead. due network latency, when calling remote object want pack data in remote call, while in local object prefer keep method calls fine-grained possible, can reusable oo point of view.

these 2 requirements of method reusability , low network overhead conflict , end result api of remote object going different api of local object, if technology existed make calls remote objects completelly transparent.

the solution nowadays widelly adopted send dtos (data transfer objects) on wire, data objects. can done in rmi, http (rest), soap or other protocols.

then @ each end mapping can made domain model, service , persistence layer can written in it. dto model on other hand not meant cross presentation layer.


Comments

Popular posts from this blog

Android layout hidden on keyboard show -

google app engine - 403 Forbidden POST - Flask WTForms -

c - Why would PK11_GenerateRandom() return an error -8023? -