本文介绍了com.sun.tools.xjc.Plugin:提供者<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".

我尝试将这两个插件的 jar 放入 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 不是亚型

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 库可以进入系统类路径,因为它们导出的包没有被筛选,但 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 进行了类路径加载器筛选,以便能够在 JRE 中加载更高版本的 JAXB API,而 JRE 的 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:提供者&lt;plugin&gt;不是子类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-19 03:54