com.sun.tools.xjc.Plugin:Provider <plugin>不是子类型</plugin>

时间:2015-01-16 04:49:47

标签: maven gradle jaxb cxf jaxb-xew-plugin

我有一个使用Maven构建的CXF JAX-RS应用程序。我正在努力将其转换为Gradle,但使用Ant XJC任务。

当前版本使用了几个扩展,其中一个是&#34;元素包装器的副本&#34;插件,另一个是&#34; jaxb-fluent-api&#34;。

我尝试将这两个插件的jar放入xjc类路径中,但是当我运行XJC任务时,我得到以下内容:

  

java.util.ServiceConfigurationError:com.sun.tools.xjc.Plugin:   提供者dk.conspicio.jaxb.plugins.XmlElementWrapperPlugin不是   亚型

XmlElementWrapperPlugin类扩展&#34; com.sun.tools.xjc.Plugin&#34;。

知道这里发生了什么吗?

如果重要,我的xjc插件的Maven配置如下所示:

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

这是我的&#34; build.gradle&#34;,只有存储库被省略:

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

更新

我已经确定这不是&#34; Element Wrapper&#34;延期。如果我从类路径中删除该jar并重建,它会为&#34; Fluent API&#34;报告相同的错误。插件。

我也确定这不是严格的Gradle问题。我得到了与Ant&#34; build.xml&#34;相同的症状,甚至是直接调用&#34; XJCFacade&#34;的简单shell脚本。 Java类。事实上,我甚至可以通过甚至不指定任何模式文件来简化这个脚本,这使得很明显这个错误甚至在尝试处理任何模式之前就会发生。

以下是我目前的脚本:

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

您可以通过将所有这些工件下载到Gradle或Maven缓存并将它们复制到简单的文件夹结构中来构建相同的测试。

另请注意,我主要在Windows 7上运行此测试,但我将此项目压缩并将其移至我的CentOS VM,它给了我完全相同的错误。

4 个答案:

答案 0 :(得分:13)

我试过了

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

并且确实以Exception in thread "main" java.util.ServiceConfigurationError: com.sun.tools.xjc.Plugin: Provider com.sun.tools.xjc.addon.xew.XmlElementWrapperPlugin not a subtype失败,因此问题显然是可重现的。我调试了java.util.ServiceLoader,结果证明插件应该作为参数传递给XJC(而不是Java的类路径)。实际上,所有maven插件(如jaxb2-maven-pluginmaven-jaxb2-plugin ...)都知道此功能并正确形成XJC参数。所以正确的命令行是:

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

请注意-classpath是XJC的参数。 commons-xxx库可以转到系统类路径,因为它们导出的包不会被筛选,但jaxb2-basics-tools应该在XJC类路径中。如果您对细节感兴趣:

这是因为XJC进行了类路径加载器筛选,以便能够在具有较低内置版本API的JRE中加载更高版本的JAXB API。见XJCFacade.java line 69。这意味着com.sun.tools.xjc.Plugin由自定义XJCFacade类加载器加载一次,而同一个类在调用Class.forName("com.sun.tools.xjc.addon.xew.XmlElementWrapperPlugin")时再次由另一个(实际上是父类)类加载器加载,但现在类不相等。

实际上你可以解决这个问题(在源代码检查后找到解决方案):

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

请注意,我已从Java类路径中删除了jaxb-api-2.2.7.jar,但您最好将JAXB API放入lib/endorsed,因为它可能无法在不同的Java版本上运行:适用于Java 7,因为{{3但是,可能不适用于Java 6 + JAXB API 2.2.11。

答案 1 :(得分:4)

向dma_k致敬,但从未提供过工作的gradle解决方案。经过一些实验,这对我有用:

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

答案 2 :(得分:0)

我不会将ant或maven任务用于gradle,而是直接调用Java类,如I did this for org.apache.cxf.tools.wsdlto.WSDLToJava

答案 3 :(得分:-1)

不应强制构建/发布工程师或jaxb-xjc实现者使用内部专有的JAXB-JXC ClassLoader。最初的设计是如此JDK 1.x用户不会加载JAXB-2.2.0.jar ..自2010年以来,JAXB没有重大的版本更改,jaxb-xjc开发人员停止维护JDK 5,6的这个插件, 7,8。我于1月31日向CXF-Metro的甲骨文大师发送了一封电子邮件。如果我们没有收到他们的回复,请求Oracle向OpenSource发布代码,这样至少可以维护它。 这个插件的每个实现者都被这个短暂的解决方案绊倒了。没有必要进一步惩罚未来的实现者使用无法维护的代码,这些代码遭受短期黑客攻击。 此外,-DClassLoaderBuilder.noHack选项完全绕过了Oracles自己的安全管理器..这是银行和金融机构的VERBOTEN ...... 当我从CXF Metro收到回复时,我会回复。