Building the MedRec Applications

Tutorial 11: Exposing a Stateless Session EJB as a Web Service

This tutorial describes how to expose a stateless session EJB as a Web Service. Tutorial 12: Invoking a Web Service from a Client Application describes how this Web Service can be invoked by a variety of client applications using SOAP.

WebLogic Web Services Ant tasks expose an existing stateless session EJB as a WebLogic Web Service. In particular, the Ant tasks:

- Generate a web-services.xml deployment descriptor file that tells WebLogic Server how to deploy the Web Service.
- Generate the serialization classes, XML Schema representation, and type mapping information for all non-built-in data types that are used as parameters and return values of the EJB methods.
- Package all the components into a Web Application within an EAR file, along with any needed EJB JAR files.

This tutorial shows you how to use the individual Ant tasks autotype and source2wsdd. BEA also provides another Ant task, servicegen, which can automate many tasks for you.

The tutorial includes the following sections:

- Prerequisites
- Procedure
- Best Practices
- The Big Picture
- Related Reading

Prerequisites

Previous tutorials work exclusively with the Physician application, physicianEar. This tutorial uses the main MedRec application, medrecEar, which contains the session and entity EJBs that handle patient information such as personal data and records of doctor visits.

It is assumed that you have already created the split directory structure for the MedRec application, and compiled the EJBs that make up the application (in particular the MedRecWebServices stateless session EJB) into their respective class files. To accomplish these tasks, you must:

1. Create the project directory and copy over the source files and output directories using the instructions in Tutorial 5: Creating the MedRec Project Directory.

2. Change to the medrecEar subdirectory in the MedRec project directory:

   >     cd c:\medrec_tutorial\src\medrecEar

3. Set your environment using the MedRecDomain environment script:

   >     c:\bea\user_projects\domains\MedRecDomain\setEnv.cmd

4. Execute the existing build.xml Ant file, specifying the prepare and build.split.dir targets:

   >     ant prepare build.split.dir

   The prepare target creates needed directories, sets up the Web Application directories, and copies the shared utility JAR files to the build directory. The build.split.dir target compiles all the EJBs into class files.

   After running the Ant task, examine the c:\medrec_tutorial\build\medrecEar directory; you will see subdirectories representing all the EJBs of the MedRec application, as well as Web Application directories. The ws_medrec Web Application will contain the Web Services information. This tutorial shows how to convert the stateless session EJB located in the webServicesEJB directory, com.bea.medrec.webservices.MedRecWebServices, into a WebLogic Web Service.

Procedure

To expose the MedRecWebServices EJB as a Web Service, follow these steps:

- Step 1: Create the build file that contains calls to the Web Services Ant tasks.
- Step 2: Execute the Web Services Ant tasks and create the Web Service.
- Step 3: Deploy the Web Service and view its home page.

Step 1: Create the build file that contains calls to the Web Services Ant tasks.

WebLogic Server provides a variety of Ant tasks that help you expose an existing stateless session EJB as a Web Service. This tutorial shows how to use the following Ant tasks:

- autotype: Generates the serialization classes, XML Schema representation, and type mapping information for the non-built-in Java data types that are used as parameters and return values of the EJB methods. The serialization class converts data between its XML and Java representations during the invoke of a Web Service operation.
- source2wsdd: Generates the web-services.xml deployment descriptor file that describes the Web Service. The source2wsdd Ant task uses information generated from the autotype task (such as the type mapping information) as well as information from the EJB being exposed (such as its methods and parameters) to generate the web-services.xml file.

For detailed information about these Ant tasks, see Web Service Ant Tasks and Command-Line Utilities.

In this tutorial, all components will be generated directly into the ws_medrec Web Application of the MedRec build directory.

1. Change to the medrecEar subdirectory in the MedRec project directory:

   >     cd c:\medrec_tutorial\src\medrecEar

2. Use your favorite text editor to create a file called my_webserv.xml file (which will contain calls to the Ant tasks) in the medrecEar directory:

   >     notepad my_webserv.xml

   Note: If you do not want to enter the build file manually, copy the file webservices_tutorial.xml file to the new file name, my_webserv.xml. Then follow along to understand the file contents. The webservices_tutorial.xml file assumes that your MedRec project directory is c:/medrec_tutorial.

3. Add the following lines to the my_webserv.xml file (substituting, if necessary, your actual MedRec project directory for c:/medrec_tutorial):

   >     <project name="WebServicesTutorial" default="build.ws">

   >       <target name="build.ws">

   >        <autotype

   >             javaComponents="com.bea.medrec.webservices.MedRecWebServices"

   >             targetNamespace="http://localhost:7101/ws_medrec/MedRecWebServices"

   >             packageName="com.bea.medrec.webservices"

   >             earClasspath="c:/medrec_tutorial/build/medrecEar"

   >             keepGenerated="false"

   >             destDir="c:/medrec_tutorial/build/medrecEar/ws_medrec/WEB-INF/classes"

   >         />

   >         <source2wsdd

   >     javaSource="webServicesEjb/com/bea/medrec/webservices/MedRecWebServices.java"

   >             ejbLink="webServicesEjb#MedRecWebServicesEJB"

   >     typesInfo="c:/medrec_tutorial/build/medrecEar/ws_medrec/WEB-INF/classes/types.x
   >     ml"

   >     ddFile="c:/medrec_tutorial/build/medrecEar/ws_medrec/WEB-INF/web-services.xml"

   >             serviceURI="/MedRecWebServices"

   >             earClasspath="c:/medrec_tutorial/build/medrecEar"

   >     classpath="${java.class.path};c:/medrec_tutorial/build/medrecEar/ws_medrec/WEB-
   >     INF/classes"

   >             wsdlFile="c:/medrec_tutorial/dist/MedRecService.wsdl"

   >       />

   >       </target>

   >     </project>

   Table 1: Attributes of the autotype and source2wsdd Ant Tasks

   Ant Task | Attribute | Description
   --- | --- | ---
   autotype | javaComponents | The class name of the remote interface of the MedRecWebServices stateless session EJB. The autotype Ant task introspects this class to find the list of non-built-in Java data types for which it needs to create the serialization class, XML Schema representation, and type mapping information.
   targetNamespace | Namespace URI of the Web Service.
   packageName | Package name of the generated serialization classes.
   earClasspath | Specifies that the EJB JAR files and classes in the APP-INF directory of the MedRec application build directory be added to the CLASSPATH of the autotype Ant task. This ensures that autotype finds the compiled Java classes of the MedRecWebServices EJB, as well as the compiled classes of non-built-in data types, that were generated as a prerequisite to this tutorial.
   keepGenerated | Specifies that only the class files, and not the Java source files, of the generated serialization classes should be generated to the build directory.
   destDir | Full pathname of the directory that will contain the generated components. The serialization classes will be placed in a directory structure that mirrors their package name and the XML Schema representation and type mapping information is generated in a file called types.xml. In this tutorial, the components are generated directly into the WEB-INF directory of the ws_medrec Web Application of the MedRec enterprise application.
   source2wsdd | javaSource | Name of the Java source file of the MedRecWebService EJB. In the tutorial, this is a relative path, starting with webServicesEjb, which contains the Java source files for the MedRecWebService EJB.
   ejbLink | At runtime, WebLogic Server uses this element to determine the name of the stateless session EJB, and the EJB JAR file in which it is contained, that is being exposed as a Web Service. In particular, this attribute specifies the value of the <ejb-link> child element of the <stateless-ejb> element in the generated web-services.xml file.
   typesInfo | Full pathname of the types.xml file that contains the XML Schema representation and type mapping information for the non-built-in data types. This file was generated by the autotype Ant task.
   ddFile | Full pathname of the generated web-services.xml deployment descriptor file. In this tutorial, the file is generated directly into the WEB-INF directory of the ws_medrec Web Application of the MedRec application, medrecEar.
   serviceURI | The Web Service URI portion of the URL used by client applications to invoke the deployed Web Service.
   earClasspath | Specifies that the EJB JAR files and classes in the APP-INF directory of the MedRec application build directory be added to the CLASSPATH of the source2wsdd Ant task. This ensures that source2wsdd finds all the compiled classes that were generated as a prerequisite to this tutorial.
   classpath | Adds the classes in the WEB-INF/classes directory of the ws_medrec Web Application of the build directory to the CLASSPATH of the source2wsdd Ant task. The ws_medrec/WEB-INF/classes directory contains the serialization classes generated by the autotype Ant task.
   wsdlFile | Specifies that you also want to generate a hard copy of the WSDL (public contract of the Web Service) into the specified directory. Note: The generated WSDL is used in Tutorial 12: Invoking a Web Service from a Client Application to generate a client JAR file that contains much of the Java code needed by Java client applications to invoke the Web Service. This step is performed now only to set up a later tutorial; you typically never need to create a static copy of the WSDL file. This is because WebLogic Server dynamically publishes the WSDL of any deployed Web Services at a known URI.

Step 2: Execute the Web Services Ant tasks and create the Web Service.

After you have created the my_webserv.xml file, use it to execute the autotype and source2wsdd Ant tasks to create the Web Service components:

1. Set your environment using the MedRecDomain environment script:

   >     c:\bea\user_projects\domains\MedRecDomain\setEnv.cmd

2. Move to the medrecEar directory:

   >     cd c:\medrec_tutorial\src\medrecEar

3. Execute the Web Service Ant tasks by running the my_webserv.xml script using ant:

   >     ant -f my_webserv.xml

   Although you did not add any informational messages to your build script, the autotype and source2wsdd Ant tasks produce output to show their progress:

   >     Buildfile: my_webserv.xml

   >     build.ws:

   >      [autotype] Autotyping for javaComponents
   >     com.bea.medrec.webservices.MedRecWebServices

   >     [source2wsdd] Loading source file
   >     c:\medrec_tutorial\src\medrecEar\webServicesEjb\com\bea\medrec\webservices\MedR
   >     ecWebServices.java...

   >     [source2wsdd] Constructing Javadoc information...

   >     BUILD SUCCESSFUL

   >     Total time: 17 seconds

1. Move to the MedRec build directory to see what the Ant tasks generated:

   >     cd c:\medrec_tutorial\build\medrecEar

   The generated Web Service components are in subdirectories of the ws_medrec Web Application directory:

   - The web-services.xml file is in the WEB-INF directory.

   - The serialization classes are in the WEB-INF\classes directory, in a sub-directory structure that corresponds to the package name.

Step 3: Deploy the Web Service and view its home page.

In this section, deploy the entire MedRec application, which includes the MedRecWebService Web Service, in the same way that you deployed the Physician application in Tutorial 9: Deploying MedRec from the Development Environment.

Once the Web Service is deployed, you can view its home page where you can test its operations, view the WSDL of the Service, and so on.

1. Start MedRecServer, if it is not already running, by executing its start script:

   >     c:\bea\user_projects\domains\MedRecDomain\startweblogic.cmd

2. Open another command shell and set your environment:

   >     c:\bea\user_projects\domains\MedRecDomain\setenv.cmd

3. Move to the medrecEar subdirectory if you are not already there:

   >     cd c:\medrec_tutorial\src\medrecEar

4. Use your favorite text editor to edit the my_webserv.xml file:

   >     notepad my_webserv.xml

5. Add a new target to the file by adding the following text directly after the </target> tag which ends the existing build.ws target:

   >       <target name="deploy">

   >          <wldeploy user="weblogic" password="weblogic"
   >     adminurl="t3://localhost:7101" action="deploy"
   >     name="medrec_deployment"
   >     source="c:\medrec_tutorial\build\medrecEar"/>

   >       </target>

   Note: If you do not want to enter the text manually, copy the text from the file webservices_tutorial.xml file. Then follow along to understand the file contents. The webservices_tutorial.xml file assumes that your MedRec project directory is c:/medrec_tutorial.

   Save the file and exit your text editor.

6. In the same command shell, enter the following command to execute just the deploy target of the build script:

   >     ant -f my_webserv.xml deploy

   You should receive the following output from the wldeploy task:

   >     Buildfile: my_webserv.xml

   >     deploy:

   >     [wldeploy] weblogic.Deployer -noexit -name medrec_deployment
   >     -source D:\medrec_tutorial\build\medrecEar -adminurl
   >     t3://localhost:7101 -user weblogic -password weblogic -deploy

   >      [wldeploy] Initiated Task: [3] [Deployer:149026]Deploy
   >     application medrec_deployment on MedRecServer.

   >      [wldeploy] Task 3 completed: [Deployer:149026]Deploy
   >     application medrec_deployment on MedRecServer.

   >      [wldeploy] Deployment completed on Server MedRecServer

   >      [wldeploy]

   >     BUILD SUCCESSFUL

   >     Total time: 18 seconds

   If you do not receive the above output, MedRecServer may not have finished starting up, or you may have made a typo in creating the deploy target in the my_webserv.xml file. If this occurs, wait until the server has finished starting up, and try to deploy using the installed tutorial file (it is assumed that the MedRec project directory is c:\medrec_tutorial):

   >     ant -f webservices_tutorial.xml deploy

7. To verify that the Web Service deployed, open a new browser window and enter the URL for the Web Service's home page:

   >     http://localhost:7101/ws_medrec/MedRecWebServices

   From the home page you can test the operations of the Web Service by clicking on the operation name; view the WSDL by clicking on the Service Description link; and view the SOAP request and response messages of a successful invocation of the operations.

Best Practices

- A WebLogic Web Service can be implemented with a stateless session EJB or a Java class. Use a stateless session EJB when you want to take advantage of standard EJB features, such as transactions, pooling, and so on. Use a Java class if you do not need these features and you want to develop or prototype a Web Service quickly.
- When creating a Web Service, use a stateless session EJB or Java class facade that exposes a simple interface to your application. This facade will not necessarily do much other than call other session EJBs, which in turn might call entity EJBs, that do the work. Encapsulating the main application logic into one EJB facade that you expose as a Web Service, rather than exposing all the session EJBs of your application, makes the public interface to your application simpler and cleaner. It also allows you to change the supporting EJBs without having to change the public face of your application.
- Think about the non-built-in XML data types that your application uses and whether they will interoperate with all client applications that will be invoking your Web service. For example, although the autotype Ant task can create a serialization class and XML Schema for the java.utils.Collection Java data type, the resulting XML Schema data type might not necessarily interoperate with all client applications.

For this reason, consider using simpler data types (such as Arrays) in the EJB facade that will be exposed as a Web Service, and then, inside of the EJB facade, convert these data types into the more complex Java types (such as java.utils.Collection) used by the session EJBs that do the actual work.

- WebLogic Server provides a variety of Ant tasks to help you expose an EJB or Java class as a Web Service. If your Web Service is fairly simple and straightforward, use the servicegen Ant task which does everything for you, including optionally configuring your Web Service for security, reliable SOAP messaging, and handler chain, as well as packaging the Web Service into an EAR file. If, however, you want more control over the various stages of assembling the Web Service, and want to package it yourself as part of a bigger J2EE application, then use the individual Ant tasks that are targeted for specific jobs, such as autotype and source2wsdd. This tutorial shows how to use the individual Ant tasks.
- Every deployed WebLogic Web Service has a home page from which you can perform preliminary and simple testing of the service's operations, view its WSDL, and view SOAP messages of successful invokes of the operations. Use the home page for a first-pass testing of your Web Service; use a client application for more rigorous testing. See Deploying and Testing WebLogic Web Services for detailed information on the URL used to invoke the home page.

The Big Picture

The com.bea.medrec.webservices.MedRecWebServices stateless session EJB of the MedRec application contains methods to view and update patient and record information, such as addRecord(), updatePatient() and so on. These methods do not actually perform any of the business logic; rather, they call the existing session EJBs (such as com.bea.medrec.controller.PatientSession and com.bea.medrec.controller.RecordSession) to do the real work of viewing and searching for the patient and record information. You can think of the MedRecWebServices EJB as a facade that takes incoming requests to the MedRec application and hands them off to the other session and entity EJBs that do the actual work.

For this reason, the MedRecWebServices EJB is a good candidate to be exposed as a Web Service so that all kinds of different client applications, from EJBs running on a different WebLogic Server instance to a .NET client, can easily get to and update the patient and record information managed by the MedRec application. The client applications use SOAP to invoke a Web Service operation, and WebLogic Server in turn uses SOAP to send the information back to the client.

The methods of the MedRecWebServices EJB use the following complex non-built-in data types as parameters and return values:

- AddressWS
- PatientWS
- PrescriptionWS
- RecordWS
- RecordSummaryWS
- VitalSignsWS

These data types are almost exactly the same as the com.bea.medrec.value.* value objects used by the other session and entity EJBs of the MedRec application. The only difference is that the Web Service-specific ones do not use Java types such as java.util.List and java.util.Collection to represent collections of data, but use arrays. The reason for this is that arrays are much more interoperable and type-bound than List and Collection. The autotype Ant task creates the serialization class to convert between the Web Service data types and their equivalent XML Schema type, and then the MedRecWebServices EJB converts the data between the Web Service Java data type (such as AddressWS) and its equivalent Value object (such as Address).

Related Reading

- Programming WebLogic Web Services
- Programming WebLogic XML
- Programming WebLogic Enterprise Java Beans
- Simple Object Access Protocol (SOAP) 1.1 Specification
- Web Services Description Language (WSDL) 1.1 Specification