ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Gainty <mgai...@hotmail.com>
Subject RE: Error about "Provider xx not a subtype" from using Ant XJC task
Date Fri, 30 Jan 2015 02:18:56 GMT



> From: dk068x@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-unsubscribe@ant.apache.org
> For additional commands, e-mail: user-help@ant.apache.org
> 
 		 	   		  
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message