Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo


Classloader issues

  • veit


    I'm using JPF in an webapp which offers webservices with JAX-WS. I'm using plugins for solving different tasks. This worked so far.
    But now I added a plugin with lib dependencies (JAX-WS) that already exist on the webapp classloader of the application but in a different version.
    So I activated the switch:


    To my boot.properties. The debug msg of jpf shows me that the options was activated correctly:

    [05.02. 22:29:37,DEBUG,StandardPluginLifecycleHandler,]: probeParentLoaderLast parameter value is true
    [05.02. 22:29:37,DEBUG,StandardPluginLifecycleHandler,]: stickySynchronizing parameter value is false
    [05.02. 22:29:37,DEBUG,StandardPluginLifecycleHandler,]: localLoadingClassOptimization parameter value is true
    [05.02. 22:29:37,DEBUG,StandardPluginLifecycleHandler,]: foreignClassLoadingOptimization parameter value is true

    But when I try to create an instance of the plugin which uses the newer version of jax-ws, it comes to different errors like:

    Caused by: javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory not found
        at javax.xml.stream.FactoryFinder.newInstance(FactoryFinder.java:72)
        at javax.xml.stream.FactoryFinder.find(FactoryFinder.java:178)
        at javax.xml.stream.FactoryFinder.find(FactoryFinder.java:92)
        at javax.xml.stream.XMLInputFactory.newInstance(XMLInputFactory.java:136)
        at com.sun.xml.ws.api.streaming.XMLStreamReaderFactory.getXMLInputFactory(XMLStreamReaderFactory.java:109)
        at com.sun.xml.ws.api.streaming.XMLStreamReaderFactory.<clinit>(XMLStreamReaderFactory.java:78)
        at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:805)
        at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(RuntimeWSDLParser.java:262)
        at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:129)
        at com.sun.xml.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:265)
        at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:228)
        at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:176)
        at com.sun.xml.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:104)
        at javax.xml.ws.Service.<init>(Service.java:56)

    A look at the FactoryFinder.find method shows, that it tries to load a class by one of the different ways:

                classloader = Thread.currentThread().getContextClassLoader();
                is = ClassLoader.getSystemResourceAsStream(serviceId);
                is = classLoader.getResourceAsStream(serviceId);

    First I manual set the Threads contextclassloader to the PluginClassloader of JPF. But AFAIR getSystemResource and getResource* are using the PARENT classloader. I found out that the parent classloader of  the pluginclassloader is the webapp classloader. So it loaded some
    classes from there which led to other problems. So I started to write my own classloader (just delegates) and injected the pluginclassloader as its parent. This worked to come a bit further. But know I'm stuck with the above Provider exception.

    Now my question is: is there an easy way to solve this problem with JPF in general? I thought it is possible to have different versions of dep libraries separately or in the parent classloader. But this doesn't seem to work out for me. Do I miss something?

    btw: I _have_ a stax implementation on the pluginclassloader (common cause of the Provider exeception above).


    • veit

      For all who are interested in this issue.
      I figured out that parentClassLoaderFirst setting doesn't work in some cases.
      I added a patch that fixes the StandardPluginClassloader. Perhaps someone finds it useful.

    • Mark

      Is the patch available anywhere?