Troubleshooting
The following sections describe how to troubleshoot WebLogic Web Services:
- Using the Web Service Home Page to Test Your Web Service
- Viewing SOAP Messages
- Posting the HTTP SOAP Message
- Debugging Problems with WSDL
- Verifying a WSDL File
- Verifying an XML Schema
- Debugging Data Type Generation (Autotyping) Problems
- Debugging Performance Problems
- Performance Hints
- Re-Resolving IP Addresses in the Event of a Failure
- BindingException When Running clientgen or autotype Ant Task
- Client Error When Using the WebLogic Web Service Client to Connect to a Third-Party SSL Server
- Client Error When Invoking Operation That Returns an Abstract Type
- Including Nillable, Optional, and Empty XML Elements in SOAP Messages
Using the Web Service Home Page to Test Your Web Service
Every Web Service deployed on WebLogic Server has a Home Page. From the Home page you can:
- View the WSDL that describes the service.
- Test each operation with sample parameter values to ensure that it is working correctly.
- View the SOAP request and response messages from a successful execution of an operation.
URL Used to Invoke the Web Service Home Page
To invoke the Web Service Home page for a particular service in your browser, use the following URL:
[protocol]://[host]:[port]/[contextURI]/[serviceURI]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-services.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
Testing the Web Service
The Web Service Home Page lists the operations that can be invoked for this service. To test a particular operation:
- Click on the operation link.
- Enter sample values for the parameters in the table. The first two columns of the table list the name and Java data type of the operation.
- Click Invoke.
The SOAP request and response messages and the value returned by the operation are displayed in a new browser window.
The main Web Service Home Page also displays an example of the Java code to invoke one of the operations and a sample build.xml file for executing the clientgen Ant task to generate the Web Service-specific client JAR file.
Viewing SOAP Messages
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, 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 my.app.RunService:
prompt> java -Dweblogic.webservice.verbose=true my.app.RunServiceThe full SOAP request and response messages are printed in the command window from which you ran your client application.
You configure this feature by setting verbose mode to true, either with Ant or programmatically.
Setting Verbose Mode with Ant
If you use Ant to run your client application, you can set verbose mode by adding a <sysproperty> element to the build.xml file, as shown in the following example:
<java classname="my.app.RunService"> <sysproperty key="weblogic.webservice.verbose" value="true"/>
</java>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 output, BEA recommends you set this WebLogic Server flag only during the development phase.
Setting Verbose Mode Programatically
You can programmatically set verbose mode in your client application by using the weblogic.webservice.binding.BindingInfo.setVerbose(true) method, as shown in the following code excerpt:
import weblogic.webservice.binding.BindingInfo;...BindingInfo info = (BindingInfo)stub._getProperty("weblogic.webservice.bindinginfo" );info.setVerbose( true ); port.helloWorld();In the example, stub is the instance of the JAX-RPC Stub class for your Web Service. When the helloWorld() operation executes, the SOAP request and response messages will be printed in the command window from which you executed the client application.
To turn off verbose mode, invoke the setVerbose(false) method.
For more information about the weblogic.webservice.binding package, see the Javadocs. Note that the weblogic.webservice.binding package is a proprietary WebLogic API.
Posting the HTTP SOAP Message
To further troubleshoot problems with the SOAP messages, you can post the request directly to a SOAP server (rather than through a client application) and view the raw SOAP response. By-passing the client application and viewing the raw SOAP messages may pinpoint the problem. You can then update selected parts of the SOAP request by editing the text file, then re-post the request to see what fixes the problem.
Note: It is assumed that you understand the structure of a SOAP message; if you need more information about the SOAP XML Schema, see SOAP 1.1.
To post a SOAP request to a SOAP server directly:
- Create a text file that contains an HTTP SOAP request; the request should include both the HTTP headers and SOAP envelope. See Viewing SOAP Messages for details on using the weblogic.webservice.verbose property to get the SOAP request generated by the WebLogic Web Services client. The following example shows an HTTP SOAP request:
POST /asmx/simple.asmx
HTTP/1.1 Host: www.mssoapinterop.org
Content-Type: text/xml; charset=utf-8
Connection: close
SOAPAction: "http://soapinterop.org/"<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://soapinterop.org/" xmlns:types="http://soapinterop.org/encodedTypes" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <tns:echoString> <inputString xsi:type="xsd:string">string</inputString> </tns:echoString> </soap:Body>
</soap:Envelope>
- Use the weblogic.webservice.tools.debug.Post utility to post the message to a SOAP server, as shown in the following example:
java weblogic.webservice.tools.debug.Post filenamewhere filename refers to the text file that contains the HTTP SOAP request, created in the preceding step. The Post utility uses the HTTP header to determine the URL of the SOAP server.
- The SOAP server sends back the raw HTTP SOAP response which you can examine for clues about your problem.
Debugging Problems with WSDL
Another potential reason for errors produced when invoking a Web Service is that the WSDL might be invalid. Fixing a published WSDL that contains problems might be out of your hands; however, you can at least pinpoint the problem and let the provider know so that the provider can fix it.
Note: It is assumed that you understand the structure of a WSDL file; if you need more information on the WSDL XML Schema, see Web Services Description Language (WSDL) 1.1.
This section does not attempt to cover all possible problems with a WSDL file but rather, describe the following common ones:
- An invalid URL for the Web Service endpoint. This URL is listed in the <service> element of the WSDL, as shown in the following excerpt:
<service name="myservice> <port name="myport" binding="tns:mybinding"> <soap address="http://a_host:4321/service /> </port>
</service>In this case, ensure that the URL http://a_host:4321/service is indeed the Web Service endpoint.
- References to undefined elements
For example, the type attribute of the <binding> element refers to the name attribute of a <portType> element, as shown in the following excerpts:
<binding name="my-binding" type="tns:my-port"> <operation name="foo"> <input /> <output /> </operation>
</binding><portType name="my-port"> <operation name="foo"> <input message="tns:fooReq" /> <output message="tns:fooRes" /> </operation>
</portType>If, for example, the <portType> element had a name of my-port1, then the reference to it in the <binding> element would be invalid, and attempting to invoke the Web Service described by this WSDL would fail.
- Problems with the <import> element.
WSDL allows associating a namespace with a document location using an <import> element, as shown:
<definitions .... > <import namespace="http://example.com/stockquote/definitions" location="http://example.com/stockquote/stockquote.wsdl"/>
</definitions>The WSDL specified in the location attribute might itself have an import statement that points to another WSDL, and so on. Although this is a good technique for creating clearer Web Service definitions, because it separates the definitions according to their level of abstraction, it is also possible to create a problem if there are many layers of abstraction. In this case, make sure all imported WSDL files actually exist and are valid.
- The WSDL may contain XML data types that are not compatible with WebLogic Web Services.
Verifying a WSDL File
To verify that a WSDL is compatible with WebLogic Web Services, use the clientgen Ant task with the wsdl attribute, as shown in the following example:
<clientgen wsdl="http://example.com/myapp/myservice.wsdl" packageName="myapp.myservice.client" clientJar="myapps/myService_client.jar"
/>If the clientgen Ant task completes with no errors, then the WSDL is compatible and well-formed.
Verifying an XML Schema
To verify that an XML Schema is compatible with WebLogic Web Services, use the autotype Ant task with the schemaFile attribute, as shown in the following example:
<autotype schemaFile="my-schema.xsd" packageName="foo" destDir="temp_dir"
/>If the autotype Ant task completes with no errors, then the XML Schema is compatible and well-formed.
Debugging Data Type Generation (Autotyping) Problems
If you encounter an error while using the servicegen, autotype, or clientgen Ant tasks to generate the autotyping components (such as the serialization class and Java or XML representations) for any non-built-in data types, you can set the weblogic.xml.schema.binding.verbose=true property to print out verbose information about the autotyping activity taking place, and perhaps get an idea of what the problem is.
You can set this property while using the command-line versions of the autotype or clientgen Ant tasks, as shown in the following example:
java -Dweblogic.xml.schema.binding.verbose=true \ weblogic.webservice.clientgen -wsdl foo.wsdl \ -clientJar /tmp/test_client.jar -packageName foo
Common XML Schema Problems
The following list describes typical problems with your XML Schema when using the autotyping features of WebLogic Server (in other words, the autotype, servicegen, or clientgen Ant tasks) to generate the serialization class and Java representation of a non-built-in XML data type:
- A missing import statement for the namespace associated with a data type.
- Using unsupported XML Schema data types. See Non-Built-In Data Types Supported by servicegen and autotype Ant Tasks and Unsupported Features for more information.
Common Java Problems
The following list describes typical problems with your Java class when using the autotyping features of WebLogic Server (in other words, the autotype, servicegen, or clientgen Ant tasks) to generate the serialization class and XML Schema representation of a non-built-in Java data type:
- The Java class does not have a public default constructor.
- The Java class does not have both get and set methods for all private fields. In this case, the autotyping feature of the Web Services Ant tasks will ignore these private fields when generating the serialization class and corresponding XML Schema.
If you use public fields in your Java class, you do not have to create get and set methods for each field.
- Using unsupported Java data types. For the full list of the non-built-in Java data types that the autotyping feature supports, see Non-Built-In Data Types Supported by servicegen and autotype Ant Tasks
- Not being able to roundtrip generated Java/XML data types. For more information, see Non-Roundtripping of Generated Data Type Components.
Debugging Performance Problems
Web Services use SOAP as their message protocol. Other binary protocols will likely achieve better performance. For example, if you can invoke a Web Service 300 times a second, you might be able to invoke the same method 1500 times a second using RMI.
The main factors that determine the performance of a Web Service, from the most influential to the least, are as follows:
- Using HTTP as the connection protocol
- If you are using security, the process of encrypting and decrypting the SOAP message
- Parsing and generating XML, such as the SOAP message
- Converting data between its Java and XML representations
- Using very large parameters
Typically, HTTP has the most influence in the performance of a Web Service. To determine if this is true for your WebLogic Web Service, follow these guidelines:
- Create a servlet which simply receives the SOAP message that is used to invoke your Web Service and returns the SOAP response message. Your servlet should do no other processing, such as converting data between XML and Java. For details on getting the SOAP request and response, see Viewing SOAP Messages.
- Time how long it takes to invoke the Web Service in the standard way.
- Time how long it takes to send the SOAP request to the servlet and for your client to receive the response.
- Invoking the Web Service in the standard way should take only a little longer than sending the SOAP messages to the servlet. If this is true for your Web Service, then there is not much more you can do to speed up the invoke because HTTP is the main factor. However, if it takes a lot more time (such as twice as long) to invoke the Web Service than it does to use the servlet, then you might be running into one of the other factors. See Performance Hints for information on how to increase the performance of your Web Service.
Performance Hints
The following list describes performance issues you should be aware of as you program your WebLogic Web Service.
- Use the us-ascii character set whenever you can, because it is the most efficient and fast. For details, see Specifying the Character Set for a WebLogic Web Service.
- Use literal encoding rather than SOAP encoding by specifying that your Web Service be document-oriented. For details, see Choosing RPC-Oriented or Document-Oriented Web Services.
- Security, such as data encryption and digital signatures, can slow down performance significantly, so be very judicious when adding security to a Web Service.
- Be very aware of what the handlers in your handler chains are doing, because they will execute for every single Web Service operation invoke.
- Be sure to turn off all debugging flags you might have turned on during development.
Re-Resolving IP Addresses in the Event of a Failure
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.
BindingException When Running clientgen or autotype Ant Task
If you use the clientgen or autotype Ant tasks with the wsdl attribute to generate client or data type components from a WSDL file, you might sometimes get the following exception:
weblogic.webservice.tools.build.WSBuildException: Failed to do type mapping - with nested exception:
[weblogic.xml.schema.binding.BindingException: unable to find a definition for type datatypeThis exception means that there is an undefined data type in the section of the WSDL file that describes the XML Schema data types used by the Web Service. The solution to this problem is to add the data type definition to the WSDL file.
Client Error When Using the WebLogic Web Service Client to Connect to a Third-Party SSL Server
You can use the WebLogic client-side implementation of SSL in your client application to connect to a third-party SSL server, such as OpenSSL, by specifying the weblogic.webservice.client https protocol handler, as shown in the following example:
-Djava.protocol.handler.pkgs=weblogic.webservice.clientHowever, because of the way that the WebLogic client-side SSL was implemented, use the SSLAdapter class to open a URL connection to the SSL server and get an InputStream, as shown in the following code snippet:
SSLAdapter adapter = SSLAdapterFactory.getDefaultFactory().getSSLAdapter();
InputStream in = adapter.openConnection(url).getInputStream();The preceding code replaces generic code to open a connection, shown in the following example:
URLConnection con = url.openConnection();
InputStream in = con.getInputStream();If you do not use the SSLAdapter class as shown, you might get the following error when running your client:
Exception: FATAL Alert:BAD_CERTIFICATE - A corrupt or unuseable certificate was received
Client Error When Invoking Operation That Returns an Abstract Type
When a client invokes a Web Service operation implemented with a method that returns an abstract type, the client might get the following error:
java.lang.Error: cannot create abstract type: my.abstractTypeThe exact scenario for this error to occur is as follows:
abstract class Foo { }class Bar extends Foo {}class MyService { public Foo getFoo() { return new Bar(); }
}So, although the signature of the getFoo() method specifies that it returns a Foo object, the actual return statement in the implemenation of the method returns a Bar object, which extends the abstract Foo.
In this scenario, it is important that you explicitly execute the autotype Ant task for the Bar class to generate its serialization components before you execute autotype on the MyService class. The second autotype execution on the MyService class automatically generates serialization components for the Foo abstract class because it is the explicit return value of the getFoo() method. If you execute the two autotype tasks in the reverse order, you will get an error when trying to invoke the Web Service operation that is implemented by the getFoo() method, even though you will not get an error when executing the Ant tasks themselves.
The following snippet from a build.xml file shows an example of running the two autotype Ant tasks in the correct order:
<autotypejavaTypes="Bar" targetNamespace="com.bea.example" packageName="com.bea.example" keepGenerated="True" destDir="${classes}"> <classpath> <path refid="project.classpath"/> <pathelement path="${classes}"/> </classpath> </autotype><autotype javaComponents="MyService" targetNamespace="com.bea.example" typeMappingFile="${classes}/types.xml" packageName="com.bea.example" keepGenerated="True" destDir="${classes}"> <classpath> <path refid="project.classpath"/> <pathelement path="${classes}"/> </classpath> </autotype>Note: You cannot use the servicegen Ant task on the MyService class to generate all the serialization components in this scenario. This is because the servicegen Ant task will not know to generate components for the Bar class, because this class does not explicitly appear in the signatures of the methods of the MyService class.
Including Nillable, Optional, and Empty XML Elements in SOAP Messages
When WebLogic Server generates the SOAP response to an invocation of a Web Service operation, and one of the XML elements of the return value is defined as nillable and optional (or in other words, the XML Schema definition of the element includes the nillable="true" and minOccurs="0" attributes), and there is no actual data associated with the element, then WebLogic Server does not include the element in the SOAP response at all. This behavior, although not a bug in WebLogic Server, might be unexpected and could cause interoperability problems when different clients invoke the Web Service.
For example, assume the WSDL of your Web Service defines the ProductType XML data type as shown:
<xsd:complexType name="ProductType"><xsd:sequence><xsd:element type="xsd:string" name="ID" minOccurs="0" nillable="true"/> <xsd:element type="xsd:string" name="Name" minOccurs="0" nillable="true"/> <xsd:element type="xsd:string" name="Description" minOccurs="0" nillable="true"/> </xsd:sequence></xsd:complexType>Further assume a Web Service operation returns a Product, which is of type ProductType, and that in a particular invocation, the Description element is empty because the product has no description. WebLogic Server generates a SOAP response similar to the following:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"; xmlns:xsd="http://www.w3.org/2001/XMLSchema";> <env:Header/> <env:Body> <n1:Product xmlns:n1="http://mycompany.com/mywebservice"; > <n1:ID>1234</n1:ID> <n1:Name>MyFabProduct</n1:Name> </n1:Product> </env:Body>
</env:Envelope>Note that the <n1:Product> element simply does not include the <n1:Description> child element at all.
This behavior is different if the XML element is not optional (minOccurs="1"). In this case, WebLogic Server includes the empty element in the SOAP response, but with the xsi:nil="true" attribute, as shown in the following example:
... <n1:Product xmlns:n1="http://mycompany.com/mywebservice"; > <n1:ID>1234</n1:ID> <n1:Name>MyFabProduct</n1:Name> <n1:Description xsi:nil="true"></n1:Description> </n1:Product>
...This is not a bug in WebLogic Server. The difference in behavior is due to the ambiguity of the XML Schema Part 0: Primer specification, which is very clear about what should happen when minOccurs="1", but unclear in the case where minOccurs="0".
If you always want nillable and optional XML elements to appear in the SOAP response, even when they have no content, then you can do one of the following:
- Explicitly set the value of the corresponding Java object to null, using a setXXX(null) method, in the backend implementation of your Web Service operation.
- Update the WSDL of the Web Service so that all nillable="true" XML elements that might sometimes be empty also have the minOccurs="1" attribute set. This option is not always possible, however, so BEA recommends the preceding workaround.