BEA Home | Events | Solutions | Partners | Products | Services | Download | Developer Center | WebSUPPORT
| WebLogic Server Doc Home | Web Services | Previous Topic | Next Topic | Contents | Index | View as PDF

Developing WebLogic Web Services

The following sections describe how to develop WebLogic Web Services:

- Developing WebLogic Web Services: Main Steps

- Designing a WebLogic Web Service

- Implementing a WebLogic Web Service

- Assembling a WebLogic Web Service

- Deploying a WebLogic Web Service

- Developing a WebLogic Web Service: A Simple Example

Developing WebLogic Web Services: Main Steps

Most of the following steps are described in detail in later sections:

1. Design the WebLogic Web Service.

   Decide whether the Web service will be RPC-style or message-style, which EJB should implement the service, and so on. The section Designing a WebLogic Web Service discusses design considerations.

2. Implement the WebLogic Web Service.

   Write the business logic Java code for the EJBs that make up most of the WebLogic Web Service. For detailed information, see Implementing a WebLogic Web Service.

3. Package the EJBs that implement the Web service (stateless session EJB for RPC-style Web services and a message-driven bean for message-style Web services), along with any supporting EJBs, into an EJB archive file (*.jar).

   For detailed information on this step, refer to Developing WebLogic Server Applications.

4. Assemble the WebLogic Web Service.

   Package all the components that make up the service (such as stateless session EJBs, the Web application that contains a reference to the SOAP servlet, and so on) into a J2EE Enterprise Application archive (*.ear) file so that it can be deployed on WebLogic Server. You use Java Ant to assemble WebLogic Web Services. Assembling also refers to setting up other J2EE components, such as JMS destinations for message-style Web services.

   For detailed information, see Assembling a WebLogic Web Service.

5. Deploy the WebLogic Web Service.

   Make the service available to remote clients. For more information, see Deploying a WebLogic Web Service.

6. Create a client that accesses the Web service to test that your Web service is working as you expect. For detailed information, see Invoking WebLogic Web Services.

WebLogic Server includes examples of creating both RPC-style and message-style Web services and examples of both Java and Microsoft VisualBasic client applications that invoke the Web services.

The examples are located in the BEA_HOME/samples/examples/webservices directory, where BEA_HOME refers to the main WebLogic Server installation directory. The RPC-style Web service example is in the rpc directory and the message-style Web service example is in the message directory.

For detailed instructions on how to build and run the examples, invoke the Web page BEA_HOME/samples/examples/webservices/package-summary.html in your browser.

Designing a WebLogic Web Service

The bulk of WebLogic Web Services are the EJBs that do the work in the background after the SOAP request has been received and processed.

The first design issue is whether you should create an RPC-style or message-style Web service. This topic is discussed in Choosing Between an RPC-Style and a Message-Style Web Service.

The following sections discuss RPC-style design issues:

- EJB That Implements an RPC-Style Web Service

- Converting an Existing EJB Application into an RPC-Style Web Service

- Avoiding Overloaded Methods in Stateless Session EJBs

The following sections discuss message-style design issues:

- Message-Style Web Services and JMS

- Converting an Existing JMS Application Into a Web Service

The following sections discuss issues common to both types of Web services:

- Supported Data Types for Parameters and Return Values of WebLogic Web Services

- XML-Java Conversion in WebLogic Web Services

- Security Issues

Choosing Between an RPC-Style and a Message-Style Web Service

This section describes when to use an RPC-style or message-style Web service.

When to Use RPC-Style Web Services

RPC-style Web services are interface driven, which means that the business methods of the underlying stateless session EJB determine how the Web service works. When clients invoke the Web service, they send parameter values to the Web service, which executes the corresponding methods and sends back the return values. The relationship is synchronous, which means that the client waits for a response from the Web service before it continues with the remainder of its application.

Create an RPC-style Web service if your application has the following characteristics:

- The client invoking the Web service needs an immediate response.

- The client and Web service work in a back-and-forth, conversational way.

- The behavior of the Web service can be expressed as an interface.

- The Web service is process-oriented rather than data-oriented.

Examples of RPC-style Web services include providing the current weather conditions in a particular location; returning the current price for a given stock; or checking the credit rating of a potential trading partner prior to the completion of a business transaction. In each case the information is returned immediately, implying a synchronous relationship between the client and the Web service.

When to Use Message-Style Web Services

You should create a message-style Web service if your application has the following characteristics:

- the client has an asynchronous relationship with the Web service, or in other words, the client does not expect an immediate response.

- the Web service is data-oriented rather than process-oriented.

Examples of message-style Web services include processing a purchase order; accepting a request for new DSL home service; or responding to a request for quote order from a customer. In each case, the client sends an entire document, such as purchase order, to the Web service and assumes that the Web service is processing it in some way, but the client does not require an answer right away or even at all. If your Web service will work in this asynchronous, document-driven manner, then you should consider designing it as a message-style Web service.

EJB That Implements an RPC-Style Web Service

You implement an RPC-style Web service using a single stateless session EJB that either does all the actual work of the Web service or it parcels out some or all of the work to other EJBs. This EJB is the one that defines the methods that a client executes when it invokes a WebLogic Web Service.

Design your EJB to minimize the data that travels between the client and the Web service. This conversation is synchronous and over the Web, thus the fewer the requests and responses, the faster the entire transaction.

The data types of the parameters and return values of the EJB are restricted to a list of supported Web service data types, described in Supported Data Types for Parameters and Return Values of WebLogic Web Services. This data type restriction facilitates interoperability with other Web service implementation, both Java and non-Java, such as Microsoft SOAP ToolKit.

Converting an Existing EJB Application into an RPC-Style Web Service

You might be able to convert an existing stateless session EJB into an RPC-style Web service, as long as the data types of its parameters and return values are included in the list of supported Web services data types, listed in Supported Data Types for Parameters and Return Values of WebLogic Web Services.

If you cannot convert an existing EJB, then you must create a new stateless session EJB that implements the Web service, sends and receives parameters and return values from the client using the supported data types, then converts these values into the correct data types and passes the values to the existing stateless session EJB.

Alternatively, you can reprogram the existing stateless session EJB to accept as parameters and return values only the supported data types.

Avoiding Overloaded Methods in Stateless Session EJBs

Due to limitations in the SOAP specification, SOAP messages are unable to differentiate unambiguously between methods of the same name that have different signatures (overloaded methods). For this reason, WebLogic Server does not support overloaded methods in the EJBs that make up RPC-style Web services. Rather, each method should have its own unique name.

For example, assume your stateless session EJB defines a method called myMethod(), which can take as a parameter either a String or an integer. Because the SOAP specification does not force you to declare the data types of parameters in a SOAP message, the WebLogic Web Service might not know whether to execute myMethod(String) or myMethod(int) when a client invokes it. To clear up the confusion, rename one of the overloaded methods.

Message-Style Web Services and JMS

Message-style Web services use JMS listeners (such as message-driven beans) rather than stateless session EJBs as their entry points. This section describes the relationship between JMS and WebLogic Web Services and design considerations for developing message-style Web services.

Choosing a Queue or Topic

JMS queues implement a point-to-point messaging model whereby a message is delivered to exactly one recipient. JMS topics implement a publish/subscribe messaging model whereby a message is delivered to multiple recipients.

When you implement a message-style Web service you must make the following two decisions:

- Whether you want to use a JMS queue or topic.

- Whether the client application that invokes the Web service sends or receives the document to or from the service. The same service cannot support both sending and receiving.

Retrieving and Processing Documents

After you decide what type of JMS destination you are going to use, you must decide what type of J2EE component will retrieve the document from the JMS destination and process it. Typically this will be a message-driven bean. This message-driven bean can do all the document-processing work, or it can parcel out some or all of the work to other EJBs. Once the message-driven bean finishes processing the document, the execution of the Web service is complete.

This means that if you want the client that invokes the Web service by sending documents to receive some sort of response or data, you must create a second message-style Web service that the client subsequently invokes to retrieve a response. The second Web service is related to the original Web service because the original message-driven bean that processed the document puts the resulting information or response on the JMS destination corresponding to the second Web service. Again, you must decide whether the second JMS destination is a topic or a queue.

Example of Message-Style Web Services

As a simple example, Figure 2-1 shows two separate Web services, one for receiving a document from a client and one for sending a document back to the client. The two Web services have their own JMS destinations. The message-driven bean gets messages from the first JMS destination, processes the information, then puts a message back onto the second JMS destination. The client invokes the first Web service to send the document to WebLogic Server and then invokes the second Web service to receive a document back from WebLogic Server.

Figure 2-1 Data Flow Between Message-Style Web Services and JMS

Converting an Existing JMS Application Into a Web Service

You might be able to convert an existing JMS application into a message-style Web service, as long as the message-driven bean that gets messages from the JMS destination can handle the Java objects that end up on the JMS destination. For example, WebLogic Web Services convert standard XML documents from a client into org.w3c.dom.Document objects, as described in XML-Java Conversion in WebLogic Web Services.

If the message-driven bean in your existing JMS application expects some other type of document object, then you can do one of two things: either reprogram the message-driven bean to accept org.w3c.dom.Document objects, or create a new message-driven bean that accepts org.w3c.dom.Document objects; converts them into the data type accepted by the original message-driven bean; and puts the new object on a JMS destination for the original message-driven bean to pick up.

Supported Data Types for Parameters and Return Values of WebLogic Web Services

To facilitate interoperability with other Web service implementations, both Java and non-Java, WebLogic limits the data types that can be used as parameters and return values to the Web service.

The following table lists the mapping between the supported Java data types and their XML equivalent.

Table 2-1 Java to XML Mapping

Java Data Type | Corresponding XML Data Type
--- | ---
int | int
boolean | boolean
float | float
long | long
short | short
double | double
java.lang.Integer | int
java.lang.Boolean | boolean
java.lang.Float | float
java.lang.Long | long
java.lang.Short | short
java.lang.Double | double
java.lang.String | string
java.math.BigDecimal | decimal
java.util.Date | dateTime
byte[] | base64Binary
java.lang.Object | anyType
JavaBeans whose properties are of the supported Java data types listed in this table or another JavaBean. | Compound struct whose members are of the supported XML data types listed in this table or another compound struct.
Arrays of supported Java data types listed in this table (except for the reference equivalents of primitive types, such as java.lang.Integer). Single-dimensional arrays only. | SOAP array of supported XML data types listed in this table. Single-dimensional arrays only.
org.w3c.dom.Document | No XML equivalent.
org.w3c.dom.DocumentFragment | No XML equivalent.
org.w3c.dom.Element | No XML equivalent.

The following table lists the mapping between the supported XML data types and their Java equivalent.

Table 2-2 XML to Java Mapping

XML Data Type | Corresponding Java Data Type
--- | ---
int | java.lang.Integer
boolean | java.lang.Boolean
float | java.lang.Float
long | java.lang.Long
short | java.lang.Short
double | java.lang.Double
decimal | java.math.BigDecimal
dateTime | java.util.Date
timeInstant | java.util.Date
byte | java.lang.Byte
base64Binary | byte[]
hexBinary | byte[]
Compound struct whose members are of the supported XML data types listed in this table or another compound struct. | JavaBeans whose properties are of the supported Java data types listed in this table or another JavaBean.
SOAP array of supported XML data types listed in this table. Single-dimensional arrays only. | Arrays of supported Java data types listed in this table (except for the reference equivalents of primitive types, such as java.lang.Integer). Single-dimensional arrays only.

XML-Java Conversion in WebLogic Web Services

WebLogic Web Services support the following two encoding styles:

- http://schemas.xmlsoap.org/soap/encoding/

- http://xml.apache.org/xml-soap/literalxml

Note: The preceding URIs are not "real" in the sense that you can actually invoke them in a browser. Rather, it is a standard convention to name encoding styles using URIs.

When a WebLogic Web Service receives data from a client, it uses the encoding style specified in the SOAP message to identify the data type of the parameter or message so that it can be converted to the correct Java object.

Note: If you create a Java client using WebLogic's generated Java client JAR file, you do not need to know about specific encoding styles, because the Java client JAR file contains code that handles it for you. This section is included for programmers who create non-Java clients that invoke WebLogic Web Services and need to know how they handle encoding styles.

If the SOAP packet specifies the SOAP encoding style, then the Web service tries to convert the XML data inside the body of the SOAP message into one of the Java data types listed in Supported Data Types for Parameters and Return Values of WebLogic Web Services.

If the conversion is unsuccessful (for example, if there is no corresponding Java data type defined for one of the parameters), then the Web service returns a SOAP fault to the client that invoked the Web service.

If the conversion from XML to Java is successful, then the different styles of Web services do different things:

- RPC-style Web services pass the resulting Java objects to the appropriate stateless session EJBs.

- Message-style Web services wrap the Java object into a JMS javax.jms.ObjectMessage data type and put the message on the appropriate JMS destination.

If the SOAP packet specifies the Literal XML encoding style, the Web service converts the XML data inside the body of the XML message into a org.w3c.dom.Element data type, and then either sends the document to a stateless session EJB or wraps the document in a javax.jms.ObjectMessage data type and puts the message on the appropriate JMS destination, depending on whether the Web service is RPC-style or message-style, respectively.

The reverse happens when WebLogic Web Services send data back to the client: org.w3c.dom.Element return values are encoded using the Literal XML encoding style before being sent back to the client, and other Java data types are encoded using the SOAP encoding style.

Security Issues

As previously discussed, WebLogic Web Services are packaged as standard J2EE Enterprise applications. Consequently, to secure access to the Web service, you secure access to some or all of the following standard J2EE components that make up the Web service:

- The SOAP servlets

- The stateless session EJB upon which an RPC-style Web service is based

You can use basic HTTP authentication or SSL to authenticate a client that is attempting to access a WebLogic Web Service. Because the preceding components are standard J2EE components, you secure them in using standard J2EE security procedures. For general information about basic HTTP authentication and SSL, see Programming WebLogic Security.

For information about implementing 2-way SSL so that a client invoking a WebLogic Web Service is required to present its digital cerficate, see Using 2-Way SSL When Invoking a WebLogic Web Service.

Securing Message-Style Web Services

You secure a message-style Web service by securing the SOAP servlet that handles the SOAP messages between the client and the service.

Note: You can also use this method to secure an RPC-style Web service, although BEA recommends instead that you secure the EJB, as described in Securing an RPC-Style Web service.

When you assemble a WebLogic Web Service, either using the wsgen Ant task or manually, you reference SOAP servlets in the web.xml file of the Web application. These SOAP servlets handle the SOAP messages between WebLogic Server and client applications. They are always deployed on WebLogic Server, and are shared by all deployed WebLogic Web Services.

The particular SOAP servlet referenced by a Web service depends on its type (RPC-style or message-style). The following list describes each SOAP servlet:

- weblogic.soap.server.servlet.DestinationSendAdapter—handles SOAP messages in a message-style Web service that receives data from a client application to a JMS destination.

- weblogic.soap.server.servlet.QueueReceiveAdapter—handles SOAP messages in a message-style Web service that sends data from a JMS Queue to a client application.

- weblogic.soap.server.servlet.TopicReceiveAdapter—handles SOAP messages in a message-style Web service that sends data from a JMS Topic to a client application.

- weblogic.soap.server.servlet.StatelessBeanAdapter—handles SOAP messages between an RPC-style Web service and a client application.

For example, assume you have created a message-style Web service in which client applications send data to a JMS destination; the SOAP servlet that handles the SOAP messages is weblogic.soap.server.servlet.DestinationSendAdapter. The wsgen Ant task used to assemble the Web service adds the following elements to the web.xml deployment descriptor of the Web application:

>     <servlet>
>       <servlet-name>sender</servlet-name>
>       <servlet-class>
>          weblogic.soap.server.servlet.DestinationSendAdapter
>       </servlet-class>
>       <init-param>
>         <param-name>topic-resource-ref</param-name>
>         <param-value>senderDestination</param-value>
>       </init-param>
>       <init-param>
>         <param-name>connection-factory-resource-ref</param-name>
>         <param-value>senderFactory</param-value>
>       </init-param>
>     </servlet>
>     ...

>     <servlet-mapping>
>       <servlet-name>sender</servlet-name>
>       <url-pattern>/sendMsg</url-pattern>
>     </servlet-mapping>

To restrict access to the DestinationSendAdapter SOAP servlet, you first define a role that is mapped to one or more principals in a security realm, then specify that the security constraint applies to this SOAP servlet by adding the following url-pattern element inside the web-resources-collection element to the web.xml deployment descriptor of the Web application:

>     <url-pattern>/sendMsg</url-pattern>

See Manually Assembling the Web Services Archive File, for information on the structure of the Enterprise Application archive created by the wsgen Ant task.

For detailed procedural information about restricting access to servlets, see Assembling and Configuring Web Applications.

Securing an RPC-Style Web service

Restrict access to an RPC-style Web service by restricting access to the stateless session EJB that implements the Web service.

Thus client applications that invoke the RPC-style Web service always have access to the Web application and SOAP servlets, but might not be able to invoke the EJB. This type of security is useful if you want to closely monitor who has access to the business logic of the EJB but do not want to block access to the entire Web service.

For information about restricting access to EJBs, see Programming WebLogic Enterprise JavaBeans.

Using 2-Way SSL When Invoking a WebLogic Web Service

In 2-way SSL, client applications that invoke a WebLogic Web Service are required to present their digital certificates to WebLogic Server, which validates digital certificates against a list of trusted certificate authorities.

To use 2-way SSL when writing a Java client to invoke a WebLogic Web Service, follow these steps:

1. Configure WebLogic Server for 2-way SSL protocol (also called mutual authentication) and certificate authentication.

   For details, see Configuring the SSL Protocol and Configuring Mutual Authentication.

2. Add the following lines of Java code to your client application before you obtain the context you are using the look up your Web service::

   >     System.out.println("********************** loading client certs");

   >     InputStream certs[] = new InputStream[3];
   >     certs[0]=new PEMInputStream(new FileInputStream("sample_key.pem"));
   >     certs[1]=new PEMInputStream(new FileInputStream("sample_cert.pem"));
   >     certs[2]=new PEMInputStream(new FileInputStream("sample_ca.pem"));

   >     h.put(SoapContext.SSL_CLIENT_CERTIFICATE, certs);

   >     String prov = "weblogic.net";

   >     String s = System.getProperty("java.protocol.handler.pkgs");
   >     if (s == null) {
   >         s = prov;
   >     } else if (s.indexOf(prov) == -1) {
   >         s += "|" + prov;
   >     }

   >     System.setProperty("java.protocol.handler.pkgs", s);

   In the preceding code excerpt:

   - sample_key.pem is the name of the file that contains the client's private key associated with the certificate.

   - sample_cert.pem is the name of the file that contains the client's certificate.

   - sample_ca.pem is the name of the file that contains the certificate of the Certificate Authority that issued the client's certificate.

Note: When establishing an SSL connection, the subject DN of the digital certificate must match the host name of the server initiating the SSL connection. Otherwise, the SSL connection is dropped. If you use the demonstration certificates provided by WebLogic Server, the host names will not match.

To avoid this situation, use the -Dweblogic.security.SSL.ignoreHostnameVerification=true flag when running your client application, or even when starting WebLogic Server if you want this to be true all the time. This flag disables the Host Name Verifier which compares the subject DNs and host names. This solution is recommended in development environments only. A more secure solution is to obtain a new digital certificate for the server making outbound SSL connections.

Implementing a WebLogic Web Service

Implementing a WebLogic Web Service refers to writing the Java code for the stateless session EJB (for RPC-style Web services) or a JMS listener (for message-style Web services) that is defined to be the entry point to the Web service. JMS listeners are typically message-driven beans. The stateless session EJB or JMS listener may contain all the Web service functionality, or it may call other EJBs to parcel out the work.

It is assumed that you have read and understood the design issues discussed in Designing a WebLogic Web Service, that you have designed your Web service, and that you essentially know the types of components you need to code.

Implementing an RPC-Style Web Service

To implement an RPC-style Web service, write the Java code for the stateless session EJB. Remember to use only the supported Java data types as the parameters and return value of the EJB, listed in Supported Data Types for Parameters and Return Values of WebLogic Web Services.

For detailed information about programming stateless session EJBs, see Programming WebLogic Enterprise JavaBeans.

Implementing Message-Style Web Services

There are two types of message-style Web services, as described in Message-Style Web Services and JMS: those that receive XML data from a client that invokes the Web service and those that send XML data to a client.

To implement a message-style Web service, follow these steps:

1. Use the Administration Console to configure the following JMS components of WebLogic Server:

   - The JMS destination (queue or topic) that will either receive the XML data from a client or send XML data to a client. Later, when you assemble the Web service as described in Assembling a WebLogic Web Service, you will use the name of this JMS destination.

   - The JMS Connection factory that the WebLogic Web Service uses to create JMS connections.

     See Configuring JMS Components for Message-Style Web Services for details on this step. For general information about JMS, see the WebLogic Server Administration Guide.

2. Write the Java code for the J2EE component (typically a message-driven bean) that will take messages off the JMS destination for message-style Web services that receive XML data from a client or will put messages on a JMS destination for message-style Web services that send XML data to a client.

   For detailed information about programming message-driven beans, see Programming WebLogic Enterprise JavaBeans.

Configuring JMS Components for Message-Style Web Services

This section assumes that you have already configured a JMS server. For information about configuring JMS servers, and general information about JMS, see the WebLogic Server Administration Guide and Programming WebLogic JMS.

To configure a JMS destination (either queue or topic) and JMS Connection Factory, follow these steps:

1. Invoke the Administration Console in your browser. For details, see Invoking the Administration Console.

2. Click to expand the Services node in the left pane and expand the JMS node.

3. Right-click the Connection Factories node and choose Configure a new JMSConnectionFactory from the drop-down list.

4. Enter a name for the Connection Factory in the Name field.

5. Enter the JNDI name of the Connection Factory in the JNDIName field.

6. Click Create.

7. Click the Targets tab.

8. Move the name of the WebLogic Server hosting the service to the Chosen list box, if not already there.

9. Click Apply.

10. Click to expand the Servers node under the JMS node in the left pane.

11. Click to expand your JMS server node.

12. Right-click the Destinations node and choose either:

    - Configure a new JMSTopic from the drop-down list if you want to create a topic

    - Configure a new JMSQueue if you want to create a queue.

13. Enter the name of the JMS destination in the Name text field.

14. Enter the JNDI name of the destination in the JNDIName text field.

15. Click Create.

Assembling a WebLogic Web Service

This section describes how to assemble all the components of a Web service so it can be deployed on WebLogic Server and accessed by remote clients.

Assembling a WebLogic Web Service Using Java Ant Tasks

Assembling a WebLogic Web Service refers to packaging all the components of the Web service, such as the EJB that implements an RPC-style Web service, supporting EJBs, the Web application that contains the SOAP servlet, and so on, into an Enterprise Application archive (*.ear) so it can be deployed on WebLogic Server.

Developers use a Java Ant task, called wsgen, to assemble WebLogic Web Services. The wsgen Ant task generates most of the WebLogic Web Service components, such as the Web application that contains the SOAP servlet and the application.xml file that describes the Enterprise Application archive. The only components you need to have previously created are the EJB or message-driven beans that implement the Web service.

For general information about Ant, see http://jakarta.apache.org/ant/index.html.

Note: The Java Ant utility included in WebLogic Server uses the ant (UNIX) or ant.bat (Windows) configuration files in the BEA_HOME\bin directory when setting the ANTCLASSPATH variable, where BEA_HOME is the directory in which WebLogic Server is installed. If you need to update the ANTCLASSPATH variable, make the appropriate changes to these files.

For detailed procedures for assembling WebLogic Web Services manually, see Manually Assembling the Web Services Archive File.

To assemble a WebLogic Web Service, follow these steps:

1. Create a temporary staging directory.

2. If you are assembling an RPC-style Web service, copy the EJB *.jar file that contains the EJB that implements the service, along with any supporting EJBs, to the staging directory.

3. Set up your environment.

   On Windows NT, execute the setEnv.cmd command, located in the directory BEA_HOME\config\domain, where BEA_HOME is the directory in which WebLogic Server is installed and domain refers to the name of your domain.

   On UNIX, execute the setEnv.sh command, located in the directory BEA_HOME/config/domain, where BEA_HOME is the directory in which WebLogic Server is installed and domain refers to the name of your domain.

4. Create a file called build.xml in the staging directory that contains the Ant task elements for assembling a WebLogic Web Service.

   For details on creating the build.xml file, refer to Example of an Ant build.xml File.

5. Change location to the staging directory and execute the Ant utility:

   $ ant

   The wsgen Ant task creates an *.ear file containing the service components in the staging directory. You are now ready to deploy this *.ear file on WebLogic Server.

Example of an Ant build.xml File

WebLogic Server includes the wsgen Ant task to help you quickly assemble the components of a WebLogic Web Service into an Enterprise archive file.

The following example shows a build.xml file that assembles three Web services: one RPC-style and two message-style (one for sending messages and one for receiving messages). Table 2-3 describes the file elements.

Listing 2-1 Example build.xml File for Assembling WebLogic Web Services

>     <project name="myProject" default="wsgen">
>        <target name="wsgen">
>           <wsgen
>                  destpath="myWebService.ear"
>                  context="/myContext"
>                  protocol="http">
>              <rpcservices path="myEJB.jar">
>                 <rpcservice
>                    bean="statelessSession"
>                    uri="/rpc_URI"/>
>              </rpcservices>
>              <messageservices>
>                <messageservice
>                  name="sendMsgWS"
>                  action="send"
>                  destination="examples.soap.msgService.MsgSend"
>                  destinationtype="topic"
>                  uri="/sendMsg"
>                  connectionfactory="examples.soap.msgService.MsgConnectionFactory"/>
>               <messageservice
>                  name="receiveMsgWS"
>                  action="receive"
>                  destination="examples.soap.msgService.MsgReceive"
>                  destinationtype="topic"
>                  uri="/receiveMsg"
>                  connectionfactory="examples.soap.msgService.MsgConnectionFactory"/>
>           </messageservices>
>           </wsgen>
>        </target>
>     </project>

Table 2-3 Description of build.xml Example

Element or Attribute | Description
--- | ---
wsgen element | Specifies the wsgen Ant task used to assemble the Web service.
destpath attribute | Specifies that the resulting Enterprise archive will be called myWebService.ear.
context attribute | Specifies that the context root of the Web service is called /myContext. You will later use this context root in the URL used to view the generated WSDL for the Web service and to download the Java client JAR file.
protocol attribute | Specifies that clients use HTTP to invoke the service.
rpcservices element | Contains the single RPC-style Web service that is associated with the /myContext context.
path attribute | Specifies that the EJBs are archived in a JAR file called myEJB.jar.
rpcservice element | Specifies the properties of the RPC-style Web service.
bean attribute | Specifies that the name of the stateless session EJB that implements the RPC-style Web service is statelessSession. This name corresponds to the ejb-name element in the ejb-jar.xml file of the EJB archive in which the EJB is contained. The path to the EJB archive is specified in the parent rpcservices element using the path attribute.
uri attribute | Specifies that the URI of the service is /rpc_URI. This URI is used in the URL to access the WSDL of the Web service.
messageservices element | Contains two message-style Web services that are associated with the /myContext context.
messageservice element | Specifies the properties of each message-style Web service.
name attribute | Assigns a unique name to each service: sendMsgWS and receiveMsgWS.
action attribute | Specifies whether a client that invokes the Web service sends or receives messages from the service. The first service specifies send, the second receive.
destination attribute | Specifies the JNDI name of the JMS destination that sends or receives messages. The first service specifies examples.soap.msgService.MsgSend, the second specifies examples.soap.msgService.MsgReceive.
destinationtype attribute | Specifies whether the JMS destination is a topic or a queue. Both services specify topic.
uri attribute | Specifies that the URIs of the services are /sendMsg and /receiveMsg, respectively. The URIs are combined to create the complete URL to the WSDL of the Web service
connectionfactory attribute | Specifies the JNDI name of the Connection Factory used to create a JMS connection. Both services use the same Factory: examples.soap.msgService.MsgConnectionFactory.

For a detailed description of the elements and attributes of the build.xml file, refer to build.xml Elements and Attributes.

Creating the build.xml Ant Build File

The following procedure describes the Ant task elements you must include in your build.xml file to correctly assemble a WebLogic Web Service; use the example in the preceding section as a guide.

For detailed description of the elements and attributes of the build.xml file mentioned in the following procedure, as well as additional elements you can specify, refer to build.xml Elements and Attributes.

See Editing XML Files for information on using the BEA XML Editor to create and edit the build.xml file.

To create a build.xml Ant build file for assembling WebLogic Web Services:

1. Create an empty file called build.xml using your favorite text editor.

2. Add one <project> element with the following two attributes:

   - name - the name of your project.

   - default - set this attribute to wsgen.

3. Within the <project> element, add a <target> element with one attribute, name; set the name attribute to wsgen.

4. Within the <target> element, add a <wsgen> element with the following attributes:

   - destpath

   - context

   - protocol

5. If you are assembling one or more RPC-style Web services, add a single <rpcservices> element within the <wsgen> element with the following attributes:

   - path

6. Within the <rpcservices> element, add an <rpcservice> element for each RPC-style Web service you are assembling, with the following attributes:

   - bean

   - uri

7. If you are assembling one or more message-style Web services, add a single <messageservices> element within the <wsgen> element.

8. Within the <messageservices> element, add a <messageservice> element for each message-style Web service you are assembling, with the following attributes that describe the JMS destination and Connection factory that you previously set up for the message-style Web service:

   - name

   - action

   - destination

   - destinationtype

   - uri

   - connectionfactory

Dynamic or Static WSDL?

WebLogic Web Services publish their WSDL files as JSPs. The WSDL JSP can either hard-code the host and port of a specific WebLogic Server, or it can dynamically generate the host and port based on the WebLogic Server that is hosting the service.

Typically, you want the WSDL of a WebLogic Web Service to dynamically generate the host and port, and you do this by not specifying the host and port attributes of the wsgen element in the build.xml Ant file used to assemble the Web service. If, however, you want the host and port to be hard-coded in the WSDL JSP, explicitly specify the host and port attributes.

Deploying a WebLogic Web Service

Deploying a WebLogic Web Service refers to making it available to remote clients. Because WebLogic Web Services are packaged as standard J2EE Enterprise applications, deploying a Web service is the same as deploying an Enterprise application.

For detailed information on deploying Enterprise applications, see BEA WebLogic Server Administration Guide.

Developing a WebLogic Web Service: A Simple Example

This section describes the start-to-finish process of developing, assembling, and deploying the sample RPC-style WebLogic Web Service provided as a product example in the directory BEA_HOME/samples/examples/rpc.

To develop the sample Weather RPC-style WebLogic Web Service, follow these basic steps:

1. Set up your environment.

   On Windows NT, execute the setEnv.cmd command, located in the directory BEA_HOME\config\domain, where BEA_HOME is the directory in which WebLogic Server is installed and domain refers to the name of your domain.

   On UNIX, execute the setEnv.sh command, located in the directory BEA_HOME/config/domain, where BEA_HOME is the directory in which WebLogic Server is installed and domain refers to the name of your domain.

2. Write the Java interfaces and classes for the Weather stateless session EJB.

   See Writing the Java Code for the EJB for details.

3. Compile the EJB Java code into class files.

4. Create the EJB deployment descriptors.

   See Creating EJB Deployment Descriptors for details.

5. Assemble the EJB class files and deployment descriptors into a weather.jar archive file.

   See Assembling the EJB for details.

6. Create the build.xml Java Ant build file used to assemble the WebLogic Web Service.

   See Creating the build.xml File for details.

7. Create a staging directory.

8. Copy the EJB weather.jar file and the build.xml file into the staging directory.

9. Execute the Java Ant utility to assemble the Weather Web service into a weather.ear archive file:

   >     $ ant

10. Auto-deploy the Weather Web service for testing purposes by copying the weather.ear archive file to the BEA_HOME/config/domain/applications directory, where BEA_HOME refers to the main WebLogic Server installation directory and domain refers to the name of your domain.

To invoke the Weather Web service from both a Java and a Visual Basic client application, see the examples in BEA_HOME/samples/examples/webservices/rpc/javaClient and BEA_HOME/samples/examples/webservices/rpc/vbClient.

For instructions for building and running the client applications, invoke the BEA_HOME/samples/examples/webservices/rpc/package-summary.html Web page in your browser.

Writing the Java Code for the EJB

The sample Weather stateless session EJB contains one public method: getTemp(). The method takes a single argument, a zip code, and returns a float value of 77 if the zip code is 90210 and -273.15 otherwise.

Note: This method obviously simulates a real-world Web service that returns the actual temperature at a given zip code.

The following Java code is the public interface of the Weather EJB:

>     package examples.webservices.rpc.weatherEJB;

>     import java.rmi.RemoteException;
>     import javax.ejb.EJBObject;

>     /**
>      * The methods in this interface are the public face of WeatherBean.
>      * The signatures of the methods are identical to those of the EJBean, except
>      * that these methods throw a java.rmi.RemoteException.
>      * Note that the EJBean does not implement this interface. The corresponding
>      * code-generated EJBObject, WeatherBean, implements this interface and
>      * delegates to the bean.
>      *
>      * @author Copyright (c) 1998 by WebLogic, Inc. All Rights Reserved.
>      * @author Copyright (c) 2001 by BEA Systems, Inc. All Rights Reserved.
>      */

>     public interface Weather extends EJBObject {
>       /**
>        * Gets the temperature of a given ZipCode.
>        *
>        * @param ZipCode           String Stock symbol
>        * @return                  double Temperature
>        * @exception               RemoteException if there is
>        *                          a communications or systems failure
>        */

>       public float getTemp(String ZipCode) throws RemoteException;
>     }

The following Java code is the actual stateless session EJB class:

>     package examples.webservices.rpc.weatherEJB;

>     import javax.ejb.CreateException;
>     import javax.ejb.SessionBean;
>     import javax.ejb.SessionContext;
>     import javax.naming.InitialContext;
>     import javax.naming.NamingException;

>     /**
>      * WeatherBean is a stateless Session Bean. This bean illustrates:
>      * <ul>
>      * <li> No persistence of state between calls to the Session Bean
>      * <li> Looking up values from the Environment
>      * </ul>
>      *
>      * @author Copyright (c) 1998 by WebLogic, Inc. All Rights Reserved.
>      * @author Copyright (c) 2001 by BEA Systems, Inc. All Rights Reserved.
>      */

>     public class WeatherBean implements SessionBean {
>       private static final boolean VERBOSE = true;
>       private SessionContext ctx;
>       private int tradeLimit;
>       // You might also consider using WebLogic's log service

>       private void log(String s) {
>         if (VERBOSE) System.out.println(s);
>       }
>       /**
>        * This method is required by the EJB Specification,
>        * but is not used by this example.
>        *
>        */
>       public void ejbActivate() {
>         log("ejbActivate called");
>       }
>       /**
>        * This method is required by the EJB Specification,
>        * but is not used by this example.
>        *
>        */
>       public void ejbRemove() {
>         log("ejbRemove called");
>       }
>       /**
>        * This method is required by the EJB Specification,
>        * but is not used by this example.
>        *
>        */
>       public void ejbPassivate() {
>         log("ejbPassivate called");
>       }
>       /**
>        * Sets the session context.
>        *
>        * @param ctx               SessionContext Context for session
>        */
>       public void setSessionContext(SessionContext ctx) {
>         log("setSessionContext called");
>         this.ctx = ctx;
>       }
>       /**
>        * This method corresponds to the create method in the home interface
>        * "WeatherHome.java".
>        * The parameter sets of the two methods are identical. When the client calls
>        * <code>WeatherHome.create()</code>, the container allocates an instance of
>        * the EJBean and calls <code>ejbCreate()</code>.
>        *
>        * @exception               javax.ejb.CreateException if there is
>        *                          a communications or systems failure
>        * @see                     examples.ejb.basic.statelessSession.Weather
>        */
>       public void ejbCreate () throws CreateException {
>         log("ejbCreate called");
>         try {
>           InitialContext ic = new InitialContext();
>         } catch (NamingException ne) {
>           throw new CreateException("Failed to find environment value "+ne);
>         }
>       }
>       /**
>        * Gets the temperature of a given ZipCode.
>        *
>        * @param ZipCode           String ZipCode
>        * @return                  float Temperature
>        * @exception               RemoteException if there is
>        *                          a communications or systems failure
>        */
>       public float getTemp(String ZipCode) {
>         log("getTemp called");
>         Float result;
>         if (ZipCode.equals("90210")) {
>           result = new Float(77.0);
>         } else {
>           result = new Float(-273.15);
>         }
>         return result.floatValue();
>       }
>     }

The following Java code is the Home interface of the Weather EJB:

>     package examples.webservices.rpc.weatherEJB;

>     import java.rmi.RemoteException;
>     import javax.ejb.CreateException;
>     import javax.ejb.EJBHome;

>     /**
>      * This interface is the home interface for the WeatherBean.java,
>      * which in WebLogic is implemented by the code-generated container
>      * class WeatherBeanC. A home interface may support one or more create
>      * methods, which must correspond to methods named "ejbCreate" in the EJBean.
>      *
>      * @author Copyright (c) 1998 by WebLogic, Inc. All Rights Reserved.
>      * @author Copyright (c) 2001 by BEA Systems, Inc. All Rights Reserved.
>      */
>     public interface WeatherHome extends EJBHome {
>       /**
>        * This method corresponds to the ejbCreate method in the bean
>        * "WeatherBean.java".
>        * The parameter sets of the two methods are identical. When the client calls
>        * <code>WeatherHome.create()</code>, the container
>        * allocates an instance of the EJBean and calls <code>ejbCreate()</code>.
>        *
>        * @return                  Weather
>        * @exception               RemoteException if there is
>        *                          a communications or systems failure
>        * @exception               CreateException
>        *                          if there is a problem creating the bean
>        * @see                     examples.ejb.basic.statelessSession.WeatherBean
>        */
>       Weather create() throws CreateException, RemoteException;
>     }

Creating EJB Deployment Descriptors

See Editing XML Files for information on using the BEA XML Editor to create and edit the ejb-jar.xml and weblogic-ejb-jar.xml files.

The following example shows the ejb-jar.xml deployment descriptor that describes the Weather EJB:

>     <?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>statelessSession</ejb-name>
>                        <home>
>                            examples.webservices.rpc.weatherEJB.WeatherHome
>                        </home>
>                        <remote>
>                            examples.webservices.rpc.weatherEJB.Weather
>                        </remote>
>                        <ejb-class>
>                            examples.webservices.rpc.weatherEJB.WeatherBean
>                        </ejb-class>
>                        <session-type>Stateless</session-type>
>                        <transaction-type>Container</transaction-type>
>                     </session>
>             </enterprise-beans>
>             <assembly-descriptor>
>                     <container-transaction>
>                        <method>
>                           <ejb-name>statelessSession</ejb-name>
>                           <method-intf>Remote</method-intf>
>                           <method-name>*</method-name>
>                        </method>
>                        <trans-attribute>Required</trans-attribute>
>                     </container-transaction>
>             </assembly-descriptor>
>     </ejb-jar>

The following example shows the weblogic-ejb-jar.xml deployment descriptor that describes the Weather EJB:

>     <?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>statelessSession</ejb-name>
>                     <caching-descriptor>
>                         <max-beans-in-free-pool>100</max-beans-in-free-pool>
>                     </caching-descriptor>
>                     <jndi-name>statelessSession.WeatherHome</jndi-name>
>             </weblogic-enterprise-bean>
>     </weblogic-ejb-jar>

Assembling the EJB

To assemble the EJB class files and deployment descriptors into a weather.jar archive file, follow these steps:

1. Create a temporary staging directory.

2. Copy the compiled Java EJB class files into the staging directory.

3. Create a META-INF subdirectory in the staging directory.

4. Copy the ejb-jar.xml and weblogic-ejb-jar.xml deployment descriptors into the META-INF subdirectory.

5. Create the weather.jar archive file using the jar utility:

   >     jar cvf weather.jar -C staging_dir .

Creating the build.xml File

See Editing XML Files for information on using the BEA XML Editor to create and edit the build.xml file.

The following build.xml file references the wsgen Java ant task that assembles the weather.jar archive file into a WebLogic Web Service weather.ear enterprise application archive file:

>     <project name="weather-webservice" default="wsgen">
>         <target name="wsgen">
>           <wsgen
>              destpath="weather.ear"
>              context="/weather">
>             <rpcservices path="weather.jar">
>                     <rpcservice bean="statelessSession" uri="/weatheruri"/>
>             </rpcservices>
>           </wsgen>
>         </target>
>     </project>

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