Skip navigation.
Downloads | Product Documentation | Support

Programming Web Services for WebLogic Server

# Programming the JWS File

The following sections provide information about programming the JWS file that implements your Web Service:

- Overview of JWS Files and JWS Annotations
- Programming the JWS File: Java Requirements
- Programming the JWS File: Typical Steps
- Accessing Runtime Information about a Web Service Using the JwsContext
- Should You Implement a Stateless Session EJB?
- Programming the User-Defined Java Data Type
- Throwing Exceptions
- Invoking Another Web Service from the JWS File
- JWS Programming Best Practices

# Overview of JWS Files and JWS Annotations

One way to program a WebLogic Web Service is to code the standard JSR-921 EJB or Java class from scratch and generate its associated artifacts manually (deployment descriptor files, WSDL file, data binding artifacts for user-defined data types, and so on). This process can be difficult and tedious. BEA recommends that you take advantage of the new JDK 5.0 metadata annotations feature and use a programming model in which you create an annotated Java file and then use Ant tasks to compile the file into the Java source code and generate all the associated artifacts.

The Java Web Service (JWS) annotated file is the core of your Web Service. It contains the Java code that determines how your Web Service behaves. A JWS file is an ordinary Java class file that uses JDK 5.0 metadata annotations to specify the shape and characteristics of the Web Service. The JWS annotations you can use in a JWS file include the standard ones defined by the Web Services Metadata for the Java Platform specification (JSR-181) as well as a set of WebLogic-specific ones.

This topic is part of the iterative development procedure for creating a Web Service, described in Iterative Development of WebLogic Web Services Starting From Java: Main Steps and Iterative Development of WebLogic Web Services Starting From a WSDL File: Main Steps. It is assumed that you have created a JWS file and now want to add JWS annotations to it.

# Programming the JWS File: Java Requirements

When you program your JWS file, you must follow a set of requirements, as specified by the JSR-181 specification (Web Services Metadata for the Java Platform). In particular, the Java class that implements the Web Service:

- Must be an outer public class, must not be final, and must not be abstract.
- Must have a default public constructor.
- Must not define a `finalize()` method.
- Must include, at a minimum, a `@WebService` JWS annotation at the class level to indicate that the JWS file implements a Web Service.
- May reference a service endpoint interface by using the `@WebService.endpointInterface` annotation. In this case, it is assumed that the service endpoint interface exists and you cannot specify any other JWS annotations in the JWS file other than `@WebService.endpointInterface` and `@WebService.serviceName`.
- If JWS file does not implement a service endpoint interface, all public methods other than those inherited from `java.lang.Object` will be exposed as Web Service operations. This behavior can be overridden by using the `@WebMethod` annotation to specify explicitly those public methods that are to be exposed. If a `@WebMethod` annotation is present, only the methods to which it is applied are exposed.

# Programming the JWS File: Typical Steps

The following sections how to use standard (JSR-181) and WebLogic-specific annotations in your JWS file to program basic Web Service features. The annotations are used at different levels, or targets, in your JWS file. Some are used at the class-level to indicate that the annotation applies to the entire JWS file. Others are used at the method-level and yet others at the parameter level. The sections discuss the following basic JWS annotations:

- `@WebService` (standard)
- `@SOAPBinding` (standard)
- `@WLHttpTransport` (WebLogic-specific)
- `@WebMethod` (standard)
- `@Oneway` (standard)
- `@WebParam` (standard)
- `@WebResult` (standard)

See Advanced JWS Programming: Implementing Asynchronous Features, for information on using other JWS annotations to program more advanced features, such as Web Service reliable messaging, conversations, SOAP message handlers, and so on.

For reference documentation about both the standard and WebLogic-specific JWS annotations, see JWS Annotation Reference.

The following procedure describes the typical basic steps when programming the JWS file that implements a Web Service. See Example of a JWS File for a code example.

1. Import the standard JWS annotations that will be used in your JWS file. The standard JWS annotations are in either the `javax.jws` or `javax.jws.soap` package. For example:

>     import javax.jws.WebMethod;
>     import javax.jws.WebService;
>     import javax.jws.soap.SOAPBinding;

2. Import the WebLogic-specific annotations used in your JWS file. The WebLogic-specific annotations are in the `weblogic.jws` package. For example:

>     import weblogic.jws.WLHttpTransport;

3. Add the standard and required `@WebService` JWS annotation at the class level to specify that the Java class exposes a Web Service.

See Specifying That the JWS File Implements a Web Service.

4. Add the standard `@SOAPBinding` JWS annotation at the class level to specify the mapping between the Web Service and the SOAP message protocol. In particular, use this annotation to specify whether the Web Service is document-literal, RPC-encoded, and so on.

Although this JWS annotation is not required, BEA recommends you explicitly specify it in your JWS file to clarify the type of SOAP bindings a client application uses to invoke the Web Service.

See Specifying the Mapping of the Web Service to the SOAP Message Protocol.

5. Add the WebLogic-specific `@WLHttpTransport` JWS annotation at the class level to specify the context path and service URI used in the URL that invokes the Web Service.

Although this JWS annotation is not required, BEA recommends you explicitly specify it in your JWS file so that it is clear what URL a client application uses to invoke the Web Service.

See Specifying the Context Path and Service URI of the Web Service.

6. For each method in the JWS file that you want to expose as a public operation, add a standard `@WebMethod` annotation. Optionally specify that the operation takes only input parameters but does not return any value by using the standard `@Oneway` annotation.

See Specifying That a JWS Method Be Exposed as a Public Operation.

7. Optionally customize the name of the input parameters of the exposed operations by adding standard `@WebParam` annotations.

See Customizing the Mapping Between Operation Parameters and WSDL Parts.

8. Optionally customize the name and behavior of the return value of the exposed operations by adding standard `@WebResult` annotations.

See Customizing the Mapping Between the Operation Return Value and a WSDL Part.

## Example of a JWS File

The following sample JWS file shows how to implement a simple Web Service.

>     package examples.webservices.simple;

>     // Import the standard JWS annotation interfaces

>     import javax.jws.WebMethod;
>     import javax.jws.WebService;
>     import javax.jws.soap.SOAPBinding;

>     // Import the WebLogic-specific JWS annotation interfaces

>     import weblogic.jws.WLHttpTransport;

>     // Standard JWS annotation that specifies that the porType name of the Web
>     // Service is "SimplePortType", the service name is "SimpleService", and the
>     // targetNamespace used in the generated WSDL is "http://example.org"

>     @WebService(name="SimplePortType", serviceName="SimpleService",
>                 targetNamespace="http://example.org")

>     // Standard JWS annotation that specifies the mapping of the service onto the
>     // SOAP message protocol.  In particular, it specifies that the SOAP messages
>     // are document-literal-wrapped.

>     @SOAPBinding(style=SOAPBinding.Style.DOCUMENT,
>                  use=SOAPBinding.Use.LITERAL,
>                  parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)

>     // WebLogic-specific JWS annotation that specifies the context path and
>     // service URI used to build the URI of the Web Service is
>     // "simple/SimpleService"

>     @WLHttpTransport(contextPath="simple", serviceUri="SimpleService",
>                      portName="SimpleServicePort")

>     /**
>      * This JWS file forms the basis of simple Java-class implemented WebLogic
>      * Web Service with a single operation: sayHello
>      *
>      */

>     public class SimpleImpl {

>       // Standard JWS annotation that specifies that the method should be exposed
>       // as a public operation.  Because the annotation does not include the
>       // member-value "operationName", the public name of the operation is the
>      // same as the method name: sayHello.

>       @WebMethod()
>       public String sayHello(String message) {
>         System.out.println("sayHello:" + message);
>         return "Here is the message: '" + message + "'";
>       }
>     }

## Specifying That the JWS File Implements a Web Service

Use the standard `@WebService` annotation to specify, at the class level, that the JWS file implements a Web Service, as shown in the following code excerpt:

>     @WebService(name="SimplePortType", serviceName="SimpleService",
>                 targetNamespace="http://example.org")

In the example, the name of the Web Service is `SimplePortType`, which will later map to the `wsdl:portType` element in the WSDL file generated by the `jwsc` Ant task. The service name is `SimpleService`, which will map to the `wsdl:service` element in the generated WSDL file. The target namespace used in the generated WSDL is `http://example.org`.

You can also specify the following additional attribute of the `@WebService` annotation:

- `endpointInterface`—Fully qualified name of an existing service endpoint interface file. If you specify this attribute, the `jwsc` Ant task does not generate the interface for you, but assumes you have already created it and it is in your CLASSPATH.

None of the attributes of the `@WebService` annotation is required. See the Web Services Metadata for the Java Platform for the default values of each attribute.

## Specifying the Mapping of the Web Service to the SOAP Message Protocol

It is assumed that you want your Web Service to be available over the SOAP 1.1 message protocol; for this reason, your JWS file should include the standard `@SOAPBinding` annotation, at the class level, to specify the SOAP bindings of the Web Service (such as RPC-encoded or document-literal-wrapped), as shown in the following code excerpt:

>     @SOAPBinding(style=SOAPBinding.Style.DOCUMENT,
>                  use=SOAPBinding.Use.LITERAL,
>                  parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)

In the example, the Web Service uses document-wrapped-style encodings and literal message formats, which are also the default formats if you do not specify the `@SOAPBinding` annotation.

You use the `parameterStyle` attribute (in conjunction with the style=SOAPBinding.Style.DOCUMENT attribute) to specify whether the Web Service operation parameters represent the entire SOAP message body, or whether the parameters are elements wrapped inside a top-level element with the same name as the operation.

The following table lists the possible and default values for the three attributes of the `@SOAPBinding` annotation.

Table 5-1 Attributes of the @SOAPBinding Annotation

Attribute | Possible Values | Default Value
--- | --- | ---
style | `SOAPBinding.Style.RPC SOAPBinding.Style.DOCUMENT` | `SOAPBinding.Style.DOCUMENT`
use | `SOAPBinding.Use.LITERAL SOAPBinding.Use.ENCODED` | `SOAPBinding.Use.LITERAL`
parameterStyle | `SOAPBinding.ParameterStyle.BARE SOAPBinding.ParameterStyle.WRAPPED` | `SOAPBinding.ParameterStyle.WRAPPED`

## Specifying the Context Path and Service URI of the Web Service

Use the WebLogic-specific`@WLHttpTransport` annotation to specify the context path and service URI sections of the URL used to invoke the Web Service over the HTTP transport, as well as the name of the port in the generated WSDL, as shown in the following code excerpt:

>     @WLHttpTransport(contextPath="simple", serviceUri="SimpleService",
>                      portName="SimpleServicePort")

In the example, the name of the port in the WSDL (in particular, the `name` attribute of the `<port>` element) file generated by the`jwsc` Ant task is `SimpleServicePort`. The URL used to invoke the Web Service over HTTP includes a context path of `simple` and a service URI of `SimpleService`, as shown in the following example:

>     http://host:port/simple/SimpleService

For reference documentation on this and other WebLogic-specific annotations, see JWS Annotation Reference.

## Specifying That a JWS Method Be Exposed as a Public Operation

Use the standard `@WebMethod` annotation to specify that a method of the JWS file should be exposed as a public operation of the Web Service, as shown in the following code excerpt:

>     public class SimpleImpl {

>       @WebMethod(operationName="sayHelloOperation")
>       public String sayHello(String message) {
>         System.out.println("sayHello:" + message);
>         return "Here is the message: '" + message + "'";
>       }
>     ...

In the example, the `sayHello()` method of the `SimpleImpl` JWS file is exposed as a public operation of the Web Service. The `operationName` attribute specifies, however, that the public name of the operation in the WSDL file is `sayHelloOperation`. If you do not specify the `operationName` attribute, the public name of the operation is the name of the method itself.

You can also use the `action` attribute to specify the action of the operation. When using SOAP as a binding, the value of the `action` attribute determines the value of the `SOAPAction` header in the SOAP messages.

You can specify that an operation not return a value to the calling application by using the standard `@Oneway` annotation, as shown in the following example:

>      public class OneWayImpl {

>       @WebMethod()
>       @Oneway()

>       public void ping() {
>         System.out.println("ping operation");
>       }

>     ...

If you specify that an operation is one-way, the implementing method is required to return `void`, cannot use a Holder class as a parameter, and cannot throw any checked exceptions.

None of the attributes of the `@WebMethod` annotation is required. See the Web Services Metadata for the Java Platform for the default values of each attribute, as well as additional information about the `@WebMethod` and `@Oneway` annotations.

## Customizing the Mapping Between Operation Parameters and WSDL Parts

Use the standard `@WebParam` annotation to customize the mapping between operation input parameters of the Web Service and elements of the generated WSDL file, as well as specify the behavior of the parameter, as shown in the following code excerpt:

>      public class SimpleImpl {

>       @WebMethod()
>       @WebResult(name="IntegerOutput",
>                  targetNamespace="http://example.org/docLiteralBare")
>       public int echoInt(
>           @WebParam(name="IntegerInput",
>                     targetNamespace="http://example.org/docLiteralBare")
>           int input)

>       {
>           System.out.println("echoInt '" + input + "' to you too!");
>           return input;
>       }
>     ...

In the example, the name of the parameter of the `echoInt` operation in the generated WSDL is `IntegerInput`; if the `@WebParam` annotation were not present in the JWS file, the name of the parameter in the generated WSDL file would be the same as the name of the method's parameter: `input`. The `targetNamespace` attribute specifies that the XML namespace for the parameter is `http://example.org/docLiteralBare`; this attribute is relevant only when using document-style SOAP bindings where the parameter maps to an XML element.

You can also specify the following additional attributes of the `@WebParam` annotation:

- `mode`—The direction in which the parameter is flowing (`WebParam.Mode.IN`, `WebParam.Mode.OUT`, or `WebParam.Mode.INOUT`). The OUT and INOUT modes may be specified only for parameter types that conform to the JAX-RPC definition of `Holder` types. OUT and INOUT modes are only supported for RPC-style operations or for parameters that map to headers.
- `header`—Boolean attribute that, when set to `true`, specifies that the value of the parameter should be retrieved from the SOAP header, rather than the default body.

None of the attributes of the `@WebParam` annotation is required. See the Web Services Metadata for the Java Platform for the default value of each attribute.

## Customizing the Mapping Between the Operation Return Value and a WSDL Part

Use the standard `@WebResult` annotation to customize the mapping between the Web Service operation return value and the corresponding element of the generated WSDL file, as shown in the following code excerpt:

>      public class Simple {

>       @WebMethod()
>       @WebResult(name="IntegerOutput",
>                  targetNamespace="http://example.org/docLiteralBare")
>       public int echoInt(
>           @WebParam(name="IntegerInput",
>                     targetNamespace="http://example.org/docLiteralBare")
>           int input)

>       {
>           System.out.println("echoInt '" + input + "' to you too!");
>           return input;
>       }
>     ...

In the example, the name of the return value of the `echoInt` operation in the generated WSDL is `IntegerOutput`; if the `@WebResult` annotation were not present in the JWS file, the name of the return value in the generated WSDL file would be the hard-coded name `return`. The `targetNamespace` attribute specifies that the XML namespace for the return value is `http://example.org/docLiteralBare`; this attribute is relevant only when using document-style SOAP bindings where the return value maps to an XML element.

None of the attributes of the `@WebResult` annotation is required. See the Web Services Metadata for the Java Platform for the default value of each attribute.

# Accessing Runtime Information about a Web Service Using the JwsContext

When a client application invokes a WebLogic Web Service that was implemented with a JWS file, WebLogic Server automatically creates a context that the Web Service can use to access, and sometimes change, runtime information about the service. Much of this information is related to conversations, such as whether the current conversation is finished, the current values of the conversational properties, changing conversational properties at runtime, and so on. (See Creating Conversational Web Services for information about conversations and how to implement them.) Some of the information accessible via the context is more generic, such as the protocol that was used to invoke the Web Service (HTTP/S or JMS), the SOAP headers that were in the SOAP message request, and so on.

You can use annotations and WebLogic Web Service APIs in your JWS file to access runtime context information, as described in the following sections.

## Guidelines for Accessing the Web Service Context

The following example shows a simple JWS file that uses the context to determine the protocol that was used to invoke the Web Service; the code in bold is discussed in the programming guidelines described after the example.

>     package examples.webservices.jws_context;

>     import javax.jws.WebMethod;
>     import javax.jws.WebService;

>     import weblogic.jws.WLHttpTransport;
>     import weblogic.jws.Context;

>     import weblogic.wsee.jws.JwsContext;
>     import weblogic.wsee.jws.Protocol;

>     @WebService(name="JwsContextPortType", serviceName="JwsContextService",
>                 targetNamespace="http://example.org")

>     @WLHttpTransport(contextPath="contexts", serviceUri="JwsContext",
>                      portName="JwsContextPort")

>     /**
>      * Simple web service to show how to use the @Context annotation.
>      */

>     public class JwsContextImpl {

>       @Context
>       private JwsContext ctx;

>       @WebMethod()
>       public String getProtocol() {

>         Protocol protocol = ctx.getProtocol();

>         System.out.println("protocol: " + protocol);
>         return "This is the protocol: " + protocol;
>       }
>     }

Use the following guidelines in your JWS file to access the runtime context of the Web Service, as shown in the code in bold in the preceding example:

- Import the `@weblogic.jws.Context` JWS annotation:

>     import weblogic.jws.Context;

- Import the `weblogic.wsee.jws.JwsContext` API, as well as any other related APIs that you might use (the example also uses the `weblogic.wsee.jws.Protocol` API):

>     import weblogic.wsee.jws.JwsContext;
>     import weblogic.wsee.jws.Protocol;

See the weblogic.wsee.* Javadocs for reference documentation about the context-related APIs.

- Annotate a private variable, of data type `weblogic.wsee.jws.JwsContext`, with the field-level `@Context` JWS annotation:

>      @Context
>      private JwsContext ctx;

WebLogic Server automatically assigns the annotated variable (in this case, `ctx`) with a runtime implementation of `JwsContext` the first time the Web Service is invoked, which is how you can later use the variable without explicitly initializing it in your code.

- Use the methods of the `JwsContext` class to get, and sometimes change, runtime information about the Web Service. The following example shows how to get the protocol that was used to invoke the Web Service:

>     Protocol protocol = ctx.getProtocol();

See Methods of the JwsContext for the full list of available methods.

## Methods of the JwsContext

The following table briefly describes the methods of the `JwsContext` that you can use in your JWS file to access runtime information about the Web Service. See weblogic.wsee.* Javadocs for detailed reference information about `JwsContext`, and other context-related APIs, as `Protocol` and `ServiceHandle`.

Table 5-2 Methods of the JwsContext

Method | Returns | Description
--- | --- | ---
isFinished() | boolean | Returns a boolean value specifying whether the current conversation is finished, or if it is still continuing. Use this method only in conversational Web Services, or those that have been annotated with the `@Conversation` or `@Conversational` annotation.
finishConversation() | void | Finishes the current conversation. This method is equivalent to a client application invoking a method that has been annotated with the `@Conversation (Conversation.Phase.FINISH)` JWS annotation. Use this method only in conversational Web Services, or those that have been annotated with the `@Conversation` or `@Conversational` annotation.
setMaxAge(java.util.Date) | void | Sets a new maximum age for the conversation to an absolute `Date`. If the date parameter is in the past, WebLogic Server immediately finishes the conversation. This method is equivalent to the `maxAge` attribute of the `@Conversational` annotation, which specifies the default maximum age of a conversation. Use this method to override this default value at runtime. Use this method only in conversational Web Services, or those that have been annotated with the `@Conversation` or `@Conversational` annotation.
setMaxAge(String) | void | Sets a new maximum age for the conversation by specifying a `String` duration, such as `1 day`. Valid values for the `String` parameter are a number and one of the following terms: `seconds` `minutes` `hours` `days` `years` For example, to specify a maximum age of ten minutes, use the following syntax: `ctx.setMaxAge("10 minutes")` This method is equivalent to the `maxAge` attribute of the `@Conversational` annotation, which specifies the default maximum age of a conversation. Use this method to override this default value at runtime. Use this method only in conversational Web Services, or those that have been annotated with the `@Conversation` or `@Conversational` annotation.
getMaxAge() | long | Returns the maximum allowed age, in seconds, of a conversation. Use this method only in conversational Web Services, or those that have been annotated with the `@Conversation` or `@Conversational` annotation.
getCurrentAge() | long | Returns the current age, in seconds, of the conversation. Use this method only in conversational Web Services, or those that have been annotated with the `@Conversation` or `@Conversational` annotation.
resetIdleTime() | void | Resets the timer which measures the number of seconds since the last activity for the current conversation. Use this method only in conversational Web Services, or those that have been annotated with the `@Conversation` or `@Conversational` annotation.
setMaxIdleTime(long) | void | Sets the number of seconds that the conversation can remain idle before WebLogic Server finishes it due to client inactivity. This method is equivalent to the `maxIdleTime` attribute of the `@Conversational` annotation, which specifies the default idle time of a conversation. Use this method to override this default value at runtime. Use this method only in conversational Web Services, or those that have been annotated with the `@Conversation` or `@Conversational` annotation.
setMaxIdleTime(String) | void | Sets the number of seconds, specified as a `String`, that the conversation can remain idle before WebLogic Server finishes it due to client inactivity. Valid values for the `String` parameter are a number and one of the following terms: `seconds` `minutes` `hours` `days` `years` For example, to specify a maximum idle time of ten minutes, use the following syntax: `ctx.setMaxIdleTime("10 minutes")` This method is equivalent to the `maxIdleTime` attribute of the `@Conversational` annotation, which specifies the default idle time of a conversation. Use this method to override this default value at runtime. Use this method only in conversational Web Services, or those that have been annotated with the `@Conversation` or `@Conversational` annotation.
getMaxIdleTime() | long | Returns the number of seconds that the conversation is allowed to remain idle before WebLogic Server finishes it due to client inactivity. Use this method only in conversational Web Services, or those that have been annotated with the `@Conversation` or `@Conversational` annotation.
getCurrentIdleTime() | long | Gets the number of seconds since the last client request, or since the conversation's maximum idle time was reset. Use this method only in conversational Web Services, or those that have been annotated with the `@Conversation` or `@Conversational` annotation.
getCallerPrincipal() | java.security.Principal | Returns the security principal associated with the operation that was just invoked, assuming that basic authentication was performed.
isCallerInRole(String) | boolean | Returns `true` if the authenticated principal is within the specified security role.
getService() | weblogic.wsee.jws.ServiceHandle | Returns an instance of `ServiceHandle`, a WebLogic Web Service API, which you can query to gather additional information about the Web Service, such as the conversation ID (if the Web Service is conversational), the URL of the Web Service, and so on.
getLogger(String) | weblogic.wsee.jws.util.Logger | Gets an instance of the `Logger` class, which you can use to send messages from the Web Service to a log file.
getInputHeaders() | org.w3c.dom.Element[] | Returns an array of the SOAP headers associated with the SOAP request message of the current operation invoke.
setUnderstoodInputHeaders(boolean) | void | Indicates whether input headers should be understood.
getUnderstoodInputHeaders() | boolean | Returns the value that was most recently set by a call to setUnderstoodInputHeader.
setOutputHeaders(Element[]) | void | Specifies an array of SOAP headers that should be associated with the outgoing SOAP response message sent back to the client application that initially invoked the current operation.
getProtocol() | weblogic.wsee.jws.Protocol | Returns the protocol (such as HTTP/S or JMS) used to invoke the current operation.

# Should You Implement a Stateless Session EJB?

Typically, when you program the JWS file, you do not need to know what the underlying implementation of the Web Service is; instead, you let the `jwsc` Ant task that later compiles the JWS file determine the best implementation. The `jwsc` Ant task either implements the Web Service as a standard Java class packaged in a Web application, or adds a stateless session EJB "wrapper" in front of the Java class if the JWS file implements certain features, such as conversations or reliable messaging. In the latter case, the business logic of the Web Service is still in the Java class, but the EJB wrapper takes care of the additional framework needed to implement certain features. The `jwsc` Ant task packages these Web Services in an EJB JAR file.

In some cases, however, you must explicitly implement a stateless session EJB in your JWS file; this is because the Web Service itself must be implemented with an EJB, rather than just have an EJB wrapper in front of the Java class. You must explicitly implement an EJB when you use the following JWS annotations in your JWS file:

- `@weblogic.jws.Transactional`
- `@weblogic.jws.Context`
- `@weblogic.jws.security.SecurityRoles` (deprecated as of Version 9.1 of WebLogic Server)
- `@weblogic.jws.security.SecurityIdentity` (deprecated as of Version 9.1 of WebLogic Server)

If you use any of the preceding annotations in a JWS file that does not explicitly implement an EJB, the `jwsc` Ant task will later fail with an error.

## Programming Guidelines When Implementing an EJB in Your JWS File

The general guideline is to always use EJBGen annotations in your JWS file to automatically generate, rather than manually create, the EJB Remote and Home interface classes and deployment descriptor files needed when implementing an EJB. EJBGen annotations work in the same way as JWS annotations: they follow the JDK 5.0 metadata syntax and greatly simplify your programming tasks.

For more information on EJBGen, see the EJBGen Reference section in Programming WebLogic Enterprise JavaBeans.

Follow these guidelines when explicitly implementing a stateless session EJB in your JWS file. See Example of a JWS File That Implements an EJB for an example; the relevant sections are shown in bold:

- Import the standard J2EE EJB classes:

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

- Import the EJBGen annotations, all of which are in the `weblogic.ejbgen` package. At a minimum you need to import the `@Session` annotation; if you want to use additional EJBGen annotations in your JWS file to specify the shape and behavior of the EJB, see the EJBGen reference guide for the name of the annotation you should import.

>     import weblogic.ejbgen.Session;

- At a minimum, use the `@Session` annotation at the class level to specify the name of the EJB:

>     @Session(ejbName="TransactionEJB")

`@Session` is the only required EJBGen annotation when used in a JWS file. You can, if you want, use other EJBGen annotations to specify additional features of the EJB.

- Ensure that the JWS class implements `SessionBean`:

>     public class TransactionImpl implements SessionBean {...

- You must also include the standard EJB methods `ejbCreate()`, `ejbActivate()` and so on, although you typically do not need to add code to these methods unless you want to change the default behavior of the EJB:

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

If you follow all these guidelines in your JWS file, the `jwsc` Ant task later compiles the Web Service into an EJB and packages it into an EJB JAR file inside of the Enterprise Application.

## Example of a JWS File That Implements an EJB

The following example shows a simple JWS file that includes the @Transactional annotation. For this reason, the JWS file must also explicitly implement a stateless session EJB. The relevant code is shown in bold.

>     package examples.webservices.transactional;

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

>     import javax.jws.WebMethod;
>     import javax.jws.WebService;

>     import weblogic.jws.WLHttpTransport;
>     import weblogic.jws.Transactional;

>     import weblogic.ejbgen.Session;

>     @Session(ejbName="TransactionEJB")

>     @WebService(name="TransactionPortType", serviceName="TransactionService",
>                 targetNamespace="http://example.org")

>     @WLHttpTransport(contextPath="transactions", serviceUri="TransactionService",
>                      portName="TransactionPort")

>     /**
>      * This JWS file forms the basis of simple EJB-implemented WebLogic
>      * Web Service with a single operation: sayHello.  The operation executes
>      * as part of a transaction.
>      *
>      */

>     public class TransactionImpl implements SessionBean {

>       @WebMethod()
>       @Transactional(value=true)

>       public String sayHello(String message) {
>         System.out.println("sayHello:" + message);
>         return "Here is the message: '" + message + "'";
>       }

>       // Standard EJB methods.  Typically there's no need to override the methods.

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

# Programming the User-Defined Java Data Type

The methods of the JWS file that are exposed as Web Service operations do not necessarily take built-in data types (such as Strings and integers) as parameters and return values, but rather, might use a Java data type that you create yourself. An example of a user-defined data type is `TradeResult`, which has two fields: a `String` stock symbol and an integer number of shares traded.

If your JWS file uses user-defined data types as parameters or return values of one or more of its methods, you must create the Java code of the data type yourself, and then import the class into your JWS file and use it appropriately. The `jwsc` Ant task will later take care of creating all the necessary data binding artifacts, such as the corresponding XML Schema representation of the Java user-defined data type, the JAX-RPC type mapping file, and so on.

Follow these basic requirements when writing the Java class for your user-defined data type:

- Define a default constructor, which is a constructor that takes no parameters.
- Define both `getXXX()` and `setXXX()` methods for each member variable that you want to publicly expose.
- Make the data type of each exposed member variable one of the built-in data types, or another user-defined data type that consists of built-in data types.

These requirements are specified by JAX-RPC 1.1; for more detailed information and the complete list of requirements, see the JAX-RPC specification.

The `jwsc` Ant task can generate data binding artifacts for most common XML and Java data types. For the list of supported user-defined data types, see Supported User-Defined Data Types. See Supported Built-In Data Types for the full list of supported built-in data types.

The following example shows a simple Java user-defined data type called `BasicStruct`:

>     package examples.webservices.complex;

>     /**
>      * Defines a simple JavaBean called BasicStruct that has integer, String,
>      * and String[] properties
>      */

>     public class BasicStruct {

>       // Properties

>       private int intValue;
>       private String stringValue;
>       private String[] stringArray;

>       // Getter and setter methods

>       public int getIntValue() {
>         return intValue;
>       }

>       public void setIntValue(int intValue) {
>         this.intValue = intValue;
>       }

>       public String getStringValue() {
>         return stringValue;
>       }

>       public void setStringValue(String stringValue) {
>         this.stringValue = stringValue;
>       }

>       public String[] getStringArray() {
>         return stringArray;
>       }

>       public void setStringArray(String[] stringArray) {
>         this.stringArray = stringArray;
>       }

>     }

The following snippets from a JWS file show how to import the `BasicStruct` class and use it as both a parameter and return value for one of its methods; for the full JWS file, see Sample ComplexImpl.java JWS File:

>     package examples.webservices.complex;

>     // Import the standard JWS annotation interfaces

>     import javax.jws.WebMethod;
>     import javax.jws.WebParam;
>     import javax.jws.WebResult;
>     import javax.jws.WebService;
>     import javax.jws.soap.SOAPBinding;

>     // Import the WebLogic-specific JWS annotation interface

>     import weblogic.jws.WLHttpTransport;

>     // Import the BasicStruct JavaBean

>     import examples.webservices.complex.BasicStruct;

>     @WebService(serviceName="ComplexService", name="ComplexPortType",
>                 targetNamespace="http://example.org")

>     ...

>     public class ComplexImpl {

>       @WebMethod(operationName="echoComplexType")
>       public BasicStruct echoStruct(BasicStruct struct)

>       {
>         return struct;
>       }
>     }

# Throwing Exceptions

When you write the error-handling Java code in methods of the JWS file, you can either throw your own user-defined exceptions or throw a `javax.xml.rpc.soap.SOAPFaultException` exception. If you throw a `SOAPFaultException`, WebLogic Server maps it to a SOAP fault and sends it to the client application that invokes the operation.

If your JWS file throws any type of Java exception other than `SOAPFaultException`, WebLogic Server tries to map it to a SOAP fault as best it can. However, if you want to control what the client application receives and send it the best possible exception information, you should explicitly throw a `SOAPFaultException` exception or one that extends the exception. See the JAX-RPC 1.1 specification for detailed information about creating and throwing your own user-defined exceptions.

The following excerpt describes the `SOAPFaultException` class:

>     public class SOAPFaultException extends java.lang.RuntimeException {
>         public SOAPFaultException (QName faultcode,
>                                    String faultstring,
>                                    String faultactor,
>                                    javax.xml.soap.Detail detail ) {...}
>         public Qname getFaultCode() {...}
>         public String getFaultString() {...}
>         public String getFaultActor() {...}
>         public javax.xml.soap.Detail getDetail() {...}
>     }

Use the SOAP with Attachments API for Java 1.1 (SAAJ) `javax.xml.soap.SOAPFactory.createDetail()` method to create the `Detail` object, which is a container for `DetailEntry` objects that provide detailed application-specific information about the error.

You can use your own implementation of the `SOAPFactory`, or use BEA's, which can be accessed in the JWS file by calling the static method `weblogic.wsee.util.WLSOAPFactory.createSOAPFactory()` which returns a `javax.xml.soap.SOAPFactory object`. Then at runtime, use the `-Djavax.xml.soap.SOAPFactory` flag to specify BEA's `SOAPFactory` implementation as shown:

>     -Djavax.xml.soap.SOAPFactory=weblogic.xml.saaj.SOAPFactoryImpl

The following JWS file shows an example of creating and throwing a `SOAPFaultException` from within a method that implements an operation of your Web Service; the sections in bold highlight the exception code:

>     package examples.webservices.soap_exceptions;

>     import javax.xml.namespace.QName;
>     import javax.xml.soap.Detail;
>     import javax.xml.soap.SOAPException;
>     import javax.xml.soap.SOAPFactory;
>     import javax.xml.rpc.soap.SOAPFaultException;

>     // Import the @WebService annotation

>     import javax.jws.WebService;

>     // Import WLHttpTransport

>     import weblogic.jws.WLHttpTransport;

>     @WebService(serviceName="SoapExceptionsService",
>                 name="SoapExceptionsPortType",
>                 targetNamespace="http://example.org")

>     @WLHttpTransport(contextPath="exceptions",
>                      serviceUri="SoapExceptionsService",
>                      portName="SoapExceptionsServicePort")
>     /**
>      * This JWS file forms the basis of simple Java-class implemented WebLogic
>      * Web Service with a single operation: sayHelloWorld
>      *
>      * @author Copyright (c) 2005 by BEA Systems.  All rights reserved.
>      */

>     public class SoapExceptionsImpl {

>       public SoapExceptionsImpl() {

>       }

>       public void tirarSOAPException() {

>         Detail detail = null;

>         try {

>           SOAPFactory soapFactory = SOAPFactory.newInstance();
>           detail = soapFactory.createDetail();

>         } catch (SOAPException e) {
>             // do something
>         }

>         QName faultCode = null;
>         String faultString = "the fault string";
>         String faultActor = "the fault actor";
>         throw new SOAPFaultException(faultCode, faultString, faultActor, detail);
>       }
>     }

The preceding example uses the default implementation of `SOAPFactory`.

Warning: If you create and throw your own exception (rather than use `SOAPFaultException`) and two or more of the properties of your exception class are of the same data type, then you must also create setter methods for these properties, even though the JAX-RPC specification does not require it. This is because when a WebLogic Web Service receives the exception in a SOAP message and converts the XML into the Java exception class, there is no way of knowing which XML element maps to which class property without the corresponding setter methods.

# Invoking Another Web Service from the JWS File

From within your JWS file you can invoke another Web Service, either one deployed on WebLogic Server or one deployed on some other application server, such as .NET. The steps to do this are similar to those described in Invoking a Web Service from a Stand-alone JAX-RPC Java Client, such as running the `clientgen` Ant task to generate the client stubs and using standard JAX-RPC APIs in the client application; however, in this case, you use these APIs in the JWS file that implements the Web Service that invokes the other Web Service rather than in the stand-alone Java client application.

See Invoking a Web Service from Another Web Service for detailed instructions.

# JWS Programming Best Practices

The following list provides some best practices when programming the JWS file:

- When you create a document-literal-bare Web Service, use the `@WebParam` JWS annotation to ensure that all input parameters for all operations of a given Web Service have a unique name.

Because of the nature of document-literal-bare Web Services, if you do not explicitly use the`@WebParam` annotation to specify the name of the input parameters, WebLogic Server creates one for you and run the risk of duplicating the names of the parameters across a Web Service.

- In general, document-literal-wrapped Web Services are the most interoperable type of Web Service.
- Use the `@WebResult` JWS annotation to explicitly set the name of the returned value of an operation, rather than always relying on the hard-coded name `return`, which is the default name of the returned value if you do not use the `@WebResult` annotation in your JWS file.
- Use SOAPFaultExceptions in your JWS file if you want to control the exception information that is passed back to a client application when an error is encountered while invoking a the Web Service.
- Even though it is not required, BEA recommends you always specify the `portName` attribute of the WebLogic-specific `@WLHttpTransport` annotation in your JWS file. If you do not specify this attribute, the `jwsc` Ant task will generate a port name for you when generating the WSDL file, but this name might not be very user-friendly. A consequence of this is that the `getXXX()` method you use in your client applications to invoke the Web Service will not be very well-named. To ensure that your client applications use the most user-friendly methods possible when invoking the Web Service, specify a relevant name of the Web Service port by using the `portName` attribute.