java - 使用 JAXB/XJC 插件时出现无法识别的参数 -XsomePlugin 错误

标签 java jaxb xjc maven-jaxb2-plugin

我正在使用 JAXB/XJC 编译 XML 架构,并且我想使用一些 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 没有选择该插件或未激活该插件。

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

最佳答案

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-<version>.jar人工制品。使用(除其他外)于 .
  • 与 JDK 一起打包的“内部”XJC。这是当您调用 xjc 时调用的内容从命令行。

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

当 XJC 为 JDK 打包时,所有 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 版本和 2.3 之前版本的兼容性

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

因此在XJC 2.3中类Aspect已从包中移出 com.sun.tools.xjc.model到包裹com.sun.tools.xjc.outline 。这意味着使用 com.sun.tools.xjc.model.Aspect 的插件在 2.3 之前的 XJC 版本中,不能与 2.3 一起使用。可能还有其他示例。

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

关于java - 使用 JAXB/XJC 插件时出现无法识别的参数 -XsomePlugin 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50669567/

相关文章:

java - 通过命令行选择 FindBugs 插件

java - 从没有时区的字符串到欧洲/柏林的时间

java - 在gradle中或通过xjc下载复杂的架构/wsdl

jaxb - 如何从 WSDL 生成 *.xjb 文件?

java - Cassandra ;关于索引的最佳实践?

java - 将 Maven 项目迁移到模块 - 忽略 module-info.java

java - 如何将attributeGroup与JAXB绑定(bind)?

jaxb - 禁用 jaxb 1 编码器的验证

java - xjc 或 jaxb2-maven-plugin 或 maven : weird behavior while compiling XSDs, 处理文件两次但名称已更改?

java - 使用jaxb2-maven-plugin实现不同的接口(interface)