-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Nicolai,
On 7/26/18 6:41 AM, Nicolai Parlog wrote: > 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/catali na/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.ja va: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.j ava: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/bi nd/JAXBContext.class > to > jar:file:.../webapps/$app/WEB-INF/lib/jaxb-api-2.3.0.jar!/javax/xml/bi nd/JAXBContext.class. > > Please make sure that you are specifying the proper ClassLoader. > at > javax.xml.bind.ContextFinder.handleClassCastException(ContextFinder.ja va: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.initializeCo mmandExtractor(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.ht ml#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? You will likely need to include these classes in Tomcat's CATALINA_BASE/lib directory; it appears that placing them into your application is causing some confusion. You should not put any JAR files that are bundled into your application into Tomcat's CLASSPATH. Better to simply move the JARs from your application's WEB-INF/lib directory to Tomcat's CATALINA_BASE/lib directory and make no changes to the CLASSPATH. - -chris -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAltZ6rAACgkQHPApP6U8 pFi6ZA/8DXK7Y4M7/VW0wxbZ5Psr5+IwlPGk1SZb/+ZlpylPNcOjsW2K+MzycK1P VT5+fqsCD7Aj9u6OF8D0B2aN7khDJp53F0UqwLw3kymHP3/0b/oeoZWgeDkYpXpQ QKoEwpS1N0FVjeHH11R5sdJBv7nURLAaV85VZo1TfLqqfs9RmJUxiV6c5u46gM1d vODdOgoRwqRJxLMGNJBnGAMMYkGS6/jcX+eteopeEO/rtia6imxgU+dLLsrNoPDk ilEK3xETrKFeT4PFkLujMBlu7/Zf+HAik53IL/u5C1h72iiEkIRv/+9kmuBprVww pj2nEmDZkZgUylYYCb1RDK/5qWInwXaXO3dpz9IJbnNq5UDUs8pSiRb2Gi1eMNvM 7zXCz7usg73N7fJMnFdvPmugsqucTXiuLzN6JYQIi+qY8iKHLDL0n2scNJKXKluq +ad2mKUSOBnELf2cyoDQ6lWt3iNOFNHHmB4F5bbyw19NVIndnRiej2KFZ6HkFutd BkpMoaX0PWiRAb657DqHT+3kJTBhcA4npkUPLUi5rjyQogh3p74I+WVHO67dx/f2 6TGamIgunxY25tQTGfW4alCLwpEmW+2tdzxAJ2NHv3Yxs793vtgE3puptgrxt5Lr Q8Enku/ugN6tFsdpaCaEqdwyJkgoC3LsT3+sbZQ1cHtvofdrtrg= =PzJF -----END PGP SIGNATURE----- --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org