The RPC classes are in package equip2.rpc
and sub-packages. A request is represented by a serialised version of
an instance of class equip2.core.marshall.MethodCallRequest
and a response is represented by a serialised version of an instance of
calss equip2.core.marshall.MethodCallReply.
(These classes are generated using Simple_Bean_Generator
from ../etc/equip2.core.marshall.MethodCallRequest.xml
and ../etc/equip2.core.marshall.MethodCallReply.xml.
The definitions are based directly on the Hessian request and
reply formats.
An abstract client stub implementation is provided by equip2.rpc.GenericHessianClient which extends equip2.rpc.GenericAbstractClient. This maps a generic request made as a call to (the GenericAbstractClient-defined):
Object doRpc(String method, Object arguments[]) throws equip2.rpc.RpcException;
onto a call to its own abstract method:
java.io.InputStream doRpc(byte request[], int offset, int length)
throws equip2.rpc.RpcException;
which passes a Hessian encoded request as the contents of the request byte array, and will
attempt to read a Hessian encoded reply from the returned InputStream.
A client can work with a normal application-specific API, rather
than the above generic API, by using a build-time generated custom
client class or using J2SE reflection (java.lang.reflect.Proxy). A
simple application-specific client class can be generated using the
provided XLST scripts, etc/interface2javainterface.xsl
(which generates a Java interface) and etc/interface2javaclient.xsl
(which generates a client (..._client)
which implements the interface and delegates actual invocations to a
constructor-provided subclass of equip2.core.GenericAbstractClient).
These expect the interface to be defined in a simple XML format, of
which the following is a representative example:
<?xml version="1.0"?>
<interface package="equip2.rpc.test" class="TestInterface1">
<description>test interface (API)</description>
<method name="reverse">
<description>reverse a given value.</description>
<argument name="input" javatype="java.lang.String">
<description>the value to be reversed</description>
</argument>
<return name="input" javatype="java.lang.String">
<description>the input, but reversed</description>
</return>
<exception javatpye="equip2.rpc.test.TestException">
<description>Refuses to reverse strings which are palindromes</description>
</exception>
</method>
</interface>
The following transport-specific extensions of equip2.rpc.GenericHessianClient
are intended:
GenericDelegatingServer(Object delegate);
...
MethodCallReply handleRequest(MethodCallRequest request);
byte[] handleRequest(InputStream requestStream) throws RpcException;
Note that exceptions should normally be trapped and encoded in a
suitable MethodCallReply
object.
Alternatively, where reflection is not available (e.g. J2ME or C++)
the XSLT script etc/interface2javaserver.xslt
will generate a server skeleton (..._server) which extends the
abstract equip2.rpc.GenericAbstractServer, implementing its main method:
public MethodCallReply doRpc(MethodCallRequest request) throws RpcException
and mapping the request to calls on a delegate object
implementing the original Java interface (provided to the skeleton
constructor), e.g.:
public IRemoteDataspace_server(IRemoteDataspace delegate) ...
As yet there is no standard server framework for using the generated
skeleton, but it would be quite simple to adapt the GenericDelegatingServer to use
the generated skeleton (replacing the use of reflection in the method handleRequest).