Tag Archives: java

SOAP and JAX-WS, RPC versus Document Web Services

JAX-WS and RPC versus Document Web Services

I have had this buried on this web site for years and am publishing it on the blog as well.

This article will take a journey that ends with a clear and cogent elucidation of the differences between the various styles of SOAP styles for web services. The styles covered are RPC Literal versus Document Literal versus Document Wrapped. We also talk about WS-I Basic Profile that web services need to be compliant of in order to achieve interoperability with consumers on a different platform, technology stack etc.

The article assumes familiarity with XML, WSDL, SOAP as well as Java (upwards of Java 5 including annotations). You can run any of the examples with JDK 1.6 without downloading any extensions or any other libraries.

With the advent of JDK 1.6, JAX-WS and JAXB support is intrinsically available without the need to download any new libraries since Metro is part of the JDK release now.

Without digressing, lets come down to the differences between RPC and Document styles with respect to the java codebase, the WSDL and the SOAP requests and responses. For the purpose of this illustration, we would create an example with a java interface that would be annotated with JAX-WS annotations to translate it into a web service and then generate the artifacts and detail the WSDL and the SOAP requests and responses so generated.

Note: the coverage extends to styles that are mandated by the WS-I BP 1.1 (Basic Profile for interoperability of web services).

We will use the Bottoms-Up approach where in the java interface would be coded first and then the WSDL would be generated off it.

There would be java classes used for the purpose of illustrating the differences and the WSDL and Schema as well as the SOAP requests and responses would also be displayed for demonstrating the differences between the following SOAP styles:

  1. RPC Literal (Wrapped)
  2. Document Literal
  3. Document Wrapped

The following java classes are used. They are listed in entirety (except the package or import statements for the purpose of brevity) and any differences introduced for different SOAP styles are highlighted in the relevant sections.

  1. MyServiceIF => this is the web service interface
  2. MyServiceImpl => this is the implementation of the MyServiceIF.
  3. HolderClass1 => this is singular argument in the exposed web service operation
    • HolderClass2 => this is one of the instance variables of the HolderClass1 besides a string and an integer.
  4. EndPointPublisher => as the name suggests, this publishes the web service and automatically generates the artifacts such as the WSDL.

Once the java codebase, WSDL, Schema, SOAP Request and Response are outlined for each of the SOAP styles, thereafter a section explaining the various differences is provided.


RPC Literal Wrapped

RPC-Literal is always wrapped (not BARE).  This is a listing of the java classes mentioned earlier.

Source Code:

MyServiceIF


MyServiceImpl


HolderClass1


HolderClass2


EndPointPublisher

Listing 1: The Java codebase.

WSDL and Schema

The WSDL generated for RPC Literal is as follows:

RPC-Lit_WSDL

The schema that this WSDL refers to is:

RPC-Lit_Schema

SOAP Request

RPC-Lit SOAP Request

SOAP Response

 

RPC-Lit SOAP Response

 


Document Literal (BARE)

The java codebase remains the same except for the following:

  1. The SOAP Binding for the MyServiceIF is updated to specify Document as the style:@SOAPBinding(style=Style.DOCUMENT, use=Use.LITERAL, parameterStyle=ParameterStyle.BARE)
  2. The WebParam annotation now specifies a partName as well. This is to elucidate where the partName would be translated to in the WSDL that would be created.
  3. Since WS-I BP 1.1 specifies that there should be only one child in the body of the element. Since this is a Document Literal service, there would not be an element (such as the name of the operation) that encapsulates all the parameters (such as class1 and intArg). This implies that such a case would not be WS-I BP 1.1 compliant. Therefore JAX WS will not allow it and as a result spew out this error:
    Exception in thread “main” com.sun.xml.internal.ws.model.RuntimeModelerException: runtime modeler error: SEI server.MyServiceImpl has method getHolderClass annotated as BARE but it has more than one parameter bound to body. This is invalid. Please annotate the method with annotation: @SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
    To overcome this issue and to continue to demonstrate this style, we would remove one of the arguments in the method.

Java Listing

@WebService

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

publicinterface MyServiceIF {

@WebMethod(operationName=“getHolder”)

HolderClass1 getHolderClass(@WebParam( name=“holderClass1Param”, partName=“holderClass1Param2″) HolderClass1 class1);

}

 

WSDL and Schema

The WSDL so generated for this style is:

Doc Literal WSDL

And the schema that is refers to is:

Doc Literal Sche,a

SOAP Request

<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:ser=”http://server/”>

<soapenv:Header/>

<soapenv:Body>

<ser:holderClass1Param>

<holder2>

<i>2</i>

<name>?</name>

</holder2>

<i>1</i>

<name>?</name>

</ser:holderClass1Param>

</soapenv:Body>

</soapenv:Envelope>

SOAP Response

<S:Envelope xmlns:S=”http://schemas.xmlsoap.org/soap/envelope/”>

<S:Body>

<ns2:getHolderResponse xmlns:ns2=”http://server/”>

<holder2>

<i>6</i>

<name>name_holderClass2</name>

</holder2>

<i>2</i>

<name>name_holderClass1</name>

</ns2:getHolderResponse>

</S:Body>

</S:Envelope>


Document Literal Wrapped

The java codebase remains the same except for the following:

  1. The SOAP Binding for the MyServiceIF is updated to specify Wrapped as the parameter style. The parameterStyle attribute in the SOAPBinding annotation is removed and that implies the service is wrapped due to “Wrapped” being the default for the attribute.@SOAPBinding(style=Style.DOCUMENT, use=Use.LITERAL)

Java Listing

Doc-Wrapped_MyServiceIF

WSDL and Schema

The WSDL so generated for this style is:

Doc Wrapped WSDL

And the schema that is refers to is:

Doc  Wrapped Schema

SOAP Request

Doc Wrapped SOAP Request

SOAP Response

Doc Wrapped SOAP Response


Differences between the Styles

RPC Literal (Wrapped) Document Literal Document Wrapped
Request Message The operation name appears immediately after the soap:body. The operation name is specified by the binding:operation element in the binding section of the WSDL.
The name attribute of the message:part follows immediately. It is not qualified by a namespace
Thereafter the names of the elements in the types section of the WSDL are specified.
The operation name is not specified in the request.
The value specified by the element attribute of message:part is the first line following the soap:body. It is qualified by a namespace. Note that this value of the element attribute is actually the value of the name attribute of the schema element in the types section.
Thereafter it is similar to RPC Literal in the way that the names of the elements in the types section of the WSDL are specified.
It is similar to “Document Literal Bare” style with one exception => the value of the “element” attribute in the message:part is defined to be the name of the operation. Therefore the name of the operation is part of the request.
The operation name appears immediately after the soap:body.
Thereafter it is similar to RPC Literal.
WS-I BP 1.1 Compliance It is WS-I BP 1.1 compliant even though there are many parts in the input message. This is because the first element after the soap:body is the name of the operation and that encapsulates it all. Since it can have multiple parts immediately following the soap:body, it is not WS-I BP 1.1 compliant. Therefore to make it compliant, a wrapper needs to be defined and this implies that the web method can only have one argument. You could circumvent this requirement by defining the arguments to be part of the SOAP header instead of the body. It is WS-I BP 1.1 compliant.
WSDL There could be many parts in the input message.
The parts are always specified with a “type” attribute.
There could be many parts in the input message
The parts are always specified with an “element” attribute
There is only one part in the input message.
The part is always specified by an “element” attribute.
This part is the entire message payload and is completely defined in the types section.

 

The heap data structure

A sample implementation of the heap data structure is at:

https://github.com/Khanna111/DS/tree/master/Heap/src/com/khanna111

You would find two classes that implement the “siftDown” approach that creates a heap from an input array of “n” elements in O (n) complexity.

For details on the “siftDown” approach and the complexity being O (n), please refer to:

http://en.wikipedia.org/wiki/Heapsort

JMeter (Java) and DNS and SSL and CRL and OCSP

While utilizing JMeter for some load testing of a web service on HTTPS, wanted to confirm the external invocations being made by the program for OCSP and CRL etc. The easiest way is to utilize the “strace” command to display the network system calls:

strace -f -s 1024 -e trace=network ./jmeter.sh

[pid  7361] connect(86, {sa_family=AF_INET6, sin6_port=htons(443), inet_pton(AF_INET6, “::ffff:10.0.0.xx, &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
[pid  7361] getsockname(86, {sa_family=AF_INET6, sin6_port=htons(35606), inet_pton(AF_INET6, “::ffff:10.0.0.xx”, &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0
[pid  7361] socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 87
[pid  7361] connect(87, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr(“10.0.0.xx”)}, 16) = 0
[pid  7361] sendto(87, “\226q\1\0\0\1\0\0\0\0\0\0\00274\0010\0010\00210\7in-addr\4arpa\0\0\f\0\1″, 40, MSG_NOSIGNAL, NULL, 0) = 40
So the snippet above determines that there is a DNS call to port 53 of the name server (in bold above).
There are no OCSP calls being made as well. By default all of that is disabled. To allow for OCSP calls and CRL checking, one needs to set the appropriate system properties. Please see: https://blogs.oracle.com/xuelei/entry/enable_ocsp_checking

A snippet to enable OCSP and CRL is:
// params is an instance of PKIXParameters
params.setRevocationEnabled(true);
Security.setProperty("ocsp.enable", "true");
// for CRL
System.setProperty("com.sun.security.enableCRLDP", "true");

Java PermGen

Recently I was asked to investigate an OutOfMemory issue with the PermGen running out of allocated space. Sounds simple in the sense that if I open up the heap dump, check out the classes that are loaded and figure out where the issue is. However, this happened on production and there was no heap dump available. This was on a Sun Java SDK 1.6.x.

As a consequence of this exercise, I brushed up on some of my concepts of Java Garbage Collection and discovered some intricacies of the tools in the process.

Before, we go any further, I would like to elucidate with some authority gained from past experience that analyzing and resolving OutOfMemory PermGen issues requires not only a clear understanding of the Java GC concepts but an intricate knowledge of your application as well. Consequently to cover the former, please take a look at the “Java Garbage Collection” details especially the concept of generations and heap versus non heap.

PermGen allocation is separate from the heap and therefore the parameters to set that are different from the regular -Xms and -Xmx. Please take a look at the Java VM options (do a google search and check out PermSize options – one to set the minimum bound and the other for the maximum). Also, please note that PermGen holds the class metadata, class definitions and so on. Once the class is loaded then any static references from it are stored in the heap (young or old) along with any instances.

Since we are tracking the PermGen, what we need to do is to replicate the issue which is easier said than done since you probably do not have enough information as to:

  1. In what flow of your application did it happen? Perhaps this can be gleamed from the logs as well as the stack traces.
  2. What was the load on the application that led to this?

Thereafter, what you could do is to lower the PermGen allocated to your application and perform the following steps:

  1. Specify the “printGCDetails” along with the verboseGC options for the VM.
  2. Specify the “on OutOfMemory, generate heap dump” VM option. Note that sometimes even with this option specified the heap dump is not generated since the VM becomes unstable when a OOM happens.
  3. Options to generate the listing of classes that are loaded and unloaded by the GC process.

I would recommend that these setting (no 1 and no 2 above) be part of any VM process even that that is running in Production environments. They are of immense use in resolving OOM issues.

Sometimes, you would also see OOM PermGen stack traces in the log but that resolve themselves and the application continues to perform and run as planned. These ephemeral OOM PermGen stack traces do not seem to impact the longevity and stability of the process but at the same time they need to be investigated and the conclusion of such an investigation can lead to an increases in the PermGen space allocation and that would be the resolution.

The first thing to do is to inspect the dump. In case the heap dump is not available then the only option is to replicate the issue.

If you are able to replicate the issue then the next step would be to inspect the heap dump and there are some very useful tools out there. The one that I found most useful was the Eclipse Memory Analyzer. You would need to review the usage and options of this tool and they are well documented. At this time, you have the following data set with you:

  1. List of the classes that have been loaded and unloaded.
  2. You could take the complement of the intersection of the loaded and unloaded i.e. all the classes that have not been unloaded.

Fire up an OQL query (select query: please see the OQL examples) and trace the graph to the entity that is responsible for retaining the class to evaluate a leak. At this juncture, the familiarity of the codebase of the application is required.

If you are not able to replicate the issue and you do not get an OOM PermGen stack trace, do not loose heart. You could also try to run your application for a period of time and watch the PermGen grow and then introduce a PermGen collection as part of the Full GC and evaluate if the allocation is reduced. Repeat the process of loading the application, introducing PermGen collection and evaluating the heap dump to investigate the classes that are not being unloaded and that could point to a possible leak. One thing to note is that PermGen Collection is generally not part of the Full Garbage Collection unless the appropriate VM option is specified or the PermGen gets filled up so as to trigger a PermGen Collection. The latter technique is demonstrated in a link in the references section below.

You could also try figuring out if there is a class loader leak => if the application is un-deployed as in the case of an application deployed in a J2EE container as in JBoss, does the class loader responsible for the application is made available for GC? This technique is also detailed in a link in the references section below.

I have also tried to use the JHAT tool but gave up on that in preference to the Eclipse Memory Profiler since the JHAT tool required a lot of memory and was slow. I believe this has been patched in a later version of JDK 1.6 and you could try that as well.

References:

  1. http://minmaxmim.blogspot.com/2010/01/javalangoutofmemoryerror-permgen-space.html
  2. http://blogs.oracle.com/fkieviet/entry/how_to_fix_the_dreaded
  3. http://wiki.eclipse.org/index.php/MemoryAnalyzer
  4. http://memoryanalyzer.blogspot.com/2010/02/heap-dump-analysis-with-memory-analyzer.html