The Source for Java Technology Collaboration
User: Password:



Rama Pulavarthi's Blog

Community: Java Web Services and XML Archives


JDK 6 Update 6 is out

Posted by ramapulavarthi on April 16, 2008 at 02:41 PM | Permalink | Comments (0)

You can find javac compilation issue with classes in javax.xml.ws.wsaddressing package in my previous blog "A little update for JAX-WS 2.1 users with JDK 6 Update 4 and Update 5" The corresponding bug 6672868 is fixed in JDK 6 update 6. The fix should be available in Open JDK 6 as well. So, you don't have to use the compiler switches or workarounds as mentioned in my previous blog to make it work :)

Status of WS-Addressing and MTOM Interop scenarios at Plugfest

Posted by ramapulavarthi on March 25, 2008 at 11:28 AM | Permalink | Comments (0)

I attended the Interop Plugfest @Microsoft from March 18th - 20th. This was my first time at Plugfest and to Microsoft campus. You can find more about the Interop Plugfest here, where all the test scenarios and wsdls are published. It was good meeting people face to face and interact with people working on the same technologies. I was mostly testing the WS-Addressing and MTOM scenarios between Metro and .NET 3.5.

You can find the last report from the Plugfest held in November 2007 from Harold's blog. Here is the status on WS-Addressing and MTOM scenarios.

WS-Addressing
--------------------------------------------------------------
Metro -> Metro:
WS-Addressing CR SOAP 1.1:                24/24
WS-Addressing CR SOAP 1.2:                29/29
WS-Addressing Member Submission SOAP 1.1: 18/18
WS-Addressing Member Submission SOAP 1.2: 19/19

Metro -> .NET 3.5:
WS-Addressing CR SOAP 1.1:                22/23 (1143 failed)
WS-Addressing CR SOAP 1.2:                24/25 (1243 failed)
WS-Addressing Member Submission SOAP 1.1: 10/10
WS-Addressing Member Submission SOAP 1.2: 11/11

*** Test 1143 and Test1243 have been rerun with updated enpoints made 
available on separate ports have been tried and verified to work 
and the fix might be available in upcoming major release of WCF. 

.NET 3.5 -> Metro:
WS-Addressing CR SOAP 1.1:                24/25 (1152 failed)
WS-Addressing CR SOAP 1.2:                26/26 (1152 failed)
WS-Addressing Member Submission SOAP 1.1: 10/11 (1152 failed)
WS-Addressing Member Submission SOAP 1.2: 11/12 (1152 failed) 

*** Test 1152 is being investigated by Microsoft.

*** Test 1299 has been added to SOAP 1.2 endpoints and has been tested separately. 
This test is added to test wsa:Action based Dispatching.
This has been tested to work in all the scenarios. 

MTOM:
--------------------------------------------------------------
Scenarios:
Soap11MtomSignEncrypt        4  
Soap11MtomSignOnly           5 
Soap11MtomUtf16              5 
Soap11MtomUtf8               5  
Soap12MtomUtf8               5  
Soap12MtomUtf8Aug04          5  
Soap12MtomUtf8Security       5   
Soap12MtomUtf8SecurityAug04  4 

As you can see a decrease in number of tests, testEchoBinaryHeaderasString 
in Soap11MtomSignEncrypt and  Soap12MtomUtf8SecurityAug04 has been removed from the test suite
(as there is no standard way for encrypting a SOAP Header in WSS 1.0 unlike in WSS 1.1)

Metro -> Metro: 38/38
Metro -> .NET 3.5: 38/38
.NET 3.5 -> Metro: 38/38 

***There are some random failures when I run the tests 
repeatedly in WCF -> Metro scenario. Metro service throws an exception and is being investigated.

As you can clearly see, there are very few failures in WS-Addressing and MTOM compared to the last Plugfest in November 2007 as we fixed some testcase issues and got some issues resolved by Microsoft. Its a good progress !!! Currently, There are no direct WS-Addressing 1.0 tests that use WS-Addressing 1.0 Metadata. WS-Addressing Metadata is being tested indirectly in some Security scenrios. Hopefully, some of these tests will be updated to use Metadata and that gives a way to test interoperability when we implement the Metadata specification.

Technorati:
JAX-WS   Metro   WCF  



A little update for JAX-WS 2.1 users with JDK 6 Update 4 and Update 5.

Posted by ramapulavarthi on March 07, 2008 at 05:00 PM | Permalink | Comments (1)

Some issues on compiling using classes in javax.xml.ws.wsaddressing package have come to our attention (You can follow the thread in the Metro User forum). As you can see, javax.xml.ws.wsaddressing package along with the classes W3CEndpointReference and W3CEndpointReferenceBuilder are infact there in rt.jar. But javac complains package javax.xml.ws.wsaddressing does not exist.

This is due to the fact that JAVA_HOME/lib/ct.sym was not updated with these new api. This problem is in the JDK 6 Update 4 and Update 5, should not effect you unless you are using W3CEndpointReference and W3CEndpointReferenceBuilder in your applications. We are actively working on providing a fix in future update release. In the mean while, you could use one of these following workarounds.

  • Use the compiler switch -XDignore.symbol.file=true (Note that this is undocumented option).
  • Put rt.jar explicitly in your claspath for javac
  • Remove ct.sym from JAVA_HOME/lib ( not recommended as it requires changes to your JDK installation)

We will be very soon fixing this glitch. Thanks for your cooperation.



A Tip on Using JAX-WS with Maven

Posted by ramapulavarthi on January 18, 2008 at 03:08 PM | Permalink | Comments (0)

A tip on Using Maven with JAX-WS is available as Enterprise Java Technologies Tech Tips. You can find more Enterprise Java Technical Tips that are posted every month here. In this tip, I talk about using JAX-WS Maven plugin to build Web Services.

The JAX-WS Maven Plugin is developed as part of the jax-ws-commons project, where useful plugins and extensions around the JAX-WS RI are collected. This tip explores the JAX-WS maven plugin's two goals wsimport and wsgen and shows it with a simple sample. In this tip, I used NetBeans 6.0 to walk through the programming model for Web Services development using Maven. Netbean 6.0 has good support for Maven making it easy for developing web applications and deploying on to GlassFish server with a few mouse clicks.

Though NetBeans 6.0 has good support for Maven, it does n't support Web Services development using Maven directly. I heard NetBeans guys are working on improving the support in this area so that you can get Maven based Web Services project instead of ant based Web Services project. Then some of the configuration steps explained in the tip will not be necessary. I am eagerly waiting for it.

If you are a command-line person, I plan to post a similar tip on using Maven CLI to build Web Services using JAX-WS maven plugin and deploy on to a container using Cargo Plugin. If you have any questions on using the plugin, please post them to users@metro.dev.java.net

Technorati:
JAX-WS   Metro   Maven   GlassFish   NetBeans  

JAX-WS 2.1 and JAXB 2.1 is available in JDK 6 Update 4 release

Posted by ramapulavarthi on January 11, 2008 at 05:02 PM | Permalink | Comments (4)

Finally, JDK6 Update 4 release, which has JAX-WS 2.1 and JAXB 2.1 implementation is out and available here.

What it means to you as a user:
You can use JAX-WS 2.1 (Metro 1.1) very smoothly on JDK 6 U4 and later.

Earlier releases of JDK 6 have JAX-WS 2.0 and JAXB 2.0 implementations. After the release of JDK 6 FCS, JAX-WS RI has been re-architected to perform better (infact a lot better ) and make it extensible for other technologies to be implemented using the core framework. Since the re-architecture and release of JAX-WS 2.1, JAX-WS user and developer community have been asking for the update of JAX-WS in JDK 6. Currently to use JAX-WS 2.1 on earlier JDK 6 releases, one has to use endorsed overide mechanism as explained here in detail. Using the endorsed mechanism, it has been little painful to use latest JAX-WS in applets and other scenarios. This has been the case for any evolving technology.

Since then, We have been planning to update JAX-WS in JDK 6 in Update release. It is little unusual for a major component such as JAX-WS to update its version without revving up the Java Major version. After discussions and the approval process, JAX-WS 2.1 has been integrated and tested thoroughly. This has took longer than we expected for it to come out due to unforeseen circumustances. Finally, JAX-WS 2.1 along with JAXB 2.1 is integrated in JDK 6 Update 4 release and is available for download. Rest assured, All your old web-services applications should work fine and may even perform better. JDK 6 U4 has bits based on JAX-WS 2.1.1 FCS and JAXB 2.1.1 FCS. The main change in JAX-WS API is the addition of API to support WS-Addressing 1.0. You can find the JAX-WS/JAXB changes and bug fixes that got into JDK 6 U4 here at JAX-WS change log and JAXB change log

You might also notice that OpenJDK6 still has JAX-WS 2.0. We are actively working on updating the bits in Open JDK as tracked on this bug report.

If you want to use the latest releases of JAX-WS/JAXB for other bug fixes, you can use the latest releases of JAX-WS and JAXB by putting the JAX-WS/JAXB jars in the classpath like any other Java library. So with JDK6 U4, you don't need to use the endorsed mechanism. The latest release of JAX-WS 2.1.3 has these changes and JAXB 2.1.6 has these changes

Also you might want to download Metro 1.1, which has JAX-WS 2.1.3 and Web Services Interoperability Technologies (WSIT) 1.1 that implements the WS-* specs and provides advanced Web Services support in terms of Quality of Service and Security. To use Metro 1.1 on JDK6 U4, you just have to put the Metro jars in the classpath.

Life is getting better. Isn't it?

Technorati:
JAX-WS   Metro   GlassFish   JDK

Extend your Web Service applications with the new efficient Handlers in JAX-WS RI

Posted by ramapulavarthi on December 13, 2007 at 06:28 PM | Permalink | Comments (3)

Ealier in my blog "Understanding Handlers in JAX-WS", I talked about Handler Framework in JAX-WS and showed some examples of using handlers to intercept the messages for additional processing on the server and client. Overall, JAX-WS handlers provide good API to abstract your application logic as a handler and plug it in easily with any service. But the standard handlers have some limitations. LogicalHandler provides access to payload only and does n't provide access to SOAP headers and binary data carried as attachments in the SOAP Message and is more suited for XML/HTTP binding. Though SOAPHandlers provide access to whole SOAP Message, it has performance implications as SOAPMessage is based on DOM and tries to load the whole message in memory. JAX-WS RI reads the message in Streaming fashion and tries to read the information lazily to provide better performance. But each time a SOAPHandler acceses the message, it is converted to DOM based SOAP Message. This can hurt your application performance. Though the SOAPHandlers have the performance limitation due to the above mentioned reasons, The JAX-WS Specification defined a pretty extensible framework, so that other types of protocol handlers can be plugged-in easily.

JAX-WS RI has been fine tuned to perform better and better. JAX-WS RI defines Message abstraction thats hides the actual data representation either the message be constructed from a JAXB object or InputStream of a HttpConnection. The Message API provides various ways to access the payload and implementations can implement those methods in the best possible way. JAX-WS Runtime chooses the right Message representation when it is constructing a new message. It also provides some commonly used implementations of Message (like JAXBMessage, DOMMessage, SAAJ Message, ProtocolSourceMessage etc). Each kind of Message has particular characteristic and is more useful or suited depending on the situation. Along with it, RI also provides some static factory methods to easily create messages with the Messages API. Using these one can easily access/create messages irrespective of the actual data representation. More about the API can be found in the JAX-WS architecture document.

MessageHandler:
Utilizing the extensible Handler framework provided by JAX-WS Specification and the better Message abstraction in RI, We introduced a new handler called MessageHandler to extend your Web Service applications. MessageHandler is similar to SOAPHandler, except that implementations of it gets access to MessageHandlerContext (an extension of MessageContext).  Through MessageHandlerContext one can access the Message and process it using the Message API. As I put in the title of the blog, this handler lets you work on Message, which provides efficient ways to access/process the message not just a DOM based message. The programming model of the handlers is same and the Message handlers can be mixed with standard Logical and SOAP handlers. I have added a sample in JAX-WS RI 2.1.3 showing the use of MessageHandler to log messages and here is a snippet from the sample.
public class LoggingHandler implements MessageHandler<MessageHandlerContext> {
    public boolean handleMessage(MessageHandlerContext mhc) {
        Message m = mhc.getMessage().copy();
        XMLStreamWriter writer = XMLStreamWriterFactory.create(System.out);
        try {
            m.writeTo(writer);
        } catch (XMLStreamException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public boolean handleFault(MessageHandlerContext mhc) {
        ..... 
        return true;
    }
    
    public void close(MessageContext messageContext) {    }
   
    public Set getHeaders() {
        return null;
    }
}

MessageHandler as light weight Tube:
JAX-WS RI also provides pugglable framework for JAX-WS extensions to process the messages represented as Packets through Tubes. Packets are just a containers for Message and hold additional Metadata properties relating to the message. Tubes are like filters that work on the packet. Most of the WS-* spec imlementations are done as Tube/Pipe implementation in WSIT. Tubes are very convenient and targeted for developers where in the extensions providing Tube implementation adhere to the Tube API to dotheir part of processing in a bigger chain. But for your Tube to be recognized by the JAX-WS Runtime, you need to plugin your Tube in a TubelineAssembler and make it available to the RI runtime. I talked more about extending JAX-WS through annotations and Tubes here.

Most of the work that can be done in Tubes can be done in a MessageHandler, there by providing light-weight framework for the users to take advantage of the Message abstraction and easy pluggability without change to the already familiar in programming model. You don't have to implement your TubelineAssembler to plug in your logic. Along with the standard properties exposed by the Messagecontext, MessageHandlerContext provides access to SEI Model, WSDL Model and other information to the handler, so that the handler can almost do what a tube can do. Infact you can implement the functionalioty of  MUHeaderTube ( a Tube that does SOAP MustUnderstand Header processing) in a handler efficiently. One downside of implementing it as a handler is that if you implement it as a Tube and extend TublineAssembler, you can make it available to all applications  and even to the existing applications with out touching the code. But with handlers approach, you need to modify the application a bit to configure handlers.

I see advantanges to both ways of extensions to JAX-WS. Extending JAX-WS as a Tube is mostly for developers enhancing the JAX-WS Runtime to provide some extra functionality. MessageHandlers are easier to develop handlers by the end users and are natural choice if your applications are already using JAX-WS handler framework.

Get the latest Metro 1.1 bits and give it a try.

Technorati:
JAX-WS   Metro   GlassFish  

Metro @ SiliconValley CodeCamp 2007

Posted by ramapulavarthi on October 31, 2007 at 12:41 AM | Permalink | Comments (0)

I attended the SiliconValley CodeCamp at FootHill College, Los Altos this weekend. This is a free conference by developers for developers in a beautiful location. Overall, good number of people attended the conference. I liked the conference as it is light weight and free. Another interesting thing is that there were sessions covering topics on .NET, Java and Web 2.0 technologies. My wife is a .NET developer and me being a Java developer, It was good that we both could attend and participate in our areas of interest.

I and Arun presented about Metro in Glassfish at SiliconValey CodeCamp this saturday on Metro. We had some glitches with the projector during our presentation, but the spirit of the audience helped us continue with the presentation and it went well later on. Some of the audience are very familiar with JAX-WS and are trying JAX-WS 2.1.3 as well :).

Rama_SiliconValleyCodeCamp2007.jpg

Here is a photo showing me in action at SiliconValley CodeCamp(Thanks Arun for taking the photo).

The slides are available here . The demos Using EXCEL with WSIT, Web services development using NetBeans IDE and GlassFish and other screencasts are available here.

Here is a photo with the Silicon Valley JUG leaders Aaron Houston , Van Riper, Kevin Nelson chatting about the sessions and JUGs.

Rama_JUG.JPG

Java Posse had a live recording of their podcast covering the weekly happenings and issues centered on Java. It was nice to watch the four guys expressing their views on various topics and Listening to their podcast is like a quick recap of the news around Java. This week it was mainly on Apple not including Java SE 6 in Mac OS 10.5 Leopard, Mozilla's Prism to run Web Applications outside of browser, the rumor that Java ME is dead, and Google Collection API and others.

Rama_JavaPosse.JPG

Here is a photo of me with Java Posse guys [Tor Norbye (Sun Microsystems), Carl Quinn (Google), Dick Wall (Google) and Joe Nuxoll (Apple)]. I liked the session and seeing them in live with their funny hats on.

I will be waiting for the next SiliconValley CodeCamp.

Technorati: siliconvalleycodecamp metro glassfish webservices netbeans



JAX-WS 2.1 in Java SE 6 Update N

Posted by ramapulavarthi on October 03, 2007 at 09:25 PM | Permalink | Comments (1)

Java SE 6 Update N (formerly know as the "Consumer JRE" project) is an update release that introduces new features and enhancements aimed at providing an optimized consumer end user experience. Along with the features and enhancements listed here, it also brings in JAX-WS 2.1. This is just an early access release and some other enhancements may trickle in as it goes final.

As you all know JAX-WS 2.1 is re-architected implementation of JAX-WS 2.0 RI that has lot of performance improvements. Currently to reap the benefits of the JAX-WS improvements, using it on JDK 6 is little tricky. To use JAX-WS 2.1, You need use the endorsed override mechanism by placing jaxws-api.jar and jaxb-api.jar in JAVA_HOME/jre/lib/endorsed. More about using JAX-WS 2.1 on JDK 6 has been described here earlier. JAX-WS 2.0 is part of JDK 6 and I can say that recently released JDK 6 Update 3 will be the last Java SE 6 release using JAX-WS 2.0.

A good news for you all, JAX-WS 2.1.1 RI FCS is being integrated to the future Update Releases. Yay, no more endorsed mechanism to use JAX-WS 2.1. An early access build of Java SE 6 Update 5 Release is available for you to try.

Technorati:
JAX-WS
JDK


Web Services Addressing 1.0 - Metadata is now a W3C Recommendation.

Posted by ramapulavarthi on September 06, 2007 at 09:53 AM | Permalink | Comments (1)

Good News Everyone !!!

Web Services Addressing 1.0 Metadata specification produced by Web Services Addressing Working Group is now a W3C recommendation. This Metadata specification defines standard way to express the abstract properties of Web Services Addressing 1.0 core in WSDL and to express support and conformance to Web Services Addressing 1.0 in the wsdl. It also defines how WSDL Metadata is included in an Endpoint Reference (EPR).

This WS-Addressing Metadata specification replaces the previous Web Services Addressing 1.0 - WSDL Binding specification in candidate recommendation earlier. The main difference is in the way support for Addressing is expressed in wsdl and of course the namespace (change from wsaw:http://www.w3.org/2006/02/addressing/wsdl to wsam:http://www.w3.org/2007/05/addressing/metadata). In WSDL Binding specification, an WSDL extensibility element <wsaw:UsingAddressing> was used. This Metadata specification uses Web Services Policy Framework (WS Policy 1.5) and Web Services Policy - Attachment [WS Policy 1.5 - Attachment] specifications to express the support of Web Services Addressing 1.0. A new policy assertion <wsam:Addressing> is defined to express it.

New policy Assertions:

When <wsam:Addressing> is present in a Policy alternative, one is required to use WS-Addressing to communicate with the subject.

<wsam:Addressing wsp:Optional="true"> can be used to indicate support for WS-Addressing but does not require the use of it. In these cases, there are no restrictions about the use of WS-Adressing.

Nested asertions can be used to restrict the use of WS-Addressing inside the <wsam:Addressing> assertion.

For example,
<wsam:Addressing>
    <wsp:Policy>
        <wsam:NonAnonymousResponses/>
    </wsp:Policy>
</wsam:Addressing>

can be used to indicate that the subject requires WS-Addressing and requires the use of non-anonymous response EPRs

<wsam:Addressing>
    <wsp:Policy>
        <wsam:AnonymousResponses/>
    </wsp:Policy>
</wsam:Addressing> 

can be used to indicate that the subject requires WS-Addressing and requires the use of anonymous responses.

I discussed briefly in my earlier blog about including WSDL Metadata in EPR. In a future blog, I will write about how abstract Addressing properties like action and reference parameters are descibed in WSDL.

As you know, JAX-WS 2.1 did not define WSDL binding for WS-Addressing as things were in flux during the release of 2.1 specification. Now that Metadata specification is final, JAX-WS can use these standard policy assertions and description of abstract addressing properties in wsdl.

Technorati:
JAX-WS
WS-Addressing


Running JAX-WS Samples with Tomcat 6.x

Posted by ramapulavarthi on July 20, 2007 at 04:48 PM | Permalink | Comments (2)

I tried to run JAX-WS samples with Tomcat 6.0 and stumbled with the classloading problem. After reading the docs, I figured it out and thought of sharing this to all.

The JAX-WS Samples documentation describes steps for running samples with Glassfish and Tomcat 5.x. It suggests you to copy all web services jars to $CATALINA_HOME/shared/lib when running with Tomcat, so that these libraries can be available to all Web applications.

When you are running with Tomcat 6.x, the classloading mechanism has changed a bit from earlier versions of Tomcat. You can notice there is no common, server, shared directories in the Tomcat installation. All you see is the lib directory. It seems this is done to avoid confusion for the users. You can find more details about the Tomcat 6.0 classloading here

To run the samples with Tomcat 6 follow these steps. Edit $CATALINA_HOME/conf/catalina.properties and set shared.loader={RI Installation Directory}/lib/*.jar If you are running multiple instances of Tomcat, then edit CATALINA_BASE/conf/catalina.properties for that particular instance. The same technique can be used with Tomcat 5.x if you don't like to copy all the jars to $CATALINA_HOME/shared/lib

For the complete steps for running the samples, follow as instructions listed in the samples document.

Technorati:
JAX-WS Samples
Tomcat


Sun's participation in Web Services Addressing 1.0 - Metadata Interop Testing

Posted by ramapulavarthi on June 29, 2007 at 12:38 PM | Permalink | Comments (0)

The Web Services Addressing Working Group has requested to transition the second Last Call Working Draft of Web Services Addressing 1.0 - Metadata ( which addressed the issues received during the previous Last Call phase relating WS-Policy assertions from WS-Policy wokring group). Section 2.1 Referencing WSDL Metadata from an EPR and section 2.2 Embedding WSDL Metadata in an EPR are marked as risk requiring two interoperable implementations for those features. All the features in the specification except the sections marked at risk were tested for interoperability previuosly.

I am pleased to participate in the interop testing of section 2.1 in Metadata Specification with IBM. The test plan for this feature has been approved by the WG in the last call. Though Sun's implementation of WS Addressing does n't support complete Metadata specification now, it has partial implementation to support EPR's conforming to Metadata specification. Sun has passed all the mandatory as well as optional tests related to this feature. I was pleased to work with David Illsley from IBM in the interop testing from Sun's side. Hopefuly these results will be approved by the WG and then section 2.1 will stay during the transtion from CR to PR phase.

A brief look at how this feature can be helpful when using EPRs to reference Web Services. In JAX-WS you can create proxy from an EPR if the runtime can get all the binding related information from the EPR. This enables the EndpointReference.getPort(SEI) API in JAX-WS to work, as it can get the wsdl metadata from EPR, which can be really useful when dealing with Stateful Web Services feature utilizing addressing headers and EPRS in the background.

If these results are approved by the WSA WG, Section 2.1 is going to stay in PR. Though the plans for full support for WS Addressing Metadata in JAX-WS RI are not concrete yet, this will be available in the near future. I will explain how to reference wsdl metadata in an EPR in a follow up blog.

Technorati:
JAX-WS



Useful Goodies for Web Service Developers in JAX-WS 2.1 RI

Posted by ramapulavarthi on February 02, 2007 at 11:24 AM | Permalink | Comments (5)

JAXWS 2.1 RI comes with bunch of goodies for the ease of use/development of Web Services. Some of these are configurable through system-wide properties, features and annotations in the com.sun.xml.ws.developer package, which means they are proprietary and will not work with other implementations. Who knows, some of these might end up in future versions of the Spec, if you find them useful as we think.

Accessing Inbound SOAP Headers: To access all the headers (including headers that are not bound to parameters) in the endpoint implementation, one has to write a handler to access those from the SOAPMessage. Instead on can use the read-only property JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY from WebServiceContext directly.

Adding Outbound SOAP Headers: Sometimes, one may need to send some additional headers that are not defined in the wsdl or bound to parameters. Instead of writing a SOAP Handler and doing the dirty work one can easily do this by downcasting the proxy to WSBindingProvider and set the Outbound headers.

HelloPort port = helloService.getHelloPort();
WSBindingProvider bp = (WSBindingProvider)port;
bp.setOutboundHeaders(
  // simple string value as a header, like stringValue
  Headers.create(new QName("simpleHeader"),"stringValue"),
  // create a header from JAXB object
  Headers.create(jaxbContext,myJaxbObject)
);

As you see Headers are created using com.sun.xml.ws.api.message.Headers class, which provides factory methods to create headers in different wasy easily. More information on using this feature can found in Kohsuke's blog Adding SOAP headers

Creating Stateful Web Services:

Using @HttpSessionScope: One way to bring state to Web Services is to use Http Session cookies. Storing the state and accessing it from the HttpSession (from WebServiceContext) for each request takes multiple steps and does n't fit well with the OO way of accessing/storing it with instance fields. One can use @com.sun.xml.ws.developer.servlet.HttpSessionScope annotation tells the JAX-WS RI to create one instance of Hello per each HTTP session. As you see this approach still relies on Http cookies but makes it easier to access state from the context just like normal instance variables.

Using @Stateful: JAX-WS also provides a transport neutral mechanism to do this and makes use of the WS-Addressing standard. It introduces @com.sun.xml.ws.developer.Stateful to take care of maintaining all the state and the user can access it using instance variables. All the user needs to do is to add @Stateful and @Addressing to Web Service implementation. As you see, this is requires support for Addressing.
More information about using this feature can be found from stateful sample in the JAX-WS 2.1 bundle and in Kohsuke blogs Stateful web services with JAX-WS RI and HttpSessionscope.

Logging of SOAP Messages: Web Services developers generally need to see SOAP Messages that are transferred between client and service for debugging. There are couple of SOAP Monitors for this job, but you need modify the client or server code to use those tools. JAX-WS provides logging of SOAP messages by using a System property com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true on client-side. My blog about Monitoring SOAP Messages talks more about it. If you are using Glassfish, it provides nice GUI tools to montior SOAP messages for Web Service. Unfortunately this works only with 109 based Web Services. For Servlet based WebServices, you can use com.sun.xml.ws.transport.http.HttpAdapter.dump system property to dump the SOAP traffic.

Propagation of Server-side Stacktrace: This is a very useful feature while developing Web Services. Often the soap fault messages does n't convey enough information about the problem. JAX-WS relieves you from digging out the server logs to find out the stacktrace. Now the whole stacktrace (including nested exceptions) is propagated in the SOAP Fault and the complete exception stacktrace is visible to the client. Propation of Stacktrace is on by default, If you think its not safe for your Web Service Application to send the complete stacktrace, you can turn off this functionality by setting the System property com.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTrace.

Support for MemberSubmission Addressing: One can use @com.sun.xml.ws.developer.MemberSubmissionAddressing or com.sun.xml.ws.developer.MemberSubmissionAddressingFeature to use member submission version of Addressing. You can follow the fromjava-wsaddressing sample in JAX-WS 2.1 bundle except that @MemberSubmissionAddressing and MemberSubmissionAddressingFeature is used instead if @Addressing and AddressingFeature.

Most interesting part, all of these features are done using extensions points provided by the JAXWS RI. You can develop similar features using JAXWS pluggability architecture and more on this can be found in my blog Extending JAX-WS With Annotations.

We hope these developer properties and features are useful and make using Web Services a bit easier. Do provide your valuable feedback to dev@jax-ws.dev.java.net



Using Addressing With JAX-WS Clients without WSDL

Posted by ramapulavarthi on January 21, 2007 at 01:54 AM | Permalink | Comments (3)


Addressing can be enabled on client by having a wsdl with <wsaw:UsingAddressing/> in the wsdl definitions or enabling AddressingFeature while creating the client proxy. In EA3, Although Addressing is enabled, for it to work the clients (esp. Dispatch) have to be created with wsdl, otherwise Addressing headers are not sent automatically by the JAX-WS Runtime.

The reason was wsa:Action header which is mandatory comes from wsdl either it be explicitly specified or implicitly computed using wsdl:operation's definition. All other addressing headers can be computed without WSDL or assume default values. The same wsa:Action header is used as SOAPAction http header.

JAX-WS API provides way to set SOAPAction header in the message context. Using this mechanism, Recently I made a fix to use Addressing runtime. Now for Addressing to work, WSDL is no more needed. All you need to do is set BindingProvider.SOAPACTION_URI_PROPERTY property. An example below shows its usage.

Service service = Service.create(SERVICE_QNAME);
service.addPort(PORT_QNAME, SOAPBinding.SOAP11HTTP_BINDING, "http://localhost:8080/service/example");
Dispatch<Source> dispatch = service.createDispatch(PORT_QNAME, Source.class,
Service.Mode.PAYLOAD, new AddressingFeature());
dispatch.getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, true);
dispatch.getRequestContext().put(BindingProvider.SOAPACTION_URI_PROPERTY,"http://example.com/action/dothis");
dispatch.invoke(requestSrc);

If you set these properties, JAXWS Runtime  takes care of sending all the addressing headers in the SOAP Message.
These are the messages with Addressing disabled(default)/enabled with the dispatch client.

Addressing not enabled:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Body>
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
      <S:Body>
<addNumbers xmlns="http://example.com/">
  <number1>10</number1>
  <number2>10</number2>
</addNumbers>
</S:Body>
    </S:Envelope>
  </S:Body>
</S:Envelope>

Addressing enabled:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Header>
    <To xmlns="http://www.w3.org/2005/08/addressing">http://localhost:8080/service/example</To>
    <Action xmlns="http://www.w3.org/2005/08/addressing">http://example.com/action/dothis</Action>
    <ReplyTo xmlns="http://www.w3.org/2005/08/addressing">
    <Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
</ReplyTo>
    <MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:45c2f4eb-48ea-4
be4-8376-05535313ef9f</MessageID>
  </S:Header>
  <S:Body>
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
      <S:Body>
<addNumbers xmlns="http://example.com/">
  <number1>10</number1>
  <number2>10</number2>
</addNumbers>
</S:Body>
    </S:Envelope>
  </S:Body>
</S:Envelope>
 
Hope this makes it easy to use Addressing with Dispatch.


Extending JAX-WS With Annotations

Posted by ramapulavarthi on January 16, 2007 at 09:31 AM | Permalink | Comments (1)

As you know JAX-WS 2.1 is the re-architected version of JAX-WS 2.0 with high performance and additional features supporting JAX-WS 2.1 Spec. It provides a lot of extension points for developers  to utilize the plug-in mechansim to modify/extend the default JAX-WS behavior. These extension points can be used at Tool time as well as Runtime. See JAX-WS 2.1 Architecture document for more details.

Extension Points:
I will briefly go over some of the extension points and concentrate more on extending using Java annotations and leave others for you to explore.

Tube: Tube is a filter that lets you work on the Packet ( an abstraction of Message with context) and pass it on to the next tube in the chain. You can think of it like a Handler but has efficient access to the Message through different API. Tubes can run asynchronusly, which means request packet and response packet can be processed by different threads.See Tube documentation for more details.

WSDLGeneratorExtension: WSDLGenerator uses Service finder mechanism to discover WSDLGeneratorExtensions and calls them to contribute in the generation of WSDL. See WSDLGeneratorExtension documentation for more details.

WSDLParserExtension: These extensions are called by WSDL Parser at runtime to process the WSDL extensibility elements in the wsdl definitions. For example, W3CAddressingWSDLParserExtension in RI uses this to process <wsaw:UsingAddressing> extensibility element in wsdl:binding and wsdl:portType definitions. See WSDLParserExtension documentation for more details documentation for more details.

Web Service Features:
For these various extensions to be picked up and used at runtime, corresponding features have to enabled either through WSDL or Java Annotations on Endpoint implementation or Programatic configuration of features on the Client. JAX-WS 2.1 Specification introduces WebServiceFeature and WebServiceFeatureAnnotation to specify features on a client and endpoint implementation. In 2.1 RI, It uses this Web Service  feature mechanism to support W3C Addressing using @Addressing and AddressingFeature

Writing Custom Web Service Feature:
One can use similar mechanism to extend JAX-WS by defining custom annotations and its bean representation to be used by client runtime. Annotations are used on the endpoint implementation class where as features in bean form are used on client-side. For this to work, the custom annotations should follow these rules.
  • Define custom feature annotation which uses @WebServiceFeatureAnnotation and specify the WebServiceFeature bean
  • Define a feature that extends WebServiceFeature so that it can be used by Client
  • Mark one of the constructors in the bean as @FeatureConstructor. This is needed because Reflection does n't capture the parameters names at runtime, this is needed for JAX-WS to recognize the custom annotations in to its bean representation.
Feature annotations specified on endpoint implementation class are available as features on WSBinding (an implementation of javax.xml.ws.Binding) which is available to almost all extension points.

Examples:
In the following example, I will show you how one can utilize this extension mechanism.

Although W3C Addressing Specification is a recommendation, Some still use Member Submision version of addressing. To support this, there is a RI specific feature @MemberSubmissionAddressing. Look closely at @MemberSubmissionAddressing class. It uses to MemberSubmissionAddressingFeature as bean, which can be used on client-side to enable the feature.

@WebServiceFeatureAnnotation(id= MemberSubmissionAddressingFeature.ID,bean=MemberSubmissionAddressingFeature.class)
public @interface MemberSubmissionAddressing {
    /**
     * Specifies if this feature is enabled or disabled.
     */
    boolean enabled() default true;

    /**
     * Property to determine the value of the
     * <code>wsdl:required</code> attribute on
     * <code>wsaw:UsingAddressing</code> element in the WSDL.
     */
    boolean required() default false;
}

public class MemberSubmissionAddressingFeature extends WebServiceFeature
    /**
     * Create an MemberSubmissionAddressingFeature
     * @param enabled specifies whether this feature should
     *                be enabled or not.
     */
    public MemberSubmissionAddressingFeature(boolean enabled) {
        this.enabled = enabled;
    }

    /**
     * Create an <code>MemberSubmissionAddressingFeature</code>
     * @param enabled specifies whether this feature should
     * be enabled or not.
     * @param required specifies the value that will be used
     * for the <code>required</code> attribute on the
     * <code>wsaw:UsingAddressing</code> element.
     */
    @FeatureConstructor({"enabled","required"})
    public MemberSubmissionAddressingFeature(boolean enabled, boolean required) {
        this.enabled = enabled;
        this.required = required;
    }
    .............
    .............         
}

Notice that only one constructor has been marked with @FeatureConstructor which captures the names of the parameters in the corresponding annotation.

When a endpoint implementation is marked with @MemberSubmissionAddressing(required=false,enabled=true), JAX-WS Runtime makes this available to StandaloneTubelineAssembler, which plugs in the WsaTube which validates addressing headers on incoming messages.

Similarly, W3CAddressingWSDLGeneratorExtension checks if AddressingFeature is enabled on WSBinding and based on its value, adds it as wsdl extensibility element like<wsaw:UsingAddressing wsdl:required="true"> in the binding definitions.


That's all !!!

Infact, you can write your own Tube and plug it in your TubelineAssembler if a custom feature is enabled and process the messages that transferred through the Tube. See RI specific features like @Stateful, @HttpSessionScope, @MemberSubmissionAddressing to see how one can utilize this mechanism.

We hope developers will find these extension points useful to extend default JAX-WS behavior. Please send in your useful comments to dev@jax-ws.dev.java.net



Problems using JAX-WS 2.1 and JAXB 2.1 with JDK 6?

Posted by ramapulavarthi on January 12, 2007 at 12:12 AM | Permalink | Comments (10)

When using JAX-WS 2.1 and JAXB 2.1 with JDK 6, you may see errors like this when running Web Services Tools (wsimport and wsgen) in JAX-WS 2.1 installation.

While invoking wsimport:
D:\work\jax-ws\test\>%JAXWS_HOME%\bin\wsimport -d temp hello_literal.wsdl parsing WSDL... generating code... D:\work\jax-ws\test\temp\test\Hello_Service.java:63: cannot find symbol symbol : method getPort(javax.xml.namespace.QName,java.lang.Class,javax.xml.ws.WebServiceFeature[]) location: class javax.xml.ws.Service return (Hello)super.getPort(new QName("urn:test", "HelloPort"), Hello.class, features); ^ 1 error compilation failed, errors should have been reported
D:\work\jax-ws\test\>%JAXWS_HOME%\bin\wsimport -d temp hello_literal.wsdl
parsing WSDL...
Exception in thread "main" java.lang.LinkageError: JAXB 2.0 API is being loaded
from the bootstrap classloader, but this RI (from jar:file:/D:/work/axws-ri/lib/jaxb-impl.jar!
/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) needs 2.1 API. 
Use the endorsed directory mechanism to place jaxb-api.jar i
n the bootstrap classloader. (See http://java.sun.com/j2se/1.5.0/docs/guide/standards/)
        at com.sun.xml.bind.v2.model.impl.ModelBuilder.(ModelBuilder.java:135)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:389)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.(JAXBContextImpl.java:253)
        at com.sun.tools.xjc.reader.xmlschema.bindinfo.BindInfo.getJAXBContext(BindInfo.java:316)
        at com.sun.tools.xjc.reader.internalizer.SCDBasedBindingSet.apply(SCDBasedBindingSet.java:195)
        at com.sun.tools.xjc.ModelLoader.createXSOM(ModelLoader.java:502)
        at com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:211)
        at com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:69)
        at com.sun.tools.ws.processor.modeler.wsdl.JAXBModelBuilder.bind(JAXBModelBuilder.java:119)
        at com.sun.tools.ws.processor.modeler.wsdl.WSDLModeler.buildJAXBModel(WSDLModeler.java:2159)
        at com.sun.tools.ws.processor.modeler.wsdl.WSDLModeler.internalBuildModel(WSDLModeler.java:179)
        at com.sun.tools.ws.processor.modeler.wsdl.WSDLModeler.buildModel(WSDLModeler.java:127)
        at com.sun.tools.ws.wscompile.WsimportTool.run(WsimportTool.java:146)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.sun.tools.ws.Invoker.WsimportMain(Invoker.java:78)
        at com.sun.tools.ws.WsImport.main(WsImport.java:38)
While invoking wsgen:

Exception in thread "main" java.lang.LinkageError: JAXB 2.0 API is being loaded
from the bootstrap classloader, but this RI (from jar:file:/D:/work/jaxws-ri/lib/jaxb-impl.jar!
/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) needs 2.1 API. 
Use the endorsed directory mechanism to place jaxb-api.jar i
n the bootstrap classloader. (See http://java.sun.com/j2se/1.5.0/docs/guide/standards/)
        at com.sun.xml.bind.v2.model.impl.ModelBuilder.(ModelBuilder.java:135)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:389)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.(JAXBContextImpl.java:253)
        at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:84)
        at com.sun.xml.bind.api.JAXBRIContext.newInstance(JAXBRIContext.java:86)
        at com.sun.xml.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:126)
        at com.sun.xml.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:125)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.xml.ws.model.AbstractSEIModelImpl.createJAXBContext(AbstractSEIModelImpl.java:124)
        at com.sun.xml.ws.model.AbstractSEIModelImpl.postProcess(AbstractSEIModelImpl.java:63)
        at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:252)
        at com.sun.tools.ws.wscompile.WsgenTool.buildModel(WsgenTool.java:185)
        at com.sun.tools.ws.wscompile.WsgenTool.run(WsgenTool.java:89)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.sun.tools.ws.Invoker.WsgenMain(Invoker.java:115)
        at com.sun.tools.ws.WsGen.main(WsGen.java:38)

Sometimes its pretty clear what the error is, but not in all cases. JAXB 2.0 and JAX-WS 2.0 are part of JDK 6. To use JAX-WS 2.1 with JDK 6, newer versions of API jars (JAX-WS 2.1 and JAXB 2.1 API jars) need to be in bootclasspath before rt.jar. To do this you can use Java endorsed mechanism to override whats in Java platform. See http://java.sun.com/j2se/1.5.0/docs/guide/standards/ for more details on Endorsed Standards Override Mechanism.

To get around this issue, You can simply copy jaxb-api.jar, jaxws-api.jar to <java-home>/lib/endorsed Here <java-home> refers to the directory where the runtime software is installed (which is the top-level directory of the J2SE Runtime Environment or the jre directory in the JDK).

If you prefer to not change JDK, For invoking wsimport and wsgen tools in JAX-WS 2.1, you can set WSIMPORT_OPTS=-Djava.endorsed.dirs=%JAXWS_HOME%/lib & WSGEN_OPTS=-Djava.endorsed.dirs=%JAXWS_HOME%/lib, where JAXWS_HOME points to JAX-WS 2.1 installation.

If you use ant tasks, you can pass -Djava.endorsed.dirs=%JAXWS_HOME%/lib as jvmarg while calling wsimport and wsgen ant tasks. For this to work, you need to set fork="true" attribute of wsimport and wsgen ant tasks.



Support for WS-Addressing in JAX-WS 2.1 RI EA1

Posted by ramapulavarthi on September 26, 2006 at 02:29 PM | Permalink | Comments (0)

JAX-WS is undergoing a maintenance release (JAX-WS 2.1) to address some issues based on the feedback from the developer community. One of the new features added in JAX-WS 2.1 is the support for WS-Addressing. Web Services Addressing specification 1.0 [WS-Addressing] defines a mechanism to address Web Services and messages independent of the transport being used.

The proposal is to support WS-Addressing in JAX-WS with a simplified programming model. In most cases, the user does n't need to do anything apart from enabling addressing. I like the idea behind this, as a real Web Service developer would want to work on his business logic than worry about dealing with various addressing headers that are sent in each interaction. I will go over the new annotations that are introduced in JAX-WS 2.1 to enable addressing briefly.

To get your hands on the WS-Addressing implementation in JAXWS 2.1 RI get the EA1 release from here. In the EA1 bundle there are samples fromjava-wsaddressing and fromwsdl-wsaddressing showcasing the use of WS-Addressing with JAX-WS.

For a sample operation in a SEI like this

@WebMethod
public int addNumbers(int number1, int number2) throws AddNumbersException {
        return impl(number1, number2);
}

With addressing, this is how a SOAP request and response would look like.

SOAP Request:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Header>
        <To xmlns="http://www.w3.org/2005/08/addressing">http://localhost:8080/jaxws-fromjava-wsaddressing/addnumbers</To>
        <MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:6d9d4c99-95c4-41c2-bfb6-17f3f1267644</MessageID>
        <ns1:ReplyTo xmlns:ns1="http://www.w3.org/2005/08/addressing">
        <ns1:Address>http://www.w3.org/2005/08/addressing/anonymous</ns1:Address></ns1:ReplyTo>
       <Action xmlns="http://www.w3.org/2005/08/addressing">http://server.fromjava_wsaddressing/AddNumbersImpl/addNumbersRequest</Action>
     </S:Header>
    <S:Body><ns2:addNumbers xmlns:ns2="http://server.fromjava_wsaddressing/"><arg0>10</arg0><arg1>10</arg1></ns2:addNumbers></S:Body>
</S:Envelope>
SOAP Response:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Header>
        <To xmlns="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/anonymous</To>
        <Action xmlns="http://www.w3.org/2005/08/addressing">http://server.fromjava_wsaddressing/AddNumbersImpl/addNumbersResponse</Action>
        <RelatesTo xmlns="http://www.w3.org/2005/08/addressing" RelatesTo="http://www.w3.org/2005/08/addressing/reply">uuid:6d9d4c99-95c4-41c2-bfb6-17f3f1267644</RelatesTo>
    </S:Header>
    <S:Body><ns2:addNumbersResponse xmlns:ns2="http://server.fromjava_wsaddressing/"><return>20</return></ns2:addNumbersResponse></S:Body>
</S:Envelope>

Don't be scared seeing all those extra headers. You don't need to generate/consume these addressing headers. The job is done by the JAX-WS runtime. So let's see how we can make JAX-WS implementation do it for us.

Starting from WSDL:
If the wsdl uses addressing, the user does n't need to do anything. JAX-WS runtime identifies the <wsaw:UsingAddressing/> in the binding section of the wsdl:definitions and figures out that the Web Service uses WS-Addressing 1.0 as per Web Services Addressing 1.0 - WSDL Binding[WS-Addressing WSDL Binding]. JAX-WS runtime will take care of sending various addressing headers as defined by the Web Services Addressing 1.0 - SOAP Binding[WS-Addressing SOAP Binding].

Starting from Java:
To use addressing from Java, One has to enable the AddressingFeature. JAX-WS 2.1 introduces some new annotations to specify this.

@BindingType: @BindingType annotation is updated. In JAX-WS 2.0, @BindingType takes a URI identifying the binding, for example "http://schemas.xmlsoap.org/wsdl/soap/http" for SOAP 1.1 over HTTP binding etc. With the updated API, BindingType also takes an array of features (capabilities or extensions) that should be enabled/disabled on the Binding. JAX-WS 2.1 supports Addressing and MTOM feature of SOAP binding. To specify this, @Feature annotation should be used. For any feature, there might be some behaviors that may be configurable as per the User's preference. For this, there is @FeatureParameter to pass such feature configurations.

Here is a sample use of the BindingType annotation that specifies the use of AddressingFeature. It uses the default SOAP1.1/HTTP binding.

   @WebService
   @BindingType(features={@Feature(AddressingFeature.ID)})
   public class MyWebService { ... }

The wsdl generated for this endpoint will have <wsaw:UsingAddressing/> in the wsdl binding definition to indicate that the Web Service uses WS-Addressing 1.0 as per Web Services Addressing 1.0 - WSDL Binding[WS-Addressing WSDL Binding]. This also conveys that the use of addressing is not mandatory, as wsdl:required="false" by default.

Here in the following sample, BindingType annotation enables the AddressingFeature with a feature parameter.

   @WebService
   @BindingType(features={@Feature(value=AddressingFeature.ID, parameters=
	{@FeatureParameter(name=AddressingFeature.IS_REQUIRED, value="true")}) })
   public class MyWebService { ... }

The wsdl generated for this endpoint will have <wsaw:UsingAddressing wsdl:required="true"/> in the wsdl binding definition, which translates to saying that the client/server must use addressing and the endpoint cannot understand SOAP messages without addressing headers.

If you are an experienced Web Service developer and has some other mechanism to handle addressing yourself, you can even disable the feature by setting enabled=false in the Feature annotation.

   @WebService
   @BindingType(features={
                @Feature(value=AddressingFeature.ID, enabled=false)})
   public class MyWebService { ... }
JAX-WS Runtime in the above case leaves it to the user for generating/processing any addressing headers.

@Action and @FaultAction: These annotations can be used to specify explicit actions attributes for input, output and fault messages. The good thing is in most of the cases, the user does n't need to specify these. Runtime will figure out these action values from the wsdl operation name. Then you may wonder what the real use of this annotation and the corresponding action attribute in the wsdl is. The value specifed in wsaw:Action can be used for the dispatching of requests in transport independent fashion. Action based dispatching is not yet supported in EA, but this will be available soon.

For example, one can use these annotations like this,

  @javax.jws.WebService
  public class AddNumbersImpl {
      @javax.xml.ws.Action(
          input="http://example.com/inputAction",
          output="http://example.com/outputAction",
          fault = {
              @javax.xml.ws.FaultAction(className=AddNumbersException.class, value="http://example.com/faultAction")
          })
      public int addNumbers(int number1, int number2)
          throws AddNumbersException {
          return number1 + number2;
      }
  }
  

The generated WSDL looks like:

    <definitions targetNamespace="http://example.com/numbers" ...>
    ...
      <portType name="AddNumbersPortType">
        <operation name="AddNumbers">
          <input message="tns:AddNumbersInput" name="Parameters"
            wsaw:Action="http://example.com/inputAction"/>
         <output message="tns:AddNumbersOutput" name="Result"
           wsaw:Action="http://example.com/outputAction"/>
         <fault message="tns:AddNumbersException" name="AddNumbersException"
           wsaw:Action="http://example.com/faultAction"/>
        </operation>
      <portType>
    ...
    <definitions>

Refer to JAX-WS 2.1 EA1 Users Guide for more information on the usage of these annotations. Similar to Addressing Feature, MTOM can be enabled using MTOMFeature. JAX-WS 2.1 Specification also proposes programmatic configuration of these features on the client-side. Keep looking for the support for Action based dispatching, MTOM Feature and other new stuff in JAX-WS 2.1

Continue Reading...



Monitoring SOAP Messages Made Easy With JAX-WS RI 2.0.1

Posted by ramapulavarthi on August 17, 2006 at 10:32 AM | Permalink | Comments (4)

One of the things people want to do while developing Web Services is to look at what the client is sending and receiving. To monitor soap traffic, there are some GUI tools like TCP Monitor and WSMonitor. These monitors are implemented with a 'man in the middle' approach where-in, the monitor listens to a port (Client send requests to this port) and forwards it to another port (Server listens to this port). Since these tools use port forwarding, you need to change your Web Service client to send request to the port where the monitor listens (Especially, if you are using static clients generated by wsimport, the default endpoint address taken from the wsdl needs to be overidden by setting ENDPOINT_ADDRESS_PROPERTY on the proxy).

In JAX-WS 2.0.1, You can monitor the request and response messages without changing the client. When you invoke the Web Service, just pass the System property "com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true", it prints out the request and response message.

This is the sample request and response, I got by running fromwsdl sample in JAX-WS 2.0.1 M1 bundle by passing this system property.

---[HTTP request]---
SOAPAction: 
Content-Type: text/xml
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><addNumbers xmlns="http://duke.example.org"><arg0>10</arg0><arg1>20</arg1></addNumbers></S:Body></S:Envelope>--------------------

---[HTTP response 200]---
Date: Thu, 17 Aug 2006 00:35:42 GMT
Content-type: text/xml
Transfer-encoding: chunked
Server: Apache-Coyote/1.1
null: HTTP/1.1 200 OK
<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><addNumbersResponse xmlns="http://duke.example.org"><return>30</return></addNumbersResponse></S:Body></S:Envelope>--------------------

Jitu explained in his blog, how one can use local transport to test Web Services without deploying the service on to a Web Container. In such case, you can pass "com.sun.xml.ws.transport.local.LocalTransportPipe.dump=true" to monitor SOAP messages.

This can be helpful to just see what the client is sending/receiving to the server very easily. Of course, if you need sophisticated functions like replaying the request, you have to use those monitors.

Try this out yourselves by getting GlassFish 9.1 V2.



JAX-WS Customizations made easy with NetBeans 5.5

Posted by ramapulavarthi on August 11, 2006 at 01:49 PM | Permalink | Comments (4)

Often you need to override the default WSDL to Java bindings like changing XML Namespace to package mapping, generating asynchronous methods etc. Forget about vendor specific tool features or options you need to pass to customize WSDL to Java mapping. As you know, JAX-WS Specification defines a standard binding language to customize WSDL 1.1 to Java binding. Whatever JAX-WS implementation you choose, it will generate the same Java bindings with the customization file. You can specify this customization by embedding the <jaxws:bindings> in the wsdl or specify in an external file and pass it to the WSDL to Java mapping tool. wsimport tool of JAX-WS RI supports customization in both ways.

JAX-WS defines lots of ways to customize WSDL to Java mapping from modifying the XML to Java name mapping, generating wrapper style signatures, generating asynchronous methods etc. Though the binding language is rich in its options, its confusing to write a customization file (sample) by hand as you need to exactly know what customization can be applied on a particular wsdl element. There comes NetBeans to the rescue.


NetBeans 5.5 with its built-in support for JAX-WS Web Services also provides a nice GUI to customize WSDL to Java bindings easily. All you need to do is right click on a Web Service(created from WSDL) or a Web Service Reference and select "Edit Web Service Attributes" as shown above. It opens up a window categorized according to WSDL definitions. As shown below, if you want to generate asynchronous methods, select the check box "Enable Asynchronous Client".

What NetBeans does in the background is embed JAX-WS customizations in the wsdl. NetBeans is also smart enough to provide different options for Web Service and Web Service Client. For example, on a Web Service you can specify "Use Provider Interface" on a port which is not available on Web Service Client, "Enable Asynchronous Client" can only be specified on Web Service Client. Not only does it embed the customization, it regenerates the Java artifacts by invoking wsimport with the customization as shown in below. You can even specify external customization files for customizing schema mappings.

Support of JAX-WS customization is a good start. There are some improvements that can be done. Currently it embeds the customization in the wsdl. It is convenient if it were in an external file as you dont want customization to show up in the wsdl which is used for deployment. Although NetBeans regenerates the Java artifacts, it does n't refactor the references in the application. Often schemas also need to be customized. JAXB has tons of customizations to modify XML Schema to Java mapping. NetBeans does n't yet support basic things in jaxb global customization like mapping of namespace to pacakge name or generating Interfaces instead of Classes etc. I hope these will be addressed in future release of NetBeans.

There is a bug in NetBeans 5.5 Beta 2, where Web Services created from WSDL disappear after creation. It has been fixed in the recent builds. Download latest daily build of NetBeans 5.5 and try it yourself.



Maintaining Session With JAX-WS

Posted by ramapulavarthi on June 07, 2006 at 10:26 AM | Permalink | Comments (8)

Web Services are stateless by default because of the underlying HTTP protocol. The server processes each web service request as a new interaction even though it is from the same client. To have a knowledge about previous requests, Server would need to maintain state about the client through some sort. Maintaining state/session would have extra load on the client/server in terms of time and memory. Even then, sometimes stateful web services can be useful for conversational message exchange patterns, where multiple message exchanges are required between client and server.

By default JAX-WS Web Services and Clients are stateless. When a client makes a request, the server responds and sets a cookie on the connection, if it participates in a session. But, the JAX-WS client ignores that cookie and the server treats subsequent requests as new interaction. When the session is enabled, JAX-WS client sends the same cookie with each subsequent request so that server can keep track of the client session.

Lets start off with a simple Counter Web Service which tracks the user requests. Each time client calls getCounter(), the service returns the counter after incrementing by 1.

@WebService
public class Hello {
    int counter = 0;
    public int getCounter() {
        // incorrect – not unique for each client session.
        return counter++;
    }
}

Enabling session support for your web service would require little effort on the server and client.

Accessing Session on Server:

After the service endpoint is instantiated, the runtime system is required to initialize the endpoint instance before any requests can be serviced. If you are familiar with JAX-RPC based Web Service, enabling session support would require the service to implement javax.xml.rpc.server.ServiceLifecycle interface and its lifecycle methods init() and destroy(). The JAX-RPC runtime would pass the ServletEndpointContext which gives access to the message context, session, servlet context associated with each method invocation.

JAX-WS uses some handy annotations defined by Common Annotations for the Java Platform (JSR 250), to inject the Web Service context and declaring lifecycle methods. Web ServiceContext holds the context information pertaining to a request being served. You don’t need to implement javax.xml.rpc.server.ServiceLifecycle. With JAX-WS Web Service all you need to do is mark a field or method with @Resource. The type element MUST be either java.lang.Object (the default) or javax.xml.ws.WebServiceContext. If the former, then the resource will be injected into a field or a method. In this case, the type of the field or the type of the JavaBeans property defined by the method MUST be javax.xml.ws.WebServiceContext. From the WebServiceContext, message context pertaining to the the current request can be accessed. For more information on how message context can be used to share metadata is explained in this article. The following snippet from Hello Service shows the usage of annotations.

@WebService
public class Hello {
    @Resource
    private WebServiceContext wsContext;
    public int getCounter(){
        MessageContext mc = wsContext.getMessageContext();
        HttpSession session = ((javax.servlet.http.HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST)).getSession();
        // Get a session property "counter" from context
        if (session == null)
            throw new WebServiceException("No session in WebServiceContext");
        Integer counter = (Integer)session.getAttribute("counter");
        if (counter == null) {
            counter = new Integer(0);
            System.out.println("Starting the Session");
        }
        counter = new Integer(counter.intValue() + 1);
        session.setAttribute("counter", counter);
        return counter;

    }
}

JSR-250 also defines annotations for lifecycle methods, @PostConstruct and @PreDestroy. These lifecycle annotations (methods) can be used for effectively managing memory resources. After the resource injection is done, methods marked with @PostConstruct (similar to init method in JAX-RPC) are invoked before servicing any requests. Similarly methods marked with @PreDestroy are invoked before the service is destroyed.

Enabling Session on Client:

Session can be maintained just by setting the property “MessageContext.SESSION_MAINTAIN_PROPERTY” to true in the request context of the proxy/dispatch instance. For more information about setting properties in request context refer to this article.

Hello proxy = new HelloService().getHelloPort();
((BindingProvider)proxy).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PROPERTY,true);
int result = proxy.getCounter();
System.out.println(result);
result = proxy.getCounter();
System.out.println(result);

The above snippet from the HelloClient, prints 1 and 2 respectively.As shown above maintaining session with JAX-WS is easy.



Understanding Handlers in JAX-WS

Posted by ramapulavarthi on May 01, 2006 at 10:06 AM | Permalink | Comments (6)

JAX-WS provides a pluggable framework to extend the runtime processing capabilities through handlers. Handlers are message interceptors that can do pre-processing/post-processing of the messages to complement your Web Service. JAX-WS defines two types of handlers, logical handlers and protocol handlers. Protocol handlers are specific to a protocol and may access or change the protocol specific aspects of a message. Logical handlers are protocol-agnostic and act only on the payload of the message.

In this article "A little about Handlers in JAX-WS", I explain the differences between logical and SOAP handlers, and show examples to write a simple handler. The following diagram shows the differences in the message context accessible to these handlers.

messagecontext.jpg

The SOAPLoggingHandler shows how one can log inbound and outbound soap messages using a SOAP handler. In the same lines, I showed a LogicalLoggingHandler to show how one can use logical handler to process the payload of the message. The following diagram shows how SOAP handlers and logical handlers plug in to the JAX-WS runtime.

handlers2.JPG

Find more about this in the article. I hope this article helps you in understanding handlers and get you started.



Making Use Of Message Context In JAX-WS

Posted by ramapulavarthi on April 22, 2006 at 12:53 PM | Permalink | Comments (0)

Sometimes, Invoking Web Services require exchange of additional information or metadata. This metadata forms the context of message exchange. Few of the common questions I hear while creating Web Services using JAX-WS are, how do I convey this metadata with other parts of the application and how do I configure the binding to behave in a certain way.

The good thing, JAX-WS has made all this very easy. JAX-WS Specification defines some standard properties to describe the metadata and also provides a standard way to manipulate or exchange such information.

In this article "A Little bit about Message Context in JAX-WS", I briefly describe how such metadata is exchanged between various parts of the application and listed the common usage of the standard properties defined by JAX-WS. This article shows how you can change some properties to configure the binding and exchange metadata with handlers etc. For example, You can use property SOAPACTION_USE_PROPERTY to control whether soapaction is used in messages sent by the application. It also shows how one access such information in handlers and endpoint implementation.

Your comments are most welcome. If you have any questions post them in JAX-WS 2.0 forum.





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds