Java classloading is a mess, sorry. The root cause is that there are no strong names like there are in the .NET world, and therefore the runtime linker takes whatever match comes first on the classpath, regardless of whether that's the library version that the code was compiled against. The OSGi system solves this problem, but it never gained mainstream adoption.
The error message you cited:
java.lang.LinkageError: JAXB 2.1 API is being loaded from the bootstrap classloader, but this RI needs 2.2 API.
is uncharacteristically useful and specific, most of the time what happens instead is that you're left staring at a NoSuchMethodError
or something of the sort. Over time, you learn to recognise these as library version mismatches. In this case, the library author(s) have written code to recognize a common error case and print a better error message (bless 'em).
Rant over, here's some info that I hope will set you on the right track:
- Java classloaders are hierarchical and resolution is bottom-up
- but there's a blessed class loader at the root of the hierarchy that's responsible for loading the core runtime library
- vendor shenanigans have led to a lot of stuff getting included in the core runtime library that really shouldn't have been in there, as it's a shortcut to becoming dominant in an otherwise Darwinistic selection process. JAXB is one of these things, as you've just found out. JAXB2 is actually pretty decent, but it evolves independent of the core runtime and, well, here we are.
- the JDK and JRE installation has a folder called
lib\endorsed
where you can add JAR files that need to be loaded by the root loader, bypassing even what's in rt.jar
.
In summary, if you manually add the 2.2 version of the JAXB library to %JAVA_HOME%\lib\endorsed
, then it should override the included 2.1 version and your web service client will deploy. This will have to happen on every system that will run the web service client, until the JDK is updated to a 7.x version that does included JAXB 2.2. If the same JVM is running other JAXB based applications, these may or may not break as a result.
Yes, this is painful. A tangent that you could investigate is to deliberately use an older version of Metro that's built for JAXB 2.1. So long as you're bound to deploying on 1.6.0_03
, this may well be the better option, despite losing some of the recent improvements in Metro.
Updated: here's a blog post on this topic. It contains some links to further information.