com.sun.tools.xjc.Plugin:提供程序<插件>不是亚型 [英] com.sun.tools.xjc.Plugin: Provider &lt;plugin&gt; not a subtype

查看:16
本文介绍了com.sun.tools.xjc.Plugin:提供程序<插件>不是亚型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a CXF JAX-RS app being built with Maven. I'm working on converting it to Gradle, but using the Ant XJC task.

当前构建使用了几个扩展,其中一个是元素包装器"插件的副本,另一个是jaxb-fluent-api".

The current build uses a couple of extensions, one of which is a copy of the "element wrapper" plugin, and the other is the "jaxb-fluent-api".

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

I tried putting the jars for those two plugins into the xjc classpath, but when I run the XJC task, I get the following:

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

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

XmlElementWrapperPlugin 类扩展了com.sun.tools.xjc.Plugin".

The XmlElementWrapperPlugin class extends "com.sun.tools.xjc.Plugin".

知道这里发生了什么吗?

Any idea what's going on here?

如果重要的话,我的 xjc 插件的 Maven 配置看起来像这样:

If it matters, my Maven configuration for the xjc plugin looks something like this:

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

这是我的build.gradle",仅省略了存储库:

Here's my "build.gradle", with only the repositories elided:

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

更新:

我已经确定这不是元素包装器"扩展的问题.如果我从类路径中删除该 jar 并重新构建,它会为Fluent API"插件报告相同的错误.

I've determined that this is not an issue with the "Element Wrapper" extension. If I remove that jar from the classpath and rebuild, it reports the same error for the "Fluent API" plugin.

我还确定这不是严格意义上的 Gradle 问题.我用 Antbuild.xml"得到了相同的症状,甚至是直接调用XJCFacade"Java 类的普通 shell 脚本.事实上,我可以通过甚至不指定任何架构文件来稍微简化这个脚本,这清楚地表明即使在尝试处理任何架构之前也会发生此错误.

I've also determined this isn't strictly a Gradle issue. I get the same symptom with an Ant "build.xml", and even a plain shell script directly calling the "XJCFacade" Java class. In fact, I can simplify this script a bit by not even specifying any schema files, which makes it clear this error happens even before trying to process any schemas.

以下是我当前的脚本:

#! /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 缓存并将它们复制到一个简单的文件夹结构中来构建相同的测试.

You could construct the same test by downloading all of those artifacts to your Gradle or Maven cache and copying them into a simple folder structure.

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

Also note that I'm running this test mainly on Windows 7, but I zipped up this project and moved it to my CentOS VM and it gives me the exact same error.

推荐答案

我试过了

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 参数.所以正确的命令行是:

and indeed that fails with Exception in thread "main" java.util.ServiceConfigurationError: com.sun.tools.xjc.Plugin: Provider com.sun.tools.xjc.addon.xew.XmlElementWrapperPlugin not a subtype, so the problem is clearly reproducible. I have debugged java.util.ServiceLoader and it turned out that plugins should be passed as argument to XJC (not to classpath of Java). Actually, all maven plugins (like jaxb2-maven-plugin or maven-jaxb2-plugin …) know about this feature and form XJC argments correctly. So the correct command line is:

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 libs 可以进入系统类路径,因为它们导出的包没有被筛选,但是 jaxb2-basics-tools 应该在 XJC 类路径中.如果您有兴趣了解详情:

Note that -classpath is argument for XJC. commons-xxx libs can go to system classpath as the packages they export are not screened, but jaxb2-basics-tools should be in XJC classpath. If you are interested in details:

发生这种情况是因为 XJC 进行了类路径加载器筛选,以便能够在具有较低内置 API 版本的 JRE 中加载较高版本的 JAXB API.请参见 XJCFacade.java 第 69 行.这意味着 com.sun.tools.xjc.Plugin 由自定义 XJCFacade 类加载器加载一次,而同一类在 Class.forName("com.sun.tools.xjc.addon.xew.XmlElementWrapperPlugin") 被调用,但现在类不相等.

This happens because XJC does classpath loader screening to be able to load higher versions of JAXB API in JRE that has lower build-in version of API. See XJCFacade.java line 69. That means that com.sun.tools.xjc.Plugin is loaded once by custom XJCFacade classloader while the same class is loaded by another (actually, parent) classloader again when Class.forName("com.sun.tools.xjc.addon.xew.XmlElementWrapperPlugin") is called, but now classes are not equal.

其实你可以这样解决(源代码检查后找到的解决方案):

Actually you can workaround like this (solution found after source code inspection):

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 srcxsd

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

Note that I have removed jaxb-api-2.2.7.jar from Java classpath but you'd better put JAXB API into lib/endorsed as it may not work on different Java versions: works fine for Java 7, because it's JAXB API is close to 2.2.7, but may not work on Java 6 + JAXB API 2.2.11.

这篇关于com.sun.tools.xjc.Plugin:提供程序<插件>不是亚型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆