Programming WebLogic Web Services
The following sections describe how to troubleshoot WebLogic Web Services:
Every Web Service deployed on WebLogic Server has a Home Page. From the Home page you can:
To invoke the Web Service Home page for a particular service in your browser, use the following URL:
[
protocol
]://[host
]:[port
]/[contextURI
]/[serviceURI
]
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.7001
).<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.
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 Web Service Home Page lists the operations that can be invoked for this service. To test a particular operation:
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.
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.RunService
The 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.
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.
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: The weblogic.webservice.binding
package is a proprietary WebLogic API.
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 detailed information about the SOAP XML Schema, see SOAP 1.1.
To post a SOAP request to a SOAP server directly:
POST /asmx/simple.asmx HTTP/1.1
Host: www.stock.org:7001
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>
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
filename
This section describes how to create a file that contains a well-formed HTTP SOAP request generated by the WebLogic Web Services client when invoking a Web Service.
weblogic.webservice.verbose
property, as described in Viewing SOAP Messages, or cutting and pasting the SOAP message generated from testing the WebLogic Web Service from its Home Page, as described in Using the Web Service Home Page to Test Your Web Service.The following SOAP request was generated f rom an invocation of the sample examples.webservices.complex.statelessSession
Web Service , and was cut and pasted from the Web Services Home Page:
<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:Header>
<env:Body
env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<m:sell xmlns:m="http://www.bea.com/examples/Trader">
<string xsi:type="xsd:string">sample string</string>
<intVal xsi:type="xsd:int">100</intVal>
</m:sell>
</env:Body>
</env:Envelope>
<?xml version="1.0" encoding="utf-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
...
POST /filetransferAtResponse/FTService HTTP/1.1
Host: localhost:7001
Content-Type: text/xml; charset=utf-8
Connection: close
SOAPAction: ""
<?xml version="1.0" encoding="utf-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
...
You should now have a good HTTP SOAP request to post to a SOAP server.
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:
<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>
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.
<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.
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.
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.
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
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:
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:
If you use public fields in your Java class, you do not have to create get and set methods for each field.
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:
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:
The following list describes performance issues you should be aware of as you program your WebLogic Web Service.
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.
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.
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 datatype
This 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.
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.client
However, because of the way that the WebLogic client-side SSL was implemented, you must 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
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.abstractType
The 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:
<autotype
javaTypes="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.
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:
null
, using a setXXX(null)
method, in the backend implementation of your Web Service operation.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.
When a client application invokes, for the first time, a Web Service whose endpoint URL uses HTTPS, the application might get the following error:
[java] </bea_fault:stacktrace>javax.net.ssl.SSLKeyException: FATAL
Alert:BAD_CERTIFICATE - A corrupt or unuseable certificate was received.
This can happen when, for example, you initially ran the clientgen
Ant task to generate the stubs from a WSDL whose endpoint address uses HTTP, create a client application that invokes this Web Service, and then switch to an endpoint address that uses HTTPS (and thus SSL) in the client application by setting the ENDPOINT_ADDRESS_PROPERTY
property of the javax.xml.rpc.Stub
interface, as shown in the following example:
String url = "https://localhost:7002/webservice/TraderService";
((javax.xml.rpc.Stub )trader)._setProperty
(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, url);
The problem in this case could be that the client application is not using the WLSSLAdapter
class to load the client certificate, which is needed for SSL. The problem only arises when using HTTPS, which is why the problem did not occur when invoking the Web Service using HTTP.
To solve the problem, use the WLSSLAdapter.setTrustedCertificateFile()
method (for 1-way SSL) or WLSSLAdapter.loadLocalIdentity()
method (for 2-way SSL) to load the client certificate, as shown in the following example:
SSLAdapterFactory factory = SSLAdapterFactory.getDefaultFactory();
WLSSLAdapter adapter = (WLSSLAdapter) factory.getSSLAdapter();
// Uncomment following to load the client certificate for 1-way SSL
// adapter.setTrustedCertificatesFile("mytrustedcerts.pem");
// Uncomment following to load the client certificate for 2-way SSL
// adapter.loadLocalIdentity(clientCredentialFile, pwd.toCharArray());
When you use the autotype
Ant task to generate serialization classes for a list of Java data types whose class names are the same, but are in different packages, make sure you do not specify the packageName
attribute. If you do, the autotype
Ant task generates the serialization class for only the last Java data type, rather than all the specified Java data types.
For example, assume you want to generate serialization classes for the following Java data types:
The following sample autotype
Ant task specification in the build.xml
file is correct and will generate serialization classes for the two Java data types:
<autotype
destDir="/output/type_defs"
javaTypes="mypackage.MyClass,mypackage.test.MyClass"
keepGenerated="True"
overwrite="True">
<classpath refid="client.classpath"/>
</autotype>
The following autotype
specification is incorrect and will generate only one serialization class (for the mypackage.test.MyClass
class):
<autotype
destDir="/output/type_defs"
javaTypes="mypackage.MyClass,mypackage.test.MyClass"
keepGenerated="True"
overwrite="True"
packageName="mypackage">
<classpath refid="client.classpath"/>
</autotype>
If a client application includes the Authorization
HTTP header in its SOAP request when invoking a Web Service, but the Web Service has not been configured with access control security constraints, WebLogic Server still refuses the request with an HTTP 401 Error: Unauthorized Access
. This differs from the way Web Applications handle the same situation: Web Applications ignore the Authorization
HTTP header if the Web Application is not configured with security constraints.
If you want your Web Service to behave like a Web Application in this situation, set the ignoreAuthHeader="True"
attribute of the servicegen
or source2wsdd
Ant task that assembles your Web Service, as shown in the following example:
<servicegen
destEar="ears/myWebService.ear"
warName="myWAR.war">
<service
javaClassComponents="examples.webservices.basic.javaclass.HelloWorld"
targetNamespace="http://www.bea.com/examples/HelloWorld"
serviceName="HelloWorld"
serviceURI="/HelloWorld"
generateTypes="True"
ignoreAuthHeader="True"
expandMethods="True">
</service>
</servicegen>
Setting this attribute in the Ant task in turn sets the ignoreAuthHeader="True"
attribute for the <web-service>
element that describes the Web Service in the generated web-services.xml
deployment descriptor.
Warning: Be careful using the ignoreAuthHeader
attribute. If you set the value of this attribute to True
, WebLogic Server never authenticates a client application that is attempting to invoke a Web Service, even if access control security constraints have been defined for the EJB, Web Application, or Enterprise Application that make up the Web Service. Or in other words, a client application that does not provide athentication credentials is still allowed to invoke a Web Service that has security constraints defined on it.
You can configure a WebLogic Web Service so that client applications can use the JMS transport to invoke the Web Service. This feature is described in Using JMS Transport to Invoke a WebLogic Web Service. Furthermore, you can write a client application to invoke an operation of a Web Service asynchronously, which means that the client application first invokes the operation without immediately waiting for the result, and then optionally gets the results of the invoke in a later step. This feature is described in Writing an Asynchronous Client Application.
However, be aware that if you use the two features together, in certain situations the client application might never receive the asynchronous response message from WebLogic Server that includes the results of an initial invoke of the Web Service operation. In particular, assume that an asynchronous client application invokes an operation, but before the application can invoke the second request for the results of the operation, WebLogic Server is restarted. After WebLogic Server starts up again, it sees that it has a response message to send back to the client, but it does not know where to send this response, and thus the asynchronous client application never receives it. This is because the Web Service asynchronous client uses temporary, rather than permanent, JMS destinations in its implementation, and references to this temporary destination from WebLogic Server are lost after a server restart.
If you run the autotype
Ant task on a very large WSDL file, your computer might run out of resources and return any one of the following errors:
The system is out of resources.
Consult the following stack trace for details. java.lang.OutOfMemoryError
package weblogic.xml.schema.binding.internal.builtin does not exist
To solve this problem, expand the memory of the java
command used by the Ant task by increasing the heap size to at least 512M.
In particular, update the ant.bat
file, located in the BEA_HOME
/weblogic81/server/bin
directory, where BEA_HOME
is the main BEA installation directory, such as c:/bea
. Update the file by adding the -Xmx512m
option to the %_JAVACMD%
variable used in the various :runAnt
labels . For example:
:runAnt
"%_JAVACMD%"
-Xmx512m
-classpath "%LOCALCLASSPATH%" -Dant.home="%ANT_HOME%"
%ANT_OPTS% org.apache.tools.ant.Main %ANT_ARGS% %ANT_CMD_LINE_ARGS%
if errorlevel 1 exit /b 1
goto end
If your WebLogic Server domain was created by a user different from the user that installed WebLogic Server, the following error is returned when a user tries to log onto the UDDI Explorer:
An error has occurred
E_fatalError(10500): a serious technical error has occurred while
processing the request. 'Exception while attempting to instantiate
subclass of DataReader: com.acumenat.uddi.persistence.ldap.LDAPInit'
To resolve this problem, the WebLogic Server administrator must change the permissions on the uddi.properties
file to give access to all users. The uddi.properties
file, used to configure the UDDI server, is located in the WL_HOME
/server/lib
directory, where WL_HOME
refers to the main WebLogic Platform installation directory.
The autotype
Ant task does not comply with the JAX-RPC specification if the XML Schema data type (for which it is generating the Java representation) has certain characteristics; see Data Type Non-Compliance with JAX-RPC for details.