2015-01-16 6 views
5

Ich habe eine CXF JAX-RS App mit Maven gebaut. Ich arbeite daran, es in Gradle zu konvertieren, aber mit der Ant XJC-Aufgabe.com.sun.tools.xjc.Plugin: Provider <plugin> kein Untertyp

Der aktuelle Build verwendet ein paar Erweiterungen, von denen eine eine Kopie des "element wrapper" -Plugins ist, und die andere ist die "jaxb-fluent-api".

Ich habe versucht, die Gläser für die beiden Plugins in die xjc Classpath setzen, aber wenn ich die XJC Aufgabe ausführen, bekomme ich die folgende:

java.util.ServiceConfigurationError: com.sun.tools.xjc.Plugin: Provider dk.conspicio.jaxb.plugins.XmlElementWrapperPlugin not a subtype

Die XmlElementWrapperPlugin Klasse erweitert „com.sun.tools.xjc .Plugin ".

Irgendeine Idee, was hier vor sich geht?

Wenn es darauf ankommt, meine Maven-Konfiguration für das xjc Plugin sieht wie folgt aus etwas:

<plugin> 
    <groupId>org.apache.cxf</groupId> 
    <artifactId>cxf-xjc-plugin</artifactId> 
    <executions> 
     <execution> 
      <id>generate-sources</id> 
      <phase>generate-sources</phase> 
      <goals> 
       <goal>xsdtojava</goal> 
      </goals> 
      <configuration> 
       <extensions> 
        <extension>JAXBXMLElementWrapperPlugin:JAXBXMLElementWrapperPlugin:1.0.0</extension> 
        <extension>net.java.dev.jaxb2-commons:jaxb-fluent-api:2.1.8</extension> 
       </extensions> 
       <xsdOptions> 
        <xsdOption> 
         <xsd>${basedir}/src/main/resources/schema/serviceCallResults.xsd</xsd> 
         <packagename>com.att.sunlight.service.domain.serviceCallResults</packagename> 
         <extension>true</extension> 
         <extensionArgs> 
          <extensionArg>-Xxew</extensionArg> 
          <extensionArg>-summary ${basedir}/target/xew-summary.txt</extensionArg> 
          <extensionArg>-instantiate lazy</extensionArg> 
          <extensionArg>-Xfluent-api</extensionArg> 
         </extensionArgs> 
        </xsdOption> 
       </xsdOptions> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 

Hier ist meine "build.gradle", wobei nur die elided Repositories:

apply plugin: 'java' 
apply plugin: 'maven' 
apply plugin: 'war' 

group = 'SunlightDataService' 
version = '1.2.4-SNAPSHOT' 

sourceCompatibility = 1.6 
targetCompatibility = 1.6 

repositories { 
    ... 
} 

configurations { 
    jaxb 
} 

dependencies { 

    jaxb 'com.sun.xml.bind:jaxb-xjc:2.2.7-b41' 
    jaxb 'com.sun.xml.bind:jaxb-impl:2.2.7-b41' 
    jaxb 'javax.xml.bind:jaxb-api:2.2.7' 
    jaxb "JAXBXMLElementWrapperPlugin:JAXBXMLElementWrapperPlugin:1.0.0" 
    jaxb "net.java.dev.jaxb2-commons:jaxb-fluent-api:2.1.8" 

    compile group: 'org.springframework', name: 'spring-beans', version:'3.2.8.RELEASE' 
    compile group: 'org.springframework', name: 'spring-webmvc-portlet', version:'3.2.8.RELEASE' 
    compile group: 'org.apache.cxf', name: 'cxf-rt-transports-http', version:'2.7.7' 
    compile group: 'log4j', name: 'log4j', version:'1.2.16' 
    compile group: 'org.springframework', name: 'spring-jdbc', version:'3.2.8.RELEASE' 
    compile group: 'org.springframework', name: 'spring-context', version:'3.2.8.RELEASE' 
    compile group: 'org.apache.cxf', name: 'cxf-rt-frontend-jaxrs', version:'2.7.7' 
    compile group: 'org.apache.cxf', name: 'cxf-rt-bindings-xml', version:'2.7.7' 
    compile group: 'org.apache.cxf', name: 'cxf-rt-databinding-jaxb', version:'2.7.7' 
    compile group: 'org.apache.cxf', name: 'cxf-rt-core', version:'2.7.7' 
    compile group: 'org.apache.cxf', name: 'cxf-api', version:'2.7.7' 
    compile group: 'org.apache.cxf', name: 'cxf-rt-rs-extension-providers', version:'2.7.7' 
    compile group: 'org.codehaus.jettison', name: 'jettison', version:'1.3.4' 
    compile group: 'org.perf4j', name: 'perf4j', version:'0.9.14' 
    compile group: 'cglib', name: 'cglib', version:'2.2.2' 
    compile group: 'org.aspectj', name: 'aspectjweaver', version:'1.6.12' 
    compile group: 'commons-collections', name: 'commons-collections', version:'3.2.1' 
    compile group: 'esGateKeeper', name: 'GLCookieDecryption', version:'1.0.0' 
    compile group: 'joda-time', name: 'joda-time', version:'2.3' 
    compile group: 'org.apache.jackrabbit', name: 'jackrabbit-core', version:'2.4.0' 
    compile group: 'org.apache.commons', name: 'commons-lang3', version:'3.1' 
    testCompile group: 'org.springframework', name: 'spring-test', version:'3.2.8.RELEASE' 
    testCompile group: 'oracle.jdbc', name: 'oracle.jdbc.OracleDriver', version:'1.0.0' 
    testCompile group: 'com.atomikos', name: 'transactions-jta', version:'3.7.0' 
    testCompile group: 'org.apache.cxf', name: 'cxf-rt-transports-http-jetty', version:'2.7.7' 
    testCompile group: 'com.atomikos', name: 'transactions-jdbc', version:'3.7.0' 
    testCompile group: 'org.mockito', name: 'mockito-all', version:'1.9.5' 
    testCompile group: 'junit', name: 'junit', version:'4.10' 
    testCompile group: 'org.assertj', name: 'assertj-core', version:'1.6.1' 
    providedCompile group: 'javax.transaction', name: 'jta', version:'1.1' 
    providedCompile group: 'javax.servlet.jsp', name: 'jsp-api', version:'2.1' 
    providedCompile group: 'javax.servlet', name: 'servlet-api', version:'2.5' 
} 

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) { 
     schema(dir: "src/main/resources/schema", includes: "serviceCallResults.xsd") 
     arg(line: "-Xxew") 
     arg(line: "-summary target/xew-summary.txt") 
     arg(line: "-instantiate lazy") 
     arg(line: "-Xfluent-api") 
    } 
} 

compileJava.dependsOn processXSDs 

Update:

Ich habe festgestellt, dass dies kein Problem mit der Erweiterung "Element Wrapper" ist. Wenn ich dieses Jar aus dem Klassenpfad entferne und wiederherstelle, meldet es den gleichen Fehler für das "Fluent API" -Plugin.

Ich habe auch festgestellt, dass dies nicht unbedingt ein Gradle Problem ist. Ich bekomme das gleiche Symptom mit einer Ant "build.xml" und sogar einem einfachen Shell-Skript, das direkt die Java-Klasse "XJCFacade" aufruft. Tatsächlich kann ich dieses Skript ein wenig vereinfachen, indem ich nicht einmal Schemadateien vorschlage, was deutlich macht, dass dieser Fehler schon vor dem Versuch auftritt, irgendwelche Schemata zu verarbeiten.

Im Folgenden ist meine aktuelle Skript:

#! /bin/bash 
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 

Sie könnten den gleichen Test konstruieren, indem all diese Artefakte zu Ihrem Gradle oder Maven-Cache und kopiert sie in eine einfache Ordnerstruktur herunterzuladen.

Beachten Sie auch, dass ich diesen Test hauptsächlich unter Windows 7 ausführe, aber ich habe dieses Projekt gezippt und es auf meine CentOS-VM verschoben und es gibt mir genau den gleichen Fehler.

+0

Können Sie mehr von Ihrem build.grade veröffentlichen? Zumindest die 'Abhängigkeiten {...}' blockieren. –

+0

Neue Revision enthält das gesamte Skript mit Ausnahme der Repositorys. –

+0

Ersetzen Sie 'arg (line:" ... ")' durch 'arg (value:" ... ")'. –

Antwort

10

Ich habe versucht,

java -cp jaxb-api-2.2.7.jar;jaxb-core-2.2.7.jar;jaxb-xjc-2.2.7.jar;commons-logging-1.1.1.jar;commons-lang-2.2.jar;jaxb2-basics-tools-0.6.5.jar;jaxb-xew-plugin-1.3.jar com.sun.tools.xjc.XJCFacade -verbose -extension -d src xsd

und in der Tat, die mit Exception in thread "main" java.util.ServiceConfigurationError: com.sun.tools.xjc.Plugin: Provider com.sun.tools.xjc.addon.xew.XmlElementWrapperPlugin not a subtype ausfällt, so ist das Problem eindeutig reproduzierbar. Ich habe java.util.ServiceLoader debugged und es stellte sich heraus, dass Plugins als Argument an XJC übergeben werden sollten (nicht an Classpath von Java). Eigentlich wissen alle maven-Plugins (wie jaxb2-maven-plugin oder maven-jaxb2-plugin ...) über diese Funktion und formatieren XJC-Segmente korrekt. So ist die richtige Befehlszeile ist:

java -cp jaxb-api-2.2.7.jar;jaxb-core-2.2.7.jar;jaxb-xjc-2.2.7.jar;commons-lang-2.2.jar;commons-logging-1.1.1.jar com.sun.tools.xjc.XJCFacade -classpath jaxb-xew-plugin-1.3.jar;jaxb2-basics-tools-0.6.5.jar -verbose -extension -Xxew -d src xsd

Beachten Sie, dass -classpath ist Argument für XJC. commons-xxx libs können zum Systemklassenpfad gehen, da die Pakete, die sie exportieren, nicht überprüft werden, aber jaxb2-basics-tools sollte im XJC-Klassenpfad enthalten sein.Wenn Sie an Details interessiert sind:

Dies passiert, weil XJC Klassenpfad-Loader-Screening, um höhere Versionen von JAXB-API in JRE laden kann, die niedrigere integrierte Version der API hat. Siehe XJCFacade.java line 69. Das bedeutet, dass com.sun.tools.xjc.Plugin wird einmal von benutzerdefinierten XJCFacade Classloader geladen, während die gleiche Klasse wieder von einem anderen (tatsächlich Eltern) Classloader geladen wird, wenn Class.forName("com.sun.tools.xjc.addon.xew.XmlElementWrapperPlugin") aufgerufen wird, aber jetzt Klassen nicht gleich sind.

Eigentlich kann man wie diese umgehen (Lösung nach dem Quellcode Inspektion gefunden):

java -Dcom.sun.tools.xjc.XJCFacade.nohack=true -cp jaxb-core-2.2.7.jar;jaxb-xjc-2.2.7.jar;commons-lang-2.2.jar;commons-logging-1.1.1.jar;jaxb2-basics-tools-0.6.5.jar;jaxb-xew-plugin-1.3.jar com.sun.tools.xjc.XJCFacade -verbose -extension -Xxew -d src xsd

Bitte beachte, dass ich jaxb-api-2.2.7.jar von Java Classpath entfernt haben, aber Sie würden besser gestellt JAXB API in lib/endorsed, wie es kann nicht auf verschiedenen Java-Versionen arbeiten: funktioniert gut für Java 7, weil it's JAXB API is close to 2.2.7, aber möglicherweise nicht auf Java 6 + JAXB API 2.2.11 arbeiten.

+3

Sehr beeindruckend. – lexicore

+0

Um die Lösung hierfür zusammenzufassen, versuche ich den Klassenpfad zu charakterisieren, der benötigt wird, um XJC zu "referenzieren", im Gegensatz zu "laufendem" XJC. Ist es sinnvoll, sie zu diesen Bedingungen zu trennen? Zum Beispiel werden die Haupt-XJC-Jars benötigt, um XJC zu "referenzieren", aber die Erweiterungs-Jars müssen in dem "laufenden" Klassenpfad sein. Ich denke, den zweiten Teil "running" zu nennen, ist etwas vernünftig, aber den anderen Teil "reference" zu nennen, ist vielleicht nicht ganz richtig. –

+0

Vielleicht sollte "Referenz" besser "initialisieren" heißen, aber konzeptionell hast du recht: Plugins sollten auf "einen anderen" Klassenpfad hochgestuft werden. –

-1

Kein Build/Release-Ingenieur oder Jaxb-xjc-Implementierer sollte gezwungen werden, den internen proprietären JAXB-JXC ClassLoader zu verwenden. Das ursprüngliche Design war so, dass JDK 1.x Benutzer die JAXB-2.2.0.jar nicht laden würden. Seit 2010 gab es keine bedeutenden Versionsänderungen an JAXB und die jaxb-xjc Entwickler hörten auf, dieses Plugin für JDK 5,6 zu pflegen. 7,8. Ich habe am 31. Januar eine E-Mail an die Oracle-Gurus in der CXF-Metro geschickt. Wenn wir nichts von ihnen hören, bitten wir Oracle, den Code für OpenSource freizugeben, damit er zumindest aufrechterhalten wird. Jeder Implementierer dieses Plugins wurde von dieser ephemeren Lösung überrascht. Keine Notwendigkeit, zukünftige Implementatoren mit nicht mehr gepflegtem Code, der an einem Kurzzeit-Hack leidet, weiter zu bestrafen. Auch die -DClassLoaderBuilder.noHack Option VOLLSTÄNDIG umgeht Oracles eigene Sicherheit Manager..this ist VERBOTEN in Banken und Finanzinstitute ... ich Post zurück, wenn ich von CXF Metro hören zurück

+0

Irgendwelche Neuigkeiten? * [15chars] * – Alix

3

Ein großes Lob an dma_k, sondern ein Working Gradle-Lösung wurde nie zur Verfügung gestellt. Nach einigen Experimenten ist es das, was für mich gearbeitet:

def xjcGeneratedSourcesDir = "$buildDir/generated-sources/xjc" 

configurations { 
    jaxb 
    xjc 
} 

sourceSets { 
    main { 
     java.srcDir xjcGeneratedSourcesDir 
    } 
} 

dependencies { 
    jaxb 'com.sun.xml.bind:jaxb-xjc:2.2.11' 
    jaxb 'com.sun.xml.bind:jaxb-core:2.2.11' 
    jaxb 'com.sun.xml.bind:jaxb-impl:2.2.11' 
    jaxb 'javax.xml.bind:jaxb-api:2.2.11' 

    xjc "com.github.jaxb-xew-plugin:jaxb-xew-plugin:1.4" 
    xjc "net.java.dev.jaxb2-commons:jaxb-fluent-api:2.1.8" 

    // etc. 
} 

task wsdl2java << { 
    file(xjcGeneratedSourcesDir).mkdirs() 

    ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', 
       classpath: configurations.jaxb.asPath) 

    ant.xjc(destdir: xjcGeneratedSourcesDir, 
      package: "com.localhost.jaxb", extension: true) { 
     schema(dir: "src/main/resources/schema", includes: "*.xsd") 
     classpath(path: configurations.xjc.asPath) 
     arg(line: "-Xxew") 
     arg(line: "-Xxew:summary $buildDir/xew-summary.txt") 
     arg(line: "-Xxew:instantiate lazy") 
     arg(line: "-Xfluent-api") 
    } 
} 

compileJava.dependsOn wsdl2java 
+0

Entschuldigung, ich habe vergessen, weitere Informationen hinzuzufügen. Ich endete auch mit einer ähnlichen Lösung, fast genau in der Tat. Ich fand, dass ich die Abhängigkeit "jaxb-impl" nicht explizit angeben musste. Ich habe meine Version von "xjcGeneratedSourcesDir" in einem "ext" -Block definiert, der Gradle-ähnlicher ist, und ich habe auch meinen "ant.xjc" -Aufruf in eine Methode eingefügt, die ich mehrmals mit spezifischen Schemas zur Verarbeitung aufruft. –

+0

Danke. Es hat für mich funktioniert. – dpg

Verwandte Themen