Ben*_*ema 4 java jaxb xjc maven maven-jaxb2-plugin
我有一个项目,在同一名称空间中都有一个架构A和B。两者都导入模式C,该模式C也使用相同的名称空间。如何重用A和B的JAXB类来分离包,同时将C生成的JAXB类重用到公共包?
我已经知道我可能应该使用情节,并将为模式C生成的情节用作绑定文件,以分别执行模式A和B。问题是我不知道如何引用此生成的情节文件。
这是一个例子:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.12.3</version>
<executions>
<execution>
<id>generate-sources-C</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generatePackage>com.mymodel.commons</generatePackage>
<generateDirectory>${project.build.directory}/generated-sources/xjc-commons</generateDirectory>
<schemas>
<schema><url>src/main/resources/xsd/mymodel/c.xsd</url></schema>
</schemas>
</configuration>
</execution>
<execution>
<id>generate-sources-A</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generatePackage>com.mymodel.a</generatePackage>
<schemas>
<schema><url>src/main/resources/xsd/mymodel/a.xsd</url></schema>
</schemas>
</configuration>
</execution>
<execution>
<id>generate-sources-B</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generatePackage>com.mymodel.b</generatePackage>
<schemas>
<schema><url>src/main/resources/xsd/mymodel/b.xsd</url></schema>
</schemas>
</configuration>
</execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)
这将导致在以下情况下创建情节文件:
target/generated-sources/xjc-commons/META-INF/sun-jaxb.episode
Run Code Online (Sandbox Code Playgroud)
我如何在A和B的执行中引用此情节/绑定文件?使用情节仅提及如何从其他jar依赖项引用情节文件(或者我只是不太正确地理解它,这很有可能)。
我看到一个较旧的答案建议将其作为参数传递-b
给XJC,但这似乎对我没有任何帮助。我仍然最终从C生成了三次相同的类。
免责声明:我是maven-jaxb2-plugin的作者。
TL; DR这是一个测试项目,演示了如何执行此操作。
这是可能的,但是有点毛,所以请多多包涵。
如果a.xsd
,b.xsd
并c.xsd
在同一个命名空间,a.xsd
并且b.xsd
不能导入 c.xsd
,也只能包括它。我们希望将每个XSD生成到自己的包中,例如test.a
,test.b
并test.c
在同一个Maven项目中进行。
为此,我们需要对进行三个单独的执行maven-jaxb2-plugin
,每个执行均配置有自己的架构和目标包。例如:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<id>xjc-a</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generatePackage>test.a</generatePackage>
<generateDirectory>${project.build.directory}/xjc-a</generateDirectory>
<schemaIncludes>
<includes>a.xsd</includes>
</schemaIncludes>
</configuration>
</execution>
<!-- xjc-b and xjc-c follow -->
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)
好的,这将创建具有三个目标软件包的三个目标目录。下一个问题是from c.xsd
中将生成类,test.a
并且test.b
我们希望避免此类。
为此,我们必须告诉XJC对from test.c
的类型使用from 类c.xsd
。这实际上是情节文件的用途。该文件通常在下生成,META-INF\sun-jaxb.episode
并且包含已处理模式中所有类型的绑定。这是为生成的示例c.xsd
:
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" if-exists="true" version="2.1">
<bindings xmlns:tns="urn:test" if-exists="true" scd="x-schema::tns">
<schemaBindings map="false">
<package name="test.c"/>
</schemaBindings>
<bindings if-exists="true" scd="~tns:CType">
<class ref="test.c.CType"/>
</bindings>
</bindings>
</bindings>
Run Code Online (Sandbox Code Playgroud)
情节文件实际上是一个普通的绑定文件。因此,您可以在编译中直接使用它:
<execution>
<id>xjc-a</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generatePackage>test.a</generatePackage>
<generateDirectory>${project.build.directory}/xjc-a</generateDirectory>
<schemaIncludes>
<includes>a.xsd</includes>
</schemaIncludes>
<bindings>
<binding>
<fileset>
<directory>${project.build.directory}/xjc-c/META-INF</directory>
<includes>
<include>sun-jaxb.episode</include>
</includes>
</fileset>
</binding>
</bindings>
</configuration>
</execution>
Run Code Online (Sandbox Code Playgroud)
剩下的只有一个小问题。XJC生成的情节文件也包含以下片段:
<schemaBindings map="false">
<!-- ... -->
</schemaBindings>
Run Code Online (Sandbox Code Playgroud)
它有效地说,“别不产生在给定的命名空间的架构代码”。如果a.xsd
或b.xsd
位于其他名称空间中,这将不是问题。但是,由于它们位于同一名称空间中,因此该片段将有效地关闭a.xsd
or的所有代码生成b.xsd
。
要解决此问题,我们可以对sun-jaxb.episode
为生成的进行后处理c.xsd
。这可以通过简单的XSLT完成:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="jaxb:schemaBindings"/>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
这XSLT应的代码后运行c.xsd
,但之前的代码a.xsd
和b.xsd
生成。这可以通过将这些执行几个不同的阶段来实现(generate-sources
,process-sources
,generate-resources
)。
下面是完整的pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>divide</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.2.11</version>
</dependency>
<!-- JUnit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<version>1.0.2</version>
<executions>
<execution>
<goals>
<goal>transform</goal>
</goals>
<phase>process-sources</phase>
</execution>
</executions>
<configuration>
<transformationSets>
<transformationSet>
<dir>${project.build.directory}/xjc-c/META-INF</dir>
<outputDir>${project.build.directory}/xjc-c/META-INF</outputDir>
<includes>
<include>sun-jaxb.episode</include>
</includes>
<stylesheet>src/main/xslt/removeJaxbSchemaBindings.xslt</stylesheet>
</transformationSet>
</transformationSets>
</configuration>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.13.3</version>
<executions>
<execution>
<id>xjc-c</id>
<goals>
<goal>generate</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<generatePackage>test.c</generatePackage>
<generateDirectory>${project.build.directory}/xjc-c</generateDirectory>
<schemaIncludes>
<includes>c.xsd</includes>
</schemaIncludes>
</configuration>
</execution>
<execution>
<id>xjc-a</id>
<goals>
<goal>generate</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<generatePackage>test.a</generatePackage>
<generateDirectory>${project.build.directory}/xjc-a</generateDirectory>
<schemaIncludes>
<includes>a.xsd</includes>
</schemaIncludes>
<bindings>
<binding>
<fileset>
<directory>${project.build.directory}/xjc-c/META-INF</directory>
<includes>
<include>sun-jaxb.episode</include>
</includes>
</fileset>
</binding>
</bindings>
</configuration>
</execution>
<execution>
<id>xjc-b</id>
<goals>
<goal>generate</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<generatePackage>test.b</generatePackage>
<generateDirectory>${project.build.directory}/xjc-b</generateDirectory>
<schemaIncludes>
<includes>b.xsd</includes>
</schemaIncludes>
<bindings>
<binding>
<fileset>
<directory>${project.build.directory}/xjc-c/META-INF</directory>
<includes>
<include>sun-jaxb.episode</include>
</includes>
</fileset>
</binding>
</bindings>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1191 次 |
最近记录: |