Oracle Application Server Containers for J2EE 10g (10.0.3)

Last Updated: 03/05/2004

How-To: Rebuild Java Adventure Builder Reference Application v1.0 for OC4J

After completing this How-to you should be able to:

If you are interested in simply deploying and running the Adventure Builder, consult how-to-adventure-builder.html which describes how to deploy the pre-built archives we've provided for OC4J.

Software Requirements

The following software components are required to complete this how-to:

Notations Used

Changes Made by Oracle

The Adventure Builder is designed to be a portable J2EE 1.4 application. This section lists the steps taken by Oracle to construct the pre-built EAR files which can be deployed to OC4J.

If you are starting from the original Sun distribution of Java Adventure Builder 1.0, then you must make the following additionsto the application to deploy it to OC4J.

Oracle Specific Deployment Descriptor Changes

The great news and a real proof of the portable nature of J2EE is that you don't need to make any source code changes in the application to deploy it to OC4J**. The 'porting' process primarily involves creating and packaging a number of Oracle specific deployment descriptors within the application archive to enable it to describe itself to OC4J..

A script is also supplied to create the necessary tables in an Oracle Database instead of the Pointbase database that is used for running the application with J2EE Reference Implementation server.

** except for two minor non portable coding issues, see here for details.

Changes in the OPC.ear

You have to package an orion-application.xml in the META-INF directory of the opc.ear that directs which Data Source to use for creating tables for CMP entity beans. The table creation script supplied in the Sample does not include the script to create the underlying table and the deployment process in OC4J creates the underlying tables. You can still have this functionality by changing default-data-source from jdbc/OracleDS to jdbc/adventure/AdventureDB in the config/application.xml without having to package the orion-application.xml.

 Following is the contents of orion-application.xml:

<?xml version="1.0"?>
<!DOCTYPE orion-application PUBLIC "-//ORACLE//DTD OC4J Application runtime 9.04//EN" "http://xmlns.oracle.com/ias/dtds/orion-application-9_04.dtd">
  <orion-application deployment-version="10.0.3.0.0" default-data-source="jdbc/adventure/AdventureDB">
</orion-application>

opc-ejb.jar

You have to package the Oracle specific vendor deployment descriptors with the opc-ejb modules e.g. META-INF/oracle-webservices.xml in the opc-ejb.jar for exposing the Stateless EJB web service, META-INF/orion-ejb-jar.xml to specify the Queue location and Queue Connection Factory used by MDBs.

The OPC application accesses web services in other applications such as ActivitySupplier, AirlineSupplier, Bank and LodgingSupplier. The address, URL and more are hardcoded in the ejb-jar.xml. You have to make necessary changes as per your environment such as hostname and port# and context root. Following is code snippet that demonstrates a section that needs to be modified. A fully modified ejb-jar.xml is packaged in the %HOW_TO_HOME%/descriptors/opc directory.

    <env-entry>
          <env-entry-name>param/LodgingServiceURL</env-entry-name>
      <env-entry-type>java.lang.String</env-entry-type>
      <env-entry-value>http://localhost:8888/lodgingsupplier/LodgingPOService</env-entry-value>
       </env-entry>
       <env-entry>
          <env-entry-name>param/AirlineServiceURL</env-entry-name>
      <env-entry-type>java.lang.String</env-entry-type>
      <env-entry-value>http://localhost:8888/airlinesupplier/AirlinePOService</env-entry-value>
       </env-entry>
       <env-entry>
          <env-entry-name>param/ActivityServiceURL</env-entry-name>
      <env-entry-type>java.lang.String</env-entry-type>
      <env-entry-value>http://localhost:8888/activitysupplier/ActivityPOService</env-entry-value>
   </env-entry>

oracle-webservices.xml

The opc-ejb module exposes several Stateless EJBs as webservice. An Oracle specific vendor deployment descriptor is required to expose these webservices. The following code snippet provides an example how to specify these.A fully modified oracle-webservices.xml is packaged in the %HOW_TO_HOME%/descriptors/opc directory.

<?xml version="1.0" encoding="utf-8"?>
<oracle-webservices>
   
    <context-root>/webservice</context-root>
    <webservice-description name="OpcPurchaseOrderService">
        <port-component name="PurchaseOrderIntfPort">
           
            <endpoint-address-uri>/PoEndpointBean</endpoint-address-uri>
        </port-component>
    </webservice-description>

    <webservice-description name="OpcOrderTrackingService">
        <port-component name="OrderTrackingIntfPort">
          
            <endpoint-address-uri>/OtEndpointBean</endpoint-address-uri>
        </port-component>
    </webservice-description>
</oracle-webservices>

orion-ejb-jar.xml

The opc-ejb module contains several MDBs. The destination-location and connection-factory-location for the MDBs needs to be specified in the orion-ejb-jar.xml. The following snippet provides an example how to specify these.A fully modified orion-ejb-jar.xml is packaged in the %HOW_TO_HOME%/descriptors/opc directory.


<message-driven-deployment name="WorkFlowManagerBean" destination-location="jms/opc/WorkFlowMgrQueue" connection-factory-location="jms/opc/QueueConnectionFactory">
     <ejb-ref-mapping name="ejb/local/processmanager/ProcessManager" />
     <ejb-ref-mapping name="ejb/local/purchaseorder/PurchaseOrder" />
           
     <resource-ref-mapping name="jms/opc/QueueConnectionFactory"  location="jms/opc/QueueConnectionFactory" />
     <resource-env-ref-mapping name="jms/opc/OrderFillerQueue" location="jms/opc/OrderFillerQueue"/>
     <resource-env-ref-mapping name="jms/opc/CRMQueue" location="jms/opc/CRMQueue"/>
</message-driven-deployment>       

Changes in the ActivitySupplier.ear

You have to package an orion-application.xml in the META-INF directory of the ActivitySupplier.ear that directs which Data Source to use for creating tables for CMP entity beans. The table creation script supplied in the Sample does not include the script to create the underlying table and the deployment process in OC4J creates the underlying tables. You can still have this functionality by changing default-data-source from jdbc/OracleDS to jdbc/adventure/AdventureDB in the config/application.xml without having to package the orion-application.xml.

 Following is the contents of orion-application.xml:

<?xml version="1.0"?>
<!DOCTYPE orion-application PUBLIC "-//ORACLE//DTD OC4J Application runtime 9.04//EN" "http://xmlns.oracle.com/ias/dtds/orion-application-9_04.dtd">

  <orion-application deployment-version="10.0.3.0.0" default-data-source="jdbc/adventure/AdventureDB">
</orion-application>

activitysupplier-ejb.jar

You have to package the Oracle specific vendor deployment descriptors with the opc-ejb modules e.g. META-INF/oracle-webservices.xml in the activity-ejb.jar for exposing the Stateless EJB web service, META-INF/orion-ejb-jar.xml to specify the Queue location and Queue Connection Factory used by MDBs.

oracle-webservices.xml:

The activitysupplier-ejb module exposes one Stateless EJB as webservice. An Oracle specific vendor deployment descriptor is required to expose the webservice. The following code snippet  provides an example how to specify these. A fully modified oracle-webservices.xml is packaged in the %HOW_TO_HOME%/descriptors/activitysupplier directory.

    <context-root>/activitysupplier</context-root>
    <webservice-description name="ActivityPurchaseOrderService">
       
        <port-component name="ActivityPOIntfPort">
           
            <endpoint-address-uri>/ActivityPOService</endpoint-address-uri>
        </port-component>
    </webservice-description>

</oracle-webservices>

orion-ejb-jar.xml

The activitysupplier-ejb module contains an MDB. The destination-location and connection-factory-location for the MDBs needs to be specified in the orion-ejb-jar.xml. The following snippet provides an example how to specify these. A fully modified orion-ejb-jar.xml is packaged in the %HOW_TO_HOME%/descriptors/activitysupplier directory.

<message-driven-deployment name="ActivityMessageEJB" destination-location="jms/activity/ActivityQueue" connection-factory-location="jms/activity/QueueConnectionFactory">
            <ejb-ref-mapping name="ejb/local/activitysupplier/ActivityPurchaseOrder" />
           
            </service-ref-mapping>
        </message-driven-deployment>
   

Changes in the AirlineSupplier.ear

You have to package an orion-application.xml in the META-INF directory of the AirlineSupplier.ear that directs which Data Source to use for creating tables for CMP entity beans. The table creation script supplied in the Sample does not include the script to create the underlying table and the deployment process in OC4J creates the underlying tables. You can still have this functionality by changing default-data-source from jdbc/OracleDS to jdbc/adventure/AdventureDB in the config/application.xml without having  to package the orion-application.xml.

 Following is the contents of orion-application.xml:

<?xml version="1.0"?>
<!DOCTYPE orion-application PUBLIC "-//ORACLE//DTD OC4J Application runtime 9.04//EN" "http://xmlns.oracle.com/ias/dtds/orion-application-9_04.dtd">

<orion-application deployment-version="10.0.3.0.0" default-data-source="jdbc/adventure/AdventureDB">

</orion-application>

airline-ejb.jar

You have to package the Oracle specific vendor deployment descriptors with the airlinesupplier-ejb modules e.g. META-INF/oracle-webservices.xml in the airlinesupplier-ejb.jarfor exposing the Stateless EJB Web service, META-INF/orion-ejb-jar.xml to specify the Queue location and Queue Connection Factory used by MDBs.

oracle-webservices.xml

The airlinesupplier-ejb module expose a Stateless EJB as Web service. An Oracle specific vendor deployment descriptor is required to expose this Web service. The following code snippet provides an example how to specify these. A fully modified oracle-webservices.xml is packaged in the %HOW_TO_HOME%/descriptors/airlinesupplier-ejb directory.


    <context-root>/airlinesupplier</context-root>
    <webservice-description name="AirlinePurchaseOrderService">
            <port-component name="AirlinePOIntfPort">     
            <endpoint-address-uri>/AirlinePOService</endpoint-address-uri>
        </port-component>
    </webservice-description>

orion-ejb-jar.xml

The airlinesupplier-ejb module contains an MDB. The destination-location and connection-factory-location for the MDB needs to be specified in the orion-ejb-jar.xml. The following snippet provides an example how to specify these. A fully modified orion-ejb-jar.xml is packaged in the %HOW_TO_HOME%/descriptors/airlinesupplier directory.


<message-driven-deployment name="AirlineMessageEJB" destination-location="jms/airline/AirlineQueue" connection-factory-location="jms/airline/QueueConnectionFactory">
     <ejb-ref-mapping name="ejb/local/airlinesupplier/AirlineOrder" />          
     </service-ref-mapping>
</message-driven-deployment>

Changes in the Bank.ear

You have to package an orion-application.xml in the META-INF directory of the opc.ear that directs which Data Source to use for creating tables for CMP entity beans. The table creation script supplied in the Sample does not include the script to create the underlying table and the deployment process in OC4J creates the underlying tables. You can still have this functionality by changing default-data-source from jdbc/OracleDS to jdbc/adventure/AdventureDB  in the config/application.xml without having  to package the orion-application.xml.

 Following is the contents of orion-application.xml:

 

<?xml version="1.0"?>
<!DOCTYPE orion-application PUBLIC "-//ORACLE//DTD OC4J Application runtime 9.04//EN" "http://xmlns.oracle.com/ias/dtds/orion-application-9_04.dtd">

<orion-application deployment-version="10.0.3.0.0" default-data-source="jdbc/adventure/AdventureDB">

</orion-application>

bank-ejb.jar

You have to package the Oracle specific vendor deployment descriptors with the bank-ejb module e.g. META-INF/oracle-webservices.xml in the bank-ejb.jar for exposing the Stateless EJB Web service.

oracle-webservices.xml

The bank-ejb module exposes several Stateless EJBs as Web services. An Oracle specific vendor deployment descriptor is required to expose these Web services. The following code snippet provides an example how to specify this. A fully modified oracle-webservices.xml is packaged in the %HOW_TO_HOME%/descriptors/bank directory.

<?xml version="1.0" encoding="utf-8"?>
<oracle-webservices>
    <context-root>/bank-ejb</context-root>
    <webservice-description name="CreditCardService">
        <port-component name="CreditCardIntfPort">
           
            <endpoint-address-uri>/CreditCardIntfPort</endpoint-address-uri>
        </port-component>
    </webservice-description>

Changes in the LodgingSupplier.ear

You have to package an orion-application.xml in the META-INF directory of the opc.ear that directs the container to which Data Source to use for creating tables for CMP entity beans. The table creation script supplied in the Sample does not include the script to create the underlying table and the deployment process in OC4J creates the underlying tables. You can still have this functionality by changing default-data-source from jdbc/OracleDS to jdbc/adventure/AdventureDB  in the config/application.xml without having  to package the orion-application.xml.

 Following is the contents of orion-application.xml:

<?xml version="1.0"?>

<!DOCTYPE orion-application PUBLIC "-//ORACLE//DTD OC4J Application runtime 9.04//EN" "http://xmlns.oracle.com/ias/dtds/orion-application-9_04.dtd">

<orion-application deployment-version="10.0.3.0.0" default-data-source="jdbc/adventure/AdventureDB">

</orion-application>

lodgingsupplier-ejb.jar

You have to package the Oracle specific vendor deployment descriptors with the opc-ejb modules e.g. META-INF/oracle-webservices.xml in the lodgingsupplier-ejb.jar for exposing the Stateless EJB Web service, META-INF/orion-ejb-jar.xml to specify the Queue location and Queue Connection Factory used by MDBs.

oracle-webservices.xml

The lodgingsupplier-ejb module exposes one Stateless EJB as a Web service. An Oracle specific vendor deployment descriptor is required to expose this Web service. The following code snippet  provides an example how to specify these. A fully modified oracle-webservices.xml is packaged in the %HOW_TO_HOME%/descriptors/lodgingsupplier directory.


    <context-root>/lodgingsupplier</context-root>
    <webservice-description name="LodgingPurchaseOrderService">
       
        <port-component name="LodgingPOIntfPort">
          
            <endpoint-address-uri>/LodgingPOService</endpoint-address-uri>
        </port-component>
    </webservice-description>

orion-ejb-jar.xml

The lodgingsupplier module contains several MDBs. The destination-location and connection-factory-location for the MDBs needs to be specified in the orion-ejb-jar.xml. The following snippet provides an example how to specify these. A fully modified orion-ejb-jar.xml is packaged in the %HOW_TO_HOME%/descriptors/lodgingsupplier directory.


<message-driven-deployment name="LodgingMessageEJB" destination-location="jms/lodging/LodgingQueue" connection-factory-location="jms/lodging/QueueConnectionFactory">
   <ejb-ref-mapping name="ejb/local/lodgingsupplier/LodgingOrder" />      
</message-driven-deployment>

Changes in the ConsumerWebsite.ear

orion-web.xml

1) The EJBs refer to a DataSource jdbc/adventure/AdventureDB, however the web module refers to the same DataSource with a logical name jdbc/CatalogDB. Instead of creating a separate DataSource for Web module pointing to the same database you have add the Oracle specific deployment decriptor i.e. orion-web.xml with the following contents:

<resource-ref-mapping name="jdbc/CatalogDB" location="jdbc/adventure/AdventureDB" />

2) The Adventure Builder web application uses service-ref to include two web services exposed by the Order Processing Module. The physical address/location of these webservices need to be specified in the orion-web.xml. You need to make necessary changes according to your environment. Following is an exmaple services reference mapping in orion-web.xml:

<service-ref-mapping name="service/OpcPurchaseOrderService">
       
              <port-info>
                 <wsdl-port namespaceURI="urn:OpcPurchaseOrderService" localpart="PurchaseOrderIntfPort"/>
                   <stub-property>
                   <name>javax.xml.rpc.service.endpoint.address</name>
                   <value>http://localhost:8888/webservice/PoEndpointBean</value>
                </stub-property>                
              </port-info>
    </service-ref-mapping>

    <service-ref-mapping name="service/OpcOrderTrackingService">
              <port-info>
                 <wsdl-port namespaceURI="urn:OpcOrderTrackingService" localpart="OrderTrackingIntfPort"/>
                   <stub-property>
                        <!-- name corresponds to standard jaxrpc constant property names ..look at the link below-->
                   <name>javax.xml.rpc.service.endpoint.address</name>
                   <value>http://localhost:8888/webservice/OtEndpointBean</value>
                </stub-property>               
              </port-info>
    </service-ref-mapping>


A complete orion-web.xml has be supplied in the %HOW_TO_HOME%/descriptors/consumerwebsite directory.

Source Code Changes

As the application was being ported to run on OC4J, there were a few places where assumptions were made in code that were based on this application running on the Sun J2EE Reference Implementations. To address these portability issues, a couple of minor code changes are required in the ConsumerWebsite Web module  to make it fully portable. These changes have be communicated to the Java Blueprints team and will be addressed in the next release of Java Adventure Builder application.

1) TLD issue

The  waftags.tld in WEB-INF/ has  in the ConsumerWebsite been changed from a version JSP 1.1/DTD based TLD to a version JSP 2.0/XSD based version.  There are few issues in this file:

<shortname> is valid for 1.1 but for 2.0 it requires <short-name>
<description> tag (the one that says BluePrints Web Application Framework Tags) needs to be removed. The first description is valid, but the second one is not.
-  All occurrences of <tagclass> needs to be changed to <tag-class>

- Finally, the order is significant in schema, so the order  needs to be changed in the <tag> such that the <description> element comes first, before the <name>.

We have included a proper waftags.tld for in the %HOW_TO_HOME%/src/consumerwebsite directory that can be used for rebuilding the application.


2) consumerwebsite/waf/src/java/com/sun/j2ee/blueprints/taglibs/smart/OptionTag.java

This class was modified to make JSP 2.0 compliant.

public class OptionTag extends BodyTagSupport {
Old:    public int doAfterBody() throws JspTagException {
New:    public int doEndTag() throws JspTagException {
       …
        BodyContent bc = getBodyContent();
        String text = bc.getString();

The enter_oder_information.jsp has a number of tags that use this lib in the form of

<waf:option value="United States">United States</waf:option>

that work correctly.   However, it also has:

<waf:option value="Canada" />

When calling OptionTag’s doEndTag a null pointer exception is thrown on the above bc.getString() line because the bodyContent (bc) is null. The bodyContent is null because the tag does not have a body.

From the JSP 2.0 Spec: JSP.13.2.2 BodyTag

Properties

There is a new property: bodyContent, to contain the BodyContent object, where  the JSP Page implementation object will place the evaluation (and reevaluation, if appropriate) of the body. The setter method (setBodyContent) will only be  invoked if doStartTag() returns EVAL_BODY_BUFFERED and the corresponding action element does not have an empty body.

It can be fixed by: either

a) revert back to doAfterBody

or

b) add:

       if (bc == null ) {
           return SKIP_BODY;
       }

after getBodyContent(), line number 58.

We have supplied a modified OptionTag.java in the %HOW_TO_HOME%/src/consumerwebsite/ directory

3) Avoid ClassCastException in consumerwebsite/src/java/com/sun/j2ee/blueprints/consumerwebsite/actions/CartHTMLAction.java

The following code snippet in updateActivityHeadCounts() method in CartHTMLAction.java   is illegal and depends upon the specific feature on Tomcat and is not portable. This will result in ClassCastException in any other web container that does not rely on Tomcat.

HashMap params = (HashMap)request.getParameterMap();

The J2EE 1.4 API says --http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletRequest.html#getParameterMap)

public Map getParameterMap()

Returns a java.util.Map of the parameters of this request. Request parameters are extra information sent with the request. For HTTP servlets, parameters are contained in the query string or posted form data.

Returns:an immutable java.util.Map containing parameter names as keys and parameter values as map values. The keys in the parameter map are of type String. The values in the parameter map are of type String array.

The reason it works is that the actual object returned by Tomcat from this method call, org.apache.catalina.util.ParameterMap, extends the java.util.HashMap class.

The modified code should look like:

Map params = request.getParameterMap();

We have included the modified source code for CartHTMLAction.java in the %HOW_TO_HOME/src/consumersite directory.

Rebuilding the Applications with Oracle Specific Deployment Descriptors

If you want to rebuild the Adventure Builder application to use the Oracle specific deployment descriptors you will have to modify the application build scripts. We have supplied a working sample of the modified build scripts in the %HOW_TO_HOME%/scripts/build directory.

You will have to perform the following set up steps before you can re-build the applications in this way. After completing these steps follow the instructions outlined in the Java Adventure Builder Application 1.0 documentation.

Order Processing Center (OPC.ear)

1) Copy %HOW_TO_HOME%/descriptors/opc/orion-application.xml to %ADVENTURE_HOME%/src/apps/opc/src/conf.

2) Copy oracle-webservices.xml and orion-ejb-jar.xml in %HOW_TO_HOME%/descriptors/opc/ to %ADVENTURE_HOME%/src/opc/opc-ejb/src/conf.

3) Copy %HOW_TO_HOME%/scripts/build/opc/build.xml to %ADVENTURE_HOME%/src/apps/opc/.

Activity Supplier (ActivitySupplier.ear)

1) Copy %HOW_TO_HOME%/descriptors/activitysupplier/orion-application.xml to %ADVENTURE_HOME%/src/apps/activitysupplier/src/conf

2) Copy oracle-webservices.xml and orion-ejb-jar.xml in %HOW_TO_HOME%/descriptors/activitysupplier/ to %ADVENTURE_HOME%/src/apps/activitysupplier/activitysupplier-ejb/src/conf.

3)
Copy %HOW_TO_HOME%/scripts/build/activitysupplier/build.xml to %ADVENTURE_HOME%/src/apps/activitysupplier/.

Airline Supplier (AirlineSupplier.ear)

1) Copy %HOW_TO_HOME%/descriptors/airlinesupplier/orion-application.xml to %ADVENTURE_HOME%/src/apps/airlinesupplier/src/conf.

2)Copy oracle-webservices.xml and orion-ejb-jar.xml in %HOW_TO_HOME%/descriptors/airlinesupplier/ to %ADVENTURE_HOME%/src/apps/airlinesupplier/airlinesupplier-ejb/src/conf.


3)Copy %HOW_TO_HOME%/scripts/build/airlinesupplier/build.xml to %ADVENTURE_HOME%/src/apps/airlinesupplier/.

Bank/Credit Card Service (Bank.ear)

1) Copy %HOW_TO_HOME%/descriptors/bank/orion-application.xml to %ADVENTURE_HOME%/src/apps/bank/src/conf.

2) Copy oracle-webservices.xml in %HOW_TO_HOME%/descriptors/opc/ to %ADVENTURE_HOME%/src/apps/bank/bank-ejb/src/conf.

3) Copy %HOW_TO_HOME%/scripts/build/bank/build.xml to %ADVENTURE_HOME%/src/apps/bank/.

Lodging Supplier (Lodging Supplier.ear)

1) Copy %HOW_TO_HOME%/descriptors/lodgingsupplier/orion-application.xml to %ADVENTURE_HOME%/src/apps/lodgingsupplier/src/conf.

2) Copy oracle-webservices.xml and orion-ejb-jar.xml in %HOW_TO_HOME%/descriptors/lodgingsupplier/ to %ADVENTURE_HOME%/src/apps/lodgingsupplier/opc-lodgingsupplier/src/conf.

3) Copy %HOW_TO_HOME%/scripts/build/lodgingsupplier/build.xml to %ADVENTURE_HOME%/src/apps/lodgingsupplier/.

Adventure Web Module (ConsumerWebsite.ear)

1) Copy orion-web.xml in %HOW_TO_HOME%/descriptors/consumerwebsite/ to %ADVENTURE_HOME%/src/consumerwebsite/src/conf.


2) Copy %HOW_TO_HOME%/scripts/build/consumerwebsite/build.xml to %ADVENTURE_HOME%/src/apps/consumerwebsite/.

3) Copy %HOW_TO_HOME%/src/consumerwebsite/waftags.tld to %ADVENTURE_HOME%/src/waf/src/conf.

4) Copy %HOW_TO_HOME%/src/consumerwebsite/OptionTag.java to %ADVENTURE_HOME%/src/waf/src/java/com/sun/j2ee/blueprints/taglibs/smart.

5) Copy %HOW_TO_HOME%/src/consumerwebsite/CartHTMLAction.java to %ADVENTURE_HOME%/src/consumerwebsite/src/java/com/sun/j2ee/blueprints/consumerwebsite/actions/.

Summary

In this document you should have:

Deploying to OC4J

Following are the instructions to configure OC4J and deploy the Adventure Builder Application 1.0 into OC4J.