bea.com | products | dev2dev | support | askBEA

Download Docs | Site Map | Glossary
Search

Programming WebLogic Web Services

Invoking Web Services

The following sections describe how to invoke Web services, both WebLogic and non-WebLogic, from client applications:

- Overview of Invoking Web Services

- Creating Java Client Applications to Invoke Web Services: Main Steps

- Getting the Java Client JAR Files

- Writing the Java Client Application Code

- Writing a J2ME Client

- Creating and Using Portable Stubs

- Using a Proxy Server with the WebLogic Web Services Client

- The WebLogic Web Services Home Page and WSDL URLs

- Debugging Errors While Invoking Web Services

- WebLogic Web Services System Properties

Overview of Invoking Web Services

Invoking a Web service refers to the actions that a client application performs to use the Web service. Client applications that invoke Web services can be written using any technology: Java, Microsoft SOAP Toolkit, Microsoft .NET, and so on.

Note: This chapter uses the term client application to refer to both a standalone client that uses the WebLogic thin client to invoke a Web service, and a client that runs inside of an EJB running on WebLogic Server.

The sections that follow describe how to use BEA's implementation of the JAX-RPC specification to invoke a Web service from a Java client application. It is generally assumed that you are going to invoke any Web service rather than one running on WebLogic Server, except for those sections that describe the URLs needed to invoke a WebLogic Web service and its Home Page.

WebLogic Server provides optional Java client JAR files that include, for your convenience, all the classes, interfaces, and stubs you need to invoke a Web service. The client JAR files include the client runtime implementation of the JAX-RPC specification (called webserviceclient.jar and webserviceclient+ssl.jar) as well as Web service-specific implementations to minimize the amount of Java code needed to invoke a particular Web service.

JAX-RPC API

The Java API for XML based RPC (JAX-RPC) is a Sun Microsystems specification that defines the client API for invoking a Web service.

The following table briefly describes the core JAX-RPC interfaces and classes.

Table 8-1 JAX-RPC Interfaces and Classes

javax.xml.rpc Interface or Class | Description
--- | ---
Service | Main client interface. Used for both static and dynamic invocations.
ServiceFactory | Factory class for creating Service instances.
Stub | Represents the client proxy for invoking the operations of a Web service. Typically used for static invocation of a Web service.
Call | Used to dynamically invoke a Web service.
JAXRPCException | Exception thrown if an error occurs while invoking a Web service.

WebLogic Server includes an implementation of the JAX-RPC specification.

For detailed information on JAX-RPC, see the following Web site: http://java.sun.com/xml/jaxrpc/index.html.

For a tutorial that describes how to use JAX-RPC to invoke Web services, see http://java.sun.com/webservices/docs/ea1/tutorial/doc/JAXRPC.html.

Examples of Clients That Invoke Web Services

WebLogic Server includes the following examples of creating and invoking WebLogic Web services in the WL_HOME/samples/server/src/examples/webservices directory, where WL_HOME refers to the main WebLogic Platform directory:

- basic.statelessSession : Uses a stateless session EJB backend component with built-in data types as its parameters and return value

- basic.javaclass : Uses a Java class backend component with built-in data types as its parameters and return value

- complex.statelessSession : Uses a stateless session EJB backend component with non-built-in data types as its parameters and return value

- handler.log : Uses both a handler chain and a stateless session EJB.

- handler.nocomponent : Uses only a handler chain with no backend component.

- client.static : Shows how to create a static client application that invokes a non-WebLogic Web service.

- client.static_out : Shows how to create a static client application that invokes a non-WebLogic Web service that uses out parameters.

- client.dynamic_wsdl : Shows how to create a dynamic client application that uses WSDL to invoke a non-WebLogic Web service.

- client.dynamic_no_wsdl : Shows how to create a dynamic client application that does not use WSDL to invoke a non-WebLogic Web service.

For detailed instructions on how to build and run the examples, open the following Web page in your browser:

>     WL_HOME/samples/server/src/examples/webservices/package-summary.html

Additional examples of creating and invoking WebLogic Web services are listed on the Web services Web page on the Web Services dev2dev Download Page.

Creating Java Client Applications to Invoke Web Services: Main Steps

To create a Java client application that invokes a Web service, follow these steps:

1. Get the Java client JAR files provided by WebLogic Server and add them to your CLASSPATH.

   If your client application is running on WebLogic Server, you can omit this step.

   Note: For information about BEA's current licensing of client functionality, see the BEA eLicense Web Site.

   For details, see Getting the Java Client JAR Files.

2. Write the Java client application code.

   For details on writing different kinds of client applications (static, dynamic, and so on), see Writing the Java Client Application Code and Writing a J2ME Client.

3. Compile and run your Java client application.

Getting the Java Client JAR Files

WebLogic Server provides the following client JAR files:

- A runtime JAR file, called webserviceclient.jar, that contains the client runtime implementation of JAX-RPC. This JAR file is distributed as part of the WebLogic Server product.

- A runtime JAR file, called webserviceclient+ssl.jar, that contains the runtime implementation of SSL. This JAR file is distributed as part of the WebLogic Server product.

- A runtime JAR file, called webserviceclient+ssl_pj.jar, that contains the runtime implementation of SSL for the CDC profile of J2ME. This JAR file is distributed as part of the WebLogic Server product.

- A Web service-specific JAR file that you generate with the clientgen Ant task. This file contains the Web service-specific stubs, defined by the JAX-RPC specification, that client applications use to statically invoke a Web service (either WebLogic or non-WebLogic), such as Stub and Service. Almost all the code you need is automatically generated for you.

  Note: If you are creating dynamic client applications, you do not need to use this JAR file; BEA Systems provides the file as a convenience when you use static clients to invoke Web services.

For information about BEA's current licensing of client functionality, see the BEA eLicense Web Site.

To get the client JAR files, follow these steps:

1. Copy the file WL_HOME\server\lib\webserviceclient.jar to your client application development computer, where WL_HOME refers to the top-level directory of WebLogic Platform. This client JAR file contains the client runtime implementation of JAX-RPC.

   Note: If you are using SSL to secure your Web service and you want to use the WebLogic Server-provided implementation of the SSL client classes, copy the file WL_HOME\server\lib\webserviceclient+ssl.jar to your client application development computer. In addition to the SSL implementation, this JAR file includes the same class files as in webserviceclient.jar.

   If you are writing a J2ME client that uses SSL, copy the file WL_HOME\server\lib\webserviceclient+ssl_pj.jar to your client application computer.

2. Generate the Web service-specific client JAR file by running the clientgen Ant task.

   Specify the wsdl attribute to create a client JAR file for any Web service (including non-WebLogic ones) or the ear attribute for WebLogic Web services packaged in EAR files.

   For details and examples of running the clientgen Ant task, see Running the clientgen Ant Task. For reference information, see Web Service Ant Tasks and Command-Line Utilities.

   Note: If you are creating a client application to invoke a WebLogic Web service, you can also download the client JAR file from the Home Page. See The WebLogic Web Services Home Page and WSDL URLs for more information.

3. Put these client JAR files on your client computer and update your CLASSPATH environment variable to find them.

Running the clientgen Ant Task

To run the clientgen Ant task and automatically generate a client JAR file:

1. Create a file called build.xml that contains a call to the clientgen Ant task. For details, see Sample build.xml File for the clientgen Ant Task.

2. Set your environment.

   On Windows NT, execute the setWLSEnv.cmd command, located in the directory WL_HOME\server\bin, where WL_HOME is the top-level directory of your WebLogic Platform installation.

   On UNIX, execute the setWLSEnv.sh command, located in the directory WL_HOME/server/bin, where WL_HOME is the top-level directory of your WebLogic Platform installation.

3. Execute the Ant task or tasks specified in the build.xml file by typing ant in the same directory as the build.xml file:

   >     prompt> ant

For reference information about the clientgen Ant task, see clientgen.

Sample build.xml File for the clientgen Ant Task

The following example shows a simple build.xml file:

>     <project name="buildWebservice" default="generate-client">
>        <target name="generate-client">
>          <clientgen wsdl="http://example.com/myapp/myservice.wsdl"
>                     packageName="myapp.myservice.client"
>                     clientJar="c:/myapps/myService_client.jar"
>     />

>        </target>
>     </project>

In the example, the clientgen task creates a client JAR file (called c:/myapps/myService_client.jar) to invoke the Web service described in the http://example.com/myapp/myservice.wsdl WSDL file. It packages the interface and stub files in the myapp.myservice.client package.

Writing the Java Client Application Code

The following sections describe how to write different types of Java client applications for invoking Web services, from the simplest static client that requires almost no Java code to a more complex client that uses out parameters.

All examples use the JAX-RPC API and assume that you have the necessary BEA-provided client JAR files in your CLASSPATH.

Getting Information about a Web Service

You usually need to know the name of the Web service and the signature of its operations before you write your client code.

Look at the WSDL of the Web service. The name of the Web service is contained in the <service> element, as shown in the following excerpt of the TraderService WSDL:

>       <service name="TraderService">
>         <port name="TraderServicePort"
>              binding="tns:TraderServiceSoapBinding">
>       ...
>         </port>
>       </service>

The operations defined for this Web service are listed under the corresponding <binding> element. For example, the following WSDL excerpt shows that the TraderService Web service has two operations, buy and sell (for clarity, only relevant parts of the WSDL are shown):

>       <binding name="TraderServiceSoapBinding" ...>
>         ...
>         <operation name="sell">
>         ...
>         </operation>
>         <operation name="buy">
>         </operation>
>       </binding>

To find the full signature of the Web service operations, un-JAR the Web service-specific client JAR file (generated with the clientgen Ant task) and look at the actual *.java files. The file ServiceName Port.java contains the interface definition of your Web service, where ServiceName refers to the name of the Web service. For example, look at the TraderServicePort.java file for the signature of the buy and sell operations.

Maintaining the HTTP Session

You specify whether your client application will participate in an HTTP session with a Web service endpoint by setting the following property in your application:

>     javax.xml.rpc.Call.SESSION_MAINTAIN_PROPERTY

When a client application invokes a WebLogic Web service, an internal servlet first handles the request and creates an HttpSession object for each client. The lifetime of this HttpSession object follows the standard J2EE guideslines. For more information about HttpSession objects, see Session Tracking from a Servlet.

Handling Web Services That Crash

The first time you invoke a Web service from a client application that uses the WebLogic client JAR files, the client caches the IP address of the computer on which the Web service is running, and by default this cache is never refreshed with a new DNS lookup. This means that if you invoke a Web service, and later the computer on which the Web service is running crashes, but then another computer with a different IP address takes over for the crashed computer, a subsequent invoke of the Web service from the original client application will fail because the client application continues to think that the Web service is running on the computer with the old cached IP address. In other words, it does not try to re-resolve the IP address with a new DNS lookup, but rather uses the cached information from the original lookup.

To work around this problem, update your client application to set the JDK 1.4 system property sun.net.inetaddr.ttl to the number of seconds that you want the application to cache the IP address.

Warning: This workaround is valid only for standalone client applications; if your client application is running in WebLogic Server 7.0, you cannot set this property. This is because WebLogic Server 7.0 uses Version 1.3.1 of the JDK, and this system property exists only in JDK 1.4.

Writing a Simple Static Client

When you use a static client application to invoke a Web service, you use a strongly-typed Java interface, in contrast to a dynamic client where you indirectly reference the Web service operations and parameters. Using a dynamic client is analogous to looking up and invoking a method using the Java reflection APIs.

You must include the Web service-specific client JAR file in your CLASSPATH when statically invoking a Web service. This JAR file includes the following classes and interfaces:

- A Web service-specific implementation of the Service interface, which acts a stub factory. The stub factory class uses the value of the wsdl attribute of the clientgen Ant task used to generate the client JAR file in its default constructor.

- An interface and implementation of each SOAP port in the WSDL.

- Serialization class for non-built-in data types and their Java representations.

The following code shows an example of writing a client application that invokes the sample TraderService Web service; in the example, TraderService is the stub factory and TraderServicePort is the stub itself:

>     package examples.webservices.complex.statelessSession;

>     /**
>      * This class illustrates how to use the JAX-RPC API to invoke the TraderService
>      * Web service to perform the following tasks:
>      * <ul>
>      * <li> Buy 100 shares of some stocks
>      * <li> Sell 100 shares of some stocks
>      * </ul>
>      *
>      * The TraderService Web service is implemented using the Trader
>      * stateless session EJB.
>      *
>      * @author Copyright (c) 1998-2002 by BEA Systems, Inc. All Rights Reserved.
>      */

>     public class Client {

>       public static void main(String[] args) throws Exception {

>         // Setup the global JAXM message factory
>         System.setProperty("javax.xml.soap.MessageFactory",
>           "weblogic.webservice.core.soap.MessageFactoryImpl");
>         // Setup the global JAX-RPC service factory
>         System.setProperty( "javax.xml.rpc.ServiceFactory",
>           "weblogic.webservice.core.rpc.ServiceFactoryImpl");

>         // Parse the argument list
>         Client client = new Client();
>         String wsdl = (args.length > 0? args[0] : null);
>         client.example(wsdl);
>       }

>       public void example(String wsdlURI) throws Exception {

>         TraderServicePort trader = null;
>         if (wsdlURI == null) {
>           trader = new TraderService_Impl().getTraderServicePort();
>         } else {
>           trader = new TraderService_Impl(wsdlURI).getTraderServicePort();
>         }
>         String [] stocks = {"BEAS", "MSFT", "AMZN", "HWP" };

>           // execute some buys
>         for (int i=0; i<stocks.length; i++) {
>           int shares = (i+1) * 100;
>           log("Buying "+shares+" shares of "+stocks[i]+".");
>           TradeResult result = trader.buy(stocks[i], shares);
>           log("Result traded "+result.getNumberTraded()
>               +" shares of "+result.getStockSymbol());
>         }
>         // execute some sells
>         for (int i=0; i<stocks.length; i++) {
>           int shares = (i+1) * 100;
>           log("Selling "+shares+" shares of "+stocks[i]+".");
>           TradeResult result = trader.sell(stocks[i], shares);
>           log("Result traded "+result.getNumberTraded()
>               +" shares of "+result.getStockSymbol());

>         }

>       }

>       private static void log(String s) {
>         System.out.println(s);
>       }

>     }

The main points to notice about the example are as follows:

- The following code shows how to create a TraderServicePort stub:

  >         trader = new TraderService_Impl().getTraderServicePort();

  The TraderService_Impl stub implements the JAX-RPC Service interface. The default constructor of TraderService_Impl creates a stub based on the WSDL URI specified when using the clientgen Ant task to create the client JAR file. The getTraderServicePort() method implements the Service.getPort() method, used to return an instance of the TraderService stub implementation.

- The following code shows how to invoke the buy operation of the TraderService Web service:

  >      TradeResult result = trader.buy(stocks[i], shares);

  The trader Web service has two operations: buy() and sell(). Both operations return a non-built-in data type called TradeResult.

Writing a Dynamic Client That Uses WSDL

When you create a dynamic client that uses WSDL, you first create a service factory using the ServiceFactory.newInstance() method, then create a Service object from the factory and pass it the WSDL and the name of the Web service you are going to invoke. You then create a Call object from the Service, passing it the name of the port and the operation you want to execute, and finally use the Call.invoke() method to actually invoke the Web service operation.

When you write a dynamic client, you do not use the Web service-specific client JAR file generated with the clientgen Ant task, because this JAR file is used only for static clients. You do, however, need to include the JAR file that contains WebLogic's implementation of the JAX-RPC specification in your CLASSPATH. For more information about these JAR files, see Getting the Java Client JAR Files.

For example, assume you want to create a dynamic client application that uses WSDL to invoke the Web service found at the following URL:

>     http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl

The following Java code shows one way to do this:

>     /**
>      * This class demonstrates a java client invoking a WebService.
>      *
>      * @author Copyright (c) 2002 by BEA Systems, Inc. All Rights Reserved.
>      */

>     import java.net.URL;

>     import javax.xml.rpc.ServiceFactory;
>     import javax.xml.rpc.Service;
>     import javax.xml.rpc.Call;
>     import javax.xml.rpc.ParameterMode;

>     import javax.xml.namespace.QName;

>     public class Main {

>       public static void main(String[] args) throws Exception {

>         // Setup the global JAXM message factory
>         System.setProperty("javax.xml.soap.MessageFactory",
>           "weblogic.webservice.core.soap.MessageFactoryImpl");
>         // Setup the global JAX-RPC service factory
>         System.setProperty( "javax.xml.rpc.ServiceFactory",
>           "weblogic.webservice.core.rpc.ServiceFactoryImpl");

>         // create service factory
>         ServiceFactory factory = ServiceFactory.newInstance();

>         // define qnames
>         String targetNamespace =
>           "http://www.themindelectric.com/"
>           + "wsdl/net.xmethods.services.stockquote.StockQuote/";

>         QName serviceName =
>           new QName(targetNamespace,
>                     "net.xmethods.services.stockquote.StockQuoteService");

>         QName portName =
>           new QName(targetNamespace,
>                     "net.xmethods.services.stockquote.StockQuotePort");

>         QName operationName = new QName("urn:xmethods-delayed-quotes",
>                                         "getQuote");

>         URL wsdlLocation =
>           new URL("http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl");

>         // create service
>         Service service = factory.createService(wsdlLocation, serviceName);

>         // create call
>         Call call = service.createCall(portName, operationName);

>         // invoke the remote web service
>         Float result = (Float) call.invoke(new Object[] {
>           "BEAS"
>         });

>         System.out.println("\n");
>         System.out.println("This example shows how to create a dynamic client
>                            application that invokes a non-WebLogic Web service.");
>         System.out.println("The webservice used was:
>                             http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl");
>         System.out.println("The quote for BEAS is: ");
>         System.out.println(result);
>       }

>     }

Note: When you use the javax.xml.rpc.Call API to create a dynamic client that uses WSDL, you cannot use the following methods in your client application:

- getParameterTypeByName()

- getReturnType()

Additionally, if you want to execute the getTargetEndpointAddress() method, you must have previously executed the setTargetEndpointAddress() method, even if the targetEndPointAddress is available in the WSDL.

Writing a Dynamic Client That Does Not Use WSDL

Dynamic clients that do not use WSDL are similar to those that use WSDL except for having to explicitly set information that is found in the WSDL, such as the parameters to the operation, the target endpoint address, and so on.

The following example shows how to create a client application that invokes a Web service without specifying the WSDL in the client application:

>     /**
>      * This class demonstrates a java client invoking a WebService.
>      *
>      * @author Copyright (c) 2002 by BEA Systems, Inc. All Rights Reserved.
>      */

>     import javax.xml.rpc.ServiceFactory;
>     import javax.xml.rpc.Service;
>     import javax.xml.rpc.Call;
>     import javax.xml.rpc.ParameterMode;

>     import javax.xml.namespace.QName;

>     public class Main {

>       public static void main(String[] args) throws Exception {
>         // Setup the global JAX-RPC service factory
>         System.setProperty( "javax.xml.rpc.ServiceFactory",
>           "weblogic.webservice.core.rpc.ServiceFactoryImpl");

>         // create service factory
>         ServiceFactory factory = ServiceFactory.newInstance();

>         // define qnames
>         String targetNamespace =
>           "http://www.themindelectric.com/"
>           + "wsdl/net.xmethods.services.stockquote.StockQuote/";

>         QName serviceName =
>           new QName(targetNamespace,
>                     "net.xmethods.services.stockquote.StockQuoteService");

>         QName portName =
>           new QName(targetNamespace,
>                     "net.xmethods.services.stockquote.StockQuotePort");

>         QName operationName = new QName("urn:xmethods-delayed-quotes",
>                                         "getQuote");

>         // create service
>         Service service = factory.createService(serviceName);

>         // create call
>         Call call = service.createCall();

>         // set port and operation name
>         call.setPortTypeName(portName);
>         call.setOperationName(operationName);
>         // add parameters
>         call.addParameter("symbol",
>                           new QName("http://www.w3.org/2001/XMLSchema", "string"),
>                           ParameterMode.IN);

>         call.setReturnType(new QName( "http://www.w3.org/2001/XMLSchema","float") );

>         // set end point address
>         call.setTargetEndpointAddress("http://www.xmethods.com:9090/soap");

>         // invoke the remote web service
>         Float result = (Float) call.invoke(new Object[] {
>           "BEAS"
>         });

>         System.out.println("\n");
>         System.out.println("This example shows how to create a dynamic client
>                             application that invokes a non-WebLogic Web service.");
>         System.out.println("The webservice used was:
>      http://www.themindelectric.com/wsdl/net.xmethods.services.stockquote.StockQuote");
>         System.out.println("The quote for BEAS is:");
>         System.out.println(result);
>       }

>     }

Note: In dynamic clients that do not use WSDL, the getPorts() method always returns null. This behaviour is different from dynamic clients that do use WSDL in which the method actually returns the ports.

Writing a Client that Uses Out or In-Out Parameters

Web services can use out or in-out parameters as a way of returning multiple values.

When you write a client application that invokes a Web service that uses out or in-out parameters, the data type of the out or in-out parameter must implement the javax.xml.rpc.holders.Holder interface. After the client application invokes the Web service, the client can query the out or in-out parameters in the Holder object and treat them as if they were standard return values.

For example, the Web service described by the following WSDL has an operation called echoStructAsSimpleTypes() that takes one standard input parameter and three out parameters:

>     http://soap.4s4c.com/ilab/soap.asp?WSDL

The following static client application shows one way to invoke this Web service. The application assumes that you have included the Web service-specific client JAR file that contains the Stub classes, generated using the clientgen Ant task, in your CLASSPATH.

>     package websvc;

>     /**
>      * This class demonstrates a java client invoking a WebService.
>      *
>      * @author Copyright (c) 2002 by BEA Systems, Inc. All Rights Reserved.
>      */

>     public class Main {

>       public static void main(String[] args) throws Exception {
>         // Setup the global JAX-RPC service factory
>         System.setProperty( "javax.xml.rpc.ServiceFactory",
>           "weblogic.webservice.core.rpc.ServiceFactoryImpl");

>         InteropLab_Impl test = new InteropLab_Impl();
>         InteropTest2PortType soap = test.getinteropTest2PortType();

>         org.tempuri.x4s4c.x1.x3.wsdl.types.SOAPStruct inputStruct =
>           new org.tempuri.x4s4c.x1.x3.wsdl.types.SOAPStruct();

>         inputStruct.setVarInt(10);
>         inputStruct.setVarFloat(10.1f);
>         inputStruct.setVarString("hi there");

>         javax.xml.rpc.holders.StringHolder outputString =
>           new javax.xml.rpc.holders.StringHolder();
>         javax.xml.rpc.holders.IntHolder outputInteger =
>           new javax.xml.rpc.holders.IntHolder();
>         javax.xml.rpc.holders.FloatHolder outputFloat =
>           new javax.xml.rpc.holders.FloatHolder();

>         soap.echoStructAsSimpleTypes(inputStruct, outputString, outputInteger,
>                                      outputFloat);

>         System.out.println("This example shows how to create a static client
>                             application that invokes a non-WebLogic Web service.");
>         System.out.println("The webservice used was:
>                          http://soap.4s4c.com/ilab/soap.asp?WSDL");
>         System.out.println("This webservice shows how to invoke an operation that
>                            uses out parameters.  The set parameters are below:");
>         System.out.println("outputString.value: " + outputString.value);
>         System.out.println("outputInteger.value: " + outputInteger.value);
>         System.out.println("outputFloat.value: " + outputFloat.value);
>       }

>     }

Writing a J2ME Client

You can create a Java 2 Platform, Micro Edition (J2ME) Web service-specific client JAR file to use with client applications that run on J2ME.

Note: The specific J2ME environment that we support is the CDC and Foundation profile.

Creating a J2ME client application that invokes a Web service is almost the same as creating a non-J2ME client. For example, you use the same runtime client JAR file as non-J2ME client applications (WL_HOME\server\lib\webserviceclient.jar.)

To write a J2ME client application, follow the steps described in Creating Java Client Applications to Invoke Web Services: Main Steps but with the following changes:

- When you run the clientgen Ant task to generate the Web service-specific client JAR file, be sure you specify the j2me="True" attribute, as shown in the following example:

  >     <clientgen wsdl="http://example.com/myapp/myservice.wsdl"
  >                packageName="myapp.myservice.client"
  >                clientJar="c:/myapps/myService_clients.jar"
  >                j2me="True"
  >     />

  Note: The J2ME Web service-specific client JAR file generated by clientgen is not compliant with the JAX-RPC specification in the following ways:

- The methods of the generated stubs do not throw java.rmi.RemoteException.

- The generated stubs do not extend java.rmi.Remote.

- When you write, compile, and run your Java client application, be sure you use the J2ME virtual machine and APIs.

For more information about J2ME, see http://java.sun.com/j2me/.

Writing a J2ME Client that Uses SSL

WebLogic Server includes support for creating J2ME client applications that use SSL. If you are writing a J2ME client that uses SSL, follow these guidelines in addition to the guidelines specified in the preceding section:

- You must use the following additional class and package:

  - java.math.BigInteger (class)

  - java.util.* (entire package)

- Copy the file WL_HOME\server\lib\webserviceclient+ssl_pj.jar to your client application computer and add it to your CLASSPATH.

  Warning: Do not include the weblogic.jar file in your CLASSPATH.

- If your client application uses the WSDL file to invoke a Web service, you must use a local copy of the WSDL file stored on your client computer; you cannot access the WSDL file using a URLConnection object.

Creating and Using Portable Stubs

If you use the Web services client JAR files (both the ones distributed with the product and the Web service-specific one generated by the clientgen Ant task) as part of an application that runs in WebLogic Server, you might find that the Java classes in the JAR file collide with the classes of WebLogic Server itself. This problem is more apparent if the WebLogic Server in which the client JAR file is deployed is a different version from that which the client JAR file was generated. To solve this problem, use portable stubs.

Note: You need to use portable stubs only if your client application is deployed and running on WebLogic Server. If your client application is standalone, you do not need to use portable stubs.

To enable your client application to use portable stubs:

1. Use the WebLogic Server release-specific client JAR file called wsclient70.jar (distributed with WebLogic Server in the WL_HOME\server\lib directory) with your client application rather than the generic webserviceclient.jar client JAR file. The wsclient70.jar file contains the same class files as the standard client JAR file, but they are renamed weblogic70.*. Because these class files are version-specific, they will not collide with any weblogic.* WebLogic Server classes.

2. Run the Web-service specific client JAR file you generated with the clientgen Ant task, as well as any supporting client JAR files, through the VersionMaker utility. This utility makes the following changes to the classes in these client JAR files:

   - renames all weblogic.* classes to weblogic70.*.

   - all references to weblogic.* classes are changed to reference weblogic70.* instead.

   Use these new version-specific client JAR files with your client application.

   For details on using VersionMaker, see Using the VersionMaker Utility.

Using the VersionMaker Utility

The weblogic.webservice.tools.versioning.VersionMaker utility takes the following parameters:

- destination_dir : the destination directory that will contain the new version-specific client JAR files.

- client_jar_file : the client JAR file, generated by the clientgen Ant task, whose class files are named weblogic.* and should be renamed weblogic70.*.

- other_jar_files : supporting JAR files

Follow these steps to update your client JAR files to use version-specific WebLogic Server classes:

1. Set your environment.

   On Windows NT, execute the setWLSEnv.cmd command, located in the directory WL_HOME\server\bin, where WL_HOME is the top-level directory of your WebLogic Platform installation.

   On UNIX, execute the setWLSEnv.sh command, located in the directory WL_HOME/server/bin, where WL_HOME is the top-level directory of your WebLogic Platform installation.

2. Execute the utility weblogic.webservice.tools.versioning.VersionMaker, as shown in the following example:

   >     java weblogic.webservice.tools.versioning.VersionMaker \
   >        new_directory myclient.jar supporting.jar

   In the example, the weblogic.* classes in the myclient.jar and supporting.jar client JAR files are renamed weblogic70.*, and all references to these classes updated accordingly. The new client JAR files are generated into the directory called new_directory under the current directory.

Using a Proxy Server with the WebLogic Web Services Client

You can use a proxy server to proxy requests from a WebLogic Web Services client application to a server (either WebLogic or non-WebLogic) that is hosting a Web Service. However, be sure to set all the following system properties in your client application:

- http.proxyHost

- http.proxyPort

- weblogic.webservice.transport.http.proxy.host

- weblogic.webservice.transport.http.proxy.port

Note: If you are using HTTPS as the transport when invoking the Web Service, replace the http in the preceding properties with https. For example, use https.proxyHost instead of http.proxyHost.

For more information on these, and other, WebLogic system properties you can set in your client application, see WebLogic Web Services System Properties.

Additionally, if you have set up your proxy server to use proxy authentication, then you must also set the property weblogic.net.proxyAuthenticatorClassName in your client application to the name of the Java class that implements the weblogic.common.ProxyAuthentication interface, as shown in the following excerpt from a client application:

>         System.setProperty("weblogic.net.proxyAuthenticatorClassName", "my.ProxyAuthenticator");

In the example, my.ProxyAuthenticator is a class in the client application's CLASSPATH that implements the weblogic.common.ProxyAuthentication interface.

The weblogic.common.ProxyAuthentication interface allows a client application to provide user authentication information required when tunneling WebLogic HTTP and SSL protocols through a proxy server that requires user authentication. For details on implementing this interface, see the weblogic.common.ProxyAuthentication Javadocs.

The WebLogic Web Services Home Page and WSDL URLs

Every Web service deployed on WebLogic Server has a Home Page. From the Home page you can:

- View the WSDL that describes the service.

- Download the Web service-specific client JAR file that contains the interfaces, classes, and stubs needed to invoke the Web service from a client application.

  Note: A link to download this client JAR file appears on the Home page only if the name of the client JAR file is WebServiceName_client.jar, where WebServiceName refers to the name of the Web service, specified by the name attribute of the <web-service> element in the web-services.xml file. If this is not true for your Web service, you must use the clientgen Ant task to create the JAR file. For details, see Running the clientgen Ant Task.

- Test each operation to ensure that it is working correctly.

  As part of testing a Web service, you can edit the XML in the SOAP request that describes non-built-in data types to debug interoperability conflicts.

- View the SOAP request and response messages from a successful execution of an operation

The following URLs show first how to invoke the Web service Home page and then the WSDL in your browser:

>     [protocol]://[host]:[port]/[contextURI]/[serviceURI]

>     [protocol]://[host]:[port]/[contextURI]/[serviceURI]?WSDL

where:

- protocol refers to the protocol over which the service is invoked, either http or https. This value corresponds to the protocol attribute of the <web-service> element that describes the Web service in the web-servicex.xml file. If you used the servicegen Ant task to assemble your Web service, this value corresponds to the protocol attribute.

- host refers to the computer on which WebLogic Server is running.

- port refers to the port number on which WebLogic Server is listening (default value is 7001).

- contextURI refers to the context root of the Web application, corresponding to the <context-root> element in the application.xml deployment descriptor of the EAR file. If you used the servicegen Ant task to assemble your Web service, this value corresponds to the contextURI attribute.

  If your application.xml file does not include the <context-root> element, then the value of contextURI is the name of the Web application archive file or exploded directory.

- serviceURI refers to the URI of the Web service. This value corresponds to the uri attribute of the <web-service> element in the web-services.xml file. If you used the servicegen Ant task to assemble your Web service, this value corresponds to the serviceURI attribute.

For example, assume you used the following build.xml file to assemble a WebLogic Web service using the servicegen Ant task:

>     <project name="buildWebservice" default="build-ear">
>       <target name="build-ear">
>           <servicegen
>              destEar="myWebService.ear"
>              warName="myWAR.war"
>              contextURI="web_services">
>              <service
>                  ejbJar="myEJB.jar"
>                  targetNamespace="http://www.bea.com/examples/Trader"
>                  serviceName="TraderService"
>                  serviceURI="/TraderService"
>                  generateTypes="True"
>                  expandMethods="True" >
>              </service>
>          </servicegen>
>       </target>
>     </project>

The URL to invoke the Web service Home Page, assuming the service is running on a host called ariel at the default port number, is:

>     http://ariel:7001/web_services/TraderService

The URL to get the automatically generated WSDL of the Web service is:

>     http://ariel:7001/web_services/TraderService?WSDL

Debugging Errors While Invoking Web Services

If you encounter an error while trying to invoke a Web service (either WebLogic or non-WebLogic), it is useful to view the SOAP request and response messages that are generated because they often point to the problem.

To view the SOAP request and response messages, run your client application with the -Dweblogic.webservice.verbose=true flag, as shown in the following example that runs a client application called runService:

>     prompt> java -Dweblogic.webservice.verbose=true runService

The full SOAP request and response messages are printed in the command window from which you ran your client application.

You can also configure WebLogic Server to print the SOAP request and response messages each time a deployed WebLogic Web service is invoked by specifying the -Dweblogic.webservice.verbose=true flag when you start WebLogic Server. The SOAP messages are printed to the command window from which you started WebLogic Server.

Note: Because of possible decrease in performance due to the extra work of printing debugging messages to the command window, BEA recommends you set this WebLogic Server flag only during the development phase.

WebLogic Web Services System Properties

The following table lists the WebLogic Web services system properties you can set in client applications that invoke Web services. Use the System.setProperty() method to set the properties.

Table 8-2 WebLogic Web Services System Properties

System Property | Description | Data Type
--- | --- | ---
weblogic.webservice.transport.http.full-url | Specifies that the full URL, rather than the relative URL, of the Web Service that the client application is invoking be specified in the Request-URI field of HTTP request. Valid values are True and False. Default value is False. | Boolean.
weblogic.webservice.transport.http.proxy.host | If you use a proxy server to make HTTP connections, use this system property to specify the host name of the proxy server in your client applications. | String.
weblogic.webservice.transport.http.proxy.port | If you use a proxy server to make HTTP connections, use this system property to specify the port of the proxy server in your client applications. | String.
weblogic.webservice.transport.https.proxy.host | If you use a proxy server to make HTTPS (HTTP over SSL) connections, use this system property to specify the host name of the proxy server in your client applications. | String.
weblogic.webservice.transport.https.proxy.port | If you use a proxy server to make HTTPS (HTTP over SSL) connections, use this system property to specify the port of the proxy server in your client applications. | String.
weblogic.webservice.verbose | Enables verbose mode during Web service invocation so you can view the SOAP request and response messages. Valid values are True and False. Default value is False. For details, see Debugging Errors While Invoking Web Services. | Boolean.
weblogic.webservice.client.ssl.strictcertchecking | Enables or disables strict certificate validation when using the WebLogic-provided implementation of SSL. Set to True to enable strict certificate validation, and False to disable. Default value is False. For an example, see Using the WebLogic Server-Provided SSL Implementation. | Boolean.
weblogic.webservice.client.ssl.trustedcertfile | The name of the file (located on the client application computer) that contains the certificates of CA (certificate authority). The CAs are trusted to issue WebLogic Server certificates. The file can also contain certificates that you trust directly. | String.
weblogic.webservice.client.ssl.adapterclass | Fully qualified name of an adapter class you have implemented to use a third-party SSL implementation. For an example, see Using a Third-Party SSL Implementation. | String.
weblogic.http.KeepAliveTimeoutSeconds | Number of seconds to maintain HTTP keep-alive before timing out the request. If you do not want to use HTTP keep-alive, set this property to 0. Default value is 30 seconds. | Integer.