-
Notifications
You must be signed in to change notification settings - Fork 99
Using Episodes
Also known as Separate schema compilation.
If you're compiling large sets of schemas (like the OGC Schemas) you may probably want to compile the
schemas separately. For instance, if you have two schemas A
and B
(where B
imports A
), you may want to compile them
into two artifacts A.jar
and B.jar
such that :
- Classes relevant to
A
reside in theA.jar
artifact. - Classes relevant to
B
(and only those classes) reside in theB.jar
artifact. - The
A.jar
artifact is the dependency of theB.jar
artifact.
This task is called the separate or episodic compilation. Kohsuke described it in his blog [newlink] (webarchive link).
JAXB Maven plugin supports episodic compilation via the following configuration parameters :
-
episode
- Iftrue
, the episode file (describing mapping of elements and types to classes for the compiled schema) will be generated. -
episodeFile
- Target location of the episode file. By default it istarget/generated-sources/xjc/META-INF/sun-jaxb.episode
so that the episode file will appear asMETA-INF/sun-jaxb.episode
in the JAR - just as XJC wants it. -
addIfExistsToEpisodeSchemaBindings
- Iftrue
(default), addsif-exists="true"
attributes to thebindings
elements associated with schemas (viascd="x-schema::..."
) in the generated episode files. This is necessary to avoid the annoyingSCD "x-schema::tns" didn't match any schema component
errors. -
episodes/episode
- If you want to use existing artifacts as episodes for separate compilation, configure them asepisodes/episode
elements. It is assumed that episode artifacts contain an appropriateMETA-INF/sun-jaxb.episode
resource.-
groupId
- Group id of the episode artifact, required. -
artifactId
- Id of the episode artifact, required. -
version
- Version of the episode artifact. May be omitted. The plugin will then try to find the version using thedependencyManagement
anddependencies
of the project. -
type
- Type of the episode artifact, optional. Defaults tojar
. -
classifier
- Classifier of the episode artifact, optional. Defaults to none.
-
-
useDependenciesAsEpisodes
- Use all of the compile-scope project dependencies as episode artifacts. It is assumed that episode artifacts contain an appropriateMETA-INF/sun-jaxb.episode
resource. Default isfalse
.
For example, consider that we've built the A schema as com.acme.foo:a-schema:jar:1.0
artifact and want to use it as an episode when we compile the B schema. Here's how we configure it :
<project ...>
...
<dependencies>
...
<dependency>
<groupId>com.acme.foo</groupId>
<artifactId>a-schema</artifactId>
<version>1.0</version>
</dependency>
...
</dependencies>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb</groupId>
<artifactId>jaxb-maven-plugin</artifactId>
<configuration>
<extension>true</extension>
<useDependenciesAsEpisodes>true</useDependenciesAsEpisodes>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
Alternatively you can specify episode artifacts explicitly :
<project ...>
...
<dependencies>
...
<dependency>
<groupId>com.acme.foo</groupId>
<artifactId>a-schema</artifactId>
<version>1.0</version>
</dependency>
...
</dependencies>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb</groupId>
<artifactId>jaxb-maven-plugin</artifactId>
<configuration>
<extension>true</extension>
<episodes>
<episode>
<groupId>com.acme.foo</groupId>
<artifactId>a-schema</artifactId>
<!-- Version is not required if the artifact is configured as dependency -->
</episode>
</episodes>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
In this case JAXB will not generate classes for the imported A schema. The B.jar
artifact will only contain classes relevant to the B schema.
Note that JAXB still needs to access BOTH A and B schemas during the compilation. You may use catalogs to provide alternative locations of the imported schemas.
See the sample episode project for example.
Note that JAXB still needs to access BOTH A
and B
schemas during the compilation. And you probably don't want to manually copy or duplicate schemas.
One way to solve this is to use the maven-dependency-plugin
to unpack the required schema from schema-a.jar
.
A much better way is to use a catalog to resolve schema-a.xsd
into a resource inside the Maven artifact schema-a
:
REWRITE_SYSTEM "http://www.acme.com/foo/a/" "maven:com.acme.foo:a-schema!/"
<configuration>
<catalog>src/main/resources/catalog.cat</catalog>
<!-- ... -->
</configuration>
The import of http://www.acme.com/foo/a/a.xsd
will be then resolved to the a.xsd
resource inside the a-schema.jar
.
A combination of episodes, catalogs and referencing resources in Maven artifacts allows fully modular schema compilation. Please see the Modular Schema Compilation guide.
It is quite helpful to understand the mechanics of the episode files.
Episode is actually a JAR file which contains a META-INF/sun-jaxb.episode
resource.
This resource is nothing else but a bindings file, like those you'd use to customize
package or property names. Below is an example of the sun-jaxb.episode
for the XLink 1.0 Schema:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bindings version="2.1" xmlns="http://java.sun.com/xml/ns/jaxb">
<bindings scd="x-schema::tns" xmlns:tns="http://www.w3.org/1999/xlink">
<schemaBindings map="false">
<package name="org.hisrc.w3c.xlink.v_1_0"/>
</schemaBindings>
<bindings scd="~tns:arcType">
<class ref="org.hisrc.w3c.xlink.v_1_0.ArcType"/>
</bindings>
<bindings scd="~tns:resourceType">
<class ref="org.hisrc.w3c.xlink.v_1_0.ResourceType"/>
</bindings>
<!-- ... -->
<bindings scd="~tns:showType">
<typesafeEnumClass ref="org.hisrc.w3c.xlink.v_1_0.ShowType"/>
</bindings>
</bindings>
</bindings>
Note the following:
- The binding uses SCD (schema component designator) notation instead of the usual XPath to address schema components.
-
<bindings scd="x-schema::tns" xmlns:tns="http://www.w3.org/1999/xlink" .../>
addresses the schema with the target namespacehttp://www.w3.org/1999/xlink
. -
schemaBindings/@map="false"
instructs XJC to suppress generation of classes for this schema. -
class/@ref
binds schema components to existing classes.
In some cases, XJC still generates classes in packages which are actually suppressed by episodes. This is probably a bug in XJC.
You can use the delete
task from the maven-antrun-plugin
to remove these leftovers:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-sources</phase>
<configuration>
<tasks>
<delete dir="${basedir}/target/generated-sources/xjc/net/opengis/filter"/>
<delete dir="${basedir}/target/generated-sources/xjc/net/opengis/ows"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
If you compile several schemas at once and generate an episode file, it will contain bindings
for all of these schemas. You can recognize them by the x-schema::...
SCD-binding. For example, assume we've compiled two schemas with namespaces urn:a
and urn:b
.
<bindings xmlns:tns="urn:a" scd="x-schema::tns">
<!-- ... -->
</bindings>
<bindings xmlns:tns="urn:b" scd="x-schema::tns">
<!-- ... -->
</bindings>
If later on you'll have some schema urn:c
which depends on urn:a
(but not on urn:b
) and you'll want to use the generated episode, you'll an error like:
"SCD "x-schema::tns" didnt match any schema component"
The problem is that your episode file contains bindings for urn:b
but it is not used in your compilation. And, XJC is too strict in this case it produces an error which breaks the build.
It is possible to "soften" this behavour by adding if-exists="true"
attribute to the appropriate bindings
element. But the problem is that with episodes these elements are generated by the built-in XJC plugin, which does not generate if-exists="true"
.
To fix this, this plugin implements the addIfExistsToEpisodeSchemaBindings
feature. If it is turned on (by default), the plugin will transform the generated episode files adding the if-exists="true"
attribute to all the bindings
element having scd
which start with x-schema::
- i.e. bound to schemas using SCDs.
- Home
- Migration guide
-
JAXB Maven Plugin
- Quick Start
-
User Guide
- Basic Usage
- Specifying What To Compile
- Referencing Resources in Maven Artifacts
- Using Catalogs
- Using Episodes
- Modular Schema Compilation
- Controlling the Output
- Using JAXB Plugins
- Using a Specific JAXB Version
- Configuring Extension, Validation and XML Security
- IDE Integration
- Miscellaneous
- Configuring Proxies
- Maven Documentation
- Configuration Cheat Sheet
- Common Pitfalls and Problems
-
JAXB2 Basics Plugins
- Using JAXB2 Basics Plugins
- JSR-305 Support
-
JAXB2 Basics Plugins List
- SimpleEquals Plugin
- SimpleHashCode Plugin
- Equals Plugin
- HashCode Plugin
- ToString Plugin
- Copyable Plugin
- Mergeable Plugin
- Inheritance Plugin
- AutoInheritance Plugin
- Wildcard Plugin
- Setters Plugin
- Simplify Plugin
- EnumValue Plugin
- JAXBIndex Plugin
- FixJAXB1058 Plugin
- Commons Lang Plugin
- Default Value Plugin
- Fluent API Plugin
- Namespace Prefix Plugin
- Value Constructor Plugin
- Boolean Getter Plugin
- CamelCase Plugin
- XML ElementWrapper Plugin
- Parent Pointer Plugin
- Property Listener Injector Plugin
- Annox
- JAXB Annotate Plugin
-
HyperJAXB3
- Build System Support
- Customization Guide
- Databases
- Development guide
- Extension guide
- FAQ
- IDE Support
- Java Persistence
- JAXB
- JDK Support
- Project Templates
-
Reference
- Adding vendor-specific annotations
- Features
- Integrating Hyperjaxb3 in builds
- Introduction
- Making schema-derived classes ready for JPA
- Adding required properties
- Applying workarounds for JAXB vs. JPA conflicts
- Enforcing top-level classes
- Generating equals and hashCode methods
- Generating ORM metadata
- Generating persistence unit descriptor
- JPA 2 Support
- Making classes serializable
- Testing generated mappings
- Reference - single page
- Related Projects
- Sample projects
- Solutions
- Target Scenarios
- Test Projects
- Tutorials
- Best Practices
- FAQ
- Sample Projects
- Support
- License
- Distribution