Skip navigation.
Downloads | Product Documentation | Support

Programming WebLogic Web Services

# Using WebLogic Workshop With WebLogic Web Services

The following sections describe how to use WebLogic Workshop to create WebLogic Web Services:

- Overview of WebLogic Workshop and WebLogic Web Services
- Using WebLogic Workshop To Create a WebLogic Web Service: A Simple Example
- Using WebLogic Workshop To Create a WebLogic Web Service: A More Complex Example

# Overview of WebLogic Workshop and WebLogic Web Services

This document provides examples and scenarios of using different technologies of WebLogic Platform (Workshop IDE) to create WebLogic Web Services. The overview information is divided into the following topics:

- WebLogic Workshop and WebLogic Web Services
- EJBGen
- Using Meta-Data Tags When Creating EJBs and Web Services

## WebLogic Workshop and WebLogic Web Services

Today in Java, there are two main programming models for developing Web Services. Both of these models are supported by BEA. The first is defined in JAX-RPC, which relies on a back-end EJB or a plain Java Object to provide the business logic of the Web Service. To develop Web Services using this model you can use the WebLogic Web Services Ant tasks (such as `servicegen`). The second model is based on code annotation as defined in JSR-181, Web Services Metadata for the Java Platform. The model used to develop Web Services in WebLogic Workshop is a precursor to JSR-181. Whether you decide to use the JAX-RPC model or the WebLogic Workshop model, the Web Services you develop will deploy and run on WebLogic Server, however the SOAP implementation and dispatch model will vary depending on which programming model you choose.

Typically, this difference in SOAP implementation is transparent and unimportant. However, due to the differences in the programming models and the slight differences in the characteristics of the two runtimes, you sometimes might want to use WebLogic Workshop to create applications that run on the runtime supported by the JAX-RPC programming model. To do so, you cannot use annotated JWS files, the standard way to create Web Services in WebLogic Workshop. Rather, you use WebLogic Workshop to create the back-end component (stateless session EJB), export the EJB and an Ant build script that builds the component, then add calls to the Web Service Ant tasks to the build script to package everything up into a Web Service than runs on the runtime supported by the JAX-RPC model. The examples in this document show how to go through this process.

Once you have exported the EJB to a JAR file from WebLogic Workshop, follow the standard guidelines outlined in this book to create a Web Service that runs on the runtime supported by the JAX-RPC programming model. In particular, refer to:

- Assembling WebLogic Web Services Using Ant Tasks for procedural information about using the Ant tasks.
- Web Service Ant Tasks and Command-Line Utilities for reference information about the Ant tasks.
- Deploying and Testing WebLogic Web Services for information about deploying and testing the Web Service.

## EJBGen

When you use WebLogic Workshop to create a stateless session EJB back-end component, you are actually using a plug-in called EJBGen, an EJB 2.0 code generator. When you write the code for your EJB in Workshop, you use special `@ejbgen` Javadoc tags to describe what the EJB looks like, and then, when you build your EJB, Workshop calls the EJBGen plug-in to generate the remote and home interface classes and the deployment descriptor files.

EJBGen can also be executed as a command-line utility, which means that the same `*.ejb` file you use in Workshop can also be processed outside of Workshop. (The only difference is that you must change the extension from `*.ejb` to `*.java`.) Use the java command, as shown in the following example:

>     java weblogic.tools.ejbgen.EJBGen myEJB.java

One way of using the command-line version of EJBGen is to add it to the Ant build script that calls the Ant tasks, such as `servicegen`, to build your WebLogic Web Service so that you can re-generate your EJB without having to use Workshop.

Because you can use EJBGen both within Workhop and as a command-line utility, it is assumed in the examples in this document that you might use either flavor, even if the example describes one particular flavor.

For details about using the command-line EJBGen tool, see EJBGen Reference. For details about the EJBGen Workshop plug-in, see the Developing Enterprise JavaBeans topic in the left frame of the WebLogic Workshop Help.

## Using Meta-Data Tags When Creating EJBs and Web Services

The examples in this document show how to use meta-data tags in Java source code files to create Web Services. These meta-data tags come in two flavors:

- those used by EJBgen, specified with the `@ejbgen` Javadoc tag.
- those used by the WebLogic Web Service `source2wsdd` Ant task, specified with the `@wlws` Javadoc tag.

You use meta-data Javadoc tags in a Java source file to specify in more detail what an EJB, and the Web Service that exposes the EJB, look like. Then you use either EJBGen or the `source2wsdd` Ant task (or both) to generate the additional components. In particular, EJBGen generates the EJB deployment descriptors and the EJB Home and Remote interfaces; the `source2wsdd` Ant task generates the Web Services deployment descriptor file.

For reference information about the EJBGen tags, see EJBGen Reference. For information about the `source2wsdd` tags, see source2wsdd Tag Reference.

# Using WebLogic Workshop To Create a WebLogic Web Service: A Simple Example

This section describes a simple example of creating a WebLogic Web Service using the WebLogic Workshop IDE.

Note: This procedure works only with Service Pack 2 of WebLogic Workshop. For an example that works on the GA version of WebLogic Workshop, see Using WebLogic Workshop To Create a WebLogic Web Service: A More Complex Example.

The example first uses Workshop to create a stateless session EJB called `PurchaseOrderBean`, and then uses the `servicegen` WebLogic Web Services Ant task to expose the EJB as a Web Service that runs on the runtime supported by the JAX-RPC programming model. In this example, all the business logic is directly in the `PurchaseOrderBean`, which exposes two methods as Web Service operations: `submitPO` and `getStatus`.

Note: The following procedure does not always describe the exact steps you must perform in the IDE to create the various projects and objects. For this kind of detailed information, see the Developing Enterprise JavaBeans topic in the left frame of the WebLogic Workshop Help.

1. Invoke WebLogic Workshop from the Start menu.
2. If one does not already exist, create an application that will contain the stateless session EJB.

It is assumed in the procedure that the application is named `myApp`.

3. If one does not already exist, create an EJB project under your Workshop application.

It is assumed that the project is named `myEJBs`.

4. Create a folder under the EJB project.

It is assumed that the folder is named `myPackage`.

5. Create a Session bean under the `myPackage` folder.

It is assumed that your EJB is named `PurchaseOrderBean.ejb`.

6. Click Source View and update `PurchaseOrderBean.ejb`, replacing all the code after the `package myPackage` statement with the following code:

>     import javax.ejb.*;
>     import weblogic.ejb.*;

>     /**
>     * @ejbgen:session
>     *      ejb-name = "PurchaseOrder"
>     *
>     * @ejbgen:jndi-name
>     *      remote = "ejb.PurchaseOrderRemoteHome"
>     *
>     * @ejbgen:file-generation
>     *      remote-class = "true"
>     *      remote-class-name = "PurchaseOrder"
>     *      remote-home = "true"
>     *      remote-home-name = "PurchaseOrderHome"
>     *      local-class = "false"
>     *      local-class-name = "PurchaseOrderLocal"
>     *      local-home = "false"
>     *      local-home-name = "PurchaseOrderLocalHome"
>      */
>     public class PurchaseOrderBean
>       extends GenericSessionBean
>       implements SessionBean
>     {
>       public void ejbCreate() {
>         // Your code here
>       }

>         /**
>          * @ejbgen:remote-method
>          */
>         public long submitPO(String PoText)
>         {
>             return System.currentTimeMillis();
>         }

>         /**
>          * @ejbgen:remote-method
>          */
>         public int getStatus(long orderNo)
>         {
>             return 0;
>         }
>     }

7. Ensure that the EJB builds correctly by right-clicking on the `myEJBs` project in the application pane and selecting Build myEJBs.
8. Export the Ant build file that builds the `PurchaseOrder` EJB outside of Workshop by clicking Tools->Application Properties..., choosing Build in the left pane, and clicking the Export to Ant File button.

A file called `exported_build.xml` is generated in the project directory of your Workshop application.

Make a note of the project directory, listed under the EAR heading in the right pane.

9. Open a command window change to the project directory of your Workshop application.
10. Edit the `exported_build.xml` file, adding the following elements to invoke the `servicegen` Ant task on the `PurchaseOrder` EJB you created in Workshop:

- A taskdef definition for the `servicegen` Ant task:

>       <taskdef name="servicegen"
>                classname="weblogic.ant.taskdefs.webservices.servicegen.ServiceGenTask"
>               classpath="${server.classpath}" />

- A target for the `servicegen` Ant task:

>      <target name="servicegen">
>        <delete file="${output.file}" />
>        <servicegen
>          destEar="${output.file}"
>        >
>          <service
>             ejbJar="myEJBs.jar"
>             serviceName="PurchaseOrderService"
>             serviceURI="/PurchaseOrderService"
>             targetNamespace="http://example.com/PurchaseOrderService"
>          />
>        </servicegen>
>      </target>

1. Set your environment by executing the `setEnv.cmd` command, located in your domain directory. The default location of WebLogic Server domains is `BEA_HOME``\user_projects\domains\`domainName, where `BEA_HOME` is the top-level installation directory of the BEA products and `domainName` is the name of your domain.
2. Execute the `build` and `servicegen` Ant tasks of the `exported_build.xml` file:

>     prompt> ant -f exported_build.xml build servicegen

The `servicegen` target of the Ant task updates the application, exposing the `PurchaseOrder` EJB as a WebLogic Web Service.

3. Deploy the application as usual. For details, see Deploying and Testing WebLogic Web Services.

# Using WebLogic Workshop To Create a WebLogic Web Service: A More Complex Example

This section describes a more complex example of creating a WebLogic Web Service using the WebLogic Workshop IDE.

## Description of the Example

In the example, the `PurchaseOrderServiceBean` EJB is exposed as a Web Service, but it does not contain any business logic. It has one operation that accepts a purchase order number from an incoming SOAP request and returns a `PurchaseOrder` object in the SOAP response. The `PurchaseOrderServiceBean` EJB that is exposed as a Web Service delegates all the actual work of looking up a purchase order to a conventional session facade EJB called `PurchasingManagerBean`. This EJB implements all the business logic of the application, independent of the Web Service entry point. The EJB uses the `Item` and `PurchaseOrder` complex data types when processing purchase orders, and creates new `PurchaseOrder` objects using the `PurchaseOrderFactory`.

The `PurchaseOrderServiceBean` EJB, in addition to using EJBGen Javadoc tags as in the preceding example, also uses WebLogic Web Service `source2wsdd` tags, identified with the `@wlws` prefix. Because of the use of meta-data tags, the example uses individual Ant tasks, such as `source2wsdd` and `autotype`, to assemble a Web Service, rather than the all-encompassing `servicegen` Ant task. For details about the `source2wsdd` tags, see source2wsdd Tag Reference.

The example also shows how to use a SOAP message handler. The SOAP message handler looks for a SOAP header called My-Username in the SOAP request from a client, and if it exists, it extracts the value, and logs a message that includes the name to a log file. If the header does not exist, the SOAP message handler logs a message with `Unknown` as the username. For additional information about SOAP message handlers, see Creating SOAP Message Handlers to Intercept the SOAP Message.

## Assumptions

This main point of this example is to show how to use WebLogic Workshop to create an EJB and SOAP message handler that together will be exposed as a Web Service, and then how to package it all together into a deployable EAR file than runs on the runtime supported by the JAX-RPC programming model. For this reason, it is assumed that you have already:

- Created an application in WebLogic Workshop, called `myComplexApp`, that contains an EJB Project called `PurchaseOrderService`.
- Within the `PurchaseOrderService` EJB project, created a folder called `po` that contains the EJB that performs all the business logic (`PurchasingManagerBean`) as well as the various objects used by the `PurchasingManagerBean` EJB, such as `Item`, `PurchaseOrder`, and `PurchaseOrderFactory`.

See Source Code for Supporting Java Objects for sample source code for these objects.

## The Example

Note: The following procedure does not always describe the exact steps you must perform in the IDE to create the various projects and objects. For this kind of detailed information, see the Developing Enterprise JavaBeans topic in the left frame of the WebLogic Workshop Help.

1. Invoke WebLogic Workshop from the Start menu.
2. Create a folder under the `PurchaseOrderService` EJB project called `service`.
3. Create a Session bean under the `service` folder called `PurchaseOrderServiceBean.ejb`.
4. Click Source View and update `PurchaseOrderBean.ejb`, replacing all the Workshop-generated Java code with the following code:

>     package service;

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

>     import po.PurchasingManagerLocal;
>     import po.PurchasingManagerLocalHome;

>     /**
>      * This is the web service facade. It defines the web service
>      * operations and contains any web service-specific
>      * application logic (such as logging invokes in a handler).
>      *
>      * @ejbgen:session
>      *   ejb-name = "PurchaseOrderServiceEJB"
>      * @ejbgen:jndi-name
>      *   local = "PurchaseOrderService"
>      * @ejbgen:ejb-local-ref
>      *   link = "PurchasingManagerEJB"
>      * @wlws:webservice
>      *  name="PurchaseOrderService"
>      *  targetNamespace="http://openuri.org/easypo_service"
>      *  style="document"
>      */

>     public class PurchaseOrderServiceBean implements SessionBean {

>          // local interface of the PurchasingManager session facade
>          PurchasingManagerLocal pm = null;

>         /**
>          * This operation return a PurchaseOrder that is retrieved from
>          *  the PurchasingManager

>          *  @ejbgen:local-method
>          *  @wlws:operation handler-chain = "PurchaseOrderServiceHandlerChain"
>          */
>         public po.PurchaseOrder getPurchaseOrder(String poNumber) {
>             return pm.getPO(poNumber);
>         }
>         public void ejbCreate() throws CreateException {
>             try {
>                 InitialContext ctx = new InitialContext();
>                 PurchasingManagerLocalHome pmhome = (PurchasingManagerLocalHome) ctx.lookup("java:/comp/env/ejb/PurchasingManagerEJB");
>                 pm = pmhome.create();
>             } catch (NamingException ne) {
>                 throw new CreateException("Could not locate PurchasingManager EJB");
>             }
>         }

>         public void ejbRemove() {
>         }

>         public void ejbPassivate() {
>         }

>         public void ejbActivate() {
>         }

>         public void setSessionContext(SessionContext ctx) {
>         }

>     }

1. Create a Java class under the `service` folder called `PurchaseOrderServiceHandler.java`. This class implements the server-side SOAP message handler.
2. In the middle pane, replace all the Workshop-generated Java code of `PurchaseOrderServiceHandler.java` with the following code:

>     package service;

>     import javax.xml.rpc.handler.Handler;
>     import javax.xml.rpc.handler.MessageContext;
>     import javax.xml.rpc.handler.HandlerInfo;
>     import javax.xml.rpc.handler.soap.SOAPMessageContext;
>     import javax.xml.namespace.QName;
>     import javax.xml.soap.*;
>     import java.io.FileWriter;
>     import java.io.IOException;
>     import java.io.PrintWriter;
>     import java.util.Map;
>     import java.util.Iterator;
>     import java.util.Date;

>     /**
>      * Represents a JAX-RPC handler that intercepts an incoming SOAP message,
>      * extracts an optional header called"My-Username" and logs a message to a
>      * log file.
>      */

>     public class PurchaseOrderServiceHandler implements Handler {
>         private static final String HEADER_NAME = "My-Username";
>         private PrintWriter out;

>         public QName[] getHeaders() {
>             return new QName[]{new QName(HEADER_NAME)};
>         }

>         public boolean handleRequest(MessageContext messageContext) {
>             String userName = null;
>             try {
>                 userName = getHeaderValue(messageContext, HEADER_NAME);
>             } catch (SOAPException e) {
>                 throw new RuntimeException("Could not retrieve header value", e);
>             }
>             if (userName == null) userName = "UNKNOWN";
>               out.println(new Date() + ": Received request from username " + userName);
>             out.flush();
>             return true;
>         }

>         public boolean handleResponse(MessageContext messageContext) {
>             return true;
>         }

>         public boolean handleFault(MessageContext messageContext) {
>             return true;
>         }

>         public void init(HandlerInfo handlerInfo) {
>             Map config = handlerInfo.getHandlerConfig();
>             String logFileName = (String) config.get("logFile");
>             if (logFileName == null) {
>                 throw new RuntimeException("Could not initialize handler; logFile not specified in init-params.");
>             }
>             try {
>                 out = new PrintWriter(new FileWriter(logFileName));
>             } catch (IOException e) {
>                 throw new RuntimeException("Could not initialize handler; could not open log file " + logFileName, e);
>             }
>         }

>         public void destroy() {
>             out.close();
>         }

>         private static String getHeaderValue(MessageContext messageContext,
>                  String headerName) throws SOAPException {
>             SOAPFactory fact = SOAPFactory.newInstance();
>             SOAPMessageContext ctx = (SOAPMessageContext) messageContext;
>             SOAPHeader headers =
>                  ctx.getMessage().getSOAPPart().getEnvelope().getHeader();

>             Iterator i = headers.getChildElements(fact.createName(HEADER_NAME));
>             while (i.hasNext()) {
>                 SOAPElement elt = (SOAPElement) i.next();
>                 if (headerName.equals(elt.getElementName().getLocalName())) {
>                     return elt.getValue();
>                 }
>             }
>             return null;
>         }
>     }

1. Create an XML file called `handler-chain.xml` under the `service` folder.

This XML file will contain a description of the SOAP message handler and handler chain used by the Web Service. The file will late be used by the `source2wsdd` Ant task when generating the Web Service deployment descriptor.

2. In the middle pane, replace the Workshop-generated `<root></root>` XML elements with the following XML:

>     <handler-chains>
>         <handler-chain name="PurchaseOrderServiceHandlerChain">
>             <handler class-name="service.PurchaseOrderServiceHandler">
>                 <init-params>
>                     <init-param name="logFile" value="./posvc.log" />
>                 </init-params>
>             </handler>
>         </handler-chain>
>     </handler-chains>

3. Click Tools->Application Properties... and choose Build in the left pane. Make a note of the project directory, listed under the EAR heading in the right pane.
4. Open a command window and change to the project directory of your Workshop application.
5. Set your environment by executing the `setEnv.cmd` command, located in your domain directory. The default location of WebLogic Server domains is `BEA_HOME``\user_projects\domains\`domainName, where `BEA_HOME` is the top-level installation directory of the BEA products and `domainName` is the name of your domain
6. Ensure you can rebuild your EJB project from the command line by exeucting the `WL_HOME``\workshop\wlwBuild.cmd`, where `WL_HOME` refers to the main WebLogic Platform directory, such as `c:\beahome\weblogic81`. Use the `-project` option to pass it the name of the EJB project, as shown in the following example:

>     prompt> c:\beahome\weblogic81\workshop\wlwBuild.cmd -project PurchaseOrderService

You can add this line to your automated shell scripts that iteratively build the application.

7. In the Workshop project directory, create an Ant `build.xml` file that includes calls to the `autotype` and `source2wsdd` WebLogic Web Service ant tasks.

These Ant tasks take the compiled EJB and SOAP message handler class and create the needed Web Services components, such as the deployment descriptor and data type components. For an example of this file, see Sample build.xml File.

8. Execute the Ant tasks by running the `ant` command:

>     prompt> ant

If you use a build.xml file similar to the sample, the Ant task create a deployable EAR file called `PurchaseOrderService.ear` in a directory called output that is parallel to the Workshop project directory.

9. Deploy the `PurchaseOrderService.ear` file as usual. For details, see Deploying and Testing WebLogic Web Services.

## Sample build.xml File

>     <project name="build-scenario1" default="build">

>         <!-- WebLogic Home. -->
>         <property name="platformhome" value="/home/toddk/bea/weblogic81"/>

>         <!-- base url of the server and administrator user, password -->
>         <property name="server_url" value="http://localhost:7001"/>
>         <property name="admin_user" value="weblogic"/>
>         <property name="admin_passwd" value="gumby1234"/>

>         <!-- location of the browser executable -->
>         <property name="browser"
>                   value="/usr/local/MozillaFirebird/MozillaFirebird"/>

>         <!-- the dir into which the output of compilers and tools is directed -->
>         <property name="output_dir" value="../output"/>

>         <!-- the name of service (used in constructing war file name, WSDL, etc.) -->
>         <property name="service_name" value="PurchaseOrderService"/>

>         <!-- the Java package in which the service class is located -->
>         <property name="service_package" value="service"/>

>         <!-- the target namespace of the service -->
>         <property name="target_namespace"
>                   value="http://openuri.org/easypo_service"/>

>         <!-- name of the Workshop EJB project containing the web service EJBs -->
>         <property name="service_ejb_project" value="PurchaseOrderService" />

>         <!-- the dir that contains the exploded ear file containing the web service -->
>         <property name="output_ear" value="${output_dir}/${service_name}-ear"/>
>         <path id="build.classpath">
>             <pathelement path="${java.class.path}"/>
>             <pathelement location="${platformhome}/server/lib/webservices.jar"/>
>             <pathelement location="${output_ear}"/>
>             <pathelement location="${output_ear}/APP-INF/classes"/>
>             <pathelement location="${service_ejb_project}.jar"/>
>         </path>
>         <target name="build"
>       depends="clean, setup, webservice.build, webservice.client, build.finish"/>
>         <target name="clean" description="delete generated stuff">
>             <delete dir="${output_dir}"/>
>         </target>

>         <target name="setup" description="create output directories">
>             <mkdir dir="${output_ear}/META-INF"/>
>             <mkdir dir="${output_dir}/${service_name}-war/WEB-INF"/>
>         </target>

>         <!-- build the web service from the web service EJB JAR -->
>         <target name="webservice.build">

>             <!-- put the EJB JAR in the exploded EAR -->
>             <copy file="${service_ejb_project}.jar" todir="${output_ear}" />

>             <!-- generate XML types from the Java value types in the service -->
>             <autotype javaComponents="${service_package}.${service_name}Local"
>                 typeMappingFile="${output_ear}/APP-INF/classes/types.xml"
>                 destDir="${output_ear}/APP-INF/classes"
>                 packageName="${service_package}"
>                 classpathref="build.classpath"/>

>             <!-- build the service from the EJB and autotyper types -->
>             <source2wsdd
>                 javaSource="${service_ejb_project}/${service_package}/${service_name}Bean.ejb"
>                 ddFile="${output_dir}/${service_name}-war/WEB-INF/web-services.xml"
>                 typesInfo="${output_ear}/APP-INF/classes/types.xml"
>                 handlerInfo="${service_ejb_project}/${service_package}/handler-chain.xml"
>                 serviceURI="/${service_name}"
>                 wsdlFile="${output_dir}/${service_name}-war/${service_name}.wsdl"
>                 ejblink="${service_ejb_project}.jar#${service_name}EJB"
>                 classpathref="build.classpath">
>             </source2wsdd>

>             <!-- package the web service war -->
>             <jar destFile="${output_ear}/${service_name}.war" basedir="${output_dir}/${service_name}-war"/>

>             <!-- package the ear -->
>             <echo file="${output_ear}/META-INF/application.xml">
>                 <![CDATA[
>                 <!DOCTYPE application PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN'
>                     'http://java.sun.com/j2ee/dtds/application_1_2.dtd'>
>                 <application>
>                   <display-name> ${service_name}-Service </display-name>
>                   <module>
>                     <ejb>
>                        ${service_ejb_project}.jar
>                     </ejb>
>                   </module>
>                   <module>
>                     <web>
>                        <web-uri> ${service_name}.war </web-uri>
>                        <context-root> ${service_name} </context-root>
>                     </web>
>                   </module>
>                 </application>
>                 ]]>
>             </echo>
>             <jar destFile="${output_dir}/${service_name}.ear" baseDir="${output_ear}"/>

>         </target>

>         <target name="webservice.client">

>             <!-- generate JAX-RPC client interfaces, stubs into the client jar -->
>             <clientgen
>                 description="create a web service client from the ear"
>                 clientJar="${output_dir}/${service_name}-client"
>                 wsdl="${output_dir}/${service_name}-war/${service_name}.wsdl"
>                 typeMappingFile="${output_ear}/APP-INF/classes/types.xml"
>                 packageName="${service_package}.client"
>                 usePortNameAsMethodName="true"
>                 keepgenerated="true"
>                 classpathref="build.classpath">
>             </clientgen>
>             <!-- compile the client app into the client jar -->
>             <javac srcdir="."
>                 includes="client/*.java"
>                 destdir="${output_dir}/${service_name}-client"
>                 classpathref="build.classpath">
>             </javac>

>             <!-- package the client jar; executing the jar runs the test app -->
>             <jar
>                 destFile="${output_dir}/${service_name}-client.jar"
>                 baseDir="${output_dir}/${service_name}-client"/>

>         </target>

>         <target name="build.finish" description="clean up temp files">
>             <delete dir="${output_dir}/${service_name}-client"/>
>             <delete dir="${output_dir}/${service_name}-war"/>
>             <delete dir="${output_ear}"/>
>         </target>

>         <target name="deploy" description="deploy service">
>             <wldeploy action="deploy" source="${output_dir}/${service_name}.ear"
>                 adminurl="${server_url}"
>                 user="${admin_user}" password="${admin_passwd}"/>
>         </target>

>         <target name="undeploy" description="undeploy service">
>             <wldeploy action="undeploy" source="${output_dir}/${service_name}.ear"
>                 adminurl="${server_url}"
>                 user="${admin_user}" password="${admin_passwd}"/>
>         </target>

>         <target name="browse" description="browse test page for this service">
>             <exec executable="${browser}">
>                 <arg line="${server_url}/${service_name}/${service_name}"/>
>             </exec>
>         </target>

>         <target name="run" description="run client">
>             <java classname="client.Main" fork="true">
>                 <classpath>
>                     <pathelement path="${java.class.path}"/>
>                     <pathelement location="${output_dir}/${service_name}-client.jar"/>

>                 </classpath>
>                 <arg line="${server_url}/${service_name}/${service_name}?WSDL"/>
>                 <jvmarg line="-Dweblogic.webservice.verbose=true"/>
>             </java>
>         </target>

>     </project>

## Source Code for Supporting Java Objects

This section provides sample code for the following supporting Java objects which are already assumed to exist:

- Item.java
- PurchaseOrder.java
- PurchasingManagerBean.java
- PurchaseOrderFactory.java

### Item.java

>     package po;

>     /**
>      * Represents a single item on a purchase order.
>      */
>     public class Item {
>         private String catNumber;
>         private String description;
>         private int quantity;

>         public Item() {
>         }

>         public Item(String catNumber, String description, int quantity) {
>             this.catNumber = catNumber;
>             this.description = description;
>             this.quantity = quantity;
>         }

>         public String getCatNumber() {
>             return catNumber;
>         }

>         public void setCatNumber(String catNumber) {
>             this.catNumber = catNumber;
>         }

>         public String getDescription() {
>             return description;
>         }

>         public void setDescription(String description) {
>             this.description = description;
>         }

>         public int getQuantity() {
>             return quantity;
>         }

>         public void setQuantity(int quantity) {
>             this.quantity = quantity;
>         }

>         public String toString() {
>             StringBuffer sbuf = new StringBuffer();
>             sbuf.append("[Item");
>             sbuf.append("\n\tcatNumber = " + catNumber);
>             sbuf.append("\n\tdescription = " + description);
>             sbuf.append("\n\tquantity = " + quantity);
>             sbuf.append("\n]");
>             return sbuf.toString();
>         }
>     }

### PurchaseOrder.java

>     package po;

>     import po.Item;

>     /**
>      * Date: Oct 15, 2003
>      * Time: 3:29:23 PM
>      */
>     public class PurchaseOrder {
>         private String poNumber;
>         private Item[] items;
>         private String custName;
>         private String custAddress;

>         public PurchaseOrder() {
>         }

>         public PurchaseOrder(String poNumber) {
>             this.poNumber = poNumber;
>         }

>         public String getPoNumber() {
>             return poNumber;
>         }

>         public void setPoNumber(String poNumber) {
>             this.poNumber = poNumber;
>         }

>         public Item[] getItems() {
>             return items;
>         }

>         public void setItems(Item[] items) {
>             this.items = items;
>         }

>         public String getCustName() {
>             return custName;
>         }

>         public void setCustName(String custName) {
>             this.custName = custName;
>         }

>         public String getCustAddress() {
>             return custAddress;
>         }

>         public void setCustAddress(String custAddress) {
>             this.custAddress = custAddress;
>         }

>         public String toString() {
>             StringBuffer sbuf = new StringBuffer();
>             sbuf.append("[PurchaseOrder");
>             sbuf.append("\n\tpoNumber = " + poNumber);
>             sbuf.append("\n\tcustName = " + custName);
>             sbuf.append("\n\tcustAddress = " + custAddress);
>             if (items != null) {
>                 for (int i = 0; i < items.length; ++i) {
>                     sbuf.append("\n");
>                     sbuf.append(items[i].toString());
>                 }
>             }
>             sbuf.append("\n]");
>             return sbuf.toString();
>         }
>     }

### PurchasingManagerBean.java

>     package po;

>     import javax.ejb.SessionBean;
>     import javax.ejb.SessionContext;

>     /**
>      * This is a session facade EJB that is the entry point to the business
>      * logic ofthe application.
>      *
>      * @ejbgen:session
>      *   ejb-name = "PurchasingManagerEJB"
>      * @ejbgen:jndi-name
>      *   local = "PurchasingManager"
>      */
>     public class PurchasingManagerBean implements SessionBean {

>         /**
>          * @ejbgen:local-method
>          */
>         public PurchaseOrder getPO(String poNumber) {
>             return PurchaseOrderFactory.createPO();  // always return same thing
>         }

>         /**
>          * @ejbgen:local-method
>          */
>         public int getStatus(String poNumber) {
>             return 1;
>         }

>         public void ejbRemove() {}
>         public void ejbCreate() {}
>         public void ejbPassivate() {}
>         public void ejbActivate() {}
>         public void setSessionContext(SessionContext ctx) {}

>     }

### PurchaseOrderFactory.java

>     package po;

>     import java.util.ArrayList;
>     import java.util.List;

>     /**
>      * A Factory to create PurchaseOrders. This just creates the same
>      * dummy PO each time.
>      */
>     public class PurchaseOrderFactory {

>         /**
>          * Constructs a PurchaseOrder object
>          */
>         public static PurchaseOrder createPO() {

>             PurchaseOrder po = new PurchaseOrder("PO8048392");

>             // Add customer
>             po.setCustName("Mary Mary Quite Contrary");
>             po.setCustAddress("123 Main Street, Hogsmeade");

>             // Add Line Items
>             List items = new ArrayList();
>             items.add(new Item("S-123", "Lacewing Flies", 100));
>             items.add(new Item("S-456", "Leeches", 3));
>             items.add(new Item("S-043", "Powdered Bicon Horn", 1));
>             items.add(new Item("S-153", "Knotgrass", 5));
>             items.add(new Item("S-904", "Fluxweed", 1));
>             items.add(new Item("S-034", "Boomslang Skin", 2));
>             po.setItems((Item[]) items.toArray(new Item[]{}));

>             return po;
>         }
>     }