Powered by SmartDoc

The cdl.ejb option

The cdl.ejb option generates an EJB component from the RCDL or RIDL definition.

Parameter

The cdl.ejb option takes one of the following values as a parameter:

true
Generates an EJB component.
false
Does not generate an EJB component.

The default configuration is false. No parameter implies that the parameter is true.

Artifact

The cdl.ejb option generates base classes as follows:

In addition to these base classes, the cdl.ejb option's related classes shown below are generated.

The EJBINTERFACE is a important class for programmar. It is a JavaBeans which implements the API interface IINTERFACE. Application programs uses the EJBINTERFACE immdiately.

IINTERFACEEJB is a remote interface of EJB and IINTERFACEHome is a home interface of EJB.

INTERFACESessionBean is an Enterprise JavaBean implementation.

IINTERFACERemote, INTERFACEServerProxy, INTERFACEEJBProxy, EJBINTERFACEClient are for internal use only.

MANIFEST.MF.INTERFACE, application-client.xml.COMPONENT, and ejb-jar.xml.COMPONENT are prototypes of deployment descripters.

MANIFEST.MF, renamed from MANIFEST.MF.INTERFACE, provides meta information of the JavaBeans. application-client.xml, renamed from application-client.xml.COMPONENT, is a deployment descriptor of a client-side application.

ejb-jar.xml, renamed from ejb-jar.xml.COMPONENT, is a deployment descriptor of a EJB component.

The cdl.ejb option adds no additional methods to Relaxer objects.

Example

List 18.5.3.1[cdlEjb.rcdl] is a sample RCDL definition, and List 18.5.3.2[cdlEjb.rng] is a sample RELAX NG schema used by the RCDL definition. One operation, findAccount, is defined in the definition.

cdlEjb.rcdl
<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="cdlEjb.rng"/>
    <operation name="findAccount">
      <in name="accountNo" type="token"/>
      <out label="account"/>
    </operation>
  </interface>
</component>
cdlEjb.rng
<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.ejb option is as follows. The cdl option must be used together.

$ relaxer -cdl -cdl.ejb cdlEjb.rcdl

As a result, Relaxer generates 28 files:

Account, Address, Phone, URelaxer, RStack, and UJAXP are Relaxer Object related classes.

URComponent, IAccountManager, IAccountManagerService, IAccountManagerFilter, AbstractAccountManagerFilter, AbstractAccountManagerService, AccountManagerForwardProxy, AccountManagerContainer, AccountManagerBean, AccountManagerContainer, IAccountManagerRemote, and AccountManagerServerProxy are CDL-related classes.

IAccountManagerEJB, IAccountManagerHome, AccountManagerEJBProxy, EJBAccountManager, EJBAccountManagerClient, and AccountManagerSessionBean are EJB-related classes.

AccountManagerService.java.AccountManager is a prototype of the service provider.

MANIFEST.MF.accountManager, application-client.xml.backOffice, and ejb-jar.xml.backOffice are prototypes of deployment descripters.

List 18.5.3.3[IAccountManager.java] shows IAccountManager, a Java interface used an API.

IAccountManager.java
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.5.3.4[IAccountManagerService.java] shows IAccountManagerService, a Java interface used as an SPI.

IAccountManagerService.java
public interface IAccountManagerService extends IAccountManager {
}

List 18.5.3.5[IAccountManagerEJB.java] is an EJB remote interface mapped with the RIDL definition.

IAccountManagerEJB.java
import java.rmi.*;
import javax.ejb.*;

public interface IAccountManagerEJB extends EJBObject {
    /**
     * Remote interface of the operation findAccount.
     *
     * @param accountNo
     * @exception RemoteException
     * @return String
     */
    String findAccount(String accountNo) throws RemoteException;
}

List 18.5.3.6[IAccountManagerHome.java] is a EJB home interface to access the EnterpriseBeans specified the remote interface IAccountManagerEJB.

IAccountManagerHome.java
import java.rmi.*;
import javax.ejb.*;

public interface IAccountManagerHome extends EJBHome {
    /**
     * @exception RemoteException
     * @exception CreateException
     * @return IAccountManagerEJB
     */
    IAccountManagerEJB create() throws RemoteException, CreateException;
}

To complete the component creation, 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.5.3.7[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.

AccountManagerService.java.AccountManager
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 write a findAccount method. The service provider AccountManagerService is shown in List 18.5.3.8[AccountManagerService.java].

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));
	}
    }
}

The List 18.5.3.9[ejb-jar.xml.backOffice] is a prototype of the deployment descriptor for the J2EE EJB component. Since prototype has the least information for a deployment descriptor, you can use the deployment descriptor as it is.

ejb-jar.xml.backOffice
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise \
    JavaBeans 1.1//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">
<ejb-jar>
  <description></description>
  <display-name>backOffice</display-name>
  <enterprise-beans>
    <session>
      <description></description>
      <display-name>AccountManager</display-name>
      <ejb-name>AccountManager</ejb-name>
      <home>IAccountManagerHome</home>
      <remote>IAccountManagerEJB</remote>
      <ejb-class>AccountManagerSessionBean</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>
    </session>
  </enterprise-beans>
</ejb-jar>

The ejb-jar.xml.backOffice specifies:

The session type and the transaction type depends on the implementation. In the prototype file, Stateless is used as the session-type and Container is used as the transaction-type.

The example List 18.5.3.10[application-client.xml.backOffice] is a prototype of deployment descriptor for the J2EE application component. Since prototype at least has sufficient information as a deployment descriptor, you can use the deployment descriptor as it is.

application-client.xml.backOffice
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE application-client PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE \
    Application Client 1.2//EN" \
    "http://java.sun.com/dtd/application-client_1_2.dtd">
<application-client>
  <display-name>backOffice</display-name>
  <description></description>
  <ejb-ref>
    <description></description>
    <ejb-ref-name>ejb/AccountManager</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <home>IAccountManagerHome</home>
    <remote>IAccountManagerEJB</remote>
  </ejb-ref>
</application-client>

The file application-client.xml.backOffice specifies:

In addition to the deployment descriptor, the J2EE application component requires a JavaBeans name of the application. This information is specified at a MANIFEST.MF file in a META-INF directory of a JavaBeans JAR file. What you specifies depends what you want to execute as a concrete application. However, Relaxer generates a sample MANIFEST.MF file for your convenience.

In the example, Relaxer generates a sample MANIFEST.MF, shown in List 18.5.3.11[MANIFEST.MF.accountManager]. This configuration has a JavaBeans concrete class named "AccountManagerCommand".

MANIFEST.MF.accountManager
Manifest-Version: 1.0
Main-Class: AccountManagerCommand

You must compile both client-side and server-side programs. The client-side program is the AccountManagerCommand and the server-side program is the AccountManagerSessionBean.

Compilation of AccountManagerCommand and the AccountManagerSessionBean are shown below. No special compile options are needed.

$ javac AccountManagerCommand.java
$ javac AccountManagerSessionBean.java
$ javac IAccountManagerHome.java
$ javac AbstractAccountManagerFilter.java

Making EJB component

To make an EJB component, you must package parts of the component as an Enterprise JAR file.

Suppose a root directory for packaging is /tmp/backOffice.

Create the directory /tmp/backOffice and /tmp/backOffice/META-INF as follows:

$ mkdir /tmp/backOffice
$ mkdir /tmp/backOffice/META-INF

Copy the class files to the the root directory:

$ cp *.class /tmp/backOffice

In the example, we use ejb-jar.xml.backOffice, generated by Relaxer, as it is derived from the ejb-jar.xml deployment descriptor. Copy the file ejb-jar.xml.backOffice as the ejb-jar.xml as follows:

$ cp ejb-jar.xml.backOffice /tmp/backOffice/META-INF/ejb-jar.xml

Finally, pack all the parts with the JAR command.

$ cd /tmp/backOffice
$ jar cvf /tmp/backOffice.jar .

As a result, an EJB-JAR file, backOffice.jar, is created in the directory /tmp.

Creating a JavaBeans component

To create a client-side JavaBeans component, you must package parts of the component as a JavaBeans JAR file.

Suppose you have a root directory for packaging called /tmp/backOfficeClient.

Create the directory /tmp/backOfficeClient and /tmp/backOfficeClient/META-INF as follows:

$ mkdir /tmp/backOfficeClient
$ mkdir /tmp/backOfficeClient/META-INF

Copy the class files to the the root directory.

$ cp *.class /tmp/backOfficeClient

In the example, we use the file application-client.xml.backOffice, generated by Relaxer. It is used for appliation-client.xml, which is a deployment descriptor. Copy application-client.xml.backOffice to application-client.xml as follows:

$ cp application-client.xml.backOffice \
    /tmp/backOffice/META-INF/application-client.xml

In the example, we use MANIFEST.MF.accountManager, generated by Relaxer. It is used for MANIFEST.MF. Copy the file MANIFEST.MF.accountManager to MANIFEST.MF.

$ cp MANIFEST.MF.accuntManager \
    /tmp/backOffice/META-INF/MANIFEST.MF

Finally, pack all the parts by with the JAR command.

$ cd /tmp/backOfficeClient
$ jar cvfm /tmp/backOfficeClient.jar META-INF/MANIFEST.MF .

As a result, the JavaBeans JAR file backOfficeClient.jar is created in the directory /tmp.

Creating a J2EE Application

To execute an EJB application, you must make a J2EE application.

We have already created the EJB component and the JavaBeans so far. What you must to do is package these components into the J2EE application. The way to package the J2EE application depends on the J2EE server you want to use.

In the case of J2EE RI, it is easy to use the deploytool to make the J2EE application.

Deployment

Now we have a J2EE application, the backOffice.ear.

You must deploy the application to the J2EE server.

The way to deploy the application depends the J2EE server you use.

Execution

In case of using J2EE RI, to execute the EJB application on the client, you must use a runclient command supported by J2EE RI. The runclient command addresses various J2EE configuration and sets up a security context for the application.

$ runclient -client cdlEjbClient.jar -name AccountManager --ejb \
    java:comp/env/ejb/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 -client option followed by cdlEjbClient.jar specifies a JavaBeans JAR file, cdlEjbClient.jar.

The -name option followed by AccountManager specifies a display name of the J2EE application component as accountManager. This option is omittable.

The following parameters are for the AccountManagerCommand. The --ejb option specifies using EJB to access the target component.

The -findAccount followed by a12345 means that you want to invoke a findAccount method with a parameter a12345.

As a result, the command outputs an XML document which is sent back from the component via the EJB framework.