I am compiling an XML Schema using JAXB/XJC and I want to use some XJC plugin to augment generated code.
I include plugin into the XJC classpath and activate it using -XsomePlugin
.
However I am getting an error like:
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
So apparently the plugin is not picked up by XJC or is not activated.
What could be the reason and how can I debug this error?
XJC discovers and instantiates plugins using a "service loader" mechanism. XJC plugins provide a resource
META-INF\services\com.sun.tools.xjc.Plugin
which lists FQCN of plugin classes.There may be different reasons why the plugin could not be loaded/instantiated.
Turning on logging of plugin loading errors
Unfortunately, XJC normally does not show which specific errors occured during instantiation of the plugin. You only get this
unrecognized parameter -XsomePlugin
message and that's it.Fortunately, there is a "debug" switch which can be activated using one of the following system properties:
com.sun.tools.xjc.Options.findServices=true
com.sun.tools.internal.xjc.Options.findServices=true
(I normally set both properties, I'll explain the reason below.)
This would make XJC log the actual error which occured during instantiation of the plugin, for instance:
If you've activated these system properties but still don't see any error message about loading your plugin in the logs, most probable reasons for this are:
META-INF\services\com.sun.tools.xjc.Plugin
resource with FQCNs of the plugin classes.Internal XJC
There are two flavours of XJC out there:
jaxb-xjc-<version>.jar
artifact. Used (among others) in maven-jaxb2-plugin.xjc
from the command line.Unfortunately there is a big problem with the "internal" XJC.
When XJC is packaged for the JDK, all XJC packages are renamed from
com.sun.tools.xjc.*
tocom.sun.tools.internal.xjc.*
. I guess there are some non-technical reasons behind this but I won't speculate.When
com.sun.tools.xjc.*
packages are renamed tocom.sun.tools.internal.xjc.*
, this essentially breaks compatibility of plugins developed for the "standalone" XJC:com.sun.tools.xjc.Plugin
. "Internal" XJC expects plugin classes to extendcom.sun.tools.internal.xjc.Plugin
.META-INF\services\com.sun.tools.xjc.Plugin
. For the "internal" XJC inMETA-INF\services\com.sun.tools.internal.xjc.Plugin
.(This is also the reason why you should turn on both
com.sun.tools.xjc.Options.findServices=true
as well ascom.sun.tools.internal.xjc.Options.findServices=true
to debug loading of the plugins.)Basically, plugins developed for the "standalone" XJC are not compatible to the "internal" XJC and vice versa.
To the best of my knowledge, most of the XJC plugins are developed for the "standalone" XJC.
Compatibility of XJC versions 2.3 and pre-2.3
Another problem is that there are incompatible changes between XJC versions.
Thus in XJC 2.3 the class
Aspect
was moved from the packagecom.sun.tools.xjc.model
to the packagecom.sun.tools.xjc.outline
. This means that plugins which used thecom.sun.tools.xjc.model.Aspect
in XJC versions earlier than 2.3 won't work with 2.3. There are probably other examples as well.This means that an XJC plugin may simply be not compatible to the XJC version you use.