The cdl.rmi
option generates an RMI component
from the RCDL or RIDL definition.
The cdl.rmi option takes one of the following values as a parameter.
The default configuration is false
.
If there is no parameter, it implies that the parameter is true
.
The cdl.rmi option generates an RMI component from the RCDL or RIDL definition.
The cdl option generates the following base classes:
In addition to these base classes, the cdl.rmi option related classes shown below are generated.
The RMIINTERFACE
and the RMIINTERFACEServer
are important for programmars.
The RMIINTERFACE
is a JavaBeans
that acts as a front end against an application program.
Because of this the RMIINTERFACE
implements
the API interface IINTERFACE
.
Application programs uses the RMIINTERFACE
immdiately.
The RMIINTERFACEServer
is an RMI server.
This object is executed as the RMI server.
The INTERFACERemote
,
the INTERFACEClientProxy
,
The INTERFACEClient
are used internally.
The IINTERFACERemote
is a java interface
to be used as an RMI interface.
For this purpose, the IINTERFACERemote
extends
java.rmi.Remote
.
The INTERFACEClientProxy
is a client-side proxy object.
The RMIINTERFACEClient
is an another
client-side proxy object.
The cdl.rmi option adds no additional methods to Relaxer objects or Relaxer table objects.
List 18.3.3.1[cdlRmi.rcdl] is a sample RCDL definition, and List 18.3.3.2[cdlRmi.rng] is a sample RELAX NG schema used by the RCDL definition.
<component xmlns="http://www.relaxer.org/xmlns/cdl" namespace="http://example.com/account" name="backOffice"> <interface namespace="http://example.com/account" name="accountManager"> <grammar namespace="http://example.com/account" location="cdlRmi.rng"/> <operation name="findAccount"> <in name="accountNo" type="token"/> <out label="account"/> </operation> </interface> </component>
<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> <start> <ref name="account"/> </start> <define name="account"> <element name="account"> <attribute name="accountNo"> <data type="token"/> </attribute> <element name="balance"> <data type="int"/> </element> <element name="owner"> <data type="token"/> </element> <ref name="address"/> <zeroOrMore> <ref name="phone"/> </zeroOrMore> </element> </define> <define name="address"> <element name="address"> <attribute name="zip"> <data type="token"/> </attribute> <text/> </element> </define> <define name="phone"> <element name="phone"> <attribute name="area"> <data type="token"/> </attribute> <data type="token"/> </element> </define> </grammar>
Execution of Relaxer with the cdl.rmi option is as follows. The cdl option must be used together.
$ relaxer -cdl -cdl.rmi cdlRmi.rcdl
As a result, Relaxer generates 22 files:
List 18.3.3.3[IAccountManager.java] is the IAccountManager
which is a Java interface to be used as an API.
import java.rmi.*; public interface IAccountManager extends Remote { /** * Application interface of the operation findAccount. * * @param accountNo * @exception RemoteException * @return Account */ Account findAccount(String accountNo) throws RemoteException; }
List 18.3.3.4[IAccountManagerService.java] is
the IAccountManagerService
which is a Java interface
to be used as an SPI.
import java.rmi.*; public interface IAccountManagerService extends IAccountManager { }
To complete this process,
you must develop a service provider.
For this purpose, Relaxer generates a prototype of the service provider.
In the example,
the AccountManagerService
shown in
List 18.3.3.5[AccountManagerService.java.AccountManager] is the
prototype for the service provider.
The AccountManagerService
extends
the AbstractAccountManagerService
which is the abstract base class for the service provider.
Therefore, the AccountManagerService
implicitly implements
the SPI IAccountManagerService
.
import java.rmi.RemoteException; public class AccountManagerService extends AbstractAccountManagerService { /** * Implementation of a operation findAccount. * * @param accountNo * @exception RemoteException * @return Account */ public Account findAccount(String accountNo) throws RemoteException { throw (new UnsupportedOperationException()); } }
Copy the file "AccountManagerService.java" and create
a findAccount
method.
The service provider AccountManagerService
is shown in List 18.3.3.6[AccountManagerService.java].
import java.rmi.RemoteException; import java.io.IOException; import javax.xml.parsers.ParserConfigurationException; import org.xml.sax.SAXException; public class AccountManagerService extends AbstractAccountManagerService { /** * Implementation of a operation findAccount. * * @param accountNo * @exception RemoteException * @return Account */ public Account findAccount(String accountNo) throws RemoteException { try { Account account = new Account(); account.setAccountNo(accountNo); account.setBalance(10000); account.setOwner("XML Taro"); account.setAddress( new Address("<address zip='123'>Yokohama</address>") ); Phone phone1 = new Phone(); phone1.setArea("123"); phone1.setContent("456-7890"); account.addPhone(phone1); Phone phone2 = new Phone("<phone area='090'>123-4567</phone>"); account.addPhone(phone2); return (account); } catch (IOException e) { throw (new RemoteException(e.getMessage(), e)); } catch (SAXException e) { throw (new RemoteException(e.getMessage(), e)); } catch (ParserConfigurationException e) { throw (new RemoteException(e.getMessage(), e)); } } }
You must compile both client side and server side programs.
The client side program is the AccountManagerCommand
and
the server side program is the RMIAccountManagerServer
.
Compilation of AccountManagerCommand
and
the RMIAccountManagerServer
are shown below.
No special compile options are needed.
$ javac AccountManagerCommand.java $ javac RMIAccountManagerServer.java
Next, you must execute the rmic to generate RMI stub codes.
In the example, the RMI server RMIAccountManagerServer
is
specified as a parameter.
$ rmic RMIAccountManagerServer &
There are three steps to execute the RMI component.
First, prepare the RMI name server rmiregistry.
$ rmiregistry &
Second, start the RMI server for the RMI component as follows.
In this case, an RMI name accountManager
is bound with the RMI server
RMIAccountManagerServer
.
$ java RMIAccountManagerServer accountManager &
Finally, execute the client command AccountManagerCommand
.
$ java AccountManagerCommand --rmi accountManager -findAccount \ a12345 <account accountNo="a12345"><balance>10000</balance><owner>XML \ Taro</owner><address zip="123">Yokohama</address><phone \ area="123">456-7890</phone><phone \ area="090">123-4567</phone></account>
The --rmi
option specifies RMI to access the target component.
accountManager
, which follows --rmi
is the RMI name
for the target RMI component.
The -findAccount
followed by a12345
means invoking
a findAccount
method with the parameter a12345
.
As a result, the command outputs an XML document which is sent back from the component via RMI transport.