Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-8100

JAXB Class Not Found Exception on Java >=9 and Tomcat

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 3.3.3
    • Fix Version/s: None
    • Component/s: Core
    • Labels:
    • Environment:

      Ubuntu 18.10
      OpenJDK Runtime Environment (build 12.0.1+12)
      Tomcat 9.0.14

    • Estimated Complexity:
      Unknown

      Description

      When creating a SOAP Client with JaxWsProxyFactoryBean.create(), JAXB's class loader does not find the context factory (see stack trace at the bottom) and throws a ClassNotFound Exception. This does not happen when I run test with Junit, but it happens when I deploy my Apache CXF Application to Tomcat. All the JAXB artifacts (cxf-rt-databinding-jaxb-3.3.0.jar, jaxb-api-2.3.1.jar, jaxb-core-2.3.0.1.jar, jaxb-impl-2.3.2.jar, jaxb-runtime-2.3.1.jar and jaxb-xjc-2.3.2.jar) are in WEB-INF/lib and are therefore available to the web apps class loader.

      The reason why JAXB does not find the class is, according to the stack overflow post JAXB not available on Tomcat 9 and Java 9/10, that JAXB uses the "thread's context class loader". In Tomcat, this class loader is the system class loader, and because Tomcat builds a class loader hierarchy, the system class loader does not know about a web app's dependencies. JAXB Implementations were removed from the JRE in Java 9 and now the system class loader does not find them.

      According to the mentioned post, this problem could be solved by refactoring org.apache.cxf.common.jaxb.JAXBContextCache and switching invocations from
       

      newInstance( Class<?>[] classesToBeBound, Map<String,?> properties )
      

      to

      newInstance( String contextPath, ClassLoader classLoader, Map<String,?>  properties)
      

      , where JAXBContextCache could pass down the correct classLoader.  Another probably "hacky" solution is to wrap all interactions with JAXB in a proper thread (as described in this post: JAXB Hell on JDK 9).

      Stack trace: 

      Caused by: org.apache.cxf.service.factory.ServiceConstructionException: null
      	at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:355)
      	at org.apache.cxf.service.factory.AbstractServiceFactoryBean.initializeDataBindings(AbstractServiceFactoryBean.java:86)
      	at org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:470)
      	at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.buildServiceFromClass(JaxWsServiceFactoryBean.java:693)
      	at org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:530)
      	at org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:263)
      	at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:199)
      	at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:103)
      	at org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:91)
      	at org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:159)
      	at org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create(JaxWsProxyFactoryBean.java:142)
        ...
      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:232)
      	at javax.xml.bind.ContextFinder.find(ContextFinder.java:375)
      	at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:691)
      	at org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:346)
      	at org.apache.cxf.common.jaxb.JAXBContextCache$2.run(JAXBContextCache.java:344)
      	at java.base/java.security.AccessController.doPrivileged(AccessController.java:551)
      	at org.apache.cxf.common.jaxb.JAXBContextCache.createContext(JAXBContextCache.java:344)
      	at org.apache.cxf.common.jaxb.JAXBContextCache.getCachedContextAndSchemas(JAXBContextCache.java:246)
      	at org.apache.cxf.jaxb.JAXBDataBinding.createJAXBContextAndSchemas(JAXBDataBinding.java:498)
      	at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:353)
      	... 23 common frames omitted
        Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory
      	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
      	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
      	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
      	at javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:92)
      	at javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:125)
      	at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:230)
      

       

       

        Attachments

        1. webapp.war
          30.12 MB
          Christof R

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              mrcrab Christof R
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated: