The cdl.iiop
option generates a component based on
RMI over IIOP transport.
Relaxer calls this type of component an "IIOP component".
IIOP component is a simillar RMI component.
However, IIOP component has strong advantage against RMI component.
IIOP component can be used by various type of progurams
such as C++, Smalltalk, even COBOL via CORBA ORB.
The cdl.iiop option takes one of the following values as a parameter:
The default configuration is false
.
No parameter implies the parameter is set to true
.
The cdl option generates base classes as follows:
In addition to these base classes, the cdl.iiop option's related classes are generated as shown below.
The IIOPINTERFACE
and the IIOPINTERFACEServer
are important for programmars.
The IIOPINTERFACE
is a JavaBeans
that acts as a front end against a application program.
Because of this, the IIOPINTERFACE
implements
the API interface IINTERFACE
.
Application programs uses the IIOPINTERFACE
immdiately.
The IIOPINTERFACEServer
is an IIOP server.
This object is executed as an IIOP server.
The INTERFACERemote
,
the INTERFACEClientProxy
,
The INTERFACEClient
are used internally.
The IINTERFACERemote
is a Java interface
to be used as an IIOP interface.
For this purpose, the IINTERFACERemote
extends
the java.rmi.Remote
.
The INTERFACEClientProxy
is a client side proxy object.
The IIOPINTERFACEClient
is a another
client side proxy object.
The cdl.iiop option adds no additional methods to Relaxer objects.
List 18.4.3.1[cdlIiop.rcdl] is a sample RCDL definition, and List 18.4.3.2[cdlIiop.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="cdlIiop.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.iiop option is as follows. The cdl option must be used together with cdl.iiop.
$ relaxer -cdl -cdl.iiop cdlIiop.rcdl
As a result, Relaxer generates 22 files:
List 18.4.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.4.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 as
List 18.4.3.5[AccountManagerService.java.AccountManager], is the
prototype of 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 then write
a findAccount
method.
The service provider AccountManagerService
is shown in List 18.4.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 AccountManagerCommand
and
the server-side program is IIOPAccountManagerServer
.
Compilation of AccountManagerCommand
and
the IIOPAccountManagerServer
are shown below.
No special compile options are needed.
$ javac AccountManagerCommand.java $ javac IIOPAccountManagerServer.java
Next, you must execute the rmic with -iiop option
to generate RMI over IIOP stub code.
In the example, the RMI over IIOP server
IIOPAccountManagerServer
is
specified as a parameter.
$ rmic -iiop IIOPAccountManagerServer &
There are three steps to execute the IIOP component.
First, prepare the CORBA's COS Naming server tnameserv. In this case, port number 1050 is specified using an ORBInitialPort option.
$ tnameserv -ORBInitialPort 1050 &
Second, start the IIOP server of the IIOP component as follows.
In the example, a COS Nameing name accountManager
is bound
with the IIOP server IIOPAccountManagerServer
.
The Java properties java.naming.factory.initial
and
java.naming.provider.url
are also specified.
java.naming.factory.initial
is an initial context provider name of JNDI.
In the example, com.sun.jndi.cosnaming.CNCtxFactory
,
Sun's COS Naming implementation, is specified.
java.naming.provider.url
is an initial value for the context provider.
In the example, iiop://localhost:1050
is specified.
This means that a hostname of an initial COS naming server is localhost
and
a port number of it is 1050.
$ java \ -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory \ -Djava.naming.provider.url=iiop://localhost:1050 \ IIOPAccountManagerServer accountManager &
Finally, execute the client command AccountManagerCommand
.
Java properties java.naming.factory.initial
and
java.naming.provider.url
are also specified.
$ java \ -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory \ -Djava.naming.provider.url=iiop://localhost:1050 \ AccountManagerCommand --iiop 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 --iiop
option specifies the use of RMI over IIOP
to access the target component.
The accountManager
parameter which follows --iiop
is the COS name
for the target RMI over IIOP component.
The -findAccount
option followed by a12345
means that you are 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 CORBA's IIOP transport.