Skip Headers

Oracle® Application Server Web Services Developer's Guide 10g Release 3 (10.1.3) B14434-01 |
| Home | Solution Area | Contents | Index

Previous | Next |

# 7 Assembling a Web Service with EJBs

This chapter describes how to use the WebServicesAssembler tool to expose version 2.1 Enterprise Java Beans (EJBs) as Web services.

This chapter has the following sections.

- Exposing EJBs as Web Services

- Writing EJBs for Web Services

- Tool Support for Exposing EJBs as a Web Service

## Exposing EJBs as Web Services

You can use WebServicesAssembler to expose version 2.1 EJBs as Web services that conform to J2EE 1.4 standards. Many EJBs have been written to encapsulate business functions in the middle tier. If you use EJBs in your enterprise applications, you can expose them as Web services.

Note: WebServicesAssembler cannot be used to expose version 3.0 EJBs as a Web service.

EJB components, by design, are meant for distributed computing and are well-suited for exposure as Web services. The EJB specification supports declarative transactions, thread management, and role-based security. You can leverage these benefits if you decide to use EJB components as Web services. EJBs exposed as Web services can still be accessed by traditional RMI EJB clients as well as by SOAP protocols. J2EE 1.4 allows exposing only stateless session beans as Web services.

By their nature, SOAP and Web services are stateless. Therefore, stateless session beans are an ideal medium for exposure as Web services. Stateless session beans can be used for checking someone's credit, charging a bank account, or placing an order. Session beans that implement a business function to be used by other remote applications are a perfect fit for exposure as Web services.

Writing an EJB Web service using JAX-RPC involves writing an EJB that implements a service and provides an interface for it. The EJB should contain the business logic that a client can invoke when it makes a Web service request.

An EJB Web service does not differ from any other Web service and can be invoked by a client written in Java, .NET, or any other programming language. The client of an EJB Web service can leverage static stubs, dynamic proxies, or Dynamic Invocation Interfaces (DII).

These are the general steps for exposing an EJB as a Web service.

1. Create the service endpoint interface for the stateless EJB component.

   The developer performs this step.

2. Assemble the service artifacts. This includes generating the WSDL and mapping files, and packaging the application into a deployable archive.

   WebServicesAssembler can be used to perform this step.

"How to Assemble a Web Service from an EJB" describes these steps in greater detail.

Working with Version 2.0 EJBs

Although this chapter focuses on exposing version 2.1 EJBs as Web services, version 2.0 EJBs can also be exposed. All the functionality in Oracle Application Server Web Services for working with version 2.1 EJBs is also available for version 2.0 EJBs. OracleAS Web Services and WebServicesAssembler can detect version 2.0 EJBs and ensure that they are processed correctly. Its remote interface methods must define the methods to be exposed as a Web service.

For more information on the J2EE Web Services requirements for EJBs, see "Writing EJBs for Web Services".

### Prerequisites

Before you begin, provide the following files and information.

- Write an Enterprise Java Bean that contains the business functions that you want to expose and its interface. The EJB and its interface must conform to EJB 2.1 standards and the J2EE 1.4 standard for a Web service. For more information on these requirements, see "Writing EJBs for Web Services".

- Decide whether you want WebServicesAssembler to only generate the service files or generate and package the files into a deployable archive. The `ear` argument packages the files into an archive. If you do not specify `ear`, the files are stored in a directory specified by `output`. For more information on output and packaging arguments, see "ear", "output", and "war".

- If the methods in the EJB use nonstandard data types, such as those described in "Mapping Java Types to XML and WSDL Types" in the Oracle Application Server Advanced Web Services Developer's Guide and in Table 4-1, you must specify a custom serializer to process them. For more information on implementing a custom serializer, see "Custom Serialization of Java Value Types" in the Oracle Application Server Advanced Web Services Developer's Guide.

- If your EJB needs to work with any additional message processing components, for example to process SOAP header information, you can specify message handlers. For more information, see "Configuring Handlers in an Ant Task" and Chapter 16, "Processing SOAP Headers".

### How to Assemble a Web Service from an EJB

The following steps describe how to use WebServicesAssembler to expose a session bean as a Web service.

1. Write the EJB that you want to expose as a Web service and its service endpoint interface.

2. Inspect the `ejb-jar.xml` deployment descriptor.

   Enter a `<service-endpoint>` element and a value if it is not already in the file. This element identifies the service endpoint interface for this Web service. In the following `ejb-jar.xml` fragment the `<service-endpoint>` element is highlighted in bold.

       <enterprise-beans>
           <session>
               <ejb-name>HelloServiceBean</ejb-name>
               <service-endpoint>oracle.demo.ejb.HelloServiceIntf</service-endpoint>
               <ejb-class>oracle.demo.ejb.HelloserviceBean</ejb-class>
               <session-type>Stateless</session-type>
               <transaction-type>Container</transaction-type>
           </session>
       </enterprise-beans>

3. Generate the service artifacts by running the WebServicesAssembler tool with the `ejbAssemble` command. For example:

       java -jar wsa.jar -ejbAssemble
                      -appName helloServices-ejb
                      -ear dist/helloServices-ejb.ear
                      -output build
                      -targetNamespace http://oracle.j2ee.ws/ejb/Hello
                      -typeNamespace http://oracle.j2ee.ws/ejb/Hello/types
                      -input dist/HelloServiceejb.jar
                      -ejbName HelloServiceBean

   This command assembles the EJB 2.1 Web service by generating the WSDL and mapping files, and packaging the application into a deployable archive, `dist/helloServices-ejb.ear`. This archive contains the `helloService-ejb.jar`, which stores all of the service artifacts, such as the EJB implementation classes, the generated WSDL and mapping file, standard Web service descriptor file, `webservices.xml`, and the Oracle-proprietary deployment descriptor file `oracle-webservices.xml`. For more information on the `ejbAssemble` command, see "ejbAssemble".

4. Deploy the service and bind the application.

   EAR files are deployed into a running instance of OC4J. For more information on deployment, see the Oracle Containers for J2EE Deployment Guide. The following is a sample deployment command.

       java -jar <OC4J_HOME>/j2ee/home/admin_client.jar deployer:oc4j:localhost:port <user> <password>
                   -deploy
                   -file dist/ejbApp.ear
                   -deploymentName ejbApp
                   -bindWebApp default-web-site

   The following list describes the parameters in this code example.

   - `<OC4J_HOME>`—the directory containing the OC4J installation.

   - `<user>`—the user name for the OC4J instance. The user name is assigned at installation time.

   - `<password>`—the password for the OC4J instance. The password is assigned at installation time.

   - `ejbApp`—the name of the application.

   - `default-web-site`—the Web site to which the application will be bound. This is usually `default-web-site`. To configure Web sites, see the `server.xml` file in `<``OC4J_HOME``>/j2ee/home/config`.

   After deployment, this Web service's WSDL will be available at the following Web address. The values for context-root and endpoint-address-uri can be found in the `META-INF/oracle-webservices.xml` file.

       http://host:port/context-root/endpoint-address-uri

5. (Optional) Check that deployment succeeded. OracleAS Web Services provides a Web Service Home Page for each deployed Web service. See "Using the Web Services Home Page" for information on accessing and using the Web Service Home Page.

6. Generate the client-side code:

   - For the J2SE environment, generate stubs (client proxies) for a J2SE Web service client by running the WebServicesAssembler tool with the `genProxy` command. For more information on generating and assembling a stub, see Chapter 14, "Assembling a J2SE Web Service Client".

   - For the J2EE environment, generate a service endpoint interface and a JAX-RPC mapping file for a J2EE Web service client by running the WebServicesAssembler tool with the `genInterface` command. For more information on generating and assembling a client for a J2EE Web service, see Chapter 13, "Assembling a J2EE Web Service Client".

   For example, the following command generates stubs that can be used for a J2SE client:

       java -jar wsa.jar -genProxy
                         -output build/src/client/
                         -wsdl http://localhost:8888/hello/HelloService?WSDL
                         -packageName oracle.demo.hello

   This command generates the client proxies and stores them in the directory `build/src/client`. The client application will use the stub to invoke operations on a remote service. For more information on the required and optional arguments to `genProxy`, see "genProxy".

7. Compile and run the client.

   List the appropriate JARs on the classpath before compiling the client. Table A-2, "Classpath Components for a Client Using a Client-Side Proxy" lists all of the JAR files that can possibly be used on the client classpath. As an alternative to listing individual JARs, you can include the client-side JAR, `wsclient_extended.jar` on the client classpath. This JAR file contains all the classes necessary to compile and run a Web service client. The classes are from the individual JAR files listed in Table A-2. See "Setting the Web Service Proxy Client Classpath" for more information on `wsclient_extended.jar` and the client classpath.

#### Ant Tasks for Generating a Web Service

The current release provides Ant tasks for Web services development. The following code samples show how the WebServicesAssembler commands in the preceding examples can be rewritten as Ant tasks.

For the `ejbAssemble` command, here is an example Ant task:

    <oracle:ejbAssemble appName="ejbApp"
              targetNamespace="http://oracle.j2ee.ws/ejb/Hello"
              ear="dist/ejbApp.ear"
              output="build"
              typeNamespace="http://oracle.j2ee.ws/ejb/Hello/types"
              input dist/HelloServiceejb.jar
              ejbName HelloServiceBean
    />

For the `genProxy` command, here is an example Ant task:

    <oracle:genProxy wsdl="http://localhost:8888/hello/HelloService?WSDL"
               output="build/src/client"
               packageName="oracle.demo.hello"
    />

## Writing EJBs for Web Services

Writing EJB-based Web services using JAX-RPC involves writing an EJB that implements a service and providing an interface for it. The EJB should contain the business functions that OracleAS Web Services can invoke when a client makes a Web service request.

This section provides information on how to write an EJB Web service that returns a string, "`HELLO!! You just said:`phrase", where phrase is input from a client. The EJB Web service receives a client request with a single `String` parameter and generates a response that it returns to the Web service client.

Writing a J2EE 1.4-compliant EJB implementation for Web services consists of these tasks.

- Writing an EJB Service Endpoint Interface

- Writing an EJB

### Writing an EJB Service Endpoint Interface

To use JAX-RPC to create a Web service with EJBs, you must write a public service endpoint interface to which the EJB must conform. The requirements for creating a service endpoint interface for a stateless session bean are summarized in Section 5.3.2.1 of the Enterprise Web Services 1.1 specification. The specification is available from the following Web address.

`http://www.jcp.org/en/jsr/detail?id=921`

The interface must extend `java.rmi.Remote`, and all methods must throw a `java.rmi.RemoteException`. You can use only Java primitives and classes that are JAX-RPC value types and nonstandard data types as parameters or return types for the EJB methods defined in the service endpoint interface.

Some examples of JAX-RPC value types are non-primitives such as `java.lang.String` or `java.lang.Double` and Java mappings of Multipurpose Internet Mail Extensions (MIME) types such as `java.awt.Image` or `javax.xml.transform.Source`. The nonstandard types are defined in "Mapping Java Types to XML and WSDL Types" in the Oracle Application Server Advanced Web Services Developer's Guide and in Table 4-1.

You can use custom Java data types in the service endpoint interface, but then you must also provide a serializer to process them. For more information on using custom data types and their serialization, see "Custom Serialization of Java Value Types" in the Oracle Application Server Advanced Web Services Developer's Guide.

Example 7-1 Sample Service Endpoint Interface

    package oracle.demo.ejb;

    import java.rmi.Remote;
    import java.rmi.RemoteException;
    /**
     * This is an Enterprise Java Bean Service Endpoint Interface
     */
    public interface HelloServiceInf extends java.rmi.Remote {
        /**
         * @param phrase java.lang.String
         * @return java.lang.String
         * @throws String The exception description.
         */
        java.lang.String sayHello(java.lang.String phrase)
              throws java.rmi.RemoteException;
    }

### Writing an EJB

Create an Enterprise Java Bean by implementing the business functions that you want the Web service to expose.

The `HelloServiceBean` described in this section is a sample session bean. The class defines a public method, `sayHello`, that returns `HELLO!! You just said:` phrase, where phrase was input from a client. In general, a Java bean for a Web service defines one or more public methods.

An Enterprise Java Bean, for the purposes of Web services, is any Java class that conforms to the following requirements:

- It must have a constructor that takes no arguments.

- All properties that you want to use must be exposed through accessors.

The EJB's parameters and return types must be JAX-RPC supported data types or nonstandard data types as described in "Mapping Java Types to XML and WSDL Types" in the Oracle Application Server Advanced Web Services Developer's Guide and in Table 4-1.

To comply with the JAX-RPC standard, all the methods in `HelloServiceBean` throw a `java.rmi.RemoteException`. They must also follow all the requirements of the version 2.1 EJB specification and Enterprise Web Services 1.1 specification.

Example 7-2 Sample HelloService Session Bean

    package oracle.demo.ejb;

    import java.rmi.Remote;
    import java.rmi.RemoteException;
    import java.util.Properties;
    import javax.ejb.*;

    /**
     * This is a Session Bean Class.
     */
    public class HelloServiceBean implements SessionBean {
        public String sayHello(String phrase) {
            return "HELLO!! You just said :" + phrase;
        }

        public void setSessionContext(javax.ejb.SessionContext ctx)
                throws java.rmi.RemoteException {
        }

        public void ejbActivate() throws java.rmi.RemoteException {
        }

        public void ejbCreate()
                throws javax.ejb.CreateException,
                       java.rmi.RemoteException {
        }
        public void ejbPassivate() throws java.rmi.RemoteException {
        }

        public void ejbRemove() throws java.rmi.RemoteException {
        }
    }

## Packaging and Deploying Web Services that Expose EJBs

The packaging structure of Web services that expose EJBs is described in "Packaging for a Web Service Based on EJBs".

For a detailed description of the deployment of EJBs, see the Oracle Containers for J2EE Deployment Guide.

## Providing Transport-Level Security

You can use the `<ejb-transport-security-constraint>` and `<ejb-transport-login-config>` elements in the `oracle-werbservices.xml` deployment descriptor to configure transport-level security constraints for a version 2.1 or 3.0 EJB. These elements are described in "Securing EJB-Based Web Services at the Transport Level".

For more information on providing transport-level security for EJBs, and how to write clients to access Web services secured on the transport level, see "Adding Transport-level Security for Web Services Based on EJBs" and "Accessing Web Services Secured on the Transport Level" in the Oracle Application Server Web Services Security Guide.

## Tool Support for Exposing EJBs as a Web Service

With Oracle JDeveloper, you can use modeling tools and wizards to create, modify, and deploy J2EE-compliant EJBs. The EJB wizards can be used to perform the following tasks.

- Create the Enterprise Bean class for several types of Enterprise JavaBeans, including stateless session beans.

- Generate the home interface needed to create an EJB object. The inclusion of the `ejbCreate()` method enables you to deploy the EJB to Oracle Applications Server immediately, without having to manually code the method.

- Enable a selection of home interface methods (and create a default method).

- Generate the remote interface.

- Enable a selection of remote interface methods.

- Deploy the EJB exposed as a Web service.

For more information on using JDeveloper to create EJBs and expose them as a Web service, see the JDeveloper on-line help.

## Limitations

See "Assembling Web Services From EJBs".

## Additional Information

For more information on:

- using the Home Page to test Web service deployment, see Chapter 12, "Testing Web Service Deployment".

- building a J2EE client, see Chapter 13, "Assembling a J2EE Web Service Client".

- building a J2SE client, see Chapter 14, "Assembling a J2SE Web Service Client".

- using JAX-RPC handlers, see Chapter 15, "Understanding JAX-RPC Handlers".

- using the WebServicesAssembler tool to assemble Web services, see Chapter 17, "Using WebServicesAssembler".

- packaging and deploying Web services, see Chapter 18, "Packaging and Deploying Web Services".

- JAR files that are needed to assemble a client, see Appendix A, "Web Service Client APIs and JARs".

- Web services interoperability, see "Ensuring Interoperable Web Services" in the Oracle Application Server Advanced Web Services Developer's Guide.

- using quality of service features in Web service clients, see "Managing Web Services" in the Oracle Application Server Advanced Web Services Developer's Guide.

- adding security to a Web service, see the Oracle Application Server Web Services Security Guide.

- adding transport-level security to Web services based on EJBs, see "Securing EJB-Based Web Services at the Transport Level".

  See also "Adding Transport-level Security to a Web Service" and "Accessing Web Services Secured on the Transport Level" in the Oracle Application Server Web Services Security Guide.

- adding reliability to a Web service, see "Ensuring Web Service Reliability" in the Oracle Application Server Advanced Web Services Developer's Guide.

- adding an auditing and logging configuration to a Web service, see "Auditing and Logging Messages" in the Oracle Application Server Advanced Web Services Developer's Guide.

- processing nonstandard data types, see "Custom Serialization of Java Value Types" in the Oracle Application Server Advanced Web Services Developer's Guide.

- the JAX-RPC mapping file, see "JAX-RPC Mapping File Descriptor" in the Oracle Application Server Advanced Web Services Developer's Guide.

- data types supported by OracleAS Web Services, see "Mapping Java Types to XML and WSDL Types" in the Oracle Application Server Advanced Web Services Developer's Guide.

- JDeveloper tool support for Web service development, see the JDeveloper on-line help.