> From: dk0...@att.com
> To: user@ant.apache.org
> Subject: RE: Error about "Provider xx not a subtype" from using Ant XJC task
> Date: Thu, 29 Jan 2015 17:54:40 +0000
> 
> > -----Original Message-----
> > From: KARR, DAVID
> > Sent: Tuesday, January 20, 2015 10:59 AM
> > To: Ant Users List
> > Subject: RE: Error about "Provider xx not a subtype" from using Ant XJC
> > task
> > 
> > > -----Original Message-----
> > > From: KARR, DAVID
> > > Sent: Friday, January 16, 2015 9:44 AM
> > > To: user@ant.apache.org
> > > Subject: Error about "Provider xx not a subtype" from using Ant XJC task
> > >
> > > I'm using the Ant XJC task, and attempting to load two JAXB extensions.
> > > One is a local copy of the "element wrapper" plugin, and the other the
> > > "fluent api".
> > >
> > > When I run this, I get the following error:
> > > --------------------
> > > Caused by: java.util.ServiceConfigurationError:
> > com.sun.tools.xjc.Plugin:
> > > Provider dk.conspicio.jaxb.plugins.XmlElementWrapperPlugin not a subtype
> > >   at com.sun.tools.xjc.Options.findServices(Options.java:965)
> > >   at com.sun.tools.xjc.Options.getAllPlugins(Options.java:383)
> > > --------------------
> > >
> > > I'm asking this here because I am using an Ant task, so perhaps someone
> > > might know what that error message means.  However, I'm calling this
> > from
> > > a Gradle build script.  I'll show that in a moment if that helps to
> > > illuminate anything.
> > >
> > > I previously was doing the same work in a Maven POM, using the "cxf-xjc-
> > > plugin", which was working fine.
> > >
> > > My task looks like this:
> > > -------------------------
> > > task processXSDs() << {
> > >   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) {
> > >           classpath(path: configurations.jaxb.asPath)
> > >           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")
> > >   }
> > > }
> > > -------------
> > >
> > > If it matters, the "arg" lines were added after I first saw this error,
> > so
> > > those are irrelevant.  I also added the additional classpath reference
> > in
> > > the "xjc" task call, which also made no difference.
> > >
> > > Where I added the following to the jaxb configuration:
> > >   jaxb 'com.sun.xml.bind:jaxb-xjc:2.2.6'
> > >   jaxb 'com.sun.xml.bind:jaxb-impl:2.2.6'
> > >   jaxb 'javax.xml.bind:jaxb-api:2.2.6'
> > >   jaxb "JAXBXMLElementWrapperPlugin:JAXBXMLElementWrapperPlugin:1.0.0"
> > >   jaxb "net.java.dev.jaxb2-commons:jaxb-fluent-api:2.1.8"
> > 
> > If it matters, I've also run this with a plain Ant build.xml file and a
> > "simple" execution of the XJCFacade class on the command line, all with
> > the same results.  Note that I can generate this error with XJCFacade
> > without even specifying any schemas to process. This error happens while
> > plugins are being loaded, before it starts to process schemas.
> > 
> > I've also replaced my local build of JAXBXMLElementWrapperPlugin with the
> > public artifact of the same plugin, still with the same result.
> > 
> > If it matters, here is the complete Ant build.xml that I'm using, with one
> > small elision.  Note that I'm pulling the jars out of my Gradle cache, but
> > that doesn't rely on Gradle itself.
> > ---------------------
> > <?xml version="1.0" encoding="UTF-8"?>
> > <project name="SunlightDataService" default="build" basedir=".">
> >     <property name="baseGradleCache"
> > value="<myhome>/.gradle/caches/modules-2/files-2.1"/>
> >     <path id="jaxb.classpath">
> >             <fileset dir="${baseGradleCache}/com.sun.xml.bind/jaxb-
> > xjc/2.2.6/2f4761c3c2cb8fc503ec96e89e4b71b01f9054ae">
> >                     <include name="jaxb-xjc-2.2.6.jar"/>
> >             </fileset>
> >             <fileset dir="${baseGradleCache}/com.sun.xml.bind/jaxb-
> > impl/2.2.6/62bed5d6f40049a00c48a402c3511f02eedd1c11">
> >                     <include name="jaxb-impl-2.2.6.jar"/>
> >             </fileset>
> >             <fileset dir="${baseGradleCache}/javax.xml.bind/jaxb-
> > api/2.2.6/71f434378f822b09a57174af6c75d37408687c57">
> >                     <include name="jaxb-api-2.2.6.jar"/>
> >             </fileset>
> >             <fileset
> > dir="${baseGradleCache}/org.jvnet.jaxb2_commons\jaxb2-basics-
> > runtime\0.6.5\d6142ae0b68f06dbab141eb0533659f90e05bcde">
> >                     <include name="jaxb2-basics-runtime-0.6.5.jar"/>
> >             </fileset>
> >             <fileset dir="${baseGradleCache}/net.java.dev.jaxb2-
> > commons/jaxb-fluent-api/2.1.8/9a0c55565f17599930d1265546dbd88b2a14cbf0">
> >                     <include name="jaxb-fluent-api-2.1.8.jar"/>
> >             </fileset>
> >             <fileset
> > dir="${baseGradleCache}/javax.activation/activation/1.1.1/485de3a253e23f64
> > 5037828c07f1d7f1af40763a">
> >                     <include name="activation-1.1.1.jar"/>
> >             </fileset>
> >             <fileset
> > dir="${baseGradleCache}/javax.xml.bind/jsr173_api/1.0/c79b8431c3104315c0ae
> > aed7bf23d0ab0edbaa09">
> >                     <include name="jsr173_api-1.0.jar"/>
> >             </fileset>
> >     </path>
> >     <taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask">
> >             <classpath>
> >                     <path refid="jaxb.classpath"/>
> >             </classpath>
> >     </taskdef>
> > 
> >     <target name="build">
> >             <mkdir dir="gen"/>
> >             <xjc destdir="gen"
> > schema="src/main/resources/schema/serviceCallResults.xsd"
> > 
> > package="com.att.sunlight.service.domain.serviceCallResults"
> > extension="true" removeOldOutput="true"/>
> >     </target>
> > </project>
> > ----------------
> 
> Ok.  I have a solution to this.  You can read about the basic solution at 
> http://stackoverflow.com/questions/27977479/com-sun-tools-xjc-plugin-provider-plugin-not-a-subtype
>  .
> 
> Basically, the classpath provided for XJC has to be separated into two 
> pieces.  The jaxb-api, jaxb-core, and jaxb-xjc jars need to be provided to 
> "load" or reference XJC, but the JAXB extension jars have to be loaded ONLY 
> by XJC itself.  You will likely see this error if the extension jars are 
> loaded "too early".
> 
> In the context of using XJCTask in Ant, the extension jars need to be 
> specified ONLY on the classpath in the "xjc" task itself, and not in the 
> classpath defined in the "taskdef".

MG>this is a hack here is why with ClassLoaderBuilder.nohack specified then 
>protected static ClassLoader createProtectiveClassLoader(ClassLoader cl, 
>String v) throws ClassNotFoundException, MalformedURLException {
        if(noHack)  return cl;  // provide an escape hatch

        boolean mustang = false;

        if (SecureLoader.getClassClassLoader(JAXBContext.class) == null) {
//SecureLoader code
 static ClassLoader getClassClassLoader(final Class c) {
        if (System.getSecurityManager() == null) {
            return c.getClassLoader();
        } else {
            return java.security.AccessController.doPrivileged(
                    new java.security.PrivilegedAction<ClassLoader>() {
                        public ClassLoader run() {
                            return c.getClassLoader();
                        }
                    });
        }
    }
//end SecureLoader code
            // JAXB API is loaded from the bootstrap. We need to override one 
with ours
            mustang = true;

            List<String> mask = new 
ArrayList<String>(Arrays.asList(maskedPackages));
            mask.add("javax.xml.bind.");

            cl = new MaskingClassLoader(cl,mask);

            URL apiUrl = cl.getResource("javax/xml/bind/JAXBPermission.class");
            if(apiUrl==null)
                throw new ClassNotFoundException("There's no JAXB 2.2 API in 
the classpath");

            cl = new URLClassLoader(new 
URL[]{ParallelWorldClassLoader.toJarUrl(apiUrl)},cl);
        }
MG>nohack would bypass SecurityManager allowing unprivileged ClassLoader (the 
one that loaded facade) to execute
MG>nobody should be forced to specify multiple versions of JAXB during a build 
to satisfy local CL loading illustrated MG>here..worse it will cause lack of 
configurability for build/release managers..
MG>specify jaxb version once in outermost property
MG>and force all taskdefs and Mojos to implement this version of jaxb
MG>it almost seems that the coder here wanted to have a uber classloader that 
loads only latest JAXB classes
MG>but then threw his uber classloader code away with nohack attribute
MG>multiple classloaders do make sense when there are different domain 
boundaries (e.g. containers/appservers)
MG>not seeing benefit 2+ Classloaders in 
createProtectiveClassLoader(ClassLoader cl, String v) when 1 will suffice
MG>can we get someone to look at this to examine the use of multiple 
classloaders to explain why this is necessary?
MG>also the nohack attribute will bypass SecurityManager restrictions which is 
verboten in banks and fin institutions

MG>Dave/Stefan/Koshuke..........thoughts?

> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscr...@ant.apache.org
> For additional commands, e-mail: user-h...@ant.apache.org
> 
                                          

Reply via email to