Showing posts with label JAX-WS. Show all posts
Showing posts with label JAX-WS. Show all posts

Saturday, October 13, 2007

Highly Useful JAX-WS Introductions

As I have been learning about and working with the Java API for XML Web Services (JAX-WS), there have been several highly useful tutorials and introductions to this specification and its reference implementation. I list all of them for easy future reference and will then highlight one resource in particular from this list that I have found to be especially helpful.

I have found the following JAX-WS introductions to be especially useful:


These are all good resources for background and an introduction to web services with JAX-WS, but I have found the one listed first to be especially useful in a GlassFish environment. The main differentiator between this article and many other fine articles on the subject is that the author of this article provided the command-line syntax for running javac and the various GlassFish commands (such as asadmin commands and the wsgen and wsimport commands).

Many introductions provide Ant targets for the reader to run or illustrate how to use a specific IDE to do things (which this article does as well), but it is nice to have an author go a little further and actually provide the low-level command-line syntax to use. This allows developers who almost always seem to be in a hurry to get right at the new material without needing to make sure that the appropriate Ant build.xml file is downloaded. It also frees the developer from being required to use the IDE the author used. In this case, the developer would still be required to use GlassFish to make use of these command-line examples, but that is unavoidable due to the proprietary nature of these administrative tools.

I have also followed with interest the debate about web services development with JAX-WS with a bottom-up approach (annotation Java classes and generating appropriate artifacts) versus with a top-down approach (starting with WSDL). The article How to Develop a JAX-WS Service from a Web Service Description Language (WSDL) makes a case for using the top-down approach even though the author acknowledges that it is simpler to use the bottom-up approach. I can see where there are advantages to using the top-down approach for large, complex systems maintained by many developers, but I really like the bottom-up approach for smaller applications, demonstrations, and prototypes.

Not everyone is happy with JAX-WS. Richard Monson-Haefel has posted (2006) two blogs (JAX-WS is Bad, Bad! and Redeemed! JAX-WS Still Sucks) describing things he finds unsatisfactory about JAX-WS.

UPDATE (10 November 2007): Made some minor cosmetic changes and spelling fixes, but did not change anything of substance.

Monday, October 8, 2007

JAXBContext Issues

I really like the Java API for XML Binding (JAXB). While there are many specifications and technologies that seem oversold or otherwise disappointing, JAXB repeatedly proves itself useful, easy to work with, and lives up to its hype. That being stated, there are times when working with the JAXB reference implementation (RI) has been slightly less straightforward than I would have hoped. This blog entry summarizes a few related issues that I have run into when using JAXB and how I got around them.

As shown in the "Java Web Services Tutorial" section covering Basic Examples of Using JAXB, a JAXBContext is obtained by calling JAXBContext.newInstance(). In the examples on this page, all calls to JAXBContext.newInstance are passed a single argument (a String representing a context path). For many applications using JAXB RI, this approach to acquiring a JAXBContext is sufficient.

Unfortunately, I have run into situations where I have needed to use a different version of JAXBContext.newInstance() to get my applications to work properly without exception. As shown in the Java EE 5 Javadoc documentation for JAXBContext, there are five different versions of the newInstance method. The version that I often need to use to avoid exceptions is the newInstance method that accepts the String as a context path and accepts a ClassLoader. For the second argument, the ClassLoader, it seems best and easiest to use ClassLoader.getSystemClassLoader().

Even when explicitly passing in a ClassLoader to the newInstance method, I have observed other conditions that can cause a JAXBException to occur when trying to obtain the JAXBContext. One of these issues is the conflict between the JAXB 2.0 RI that comes with Java SE 6 and the JAXB 2.1 that comes with the GlassFish Java EE application server reference implementation. The conflict is covered in jaxb: Unofficial JAXB Guide - Migrating JAXB 2.0 Applications to Java SE 6, which explains different ways to resolve the problem. I think that the easiest method is to simply copy the appropriate libraries into the JRE endorsed area. Kohsuke Kawaguchichi's blog entry JAXB 2.1 released also covers the issue of running a JAXB 2.1 implementation (such as comes with GlassFish v2) in a Java SE 6 environment and mentions using the Java Endorsed Standards Override Mechanism. The document Which JAXB RI is Included in Which JDK provides some useful information as well.

Rama Pulavarthi covers a similar problem (and an endorsed libraries fix related to use of JAXB and JAX-WS) in his blog entry Problems Using JAX-WS 2.1 and JAXB 2.1 with Java 6.

Finally, even with an appropriate class loader explicitly passed to JAXBContext.newInstance and the proper libraries from GlassFish copied into my JRE's endorsed libraries folder, I have occasionally still run into problems trying to obtain a JAXBContext. When all of the previous recommendations have been handled, the problem has usually been conflicting versions of Java JRE on my machine. To fix this on a Windows machine, I have ensured that only one version of Java (one JDK and one JRE directory) reside in the "Program Files/Java" directory. Also, I have ensured that no other conflicting Java versions, such as in System32 directory, are causing problems.

To summarize, exceptions encountered when trying to obtain a JAXBContext can usually be resolved by taking the following steps:

  1. Ensuring that JAXB implementation classes are in my classpath. This is not covered previously in this blog and should not usually be an issue anymore (in Java SE 6) because the JAXB reference implementation comes with Java SE 6.

  2. Explicitly pass a classloader to the JAXBContext.newInstance method to avoid confusion about the appropriate class loader.

  3. Copying appropriate endorsed libraries from GlassFish directory to Java SE JRE endorsed libs directory when using GlassFish with JAXB 2.1 and Java SE 6.0 with JAXB 2.0.

  4. Removing old versions of Java from system or at least moving old, unused versions into directories other than normal location of Java installation.



This blog entry may make use of JAXB RI sound more difficult than it normally is. I have used this entry to capture my experience and lessons learned from working with the JAXB RI, but overall I have been very happy with it. I have used JAXB in many different situations and find it extremely easy to use in most cases. One nice use of JAXB is described in my OTN (Oracle Technology Network) article Better JPA, Better JAXB, and Better Annotations Processing with Java SE 6.