dev@jaxb.java.net

Re: Unable to solve "Provider xx not a subtype" problem

From: David Karr <davidmichaelkarr_at_gmail.com>
Date: Sat, 24 Jan 2015 10:24:08 -0800

By running this code in the debugger, I can confirm that a more complete
error message for this situation would be "Provider xx not a subtype of
"com.sun.tools.xjc.Plugin".

I set a breakpoint at the top of ServiceLoader$LazyIterator.next() and let
my test run.

The method is this:
------------------------------
        public S next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            String cn = nextName;
            nextName = null;
            Class<?> c = null;
            try {
                c = Class.forName(cn, false, loader);
            } catch (ClassNotFoundException x) {
                fail(service,
                     "Provider " + cn + " not found");
            }
            if (!service.isAssignableFrom(c)) {
                fail(service,
                     "Provider " + cn + " not a subtype");
            }
            try {
                S p = service.cast(c.newInstance());
                providers.put(cn, p);
                return p;
            } catch (Throwable x) {
                fail(service,
                     "Provider " + cn + " could not be instantiated: " + x,
                     x);
            }
            throw new Error(); // This cannot happen
        }
------------------

I'm able to only see some of the variables (perhaps all of the "this"
properties, but no local variables).

The value of "nextName" at this point is
"org.jvnet.jaxb2_commons.tools.xjc.plugin.fluent_api.XjcFluentApiPlugin".
The value of "service" is an instance of "com.sun.tools.xjc.Plugin". I
entered the following expression in the Display view:


service.isAssignableFrom(Class.forName("org.jvnet.jaxb2_commons.tools.xjc.plugin.fluent_api.XjcFluentApiPlugin",
false, loader))

This returns "false", which results in the symptom. When I view the
"org.jvnet.jaxb2_commons.tools.xjc.plugin.fluent_api.XjcFluentApiPlugin"
class in the provided jar and trace its ancestry, it is clearly a subclass
of "com.sun.tools.xjc.Plugin". The only way this could be false if these
two classes,
"org.jvnet.jaxb2_commons.tools.xjc.plugin.fluent_api.XjcFluentApiPlugin" or
"com.sun.tools.xjc.Plugin" were loaded by different classloaders.

I don't know what else I can do here.

On Fri, Jan 23, 2015 at 9:20 AM, David Karr <davidmichaelkarr_at_gmail.com>
wrote:

> The other minimal test I have is the following shell script, which
> directly runs XJCFacade. This fails on both Win7 and CentOS (remove the
> cygpath reference if you don't use cygwin):
> ------------------------
> #! /bin/bash
> basedir=$(cygpath -m $HOME/work/xjctest)
> cp="\
> $basedir/lib/jaxb-core-2.2.7.jar;\
> $basedir/lib/jaxb-xjc-2.2.7.jar;\
> $basedir/lib/jaxb-fluent-api-2.1.8.jar;\
> $basedir/lib/jaxb-xew-plugin-1.4.jar;\
> "
> #java -classpath
> "lib/commons-beanutils-1.7.0.jar;lib/commons-lang-2.2.jar;lib/commons-logging-1.1.1.jar;lib/istack-commons-runtime-2.16.jar;lib/jaxb2-basics-runtime-0.6.5.jar;lib/jaxb2-basics-tools-0.6.5.jar;lib/jaxb-api-2.2.7.jar;lib/jaxb-core-2.2.7.jar;lib/jaxb-fluent-api-2.1.8.jar;lib/jaxb-xew-plugin-1.4.jar;lib/jaxb-xjc-2.2.7.jar"
> com.sun.tools.xjc.XJCFacade -extension
> java -classpath "$cp" com.sun.tools.xjc.XJCFacade -extension
> ---------------------
>
>
> On Fri, Jan 23, 2015 at 9:00 AM, David Karr <davidmichaelkarr_at_gmail.com>
> wrote:
>
>> Weird. I'm now seeing that this Gradle script will fail or succeed
>> depending on what directory I execute it from. If I execute it from the
>> original project directory where I first saw this problem, it fails. If I
>> execute it from a different directory that just holds this build script, it
>> succeeds. I don't see anything significant in the project that directory
>> that might make this happen. I'm currently comparing the verbose
>> classloading output from both tests to see if I can find any clues.
>>
>> On Fri, Jan 23, 2015 at 6:58 AM, David Karr <davidmichaelkarr_at_gmail.com>
>> wrote:
>>
>>> Ok, thanks for the reply. I now have at least a minimal test case, and
>>> I've even found a situation where the test succeeds.
>>>
>>> I was able to build a minimal Gradle build script, and nothing else
>>> needs to be manually installed (except for Java and Gradle) to run the
>>> test. This test still fails on my Win7 box, but I found that it works on my
>>> CentOS VM. I just compared the environments, and right now my Win7 box has
>>> Gradle 2.2.1 and the CentOS box only 2.1. Also, the CentOS box is running
>>> JDK 1.7 and the Win7 box 1.8. I'm going to do some swapping of those
>>> versions and see what other variations provide a clue. I could also run
>>> either test with verbose class loading, but I'm not sure what I'd look for
>>> in that noise.
>>>
>>> In any case, here's my minimal Gradle test script (not that the test
>>> succeeds if it just complains about a missing schema):
>>> -----------------------------
>>> apply plugin: 'java'
>>> apply plugin: 'maven'
>>> apply plugin: 'war'
>>>
>>> sourceCompatibility = 1.7
>>> targetCompatibility = 1.7
>>>
>>> repositories {
>>> mavenCentral()
>>> }
>>>
>>> configurations {
>>> jaxb
>>> }
>>>
>>> dependencies {
>>> jaxb 'com.sun.xml.bind:jaxb-xjc:2.2.7'
>>> jaxb "com.github.jaxb-xew-plugin:jaxb-xew-plugin:1.4"
>>> jaxb "net.java.dev.jaxb2-commons:jaxb-fluent-api:2.1.8"
>>> }
>>>
>>> task processXSDs() << {
>>> URLClassLoader loader = GroovyObject.class.classLoader;
>>> configurations.jaxb.each { File file -> println file;
>>> loader.addURL(file.toURI().toURL()) }
>>>
>>> ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask',
>>> classpath: configurations.jaxb.asPath)
>>>
>>> ant.xjc(destdir: 'tmp', package:
>>> "com.att.sunlight.service.domain.serviceCallResults", extension: true) {
>>> schema(dir: "src/main/resources/schema", includes:
>>> "serviceCallResults.xsd")
>>> arg(value: "-Xxew")
>>> arg(value: "-summary target/xew-summary.txt")
>>> arg(value: "-instantiate lazy")
>>> arg(value: "-Xfluent-api")
>>> }
>>>
>>> }
>>>
>>> compileJava.dependsOn processXSDs
>>> -------------------------
>>>
>>> On Fri, Jan 23, 2015 at 3:23 AM, Marcel Valovy <marcel.valovy_at_oracle.com
>>> > wrote:
>>>
>>>> Hi David,
>>>>
>>>> one of our teams has experienced the same problem with
>>>> BeanValidationPlugin (part of EclipseLink). We are still analyzing the
>>>> problem. I suspect that it is caused by having *multiple* different
>>>> JAXB jars on classpath and having Context CL load one of the jars and
>>>> having an APP CL load the plugin. When I get the info I need about the jars
>>>> they use I will create a test case for this.
>>>>
>>>> Should you get any more information on this issue, I would greatly
>>>> appreciate if you shared it with me/the group. I will share my results with
>>>> you/the group too, after I get the required info.
>>>>
>>>> BR,
>>>> Marcel
>>>>
>>>>
>>>>
>>>> On 21/01/15 17:12, David Karr wrote:
>>>>
>>>> This is not a proper subject for a "dev" list, but I've queried
>>>> every other reasonable resource, with no result.
>>>>
>>>> I have a small app using CXF, JAX-RS, JAXB, along with two JAXB
>>>> extensions, and Maven.
>>>>
>>>> I use the "cxf-xjc-plugin" in Maven, along with the "Element Wrapper"
>>>> and "Fluent API" JAXB extensions, to generate a set of Java classes from a
>>>> set of schemas. This works fine.
>>>>
>>>> I'm attempting to convert this build from Maven to Gradle. The key
>>>> part is XJC and these JAXB extensions. Ever single way I've tried to run
>>>> XJC fails with the following exception (the referenced classname varies
>>>> depending on whether I leave in both JAXB extensions or remove one from my
>>>> classpath):
>>>>
>>>> Caused by: java.util.ServiceConfigurationError:
>>>> com.sun.tools.xjc.Plugin: Provider
>>>> com.sun.tools.xjc.addon.xew.XmlElementWrapperPlugin not a subtype
>>>> at com.sun.tools.xjc.Options.findServices(Options.java:957)
>>>> at com.sun.tools.xjc.Options.getAllPlugins(Options.java:374)
>>>> at com.sun.tools.xjc.Options.parseArgument(Options.java:688)
>>>> at com.sun.tools.xjc.Options.parseArguments(Options.java:809)
>>>> at com.sun.tools.xjc.XJC2Task._doXJC(XJC2Task.java:474)
>>>> at com.sun.tools.xjc.XJC2Task.doXJC(XJC2Task.java:457)
>>>> at com.sun.tools.xjc.XJC2Task.execute(XJC2Task.java:380)
>>>> at
>>>> com.sun.istack.tools.ProtectedTask.execute(ProtectedTask.java:103)
>>>> at
>>>> org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
>>>> at
>>>> org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
>>>>
>>>> I've tried using the Ant XJC task from Gradle. I've tried it from an
>>>> Ant "build.xml". I tried a Bash script directly calling the XJCFacade
>>>> class. They all get the same result. I have the 2.2.7 version of the xjc,
>>>> impl, and api jaxb jars in my classpath, along with the extension jars and
>>>> other dependencies of those jars.
>>>>
>>>> I've posted about this on jaxb-user, ant-user, cxf-user (to ask why
>>>> they think this only works with the cxf maven plugin), stackoverflow, and
>>>> the issues page for the ElementWrapper plugin. The only response of any
>>>> substance I got was indirectly from Martin Gainty, from my ant-user
>>>> posting, where he talked a bit about how the "ServiceLoader" framework
>>>> works. He didn't really provide a solution, but he implied that "Maven
>>>> solves the issue by inheriting System CL at CLI before tacking on
>>>> maven-core and any consequent plugins". I've tried some classpath ordering
>>>> changes along those lines, but that doesn't help.
>>>>
>>>> Any useful information or leads would be appreciated.
>>>>
>>>>
>>>>
>>>
>>
>