0 Replies Latest reply on Feb 11, 2014 2:00 PM by jameskojo

    jboss-modules: ClassNotFoundException during static initialization of __XMLEventFactory

    jameskojo

      Apologies if this is the wrong forum for jboss-modules specific questions. I couldn't find a dedicated forum for it.

       

      We are using jboss-modules as an embedded library in several of our applications, and deploying it in a Tomcat container as a webapp. A transitive dependency pulls in the woodstox parser (wstx-asl-3.2.9.jar), which eventually gets registered as a XmlEventFactory service provider by the container.

      The woodstox parser is loaded in the webapp classloader along side the jboss-modules jars. However, the static initialization code in  __XMLEventFactory seems to assume that all service providers of XmlEventFactory are in the system classloader as it swaps in the system CL for the TCCL, so of course the lookup fails.

      A call to XmlEventFactory.newInstance() before the classloader swapping works just fine in my app, which suggests that the swapping is unnecessary at least in some situations, which is also implied by the code comment.


      Could this behavior be made configurable or optional or otherwise enhanced?

      See below for detailed context.


      Thanks


      James


       


      Code in question::

          static {

              Thread thread = Thread.currentThread();

              ClassLoader old = thread.getContextClassLoader();

       

              // Unfortunately we can not use null because of a stupid bug in the jdk JAXP factory finder.

              // Lack of tccl causes the provider file discovery to fallback to the jaxp loader (bootclasspath)

              // which is correct. However, after parsing it, it then disables the fallback for the loading of the class.

              // Thus, the class can not be found.

              //

              // Work around the problem by using the System CL, although in the future we may want to just "inherit"

              // the environment's TCCL

              thread.setContextClassLoader(ClassLoader.getSystemClassLoader());

              try {

                  if (System.getProperty(XMLEventFactory.class.getName(), "").equals(__XMLEventFactory.class.getName())) {

                      System.clearProperty(XMLEventFactory.class.getName());

                  }

                  XMLEventFactory factory = XMLEventFactory.newInstance();

                  try {

                      DEFAULT_FACTORY = PLATFORM_FACTORY = factory.getClass().getConstructor();

                  } catch (NoSuchMethodException e) {

                      throw __RedirectedUtils.wrapped(new NoSuchMethodError(e.getMessage()), e);

                  }

                  System.setProperty(XMLEventFactory.class.getName(), __XMLEventFactory.class.getName());

              } finally {

                  thread.setContextClassLoader(old);

              }

          }

       

      Initialization Error:

      Caused by: javax.xml.stream.FactoryFinder$ConfigurationError: Provider com.ctc.wstx.stax.WstxEventFactory not found

      at javax.xml.stream.FactoryFinder.newInstance(FactoryFinder.java:188)

      at javax.xml.stream.FactoryFinder.newInstance(FactoryFinder.java:148)

      at javax.xml.stream.FactoryFinder.find(FactoryFinder.java:242)

      at javax.xml.stream.FactoryFinder.find(FactoryFinder.java:213)

      at javax.xml.stream.XMLEventFactory.newInstance(XMLEventFactory.java:59)

      at __redirected.__XMLEventFactory.<clinit>(__XMLEventFactory.java:76)

      at __redirected.__JAXPRedirected.initAll(__JAXPRedirected.java:80)

      at org.jboss.modules.Module$1.run(Module.java:131)

      at org.jboss.modules.Module$1.run(Module.java:118)

      at java.security.AccessController.doPrivileged(Native Method)

      at org.jboss.modules.Module.<clinit>(Module.java:118)

      at org.jboss.modules.ModuleLoader.loadModuleLocal(ModuleLoader.java:355)

      at org.jboss.modules.ModuleLoader.preloadModule(ModuleLoader.java:305)

      at org.jboss.modules.ModuleLoader.loadModule(ModuleLoader.java:238)