Jan 042012

Create a Web Service with .NET WCF. Plink, plink, done.

Create a simple Java client to call that web service. Using the default Java SE 7u2 SDK + runtime downloadable from Oracle, you run wsimport to import the service WSDL and generate proxy classes. You write a little code to instantiate the service class and call the service, run the app, and see the output from the successful web service call. Done! Well, not exactly.

When you run the Java client console app, the calls to the web service work but are accompanied by rather nasty sounding warnings about unknown policy requirements.

Jan 04, 2012 12:10:46 PM [com.sun.xml.internal.ws.policy.EffectiveAlternativeSelector] selectAlternatives
WARNING: WSP0075: Policy assertion "{http://www.w3.org/2006/05/addressing/wsdl}UsingAddressing" was evaluated as "UNKNOWN".
Jan 04, 2012 12:10:46 PM [com.sun.xml.internal.ws.policy.EffectiveAlternativeSelector] selectAlternatives
WARNING: WSP0019: Suboptimal policy alternative selected on the client side with fitness "UNKNOWN"

How do we get rid of those warnings? There are certainly ways to suppress warning reports, but that’s not the right solution. The better question is how do we resolve the issue reported in the warning?

After a great deal of digging around, here’s what I’ve found:

  1. WCF defaults to placing a wsaw:UsingAddressing WS-Policy assertion in your web service WSDL.
  2. wsaw:UsingAddressing is not actually part of any SOAP standard, it’s some sort of WSDL extension to cover the gap until an official SOAP WS-Policy standard could be defined later.
  3. Microsoft WCF supports wsaw:UsingAddressing.
  4. Java’s JAX-WS reference implementation web service core framework (JAX-WS RI 2.2.4-b01) bundled with the JDK does not support wsaw:UsingAddressing. The rationalization seems to be that wsaw:UsingAddressing isn’t part of the WS-Policy spec, so “not our problem”. JAX-WS RI supports wsam:Addressing from the official WS-Policy spec.
  5. This isn’t just Java folks thumbing their noses at Microsoft. This also causes interop problems with Java web service frameworks that support and use wsaw:UsingAddressing.
  6. Java Metro is another web service framework, and one which does support wsaw:UsingAddressing. Metro is the result of Sun and Microsoft working together to resolve cross-platform web service interop issues.
  7. Metro is easy enough to download, but how do you use it? Documentation is all about how to install Metro into an application server environment. Many app developers have asked “How do I use Metro in my Java client?”

As it turns out, Metro appears to do all of its magic at runtime. There is no IDE integration at all. All you need to do is reference the Metro .jar files in your Java project and the WS-Policy warnings will go away.

In the NetBeans IDE, this means adding each of the .jar files from the Metro/lib directory to the Libraries node in your Java project. Make sure they appear before the JDK reference. Make sure you select the actual .jar files, not just the Metro/lib directory.

In the IntelliJ IDE, this means:

  1. Right click on the JDK node under “External Libraries” in the project tree
  2. Click “Open Library Settings”
  3. Click “Libraries” under “Project Settings”
  4. Click the New Project Library tool button
  5. Click “Java”
  6. Select the Metro/lib subdir in the “Select Library Files” path selector dialog.

Note that in NetBeans, you have to select the actual .jar files; selecting only the Metro/lib directory won’t work in NetBeans.  Selecting only the Metro/lib directory works fine in IntelliJ.

To solve this UsingAddressing policy issue from the Java client end, use the Metro libraries. Period.

Another way to solve this interop issue would be to address the service end: Add wsam:Addresssing as an acceptable alternative to wsaw:UsingAddressing in the web service’s WSDL. With both addressing policies as siblings under an <ExactlyOne> element, clients that support wsaw:UsingAddressing will be happy and clients that support only wsam:Addressing will be happy. In theory, anyway.

However, I have yet to figure out how to add wsam:Addressing to the WSDL generated by a WCF service. Since I have a client-side solution I won’t be pursuing this further, but if anyone can provide a link to how to do this on the WCF WSDL side, I’d love to see that solution as well.