> 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
>