Hi!

TL;DR: On Java 10.0.1, a web app in Tomcat 9.0.8.0 has no access to JAXB
even though its reference implementation is present on the class path.

(This looks like a bug to me, but "Before you report a bug" urged me to
ask here first. :) )

NOTE: I already asked [on
StackOverflow](https://stackoverflow.com/q/51518781/2525313), where the
question is a little more readable.

On to the details...

# The Situation

We have a web app that runs on Tomcat and depends on JAXB. During our
migration to Java 9 we opted for adding [the JAXB reference
implementation as a regular
dependency](https://stackoverflow.com/a/48204154/2525313).

Everything worked when launching the app from the IDE [with embedded
Tomcat](https://tomcat.apache.org/tomcat-9.0-doc/api/org/apache/catalina/startup/Tomcat.html),
but when running it on a real Tomcat instance, I get this error:

        Caused by: java.lang.RuntimeException: javax.xml.bind.JAXBException:
                Implementation of JAXB-API has not been found on module path or 
classpath.
         - with linked exception:
        [java.lang.ClassNotFoundException:
com.sun.xml.internal.bind.v2.ContextFactory]
                at [... our-code ...]
        Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has
not been found on module path or classpath.
                at 
javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:278)
~[jaxb-api-2.3.0.jar:2.3.0]
                at javax.xml.bind.ContextFinder.find(ContextFinder.java:421)
~[jaxb-api-2.3.0.jar:2.3.0]
                at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
~[jaxb-api-2.3.0.jar:2.3.0]
                at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662)
~[jaxb-api-2.3.0.jar:2.3.0]
                at [... our-code ...]
        Caused by: java.lang.ClassNotFoundException:
com.sun.xml.internal.bind.v2.ContextFactory
                at
jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
~[?:?]
                at
jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:190)
~[?:?]
                at java.lang.ClassLoader.loadClass(ClassLoader.java:499) ~[?:?]
                at
javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122)
~[jaxb-api-2.3.0.jar:2.3.0]
                at
javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155)
~[jaxb-api-2.3.0.jar:2.3.0]
                at 
javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:276)
~[jaxb-api-2.3.0.jar:2.3.0]
                at javax.xml.bind.ContextFinder.find(ContextFinder.java:421)
~[jaxb-api-2.3.0.jar:2.3.0]
                at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
~[jaxb-api-2.3.0.jar:2.3.0]
                at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662)
~[jaxb-api-2.3.0.jar:2.3.0]
                at [... our-code ...]

Note:

> Implementation of JAXB-API has not been found on module path or classpath.

These are the relevant files in `webapps/$app/WEB-INF/lib`:

        jaxb-api-2.3.0.jar
        jaxb-core-2.3.0.jar
        jaxb-impl-2.3.0.jar

What is going on here?

# What I tried

## Adding JARs

Maybe it helps to add the JARs to Tomcat's class path in `setenv.sh`?

    CLASSPATH=
        .../webapps/$app/WEB-INF/lib/jaxb-api-2.3.0.jar:
        .../webapps/$app/WEB-INF/lib/jaxb-impl-2.3.0.jar:
        .../webapps/$app/WEB-INF/lib/jaxb-core-2.3.0.jar:
        .../webapps/$app/WEB-INF/lib/javax.activation-1.2.0.jar

Nope:

        Caused by: javax.xml.bind.JAXBException: ClassCastException: attempting
to cast
        
jar:file:.../webapps/$app/WEB-INF/lib/jaxb-api-2.3.0.jar!/javax/xml/bind/JAXBContext.class
 to
        
jar:file:.../webapps/$app/WEB-INF/lib/jaxb-api-2.3.0.jar!/javax/xml/bind/JAXBContext.class.
        Please make sure that you are specifying the proper ClassLoader.
                at
javax.xml.bind.ContextFinder.handleClassCastException(ContextFinder.java:157)
~[jaxb-api-2.3.0.jar:2.3.0]
                at 
javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:300)
~[jaxb-api-2.3.0.jar:2.3.0]
                at 
javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:286)
~[jaxb-api-2.3.0.jar:2.3.0]
                at javax.xml.bind.ContextFinder.find(ContextFinder.java:409)
~[jaxb-api-2.3.0.jar:2.3.0]
                at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721)
~[jaxb-api-2.3.0.jar:2.3.0]
                at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662)
~[jaxb-api-2.3.0.jar:2.3.0]
                at
de.disy.gis.webmapserver.factory.DefaultWmsRequestFactory.initializeCommandExtractor(DefaultWmsRequestFactory.java:103)
~[cadenza-gis-webmapserver-7.7-SNAPSHOT.jar:7.6]
                at
de.disy.gis.webmapserver.factory.DefaultWmsRequestFactory.lambda$new$0(DefaultWmsRequestFactory.java:87)
~[cadenza-gis-webmapserver-7.7-SNAPSHOT.jar:7.6]

That's clearly the same class, so apparently it has been loaded by two
class loaders. I suspect [the system class loader and the app's class
loader](https://tomcat.apache.org/tomcat-9.0-doc/class-loader-howto.html#Class_Loader_Definitions),
but why would loading `JAXBContext` be delegated to the system class
loader once but not always? It almost looks as if the delegation
behavior of the app's class loader changes while the program runs.

## Adding the module

I don't really want to add _java.xml.bind_, but I tried it anyways by
adding this to `catalina.sh`:

        JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-modules=java.xml.bind"

Doesn't work either, though:

        Caused by: java.lang.ClassCastException:
        java.xml.bind/com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl
        cannot be cast to com.sun.xml.bind.v2.runtime.JAXBContextImpl
                at [... our-code ...]

Apart from the different class and stack trace, this is in line with
what happened earlier: The class `JAXBContextImpl` was loaded twice,
once from _java.xml.bind_ (must have been the system class loader) and
one other time (I assume by the app's loader from the JAR).

## Searching for bugs

[Searching Tomcat's bug
database](https://bz.apache.org/bugzilla/query.cgi) I found
[#62559](https://bz.apache.org/bugzilla/show_bug.cgi?id=62559). Could
that be the same error?



-- 

PGP Key:
    http://keys.gnupg.net/pks/lookup?op=vindex&search=0xCA3BAD2E9CCCD509

Web:
    http://blog.codefx.org
        a blog about software development
    https://courses.codefx.org
        high-quality Java courses

Social:
    https://twitter.com/nipafx
    http://youtube.com/c/codefx

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to