XJC обнаруживает и создает экземпляры плагинов, используя механизм «service loader».Плагины 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
артефакт.Используется (среди прочих) в maven-jaxb2-plugin . - «Внутренний» XJC, поставляемый в комплекте с JDK.Это то, что вызывается при вызове
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
.Для «внутреннего» XJC в META-INF\services\com.sun.tools.internal.xjc.Plugin
.
(Это также причина, по которой вы должны включить как com.sun.tools.xjc.Options.findServices=true
, так и com.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
.Это означает, что плагины, которые использовали com.sun.tools.xjc.model.Aspect
в версиях XJC ранее 2.3, не будут работать с 2.3.Возможно, есть и другие примеры.
Это означает, что плагин XJC может быть просто несовместим с используемой версией XJC.