【问题标题】:Unrecognized parameter -XsomePlugin error when using JAXB/XJC plugins使用 JAXB/XJC 插件时出现无法识别的参数 -XsomePlugin 错误
【发布时间】:2018-06-03 18:17:33
【问题描述】:

我正在使用 JAXB/XJC 编译 XML Schema,我想使用一些 XJC 插件来增加生成的代码。
我在 XJC 类路径中包含插件并使用-XsomePlugin 激活它。

但是我收到如下错误:

Caused by: com.sun.tools.xjc.BadCommandLineException: unrecognized parameter -XsomePlugin
    at com.sun.tools.xjc.Options.parseArguments(Options.java:859)
    at com.sun.tools.xjc.XJCBase._doXJC(XJCBase.java:804)
    ... 21 more

显然该插件没有被 XJC 接收或未激活。

可能是什么原因以及如何调试此错误?

【问题讨论】:

    标签: java jaxb xjc maven-jaxb2-plugin


    【解决方案1】:

    XJC 使用“服务加载器”机制发现和实例化插件。 XJC 插件提供了一个资源META-INF\services\com.sun.tools.xjc.Plugin,其中列出了插件类的 FQCN。

    插件无法加载/实例化可能有多种原因。

    开启插件加载错误日志

    不幸的是,XJC 通常不会显示在插件实例化期间发生了哪些特定错误。您只会收到此unrecognized parameter -XsomePlugin 消息,仅此而已。

    幸运的是,有一个“调试”开关可以使用以下系统属性之一激活:

    • com.sun.tools.xjc.Options.findServices=true
    • com.sun.tools.internal.xjc.Options.findServices=true

    (我一般两个属性都设置了,下面我会解释原因。)

    这将使 XJC 记录插件实例化过程中发生的实际错误,例如:

      [xjc] java.util.ServiceConfigurationError: com.sun.tools.xjc.Plugin: Provider org.jvnet.jaxb2_commons.plugin.tostring.ToStringPlugin could not be instantiated
      [xjc]     at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:581)
      [xjc]     at java.base/java.util.ServiceLoader.access$100(ServiceLoader.java:390)
      [xjc]     at java.base/java.util.ServiceLoader$ProviderImpl.newInstance(ServiceLoader.java:799)
      [xjc]     at java.base/java.util.ServiceLoader$ProviderImpl.get(ServiceLoader.java:721)
      [xjc]     at java.base/java.util.ServiceLoader$3.next(ServiceLoader.java:1389)
      [xjc]     at com.sun.tools.xjc.Options.findServices(Options.java:1009)
      [xjc]     at com.sun.tools.xjc.Options.getAllPlugins(Options.java:385)
      [xjc]     at com.sun.tools.xjc.Options.parseArgument(Options.java:724)
      [xjc]     at com.sun.tools.xjc.Options.parseArguments(Options.java:857)
      ....
      [xjc] Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/apache/tools/ant/AntClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of org/apache/tools/ant/loader/AntClassLoader5) for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature
      [xjc]     at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:306)
      [xjc]     at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:276)
      [xjc]     at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:156)
      [xjc]     at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:132)
      [xjc]     at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:274)
      [xjc]     at org.jvnet.jaxb2_commons.plugin.AbstractPlugin.<init>(AbstractPlugin.java:28)
      .....
    

    如果您已激活这些系统属性,但在日志中仍未看到有关加载插件的任何错误消息,最可能的原因是:

    • 插件库未正确添加到 XJC 类路径中;
    • 插件库无效,即没有为 META-INF\services\com.sun.tools.xjc.Plugin 资源提供插件类的 FQCN。

    内部 XJC

    XJC 有两种口味:

    • “独立”XJC 作为jaxb-xjc-&lt;version&gt;.jar 工件提供。在 中使用(以及其他)。
    • 与 JDK 一起打包的“内部”XJC。这是当您从命令行调用 xjc 时调用的内容。

    不幸的是,“内部”XJC 有一个大问题。

    当为 JDK 打包 XJC 时,所有 XJC 包都从 com.sun.tools.xjc.* 重命名为 com.sun.tools.internal.xjc.*。我想这背后有一些非技术原因,但我不会推测。

    com.sun.tools.xjc.* 包被重命名为 com.sun.tools.internal.xjc.* 时,这从根本上破坏了为“独立”XJC 开发的插件的兼容性:

    • 为“独立”XJC 开发的 XJC 插件必须扩展 com.sun.tools.xjc.Plugin。 “内部”XJC 期望插件类扩展 com.sun.tools.internal.xjc.Plugin
    • 对于“独立”的 XJC 插件,必须在 META-INF\services\com.sun.tools.xjc.Plugin 中列出。对于META-INF\services\com.sun.tools.internal.xjc.Plugin中的“内部”XJC。

    (这也是您应该同时打开com.sun.tools.xjc.Options.findServices=truecom.sun.tools.internal.xjc.Options.findServices=true 来调试插件加载的原因。)

    基本上,为“独立”XJC 开发的插件与“内部”XJC 不兼容,反之亦然。

    据我所知,大多数 XJC 插件都是为“独立”XJC 开发的。

    XJC 2.3 和 pre-2.3 的兼容性

    另一个问题是XJC版本之间存在不兼容的变化。

    因此,在 XJC 2.3 中,类 Aspect 从包 com.sun.tools.xjc.model 移动到包 com.sun.tools.xjc.outline。这意味着在 2.3 之前的 XJC 版本中使用 com.sun.tools.xjc.model.Aspect 的插件将不适用于 2.3。可能还有其他例子。

    这意味着 XJC 插件可能与您使用的 XJC 版本不兼容。

    【讨论】:

      【解决方案2】:

      需要在插件内部添加依赖。 比如下图,

      <plugin>
                          <groupId>org.codehaus.mojo</groupId>
                          <artifactId>jaxb2-maven-plugin</artifactId>
                          <version>1.5</version>
                          <dependencies>
                          <dependency>
                              <groupId>org.andromda.thirdparty.jaxb2_commons</groupId>
                              <artifactId>collection-setter-injector</artifactId>
                              <version>1.0</version>
                          </dependency>
                          </dependencies>
                          <configuration>
                              <schemaDirectory>${project.basedir}/epc</schemaDirectory>
                              <arguments>-Xcollection-setter-injector</arguments>
                              <clearOutputDir>false</clearOutputDir>
                              <extension>true</extension>
                          </configuration>
                          <executions>
                              <execution>
                                  <id>generate-java-from-xsd-1</id>
                                  <phase>generate-sources</phase>
                                  <goals>
                                      <goal>xjc</goal>
                                  </goals>
                                  <configuration>
                                      <packageName>${package name}</packageName>
                                      <schemaFiles>example.xsd</schemaFiles>
                                      <schemaDirectory>${project.basedir}/epc</schemaDirectory>
                                      <bindingFiles>example_1.xjb</bindingFiles>
                                      <bindingDirectory>${project.basedir}/generate</bindingDirectory>
                                      <staleFile>${project.build.directory}/jaxb2/.xjc1StaleFlag</staleFile>
                                  </configuration>
                              </execution>
                    </plugin>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-21
        • 1970-01-01
        • 2013-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-26
        相关资源
        最近更新 更多