Corporate Info | News | Solutions | Products | Partners | Services | Events | Download | How To Buy
WebLogic Java Adapter for Mainframe Doc Home | Previous Topic | Next Topic | Contents | Index

Developing Java Applications

The BEA WebLogic Java Adapter for Mainframe (JAM) code generation tool, eGen COBOL, produces Java code from COBOL copybook source files. This generated Java code consists of both data mapping code and framework code for any application that will invoke the mainframe application through the gateway.

This section describes how the base Java application is generated, what role the COBOL copybook plays in the generation, and how to determine the type of application you want to generate.

This section discusses the following topics:

- Building the Base Java Application

- Obtaining the COBOL Copybook

- Generating the Java Application Source

- Using Client Diagnostic Features

Building the Base Java Application

The JAM code generation tool allows you to produce working Java code that functions within a Java Server execution model. The Java code produced is centered around typed data buffers.

In COBOL/CICS terms, a typed data buffer represents a group data item, or record, defined by a COBOL copybook that specifies the COMMAREA data area used by a CICS DPL program.

In Java terms, a typed data buffer is an object (instantiation) of a class type. The fields of the class correspond to the data fields within a record. Field values are retrieved and modified through the use of accessor functions (such as get and set functions).

Dataview Concepts

Typed data buffers are handled by the Java DataView class, which performs all necessary conversions and translations of the data fields within each record. The result is the ability to send and receive data buffers between Java clients and COBOL/CICS DPL programs. All underlying data conversions are performed transparently to each side of the application; the Java side of the application manipulates the data buffers as Java objects, and the COBOL/CICS side manipulates them as COMMAREA linkage section data items.

These Java files are then used by application programmers to write other Java source files that extend the classes defined in the generated source files. The user-defined classes typically add methods and variables that embody the business logic of the application.

The generated source files provide a simple framework centered around the typed data buffers (i.e., the COMMAREAs) of the CICS application. It is up to the Java application programmer to extend this framework of classes.

The heart of a JAM application is the sending and receiving of data records between the Java application system and the remote (mainframe) system. This data transfer is accomplished by employing a DataView that corresponds to a mainframe data record. On the mainframe side, the DataView represents the CICS COMMAREA data that is sent between DPL programs. On the Java side, the DataView represents a class object containing the COMMAREA data fields. The JAM application framework provides all of the data conversions necessary to send and receive data records between Java systems and the mainframe.

The following figure provides an illustration of how the underlying JAM generation tools work together.

Figure 4-1 Understanding the Underlying JAM Tools

The following figure provides an illustration of the JAM general application transport method.

Figure 4-2 JAM General Application Transport Method

Obtaining the COBOL Copybook

A mainframe COBOL/CICS, IMS, or mainframe application typically uses a copybook source file to define its COMMAREA. This file is specified in a COPY directive within the LINKAGE SECTION of the source program.

If the CICS application does not use a copybook file (but simply defines the COMMAREA directly in the program source), you will have to create one from the definition contained in the program source.

The JAM code generation tools support most of the COBOL data types and data clauses, however, some obsolete constructs along with floating point data types are not supported. Also, a few COBOL features are not supported. For unsupported constructs, you will have to determine if the copybook can be used without modification. In most cases, unsupported items are treated as alphanumeric data types or are simply ignored.

Each copybook's contents (which define a COMMAREA record) are parsed by the eGen COBOL application generator tool, producing DataView sub-classes that provide facilities to:

- Convert COBOL data types to and from Java data types. This includes conversions for mainframe data formats and code pages.

- Convert COBOL data structures to and from Java data structures.

- Provide tools that may be used to convert the provided data structures into other arbitrary formats.

Creating a New Copybook

If you are producing a new application on the mainframe or modifying one that did not previously support DPL, then one or more new copybooks are required. You should keep in mind the COBOL features and data types supported by JAM as you create these copybooks.

Using an Existing Copybook

When a mainframe application has an existing DPL interface, it most likely has the data for that interface described in a COBOL copybook. The first thing that must be done is to verify that no COBOL features or data types that JAM does not support are used in the interface. The easiest way to check a copybook is to attempt to process it.

An example COBOL copybook source file is shown in the following listing. It is assumed that the copybook is identical to the copybook used by the mainframe COBOL application programs.

Note: Some of the code sample listings in this topic have field names in bold for easier reading. Also, Comment-numbered items have corresponding comments at the bottom of each script example.

Listing 4-1 Sample emprec.cpy COBOL Copybook

>     1	*------------------------------------------------------
>     2	* emprec.cpy
>     3	*	An employee record.
>     4	*------------------------------------------------------
>     5
>     6	02	emp-record. (Comment 1)
>     7
>     8		04	emp-ssn			  pic 9(9)  comp-3.
>     9
>     10		04	emp-name.
>     11			06	emp-name-last		  pic x(15). (Comment 2)
>     12			06	emp-name-first	  pic x(15).
>     13			06	emp-name-mi		  pic x.
>     14
>     15		04	emp-addr. (Comment 3)
>     16			06	emp-addr-street	 pic x(30).
>     17			06	emp-addr-st		  pic x(2).
>     18			06	emp-addr-zip		  pic x(9).
>     19
>     20	* End

Script Comments

The following numbered comments refer to the numbered comments in the prior listing.

####

Table 4-1 Script Comments

Comment 1 | Declaration of a record (group) data item.
Comment 2 | An elementary item.
Comment 3 | An aggregate item.

The emprec.cpy copybook shown in the example declares a group item named emp-record. (This copybook is available in the examples/samples.jar file in JAM installation directory.

The JAM eGen Cobol utility parses a COBOL copybook and generates a Java class that encapsulates the data record declared in the copybook. It does this by parsing an eGen script file containing a DataView definition similar to the following example.

Listing 4-2 Sample emprec.egen Script

>     generate view Sample.EmployeeRecord from emprec.cpy

The prior example specifies that the COBOL copybook file named emprec.cpy is to be parsed, and that a Java source file named EmployeeRecord.java, containing the definition of class EmployeeRecord in package Sample, is to be generated from it.

Assuming this script was saved into a file named emprec.egen, the following shell command parses the copybook file named emprec.cpy and attempts to generate a Java source file named EmployeeRecord.java in the current directory:

Listing 4-3 Sample Copybook Parse Command

>     egencobol emprec.egen

If no error or warning messages are issued, the copybook is compatible with JAM and the source is created.

Note: You must establish both an execution path that includes the JAM distribution bin directory and a Java class path that refers to the JAM distribution jar file for this command to work properly. Refer to the "Error Messages" section of this document for suggestions on resolving other problems.

The following example illustrates the resulting generated Java source file, EmployeeRecord.java with unimportant comments and implementation details removed for clarity.

Listing 4-4 Generated EmployeeRecord.java Source File

>     //EmployeeRecord.java
>     //Dataview class generated by egencobol emprec.cpy

>     package Sample;(Comment 1)

>     //Imports

>     import bea.dmd.DataView.DataView;
>     ...

>     /**DataView class for EmployeeRecord buffers*/

>     public final class EmployeeRecord (Comment 2)
>     	extends DataView
>     {
>     	...

>     	// Code for field "emp-ssn"
>     	private BigDecimal			m_empSsn;(Comment 3)

>     	public BigDecimal getEmpSsn() {...}(Comment 4)

>     	/** DataView subclass for emp-name Group */
>     	public final class EmpNameV (Comment 5)
>     		extends DataView
>     	{
>     	    	 ...

>     	     	// Code for field "emp-name-last"
>     	     	private String  m_empNamelast;

>     	     	public void setEmpNameLast(String value) {...}
>     	     	public String getEmpNameLast() {...}(Comment 6)

>     		// Code for field "emp-name-first"
>     		private String  m_empNameFirsrt;

>     		public void setEmpnameFisrt (String value) {...}
>     		public String getEmpNameFirst() {...}

>     		// Code for field "emp-name-mi"
>     		private String  m_empNameMi;

>     		public void setEmpNameMi (String value) {...}
>     		public String getEmpnameMi() {...}
>     	}

>     	// Code for field "emp-name"
>     	private EmpNameV  m_empname; (Comment 7)

>     	public EmpnameV getEmpname() {...}

>     	/**DataView subclass for emp-addr Group */
>     	public final class EmpAddrV
>     		extends DataView
>     	{
>     		...

>     		// Code for field "emp-addr-street"
>     		private String  m_empAddrStreet;

>     		public void setEmpAddrStreet(Street value) {...}
>     		public String getEmpAddrStreet() {...}

>     		// Code for field "emp-addr-st"
>     		private String  m_empAddrSt;

>     		public void setEmpAddrSt(String value) {...}
>     		public String getEmpAddrSt() {...}

>     		// Code for field "emp-addr-zip"
>     		private String  m_empAddrZip;

>     		public void setEmpAddrZip(String value) {...}
>     		public String getEmpAddrZip() {...}
>     	}

>     	// Code for field "emp-addr"
>     	private EmpAddrV  m_empAddr;

>     	public EmpAddrV getEmpAddr() {...}
>     }

>     //End EmployeeRecord.java

Script Comments

The following numbered comments refer to the numbered comments in the prior listing.

####

Table 4-2 Script Comments

Comment 1 | The package name is defined in the eGen script.
Comment 2 | The data record is encapsulated in a class that extends the DataView class.
Comment 3 | Each class member variable corresponds to a field in the data record.
Comment 4 | Each data field has accessor functions.
Comment 5 | Each aggregate data field has a corresponding nested inner class that extends the DataView class.
Comment 6 | Each data field within an aggregate data field has accessor functions.
Comment 7 | Each COBOL data field name is converted into a Java identifier.

Additional options may be specified in the eGen script to change details of the DataView generation. For example, the following script will generate a dataview class that uses codepage cp500 for conversions to and from mainframe format. If the codepage clause is not specified the default codepage of cp037 is used.

>     generate view Sample.EmployeeRecord from emprec.cpy codepage cp500

The following script will generate additional output intended to support use of the dataview class with XML data.

>     generate view Sample.EmployeeRecord from emprec.cpy support xml

Additional files are listed in Table 4-3.

Table 4-3 Additional Files for DataView XML Support.

####

File Name | File Purpose
--- | ---
classname.dtd | XML DTD for XML messages accepted and produced from this dataview.
classname.xsd | XML schema for XML messages accepted and produced from this dataview.
classnameHelper.java | Source code for XML helper class. This class may be used when communicating with JAM from WebLogic Process Integrator. This class will reside in the same package as the dataview class.

Generating the Java Application Source

In addition to the COBOL copybook requirement, you must also determine which of the following application models you want to generate.

- Generating a Servlet-Only JAM Application

- Generating a Client Enterprise Java Bean-Based Application

- Generating a Server Enterprise Java Bean-Based Application

- Generating a Stand-Alone Client Application

The one you choose depends on the type of application you are building.

For all of the following applications you can generate, you must provide a script file containing definitions for the application, including the COBOL copybook file name, the DataView class names, and so forth.

Generating a Servlet-Only JAM Application

This type of application produces a Java servlet application that executes within a Java server environment (such as WebLogic Server). It is started from a web browser when the user enters a URL that is configured to invoke the servlet. The servlet presents an HTML form containing data fields and buttons. The buttons can be configured to invoke:

- EJB methods

- Remote gateway services (via the JCRMGW)

In general, servlets generated by eGen COBOL are intended for testing purposes and are not easily customized to provide a more aesthetically pleasing interface.

Generating a Servlet-only JAM application consists of the following steps;

1. Creating a script.

2. Processing a script.

3. Working with the generated files.

4. Customizing the application.

The following topics discuss these steps and offer examples of each.

Creating a Script

In order to produce a servlet-only application, the script file that describes your DataViews must be enhanced to describe the mainframe services accessed, the browser pages produced, and the servlets that produce them. Service definitions look like the following listing.

Listing 4-5 Sample Service Definition

>     service getSalary
>     	accepts EmployeeRecord
>     	returns EmployeeRecord

This listing defines a service named getSalary that accepts an input buffer of type EmployeeRecord and returns an output buffer of type EmployeeRecord. It is this service name which also requires an entry in the jcrmgw.cfg file.

A browser page that uses this service might be defined as the following.

Listing 4-6 Sample Page Definition

>     page EmployeeQuery "Employee Salary Query"
>     {
>     	view EmployeeRecord

>     	buttons
>     	{
>     		Query service (getSalary)
>     			shows EmployeeQuery
>     	}
>     }

This listing defines an HTML page named EmployeeQuery, with a text title of "Employee Salary Query", that displays an EmployeeRecord record object as an HTML form. It also specifies that the form has a button labeled "Query." When the button is pressed, the service getSalary is invoked and is passed the contents of the browser page as an EmployeeRecord object (the fields of which may have been modified by the user). Afterwards, the EmployeeQuery page is used to display the results.

The servlet that serves this page might be defined like the following listing.

Listing 4-7 Sample servlet Definition

>     servlet EmployeeQueryServlet shows EmployeeQuery

This listing defines an application servlet class named EmployeeQueryServlet, and specifies that it displays the HTML page named EmployeeQuery as its initial display page.

The following listing shows a complete script for defining a servlet application.

Listing 4-8 Sample Servlet-Only Script

>     1  #---------------------------------------------------------
>     2  # empservlet.egen
>     3  #	JAM script for a servlet-only application.
>     4  #
>     5  #  $Id: empservlet.egen,v 1.2 2000/01/25  18:34:14 david Exp$
>     6  #--------------------------------------------------------------
>     7
>     8  # DataViews (typed data records)
>     9
>     10  view sample.EmployeeRecord (Comment 1)
>     11	from emprec.cpy support xml
>     12
>     13  # Services
>     14
>     15  service sampleCreate (Comment 2)
>     16	accepts EmployeeRecord
>     17	returns EmployeeRecord
>     18
>     19  service sampleRead (Comment 2)
>     20	accepts EmployeeRecord
>     21	returns EmployeeRecord
>     22
>     23  service sampleUpdate (Comment 2)
>     24	accepts EmployeeRecord
>     25	returns EmployeeRecord
>     26
>     27  service sampleDelete (Comment 2)
>     28	accepts EmployeeRecord
>     29	returns EmployeeRecord
>     30
>     31  # Servlet HTML pages
>     32
>     33  page initial "Initial page" (Comment 3)
>     34  {
>     35	view EmployeeRecord (Comment 4)
>     36
>     37	buttons
>     38	{
>     39		"Create" (Comment 5)
>     40			service ("sampleCreate")
>     41			shows fullPage
>     42
>     43		"Read" (Comment 5)
>     44			service ("sampleRead")
>     45			shows fullPage
>     46	}
>     47  }
>     48
>     49  page fullPage "Complete page"
>     50  {
>     51	view EmployeeRecord
>     52
>     53	buttons
>     54	{
>     55		"Create"
>     56			service ("sampleCreate")
>     57			shows fullPage
>     58
>     59		"Read"
>     60			service ("sampleread")
>     61			shows fullpage
>     62
>     63		"Update"
>     64			service ("sampleDelete")
>     65			shows fullpage
>     66
>     67		"Delete"
>     68			service ("sampleDelete")
>     69			shows fullpage
>     70	}
>     71  }
>     72
>     73  # Servlets
>     74
>     75  servlet sample.SampleServlet (Comment 6)
>     76	shows initial
>     77
>     78  # End

Script Comments

The following numbered comments refer to the numbered comments in the prior listing.

####

Table 4-4 Script Comments

Comment 1 | Defines a DataView class, specifying its corresponding copybook source file and its package file.
Comment 2 | Defines a service function and its input and output parameter types.
Comment 3 | Defines an HTML page to be displayed by the servlet.
Comment 4 | Specifies the DataView class to display on the page.
Comment 5 | Defines a button and its associated class method.
Comment 6 | Defines a servlet class and its initial HTML display page.

Processing a Script

To process the script, issue the command in Listing 4-9. The egencobol command involves the JVM and is equivalent to java com.bea.jam.egen.EgenCobol empservlet.egen.

Listing 4-9 Sample Script Process Command

>     egencobol empservlet.egen
>     emprec.cpy, Lines: 21 Errors: 0, Warnings:0
>     Generating sample.EmployeeRecord...
>     Generating group emp-name
>     Generating group emp-addr
>     Generating sample.SampleServlet...

Generated Files

This script command generates the following files.

####

Table 4-5 Sample Script Generated Files

Files | Content
--- | ---
>     SampleServlet.java
| Servlet source code
>     EmployeeRecord.java
| Source for the DataView object
>     EmployeeRecord.dtd
| Generated DTD
>     EmployeeRecord.xsd
| Generated XML/Schema
>     EmployeeRecordHelper.java
| Helper class source code

SampleServlet.java Source File

The following listing illustrates the contents of the generated SampleServlet.java source file (with some parts omitted).

Listing 4-10 Sample SampleServlet.java Contents

>     //  SampleServlet.java
>     //
>     //  Servlet class generated by eGencobol on 25-Jan-2000.

>     package Sample;

>     //  Imports

>     import javax.servlet.http.HttpServlet;
>     import weblogic.html.ServletPage;
>     import com.bea.dmd.DataView.DataView;
>     import com.bea.jam.egen.EgenServlet;
>     ...

>     /** servlet class for EmployeeRecord buffers. */

>     public class SampleServlet
>     	extends EgenServlet
>     {
>     	/** Create a new servlet. */
>     	public SampleServlet()
>     	{
>     	   ...
>     	}

>     	/** Get an instance of the initial DataView for this
>     	Servlet.*/
>     	protected DataView initialDataView()
>     	{
>     	   ...
>     	}

>     	...
>     }

>     //End SampleServlet.java

Customizing a Servlet-Only JAM Application

The generated Java classes produced for servlet applications are intended for proof of concept and prototypes, and can be customized in limited ways. It is presumed that some other development tool will be used to develop a servlet or other user interface on top of the generated EJBs or client classes.

This section describes the way that generated servlet code can be customized.

The following figure illustrates the relationships and inheritance hierarchy between the JAM classes comprising the application.

Figure 4-3 The JAM Servlet Class Hierarchy

The generated Java code for a servlet application Sample Servlet is a class that inherits class EgenServlet. Class EgenServlet is provided in the JAM distribution jar file.

The base class illustrated in the following listing provides the basic framework for a servlet.

Listing 4-11 EgenServlet.java Base Class

>     //==========================================================
>     // EgenServlet.java
>     //	The base class for generated servlets.
>     //===============================================================

>     package bea.jam.egen;

>     //Imports

>     ...

>     /****************************************************************
>     * The base class for generated servlets
>     */

>     abstract public class EgenServlet
>     	extends HttpServlet
>     {
>        /** Perform an HTTP Get operation. */
>        public void doGet(HttpServletRequest req,HttpServletResponse
>        resp)
>         throws ServletException, IOException
>        {
>         DataView dv;
>         HttpSession session=reqgetSession(true);

>         ...

>         // Get the initial DataView data record
>         dv = initialDataView();

>         // Invoke the user-defined callback
>         dv = doGetSetup(dv,session);

>         // Convert the DataView into an HTML form
>         ...
>        }

>        /** Perform a HTTP Post operation. */
>        public void doPost(HttpServletRequest req,HttpServletResponse
>        resp)
>         throws ServletException, IOException
>        {
>          DataView dv;
>          HttpSession session=reqgetSession(true);

>         // Move the HTML form data into a DataView
>         ...

>         // Invoke the user-defined callback
>         dv = doPostSetup(dv, session);

>         // Execute the form button
>         ...

>         //Invoke the user-defined callback
>         dv = doPostFinal(dv, session);

>         // Convert the DataView into an HTML form
>         ...
>        }

>        /** User exit for pre-presentation processing for a GET request.
>        */
>        public DataView doGetSetup (DataView in, HttpSession session)
>        {
>         // Default behavior may be overridden
>         return in;
>        }

>        /**User exit for before business logic processing for a POST
>        request. */
>        public DataView doPostSetup (DataView in, HttpSession session)
>        {
>          // Default behavior, may be overridden
>         return in;
>        }

>        /** User exit for after business logic processing for a POST
>         request. */
>        public DataView doPostFinal (DataView in, HttpSession session)
>        {
>         // Default behavior, may be overridden
>         return in;
>        }

>        /** Get an instance of the initial DataView for this servlet. */
>        protected abstract DataView initialDataView();

>        /**
>          * The title for the initial page.
>          * This should be initialized in the subclass constructor.
>          */
>          protected String  m_initialTitle;

>        /**
>          * The buttons for the initial page.
>          * This should be initialized in the subclass constructor.
>          */
>         protected Button[] m_initialButtons;
>      }

>     // End EgenServlet.java

The EgenServlet base class provides functions for the GET and POST operations for the servlet's HTML page.

Both of these operations invoke the following default callback functions:

- doGetSetup() - invoked before the GET operation.

  This function occurs prior to the presentation of the HTML page to the user's browser. Any changes made to the DataView object will be reflected in the contents of the HTML page.

- doPostSetup() - invoked before the POST operation.

  This function occurs after the HTML page is presented and the user activates a form button. The DataView is sent to the doPostSetup() function, which operates on its contents. For example, validating the contents of the fields.

- doPostFinal() - invoked after the POST operation.

  This function occurs prior to the presentation of the HTML page to the user's browser after activating a form button. Any changes made to the DataView object will be reflected in the contents of the HTML page.

Your class (ExtSampleServlet.java), which indirectly extends the EgenServlet base class, overrides these functions and provides additional business logic to modify the contents of the DataView. Each of these functions is passed to the DataView object containing the current record data. Each is expected to return a (potentially modified) DataView object.

Note: The overriding functions must have exactly the same signature as the functions in the base class.

The following illustration shows the sequence of operations that occur during the course of a user's browser session. For example, the series of events that occur within the EgenServlet class.

Figure 4-4 User Browser-Session Flowchart

Example ExtSampleServlet.java Class

The following listing shows an sample ExtSampleServlet class that extends the generated SampleServlet class, and adds a validation function (isSsnValid()) for the emp-ssn (m_empSsn) field of the DataView EmployeeRecord class. The three callback functions are overridden by the functions in the extended class. If the emp-ssn field is determined to be invalid, an exception is thrown.

Exceptions are caught by the Java server (BEA WebLogic Server) and cause a simple informational text page to be presented to the user's browser. Any string text associated with the exception is displayed along with an execution stack trace that was in effect at the time that the exception was thrown.

Listing 4-12 Sample ExtSampleServlet.java Contents

>     //==========================================================
>     // ExtSampleServlet.java
>     // Example class that extends a generated JAM servlet application.
>     //===============================================================

>     package Sample;

>     // System imports

>     import java.math.BigDecimal;

>     import javax.servlet.http.HttpSession;
>     import com.bea.dmd.DataView.DataView;
>     import com.bea.jam.egen.EgenServlet;

>     // Local Imports

>     import sample.EmployeeRecord;
>     import sample.SampleServlet;

>     /***************************************************************
>     */ Extends the SampleServlet class, adding additional business logic

>     */

>     public class ExtSampleServlet
>     	extends SampleServlet
>     {
>     // Public functions

>     	/********************************************************
>     	* User exit for pre-presentation processing for a GET

>     	* request. This is called prior to the presentation of the
>     	* first HTML page to the user's browser.
>     	*/

>     	public DataView doGetSetup (DataView in, HttpSession session)
>     	{
>     	  EmployeeRecord erec;

>     	  // Overrides the default behavior

>     	  // Load default data into the empty DataView
>     	  erec = (EmployeeRecord) in;
>     	  erec.getEmprecord().setEmpSsn(BigDecimal.valueOf(99999));

>     	  return (erec);
>     	}

>     	/********************************************************
>     	* User exit for before business logic processing for a POST
>     	* request. This is called after the user activates a button
>     	* on the HTMl form, but before the action associated with the
>     	* button is performed.
>     	*/

>             public DataView doPostSetup (DataView in, HttpSession session)
>     	{
>     	  EmployeeRecord erec;

>     	  // Overrides the default behavior

>     	  // validate the Social Security Number field
>     	  erec = (Employeerecord) in;

>     	  if (!isSsnValid(erec.getEmpRecord().getEmpSsn()))
>     	  {
>     		// The SSN is not valid
>     		throw new Error ("Invalid Social Security Number:"
>     			= erec.getEmprecord().getEmpSsn());
>     	  }

>     	  return (erec);
>     	}

>     	/*********************************************************
>     	* User exit for after business logic processing for a POST
>     	* request. This is called after the action is performed for
>     	* the button on the HTML form is activated by the user.
>     	*/

>     	public DataView doPostFinal(DataView in HttpSession session)
>     	}
>     		// Overrides the default behavior

>     		// Nothing to do here

>     		return (in);
>     	}

>      // Private functions

>     	/********************************************************
>     	* Validates an SSN field.
>     	*
>     	* @return
>     	* True if the SSN is valid, otherwise false.
>     	*/

>     	private boolean isSsnValid(final BigDecimal ssn)
>     	{
>     		if (ssn.longValue() < 100000000)
>     		{
>     			// Oops, the SSN should not have a leading zero
>     			return (false);
>     		}
>     		else
>     			return (true);
>     	}
>      }

>      //End ExtSampleServlet.java

Once the ExtSampleServlet class has been written, it and the other servlet Java source files must be compiled and deployed in the same manner as other servlets.

Generating a Client Enterprise Java Bean-Based Application

This type of application produces Java classes that comprise an EJB application. The class methods are invoked from requests originating from other EJB classes and transfer data records to and from the mainframe (remote system). From the viewpoint of the mainframe, the Java classes act as a remote DTP or IMS client. From the viewpoint of the EJB classes, they act as regular EJB classes.

Generating a Client Enterprise Java Bean-based application consists of the following steps:

1. Creating a script.

2. Processing the script.

3. Working with the generated files.

4. Customizing the application.

5. Compiling and deploying.

The following topics discuss these steps and offer examples of each.

Creating a Script

In order to produce an EJB-based application, the script file that defines your DataViews must be enhanced to describe both the mainframe services accessed and the EJB that will access them. A service description might look like the following listing example.

Listing 4-13 Sample service Description

>     service getSalary

>     	accepts EmployeeRecord
>     	returns EmployeeRecord

This sample listing defines a service named getSalary that accepts an input buffer of type EmployeeRecord and returns an output buffer of type EmpDataView. It is this service name which also requires an entry in the jcrmgw.cfg file.

An EJB that uses this service might be defined like the following listing.

Listing 4-14 Sample getSalary Service Definition

>     client ejb MyEJBName MyEJBHome
>     {
>     	method getPay is service getSalary
>     }

This listing defines a Java bean class named MyEJBName with a method named getPay. The method corresponds to service name getSalary. The EJB home will be registered in Java Naming and Directory Interface (JNDI) under the name MyEJBHome.

The following listing shows the contents of a complete script file for defining a client EJB application.

Listing 4-15 Sample Client EJB Script

>     1  #---------------------------------------------------------
>     2  # empclient.egen
>     3  #	JAM script for an employee record.
>     4  #
>     5  #  $Id: empclient.egen,v 1.1 2000/01/25  18:34:14 david Exp$
>     6  #--------------------------------------------------------------
>     7
>     8  # DataViews (typed data records)
>     9
>     10  view sample.EmployeeRecord (Comment 1)
>     11	from emprec.cpy
>     12
>     13  # Services
>     14
>     15  service sampleCreate (Comment 2)
>     16	accepts EmployeeRecord
>     17	returns EmployeeRecord
>     18
>     19  service sampleRead (Comment 2)
>     20	accepts EmployeeRecord
>     21	returns EmployeeRecord
>     22
>     23  # Clients and servers
>     24
>     25  client ejb sample.SampleClient my.sampleBean (Comment 3)
>     26  {
>     27	method newEmployee (Comment 4)
>     28		is service sampleCreate
>     29
>     30	method readEmployee (Comment 4)
>     31		is service sampleRead
>     32  }
>     33
>     34  # End

Script Comments

The following numbered comments refer to the numbered comments in the prior listing.

####

Table 4-6 Script Comments

Comment 1 | Defines a DataView class, specifying its corresponding copybook source file and its package name.
Comment 2 | Defines a service function and its input and output parameter types.
Comment 3 | Defines a client EJB class and its home name.
Comment 4 | Defines a client class method and its service name.

Processing the Script

Issuing the following command will process the script.

Listing 4-16 Sample Script Process Command

>     egencobol empclient.egen
>     emprec.cpy, Lines: 21, Errors: 0, Warnings: 0
>     Generating sample.EmployeeRecord...
>     Generating group emp-name
>     Generating group emp-addr
>     Generating SampleClient...

Working with Generated Files

This script command generates the following files.

####

Table 4-7 Sample Script Generated Files

File | Content
>     SampleClient.java
| Source for the EJB remote interface.
>     SampleClientBean.java
| Source for the EJB implementation.
>     SampleClientHome.java
| Source for the EJB home interface.
>     EmployeeRecord.java
| Source for the DataView object.
>     SampleCient-jar.xml
| Sample deployment descriptor
>     wl-SampleClient-jar.xml
| Sample WebLogic deployment information

SampleClient.java Source File

The following listing shows the contents of the generated SampleClient.java source file.

Listing 4-17 Sample SampleClient.java Contents

>     // SampleClient.java
>     //
>     // EJB Remote Interface generated by eGenCobol on 24-Jan-2000.

>     package sample;

>     // Imports

>     import javax.ejb.EJBObject;
>     ...

>     /** Remote Interface for SampleClient EJB. */

>     public interface SampleClient (Comment 1)
>     	extends EJBObject
>     {
>     	// newEmployee (Comment 2)
>     	EmployeeRecord newEmployee (EmployeeRecord commarea)
>     		throws RemoteException, UnexpectedException;

>     	readEmployee (Comment 2)
>     	EmployeeRecord readEmployee (EmploymentRecord commarea)
>     		throws RemoteException, UnexpectedException;
>     }

>     // End SampleClient.java

Script Comments

The following numbered comments refer to the numbered comments in the prior listing.

####

Table 4-8 Script Comments

Comment 1 | Defines an EJB interface.
Comment 2 | Methods to convert a raw COMMAREA into a Java DataView object.

SampleClientBean.java Source File

The following listing shows the contents of the generated SampleClientBean.java source file.

Listing 4-18 Sample SampleClientBean.java Contents

>     // SampleClientBean.java
>     //
>     // EJB generated by eGenCobol on 24-Jan-2000.

>     package sample;

>     //Imports

>     import com.bea.jam.egen.egenClientBean;
>     ...

>     /** EJB implementation. */

>     public class SampleClientBean (Comment 1)
>     	extends egenClientBean
>     {
>     	// newEmployee

>     	public EmployeeRecord newEmployee (EmployeeRecord commarea)
>     		throws IOException, snaException (Comment 2)
>     	{
>     		...
>     	}

>     	//readEmployee

>     	public EmployeeRecord readEmployee (EmployeeRecord commarea)
>     		throws IOException, snaException (Comment 2)
>     	{
>     		...
>     	}

>     }

>     // End SampleClientBean.java

Script Comments

The following numbered comments refer to the numbered comments in the prior listing.

####

Table 4-9 Script Comments

Comment 1 | Defines an EJB client bean.
Comment 2 | The methods convert a raw COMMAREA into a Java DataView object.

SampleClientHome.java Source File

The following listing shows the contents of the generated SampleClientHome.java source file.

Listing 4-19 Sample SampleClientHome.java Contents

>     // SampleClientHome.java
>     //
>     // EJB Home interface generated by eGenCobol on 24-Jan-2000.

>     package sample;

>     // Imports

>     import javax.ejb.EJBHome;
>     ...

>     /** Home interface for SampleClient EJB. */

>     public interface SampleClientHome (Comment 1)
>     	extends EJBHome
>     {
>     	// create

>     	SampleClient create()
>     		throws CreateException, remoteException;
>     }

>     // End SampleClientHome.java

Script Comments

The following numbered comments refer to the numbered comments in the prior listing.

####

Table 4-10 Script Comments

Comment 1 | Defines an EJB home interface.

SampleClient-jar.xml Source File

The following listing shows the contents of the SampleClient-jar.xml source file. To use this file, copy it to ejb.jar.xml.

Listing 4-20 Sample SampleClient-jar.xml Contents

>     <?xml version="1.0"?>
>     <!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>
>         <enterprise-beans>
>           <session>
>             <ejb-name>SampleClient</ejb-name>
>             <home>sample.SampleClientHome</home>
>             <remote>sample.SampleClient</remote>
>             <ejb-class>sample.SampleClientBean</ejb-class>
>             <session-type>Stateless</session-type>
>             <transaction-type>Container</transaction-type>
>           </session>
>         </enterprise-beans>
>         <assembly-descriptor>
>           <container-transaction>
>             <method>
>               <ejb-name>SampleClient</ejb-name>
>               <method-intf>Remote</method-intf>
>               <method-name>*</method-name>
>             </method>
>             <trans-attribute>NotSupported</trans-attribute>
>           </container-transaction>
>         </assembly-descriptor>
>     </ejb-jar>

wl-SampleClient-jar.xml Source File

The following listing shows the contents of the wl-SampleClient-jar.xml source file. To use this file, copy it to weblogic-ejb-jar.xml.

Listing 4-21 Sample wl-SampleClient-jar.xml Contents

>     <?xml version="1.0"?>
>     <!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN' 'http://www.bea.com/servers/wls510/dtd/weblogic-ejb-jar.dtd'>
>     <weblogic-ejb-jar>
>         <weblogic-enterprise-bean>
>           <ejb-name>SampleClient</ejb-name>
>           <caching-descriptor>
>              <max-beans-in-free-pool>50</max-beans-in-free-pool>
>           </caching-descriptor>
>           <jndi-name>my.sampleBean</jndi-name>
>         </weblogic-enterprise-bean>
>     </weblogic-ejb-jar>

Customizing an Enterprise Java Bean-Based Application

Unlike the servlet applications, the generated Java classes produced for EJB applications are intended for customization.

This section describes the way that generated client EJB code can be customized.

The following figure illustrates the relationships and inheritance hierarchy between the JAM classes comprising the application.

Figure 4-5 The JAM Client EJB Class Hierarchy

The generated Java code for a client EJB application is a class that inherits class egenClientBean. The egenClientBean class is provided in the JAM distribution jar file.

This base class, illustrated in the following listing, is provided in the jam.jar file and provides the basic framework for an EJB. It provides the required methods for a Stateless Session EJB.

Listing 4-22 egenClientBean.java Base Class

>     //=========================================================
>     // egenClientBean.java
>     //   The base class for generated client EJB's.
>     //
>     //---------------------------------------------------------------

>     package com.bea.jam.egen;

>     abstract public class egenClientBean
>     	implements SessionBean
>     {
>     	//Implementation of ejbActivate(), ejbRemove(),
>     	// ejbPassiveate(), ejbCreate() and setSessionContext()
>     	...

>     	/**
>     	 * Call a service by name through the jcrmgw.
>     	 *
>     	 * @exception bea.sna.jcrmgw.snaException For Gateway errors
>     	 * @exception java.io.IOException For data translation
>     	   errors.
>     	 */
>     	protected byte[] callService(String service, byte[] in)
>     	 throws snaException, IOException
>     	}
>     	  // Low level gateway access code
>     	      ...
>     	}

>     	// Variables

>     	  protected SessionContext m_context;
>     	  protected transient Properties        m_properties;
>     }

>     // End egenClientBean.java

The generated class, illustrated in the following Listing, adds the methods specific to this EJB.

Listing 4-23 Generated SampleClientBean.java Class

>     // SampleClientBean.java
>     //
>     // EJB generated by eGenCobol on Feb 2, 2000.
>     //

>     package Sample;

>     ...

>     /**
>      * EJB implementation.
>      */
>     public class SampleClientBean extends egenClientBean
>     {
>     	// readEmployee
>     	//
>     	public EmployeeRecord readEmployee (EmployeeRecord commarea)
>     	  throws IOException, snaException
>     	{
>     		// Make the remote call.
>     		//
>     		...
>     	}

>     	// newEmployee
>     	//
>     	public EmployeeRecord newEmployee (EmployeeRecord commarea)
>     	  throws IOException, snaException
>     	{
>     	  // Make the remote call.
>     	  //
>     	  ...
>     	}
>     }

>     // END SampleClientBean.java

The following listing illustrates an example ExtSampleClientBean class that extends the generated SampleClientBean class, adding a validation function (isSsnValid()) for the emp-ssn (m_empSsn) field of the DataView EmployeeRecord class. The four methods are overridden by the methods in the extended class. If the emp-ssn field is determined to be invalid, an exception is thrown. Otherwise, the original function is called to perform the mainframe operation.

Listing 4-24 Example ExtSampleClientBean.java Class

>     //============================================================================
>     // ExtSampleClientBean.java
>     //      Example class that extends a generated JAM client EJB application.
>     //----------------------------------------------------------------------------

>     package sample;

>     // Imports

>     import java.math.BigDecimal;
>     import java.io.IOException;

>     import com.bea.sna.jcrmgw.snaException;

>     // Local imports

>     import sample.EmployeeRecord;
>     import sample.SampleClientBean;

>     /*****************************************************************************
>     * Extends the SampleClientBean EJB class, adding additional business logic.
>     */

>     public class ExtSampleClientBean
>         extends SampleClientBean
>     {
>     // Public functions

>         /*************************************************************************
>         * Read an employee record.
>         */

>         public EmployeeRecord readEmployee(EmployeeRecord commarea)
>             throws RemoteException, UnexpectedException, IOException, snaException
>         {
>             EmployeeRecord  erec = (EmployeeRecord) commarea;

>             if (!isSsnValid(erec.getEmpRecord().getEmpSsn()))
>             {
>                 // The SSN is not valid.
>                 throw new Error("Invalid Social Security Number: "
>                     + erec.getEmpRecord().getEmpSsn());
>             }

>             // Make the remote call.
>             return super.readEmployee(commarea);
>         }

>         /*************************************************************************

>         * Create a new employee record.
>         */

>         public EmployeeRecord newEmployee(EmployeeRecord commarea)
>             throws IOException, snaException
>         {
>             EmployeeRecord  erec = (EmployeeRecord) commarea;

>             if (!isSsnValid(erec.getEmpRecord().getEmpSsn()))
>             {
>                 // The SSN is not valid.
>                 throw new Error("Invalid Social Security Number:"
>                     + erec.getEmpRecord().getEmpSsn());
>             }

>             // Make the remote call.
>             return super.newEmployee(commarea);
>         }

>     // Private Functions

>         /*************************************************************************
>         * Validate an SSN field.
>         *
>         * @return
>         * True if the SSN is valid, otherwise false.
>         */

>         private boolean isSsnValid(final BigDecimal ssn)
>         {
>             if (ssn.longValue() < 100000000)
>             {
>                 // Oops, appears to be less than 9 digits
>                 return false;
>             }
>             return true;
>         }
>     }

>     // End ExtSampleClientBean.java

When the ExtSampleClientBean class has been written, it and the other EJB Java source files must be compiled and deployed in the same manner as other EJBs. Prior to deploying, the deployment descriptor must be modified; the ejb-class property must be set to the name of your extended EJB implementation class.

Compiling and Deploying

Refer to the BEA WebLogic server documentation for more information. The sample file provided with the WebLogic Server contain build script for reference.

Generating a Server Enterprise Java Bean-Based Application

This type of application produces Java classes that comprise an EJB application, similar to a Client EJB application, but acting as a remote server from the viewpoint of the mainframe. The classes process service requests originating from the mainframe (remote) system, known as "inbound" requests, and transfer data records to and from the mainframe. From the viewpoint of the Java classes, they receive EJB method requests. From the viewpoint of the mainframe application, it invokes remote DPL or IMS programs.

Generating a Server Enterprise Java Bean-based application consists of the following steps:

1. Creating a script.

2. Processing the script.

3. Working with the generated files.

4. Customizing the application.

5. Compiling and deploying.

The following topics discuss these steps and offer examples of each.

Creating a Script

The following listing shows the contents of a complete script for defining a server EJB application.

Listing 4-25 Sample Server EJB Script

>     1  #--------------------------------------------------------
>     2  # empserver.egen
>     3  #	JAM script for an employee record.
>     4  #
>     5  # $Id: empserver.egen, v 1.1 2000/01/21 23:20:40
>     6  #-------------------------------------------------------------
>     7
>     8  # DataViews (typed data records)
>     9
>     10  view sample.EmployeeRecord (Comment 1)
>     11 	from emprec.cpy
>     12
>     13  # Clients and servers (Comment 2)
>     14
>     15  server ejb sample.SampleServer my.sampleServer (Comment 3)
>     16  {
>     17	method newEmployee (EmployeeRecord)(Comment 4)
>     18		returns EmployeeRecord
>     19  }
>     20
>     21  # End

Script Comments

The following numbered comments refer to the numbered comments in the prior listing.

####

Table 4-11

Comment 1 | Defines a DataView class, specifying its corresponding copybook source file and its package name.
Comment 2 | Defines a server EJB class.
Comment 3 | my.sampleServer is the home interface identifier for this bean. This value must be included in an entry in the local Services section of the jcrmgw.cfg file for the Java gateway.
Comment 4 | Defines a server class method and its parameter.

Processing the Script

Issuing the following command will process the script.

Listing 4-26 Sample Script Process Command

>     egencobol empserver.egen
>     emprec.cpy, Lines: 21, Errors: 0, Warnings: 0
>     Generating sample.EmployeeRecord...
>     Generating group emp-name
>     Generating group emp-addr
>     Generating SampleServer...

Generated Files

This script command generates the following files.

####

Table 4-12 Sample Script Generated Files

File | Content
--- | ---
>     SampleServer.java
| Source for the EJB remote interface.
>     SampleServerBean.java
| Source for the EJB implementation.
>     SampleServerHome.java
| Source for the EJB home interface.
>     EmployeeRecord.java
| Source for the DataView object.
>     SampleServer-jar.xml
| Sample deployment descriptor
>     wl-SampleServer-jar.xml
| Sample WebLogic deployment information

SampleServer.java Source File

The following listing shows the content of the generated SampleServer.java source file.

Listing 4-27 Sample SampleServer.java Contents

>     // SampleServer.java
>     //
>     //  EJB Remote Interface generated by eGenCobol on 24-Jan-2000.

>     package sample;

>     // Imports

>     import javax.ejb.EJBObject;
>     ...

>     /** Remote Interface for SampleServer EJB. */

>     public interface SampleServer
>     	extends gwObject
>     {
>     	//dispatch
>     	byte[] dispatch(byte[] commarea, Object future)
>     		throws RemoteException, UnexpectedException;
>     }

>     // End SampleServer.java

SampleServerBean.java Source File

The following listing shows the contents of the generated SampleServerBean.java source file.

Listing 4-28 Sample SampleServerBean.java Contents

>     // SampleServerBean.java
>     //
>     EJB generated by eGenCobol on 24-Jan-2000.

>     package Sample;

>     // Imports

>     import com.bea.jam.egen.EgenServerBean;
>     ...

>     /** EJB implementation. */

>     public class SampleServerBean
>     	extends EgenServerBean
>     {
>     	// dispatch
>     	public byte[] dispatch (byte[] commarea, Object future)
>     		throws IOException
>     	{
>     		...
>     	}

>     	/**
>     	 * Do the actual work for a newEmployee operation.
>     	 * NOTE: This routine should be overridden to do actual work
>     	 */
>     	EmployeeRecord newEmployee (EmployeeRecord commarea)
>     	{
>     		return new EmployeeRecord();
>     	}
>     }

>     //End SampleServerBean.java

SampleServerHome.java Source File

The following listing shows the contents of the generated SampleServerHome.java source file.

Listing 4-29 Sample SampleServerHome.java Contents

>     // SampleServerHome.java
>     //
>     // EJB Home interface generated by eGenCobol on 24-Jan-2000.

>     package Sample;

>     //Imports

>     import javax.ejb.EJBHome;
>     ...

>     /** Home interface for SampleServer EJB. */

>     public interface SampleServerHome
>     	extends EJBHome
>     {
>     	//create
>     	SampleServer create()
>     		throws CreateException, RemoteException;
>     }

>     // End SampleServerHome.java

SampleServer-jar.xml Source File

The following listing shows the contents of the generated SampleServer-jar.xml source file. To use this file, copy it to ejb.jar.xml

Listing 4-30 Sample SampleServer-jar.xml Contents

>     <?xml version="1.0"?>
>     <!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>
>         <enterprise-beans>
>           <session>
>             <ejb-name>SampleServer</ejb-name>
>             <home>sample.SampleServerHome</home>
>             <remote>sample.SampleServer</remote>
>             <ejb-class>sample.SampleServerBean</ejb-class>
>             <session-type>Stateless</session-type>
>             <transaction-type>Container</transaction-type>
>           </session>
>         </enterprise-beans>
>         <assembly-descriptor>
>           <container-transaction>
>           <method>
>             <ejb-name>SampleServer</ejb-name>
>             <method-intf>Remote</method-intf>
>             <method-name>*</method-name>
>           </method>
>           <trans-attribute>NotSupported</trans-attribute>
>           </container-transaction>
>         </assembly-descriptor>
>     </ejb-jar>

wl-SampleServer-jar.xml Source File

The following listing shows the contents of the generated wl-SampleServer-jar.xml source file. To use this file, copy it to weblogic-ejb-jar.xml

Listing 4-31 Sample wl-SampleServer-jar.xml Contents

>     <?xml version="1.0"?>
>     <!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN' 'http://www.bea.com/servers/wls510/dtd/weblogic-ejb-jar.dtd'>
>     <weblogic-ejb-jar>
>         <weblogic-enterprise-bean>
>           <ejb-name>SampleServer</ejb-name>
>           <caching-descriptor>
>              <max-beans-in-free-pool>50</max-beans-in-free-pool>
>           </caching-descriptor>
>           <jndi-name>my.sampleBean</jndi-name>
>         </weblogic-enterprise-bean>
>     </weblogic-ejb-jar>Script Comments

Customizing a Server Enterprise Java Bean-Based Application

The generated server enterprise Java bean-based applications are only intended for customizing, since they perform no real work without customization.

This section describes the way that generated server EJB code can be customized.

The following figure illustrates the relationships and inheritance hierarchy between the JAM classes comprising the application.

Figure 4-6 The JAM Server EJB Class Hierarchy

The generated Java code for a client EJB application is a class that inherits class EgenServerBean. The EgenServerBean class is provided in the JAM distribution jar file. This base class, illustrated in the following listing, provides the basic framework for an EJB. It provides the required methods for a Stateless Session EJB.

Listing 4-32 EgenServerBean.java Base Class

>     //==========================================================
>     // EgenServerBean.java
>     //	The base class for generated server EJB's.
>     //
>     //===============================================================

>     package com.bea.jam.egen;

>     abstract public class EgenServerBean
>     	implements SessionBean
>     {
>     	// Implementation of ejbActivate(), ejbRemove(),
>     	// ejbPassivate(),
>     	// setSessionContext() and ejbCreate().
>     	...

>     	// Variables

>     	protected transient SessionContext m_context;
>     	protected transient Properties m_properties;
>     }

>     // End EgenServerBean.java

The generated class, illustrated in the following listing, adds the methods specific to this EJB.

Listing 4-33 Generated SampleServerBean.java Class

>     // SampleServerBean.java
>     //
>     // EJB generated by eGenCobol on 03-Feb-00.
>     //

>     package Sample;

>     //Imports
>     //
>     import java.io.IOException;
>     import java.util.Hashtable;
>     import com.bea.sna.jcrmgw.snaException;
>     import com.bea.base.io.MainframeWriter
>     import com.bea.base.io.MainframeReader;
>     import com.bea.jam.egen.EgenServerBean;
>     import com.bea.jam.egen.InboundDispatcher;

>     /**
>      * EJB implementation
>      */
>     public class SampleServerBean extends EgenServerBean
>      {
>        // dispatch
>        //
>        public byte[]  dispatch(byte[] commarea, Object future)
>     	throws IOException
>        {
>     	EmployeeRecord   inputBuffer
>     				= new EmployeeRecord (new
>     				MainframeReader (commarea));
>     	EmployeeRecord   result = newEmployee (inputBuffer);;
>     	return result.toByteArray (new MainframeWriter());
>        }

>        /**
>         * Do the actual work for a newEmployee operation.
>         * NOTE: This routine should be overridden to do actual work
>         */
>         EmployeeRecord newEmployee(EmployeeRecord commarea)
>         {
>     	return new EmployeeRecord();
>         }
>     }

>     // END SampleServerBean.java

The following listing shows an example ExtSampleServerBean class that extends the generated SampleServerBean class, providing an implementation of the newEmployee() method. The example method prints a message indicating that a newEmployee request has been received.

Listing 4-34 Sample ExtSampleServerBean.java Contents

>     // ExtSampleServerBean.java
>     //

>     package sample;

>     /**
>      * EJB implementation
>      */
>     public class ExtSampleServerBean extends SampleServerBean
>     {
>     	public EmployeeRecord newEmployee (EmployeeRecord in)
>     	{
>     	  System.out.println("New Employee: " +
>     		+in.getEmpRecord()in.getEmpName().getEmpNameFirst()
>     		+ " "
>     		+ in.getEmpRecord().getEmpname().getEmpNameLast());
>     	  return in;
>     	}
>     }

>     // END ExtSampleServerBean.java

Once the ExtSampleServerBean class has been written, it and the other EJB Java source files must be compiled and deployed in the same manner as other EJBs. Before deploying, the deployment descriptor must be modified; the ejb-class must be set to the name of your extended EJB implementation class.

Compiling and Deploying

Refer to the BEA WebLogic server documentation for more information. The sample file provided with the WebLogic Server contain build script for reference.

Generating a Stand-Alone Client Application

This type of application produces simple Java classes that perform the appropriate conversions of data records sent between Java and the mainframe, but without all of the EJB support methods. These classes are intended to be lower-level components upon which more complicated applications are built.

Generating a stand-alone application consists of the following steps:

1. Generating a script.

2. Processing the script.

3. Working with the generated files.

4. Customizing the application.

The following listing shows the contents of a complete script for defining a stand-alone client class with multiple services.

Listing 4-35 Sample Stand-Alone Client Class Script

>     1  #--------------------------------------------------------
>     2  # empclass.egen
>     3  #	JAM script for an employee record.
>     4  #
>     5  # $Id: empclass.egen, v 1.1 2000/01/21 23:20:40
>     6  #-------------------------------------------------------------
>     7
>     8  # DataViews (typed data records)
>     9
>     10 view sample.EmployeeRecord (Comment 1)
>     11	from emprec.cpy
>     12
>     13  # Services
>     14
>     15  service sampleCreate (Comment 2)
>     16	accepts EmployeeRecord
>     17	returns EmployeeRecord
>     18
>     19  service sampleRead (Comment 2)
>     20	accepts EmployeeRecord
>     21	returns EmployeeRecord
>     22
>     23  service sampleUpdate (Comment 2)
>     24	accepts EmployeeRecord
>     25	returns EmployeeRecord
>     26
>     27  service sampleDelete (Comment 2)
>     28	accepts EmployeeRecord
>     29	returns EmployeeRecord
>     30
>     31  # Clients and servers
>     32
>     33  client class sample.SampleClass (Comment 3)
>     34  {
>     35	method newEmployee (Comment 4)
>     36		is service sampleCreate
>     37
>     38	method readEmployee (Comment 4)
>     39		is service sampleRead
>     40  }
>     41
>     42  # End

Script Comments

The following numbered comments refer to the numbered comments in the prior listing.

####

Table 4-13 Script Comments

Comment 1 | Defines a DataView class, specifying its corresponding copybook source file and its package name.
Comment 2 | Defines a service function and its input and output parameter types.
Comment 3 | Defines a simple client class.
Comment 4 | Defines a client class method and its parameter types.

Processing a Script

Issuing the following command will process the script.

Listing 4-36 Sample Script Process Command

>     egencobol empclass.egen
>     emprec.cpy, Lines: 21, Errors: 0, warnings: 0
>     Generating sample.EmployeeRecord...
>     Generating group emp-name
>     Generating group emp-addr
>     Generating SampleClass...

Generated Files

This script command generates the following files.

####

Table 4-14 Sample Script Generated Files

File | Content
--- | ---
SampleClass.java | Source for the sample class.
EmployeeRecord.java | Source for the DataView class.

SampleClass.java Source File

The following listing contains the generated SampleClass.java source file.

Listing 4-37 Sample SampleClass.java Source File

>     // SampleClass.java
>     //
>     // Client class generated by eGenCobol on 24-Jan-2000.

>     package sample;(Comment 1)

>     // Imports

>     import com.bea.jam.egen.EgenClient;
>     ...

>     /* Mainframe client class. */

>     public class SampleClass (Comment 2)
>     	extends EgenClient
>     {
>     	// newEmployee
>     	public EmployeeRecord newEmployee (EmployeeRecord commarea)
>     		throws IOException, snaException (Comment 3)
>     	{
>     		...
>     	}

>     	// readEmployee
>     	public EmployeeRecord readEmployee (EmployeeRecord commarea)
>     		throws IOException, snaException (Comment 3)
>     	{
>     		...
>     	}
>     }

>     // End SampleClass.java

Script Comments

The following numbered comments refer to the numbered comments in the prior listing.

####

Table 4-15 Script Comments

Comment 1 | The package name is defined in the eGen script.
Comment 2 | The data record is encapsulated in a class that extends the EgenClient class.
Comment 3 | The methods convert a raw COMMAREA into a Java DataView object.

Customizing a Stand-Alone Java Application

The stand-alone client class model is the simplest JAM code generation model both in terms of the code generated and customizing the generated code.

The following figure illustrates the relationships and inheritance hierarchy between the JAM classes comprising the application.

Figure 4-7 The JAM Client EJB Class Hierarchy

The generated Java code for a client class application is a class that inherits class EgenClient. The EgenClient class is provided in the JAM distribution jar file. This base class, illustrated in the following listing provides the basic framework for a client to the jcrmgw. It provides the required methods for accessing the gateway.

Listing 4-38 Generated EgenClient.java Class

>     //==========================================================
>     // EgenClient.java
>     //	Basic functionality for clients of the jcrmgw
>     //
>     //---------------------------------------------------------------

>     package com.bea.jam.egen;

>     public class EgenClient
>      {

>     	public byte[] callService(String service, byte[] in)
>     		throws snaException, IOException
>     	{
>     		// make a mainframe request through the gateway.
>     		...
>     	}
>     }

>     // End egenClientBean.java

The generated class, illustrated in the following listing, adds the methods specific to the users application

Listing 4-39 Sample SampleClient.java Class

>     // SampleClass.java
>     //
>     // Client class generated by eGenCobol on 02-Feb-00.
>     //

>     package sample;

>     // Imports
>     //
>     import java.io.IOException;
>     import com.bea.jam.egen.EgenClient;
>     import com.bea.sna.jcrmgw.snaException;
>     import com.bea.base.io.MainframeWriter;
>     import com.bea.base.io.MainframeReader;

>     /**
>      * Mainframe client class.
>      */
>     public class SampleClass extends EgenClient
>      {
>     	// newEmployee
>     	//
>     	public EmployeeRecord newEmployee(EmployeeRecord commarea)
>     		throws IOException, snaException
>     	{
>     	  // Make the remote call.
>     	  //
>     	  byte[]  inputBuffer = commarea.toByteArray(new
>     		MainframeWriter());
>     	  byte[] rawResult = callService("sampleCreate",
>     		inputBuffer);
>     	  EmployeeRecord   result =
>     			new EmployeeRecord(new
>     			   MainframeReader(rawResult));
>     	  return result;
>     	}

>     	// readEmployee
>     	//
>     	public EmployeeRecord readEmployee(EmployeeRecord commarea)
>     		throws IOException, snaException
>     	{
>     	  // Make the remote call.
>     	  //
>     	  byte[]  inputBuffer = commarea.toButeArray(new
>     		MainframeWriter());
>     	  byte[] rawResult = callService("sampleRead", inputBuffer);
>     	  EmployeeRecord  result =
>     		new EmployeeRecord(new MainframeReader(rawResult)):
>              return result
>     	}
>     ]

>     // End SampleClass.java

Your class, which extends or uses the SampleClient class, simply overrides or calls these methods to provide additional business logic, modifying the contents of the DataView. It may also add additional methods, if desired.

The following listing shows an example ExtSampleClass class that extends the generated SampleClient class.

Listing 4-40 Sample ExtSampleClient.java Contents

>     // ExtSampleClient.java
>     //

>     package sample;

>     // Imports
>     //
>     import java.io.IOException;
>     import com.bea.jam.egen.egenClientBean;
>     import com.bea.sna.jcrmgw.snaException;
>     import com.bea.base.io.MainframeWriter;
>     import com.bea.base.io.MainframeReader;

>     /**
>      * Extended Sample Class
>      */
>     public class ExtSampleClient extends SampleClass
>     {
>     	// deleteEmployee
>     	//
>     	public EmployeeRecord deleteEmployee(EmployeeRecord
>     		commarea)
>     	throws IOException, snaException
>     	{
>     	  EmployeeRecord erec=(EmployeeRecord) in;
>     	  if (!isSsnValid(erec.getEmpRecord().getEmpSsn()))
>     	{
>     	  // The SSN is not valid.
>     	  throw new Error)"Invalid Social Security Number:"+
>     		erec.getEmpRecord().getEmpSsm());
>     	}

>     	// Make the remote call.
>     	//
>     	return super.deleteEmployee(commarea);
>     	}

>     	//updateEmployee
>     	//
>     	public EmployeeRecord updateEmployee(EmployeeRecord
>     		commarea)
>     		throws IOException, snaException
>     	{
>     	  EmployeeRecord erec = (EmployeeRecord) in;
>     	  if (!isSsnValid(erec.getEmpRecord().getEmpSsn()))
>     	  {
>     		The SSN is not valid.
>     		throw new Error ("Invalid Social Security Number:"+
>     		  erec.getEmpRecord().getEmpSsn());
>     	   }

>     		// Make the remote call.
>     		//
>     		return super.updateEmployee(commarea);
>     	}

>     	// readEmployee
>     	//
>     	public EmployeeRecord readEmployee(EmployeeRecord commarea)
>     		throws IOException, snaException
>     	{
>     		EmployeeRecord erec = )EmployeeRecord)in;
>     		if (!isSsnValid(erec.getEmpRecord().getEmpSsn()))
>     		{
>     			// The SSN is not valid.
>     			throw new Error("Invalid Social Security
>     			Number:"+
>     				erec.getEmpRecord().getEmpSsn());
>     		}

>     		// Make the remote call.
>     		//
>     		return super.readEmployee(commarea);
>     	}

>     	//newEmployee
>     	//
>     	public EmployeeRecord newEmployee(EmployeeRecord commarea)
>     		throws IOException, snaException
>     	{
>     	  EmployeeRecord erec = (EmployeeRecord) in;
>     	  if (!isSsnValid(erec.getEmpRecord().getEmpSsn()))
>     	  {
>     		// The SSN is not valid.
>     		throw new Error("Invalid Social Security Number:"+
>     			erec.getEmpRecord().getEmpSsn());
>     	  }

>              // Make the remote call.
>              //
>              return super.newEmployee(commarea);
>     	}

>     // Private functions

>     	/******************************************************
>     	* Validates an SSN field.
>     	*/

>     	private boolean isSsnValid(BigDecimal ssn)
>     	{
>     	  if (ssn.longValue() < 100000000)
>     	  {
>     	    // Ops, should not have a leading zero.
>     	    return false;
>     	  }

>              return (true);
>     	}
>     ]

>     // END ExtSampleClient.java

Once the ExtSampleClient class has been written, it and the other Java source files must be compiled and placed on to your WEBLOGICCLASSPATH.

Using Client Diagnostic Features

JAM includes several features to support diagnosing problems with eGen-based client programs. While these facilities are not designed for use in a production environment, they should be useful during development. These features are enabled by adding the following settings to your weblogic.properties file.

####

java.system.property.bea.jam.client.trace.enable | Set to "true" to enable tracing of client requests.
java.system.property.bea.jam.client.trace.codepage | Set to the name of a codepage to be used for the character portion of the trace dump.
java.system.property.bea.jam.client.loopback | Set to "true" to bypass the gateway & simply loop the request bytes back to the client.
java.system.property.bea.jam.client.stub | Set to the full name of a class to be used as a gateway stub.

Client Traffic Tracing

When this feature is enabled, all requests from eGen clients are dumped to the WebLogic console in hexadecimal and characters. The following listing shows an example of an eGen client dump.

Listing 4-41 Dump of eGen Client Requests

>     ---------------- Service: demoRead  Input data --------------

>     00 00 00 00 0f e2 d4 c9 e3 c8 40 40 40 40 40 40   .....SMITH
>     40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40
>     40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40
>     40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40
>     40 40 40 40 40 40 40 40 40 40 40 40 40 00 00 00              .
>     01 00 00 00 00 0f 00 00 00 00 0f 00 00 00 00 00   ............
>     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ............
>     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ............
>     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ............
>     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ............
>     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ............
>     --------------------------------------------------------------
>     ---------------- Service: demoRead  Output data --------------
>     00 00 00 00 0f e2 d4 c9 e3 c8 40 40 40 40 40 40   .....SMITH
>     40 40 40 40 a7 40 40 40 40 40 40 40 40 40 40 40       x
>     40 40 40 a7 94 81 89 95 40 40 40 40 40 40 40 40      xmain
>     40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40
>     40 40 40 40 40 40 40 40 40 40 40 40 40 00 00 00             ..
>     01 00 00 00 00 0f 00 00 00 00 0f                  ..........
>     --------------------------------------------------------------

Note that the dumps occur while the data is in mainframe format, and characters will usually be in some variety of EBCDIC. By default, the character data is converted using cp037, but that may be changed using another property setting.

Client Loopback

If this feature is enabled, all requests receive a response that is exactly equal to the request data. Note that this is done while the data is in mainframe format. If a service accepts one DataView subclass and returns a different one, this may result in a conversion failure trying to construct the result DataView subclass.

When this feature is enabled, no gateway is required and the gwboot startup may be removed from your weblogic.properties file.

Client Stub Operation

This feature enables you to replace the gateway with your own class, in effect providing a replacement for the entire target mainframe. This feature is valuable for testing or proof-of-concept situations where the mainframe connection is not available.

Your stub class must:

- Provide a constructor that takes no arguments.

- Be available on your WEBLOGICCLASSPATH.

- Contain a method for each service that is to be supported. This method must take some DataView subclass as its only argument and return a DataView subclass.

The client tracing feature can be used to help debug your stub class.

Copyright © 2000 BEA Systems, Inc. All rights reserved. Required browser: Netscape 4.0 or higher, or Microsoft Internet Explorer 4.0 or higher.