Page 1 of 1

Websphere Liberty and docx4j do not work?

PostPosted: Thu Aug 06, 2020 6:29 pm
by JannikL
Hi all

To jump right into it: My current understanding is that docx4j does not work with Webpshere Liberty . Please prove me wrong :-) More below.

We're migrating away from Websphere to Liberty. Docx4j worked on Websphere 8.5, with docx4j 3.3.3.

I cannot get things to work on Liberty. Running latest AdoptOpenJDK 8 hotspot version, and tried Liberty kernel versions 8.5.5.9 through 20.0.0.8, and docx4j 3.3.3 all the way up to docx4j-JAXB-Internal and docx4j-JAXB-ReferenceImpl 8.2.1.

We keep having issues. Is there anyone that managed to get Liberty and doc4j working, and if so, how?

Having the following error currently (liberty 20.0.0.8 and docx4j-JAXB-ReferenceImpl 8.2.1)

Code: Select all
Caused by: java.lang.NoClassDefFoundError: com/sun/xml/bind/marshaller/NamespacePrefixMapper
   at java.lang.ClassLoader.defineClass1(Native Method)
   at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
   at com.ibm.ws.classloading.internal.AppClassLoader.definePackageAndClass(AppClassLoader.java:370)
   at com.ibm.ws.classloading.internal.AppC
lassLoader.findClass(AppClassLoader.java:326)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
   at com.ibm.ws.classloading.internal.AppClassLoader.findOrDelegateLoadClass(AppClassLoader.java:547)
   at com.ibm.ws.classloading.internal.AppClassLoader.loadClass(AppClassLoader.java:505)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
   at java.lang.Class.forName0(Native Method)
   at java.lang.Class.forName(Class.java:264)
   at org.docx4j.jaxb.NamespacePrefixMapperUtils.tryUsingRI(NamespacePrefixMapperUtils.java:74)
   at org.docx4j.jaxb.NamespacePrefixMapperUtils.getPrefixMapper(NamespacePrefixMapperUtils.java:66)
   at org.docx4j.XmlUtils.marshaltoString(XmlUtils.java:850)
   at org.docx4j.openpackaging.contenttype.ContentTypeManager.parseContentTypesFile(ContentTypeManager.java:847)
   at org.docx4j.openpackaging.io3.Load3.get(Load3.java:146)
   at org.docx4j.openpackaging.packages.OpcPackage.load(OpcPackage.java:561)
   at org.docx4j.openpackaging.packages.OpcPackage.load(OpcPackage.java:410)
   at org.docx4j.openpackaging.packages.OpcPackage.load(OpcPackage.java:376)
   at org.docx4j.openpackaging.packages.OpcPackage.load(OpcPackage.java:341)
   at xxxxxxxxxxxx.ExportXlsxService.Export(ExportXlsxService.java:37)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:498)
   at com.ibm.ejs.container.EJSContainer.invokeProceed(EJSContainer.java:4886)
   at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:592)
   at com.ibm.ws.cdi.ejb.impl.InterceptorChain.proceed(InterceptorChain.java:119)
   at com.ibm.ws.cdi.ejb.impl.EJBCDIInterceptorWrapper.invokeInterceptors(EJBCDIInterceptorWrapper.java:131)
   at com.ibm.ws.cdi.ejb.impl.EJBCDIInterceptorWrapper.aroundInvoke(EJBCDIInterceptorWrapper.java:54)
   at sun.reflect.GeneratedMethodAccessor84.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:498)
   at com.ibm.ejs.container.interceptors.InterceptorProxy.invokeInterceptor(InterceptorProxy.java:189)
   at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:577)
   at org.jboss.weld.module.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:72)
   at com.ibm.ws.cdi.ejb.interceptor.WeldSessionBeanInterceptorWrapper.aroundInvoke(WeldSessionBeanInterceptorWrapper.java:58)
   at sun.reflect.GeneratedMethodAccessor83.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:498)
   at com.ibm.ejs.container.interceptors.InterceptorProxy.invokeInterceptor(InterceptorProxy.java:189)
   at com.ibm.ejs.container.interceptors.InvocationContextImpl.proceed(InvocationContextImpl.java:577)
   at com.ibm.ejs.container.interceptors.InvocationContextImpl.doAroundInterceptor(InvocationContextImpl.java:298)
   at com.ibm.ejs.container.interceptors.InvocationContextImpl.doAroundInvoke(InvocationContextImpl.java:267)
   at com.ibm.ejs.container.EJSContainer.invoke(EJSContainer.java:4788)
   ... 69 more
Caused by: java.lang.ClassNotFoundException: com.sun.xml.bind.marshaller.NamespacePrefixMapper
   at com.ibm.ws.classloading.internal.AppClassLoader.findClassCommonLibraryClassLoaders(AppClassLoader.java:569)
   at com.ibm.ws.classloading.internal.AppClassLoader.findClass(AppClassLoader.java:305)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
   at com.ibm.ws.classloading.internal.AppClassLoader.findOrDelegateLoadClass(AppClassLoader.java:547)
   at com.ibm.ws.classloading.internal.AppClassLoader.loadClass(AppClassLoader.java:505)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
   ... 113 more


From a working Websphere application, I debugged and noticed with Websphere 8.5/docx4j 3.3.3., it does not go into the tryUsingRI call. So my money is on the fact that Websphere has some classes in its JAXB implementation, that Liberty doesn't, and docx4j can't work without it.

Below is the code for this:
Code: Select all
   public static Object getPrefixMapper() throws JAXBException {
      
      if (prefixMapper!=null) return prefixMapper;
      
      if (haveTried) return null;
      // will be true soon..
      haveTried = true;
            
      if (testContext==null) {
         java.lang.ClassLoader classLoader = NamespacePrefixMapperUtils.class.getClassLoader();
         testContext = JAXBContext.newInstance("org.docx4j.relationships",classLoader );
      }
      
      if (testContext==null) {
         throw new JAXBException("Couldn't create context for org.docx4j.relationships.  Everything is broken!");
      }
      if (testContext.getClass().getName().equals("org.eclipse.persistence.jaxb.JAXBContext")) {
         log.info("Using MOXy NamespacePrefixMapper");
         try {
            Class c = Class.forName("org.docx4j.jaxb.moxy.NamespacePrefixMapper");
            prefixMapper = c.newInstance();
            return prefixMapper;
         } catch (Exception e) {
            throw new JAXBException("Can't create org.docx4j.jaxb.moxy.NamespacePrefixMapper", e);
         }
      }
      if (testContext.getClass().getName().equals("com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl")) {
         log.info("Using com.sun.xml.internal NamespacePrefixMapper");
         try {
            Class c = Class.forName("org.docx4j.jaxb.suninternal.NamespacePrefixMapper");
            prefixMapper = c.newInstance();
            return prefixMapper;
         } catch (Exception e) {
            throw new JAXBException("Can't create internal NamespacePrefixMapper", e);
         }
      }
      Marshaller m=testContext.createMarshaller();      
      return tryUsingRI(m);         

   }


I would expect him to go into the following (which happened in the old docx4j 3.3.3 with Websphere 8.5), which doesn't happen for Liberty:
Code: Select all
      if (testContext.getClass().getName().equals("com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl")) {
         log.info("Using com.sun.xml.internal NamespacePrefixMapper");
         try {
            Class c = Class.forName("org.docx4j.jaxb.suninternal.NamespacePrefixMapper");
            prefixMapper = c.newInstance();
            return prefixMapper;
         } catch (Exception e) {
            throw new JAXBException("Can't create internal NamespacePrefixMapper", e);
         }
      }


Any help please?

Cheers

Jannik

Re: Websphere Liberty and docx4j do not work?

PostPosted: Fri Aug 07, 2020 7:54 am
by jason
HI Jannik

Happily, I haven't done any work with WebSphere since early 2018.

Back then, docx4j worked with WebSphere versions 8.5.5.9 and 9.0.0.5 in WebSphere’s default configuration (but with IBM Java 8, which is not the default in WebSphere 8.5.5.9). As mentioned below, it was (is?) possible to configure WebSphere to instead use the JAXB implementation in the Sun/Oracle JRE; did you do this?

I don't see any reason why this would've changed in any fundamental way, but verifying this is non-trivial, since it involves setting up Websphere environments :-( Do you have a support agreement with Plutext? If not we can probably still help, but on a fee-for-service basis.

By way of background, IBM had (has?) their own proprietary JAXB implementation. By default, WebSphere uses com.ibm.xml.xlxp2.jaxb, which has the concept of fallback/ MarshallerProxy. The actual implementation it uses is in com.ibm.jaxb.tools.jar.

It is possible to configure WebSphere to instead use the JAXB implementation in the Sun/Oracle JRE, but usually you would not do this if you are using the IBM JDK. Alternatively, your application could use MOXy JAXB (by including the relevant jars).

Back then I tested with WebSphere’s default, namely:
Primary JAXBContext: com/ibm/xml/xlxp2/jaxb/JAXBContextImpl.class,
Version: 1.6.2-jaxb,

Fallback JAXBContext: com/ibm/jtc/jax/xml/bind/v2/runtime/JAXBContextImpl.class Build-Id: null

For more information, see https://stackoverflow.com/questions/487 ... eres-jaxb-
marshallerproxy-use-the-reference-implementation