Effective way of forming a WebService client
rohit.macherla Sep 1, 2010 5:58 AMWhich is more effective way of forming a WebService client out of the following ?
- Having the Service and Port objects of the generated Java artifacts (after importing the WSDL) as method-local objects. Example :
public class TestWS { ... private void testLocal() { wsdlImportedPackage.TargetService localService = new wsdlImportedPackage.TargetService(); wsdlImportedPackage.TargetServicePort localPort = localService.getTargetServicePort(); wsdlImportedPackage.TargetResponse response = localPort.invoke(); ... } }
- Having the Service and Port objects of the generated Java artifacts as static global. Example :
public class TestWS { ... wsdlImportedPackage.TargetService globalService = null; wsdlImportedPackage.TargetServicePort globalPort = null; static { globalService = new wsdlImportedPackage.TargetService(); globalPort = globalService.getTargetServicePort(); } private void testGlobal() { wsdlImportedPackage.TargetResponse response = globalPort.invoke(); ... } }
When the testLocal() method is load tested, it is observed that the code localPort = localService.getTargetServicePort() resulted in the entire WSDL being fetched and parsed and (probably) JAXB objects created for each invocation of test() method. However, load test of testGlobal() method resulted in only one full parse of WSDL, which occured when the class was loaded, as expected since the getTargetServicePort() is in the static block. Thus the testGlobal() looks efficient, what with reducing the Garbage collection (no need of collecting the service, port and other java objects which were derived from WSDL once the method is over since they are global) and network access time to download the WSDL and parse it.
Assumption to be considered:
* No table locking or resource locking occurs from the webservice.
* The target WSDL doesn't change.
* The getTargetServicePort() has the code to get the QName, etc., i.e., the relevant WS client code.
Will a single Port object be able to handle all the requests properly without any deadlocks ? (From my testing, I give it a nod, but it may depend on the WebService code as well)
Is there any other better way to cache the WSDL or stop the server from accessing the WSDL always for generating the Java artifacts, provided that the target WSDL doesn't change ?
I am unable to get proper documents from where I could find out what the getWebServicePort() method is supposed to do.
Furthermore, during load testing testLocal(), we found that the processing threads (which are found in tomcat console, i.e., http://JBOSS_IP:Port/status) of TargetService remain active even after they sent the response. These threads are of type:
GET /TargetServiceManagement-war/TargetService?wsdl HTTP/1.1
Such threads are active for a long time and when the thread count comes down we find that the following messages appear in the log:
17:47:37,938 ERROR [RequestHandlerImpl] Cannot close output stream
There are as many of such statements as there are such active threads. I am not able to understand whether this is a code issue or not, because it occurs only for our vendor API's. For a custom built API, such issue doesn't arise.
These tests were performed on JBoss 4.2.3 server and the code was developed using NetBeans 6.8 (but development environment shouldn't matter I guess).
So two questions here: What is the best away among the two? and What does this RequestHandlerImpl error mean ?
Thanks for your time.