Java 如何告诉 jaxb/Maven 生成多个模式包?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2857081/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I tell jaxb / Maven to generate multiple schema packages?
提问by M.R.
Example:
例子:
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/resources/dir1</schemaDirectory>
<schemaIncludes>
<include>schema1.xsd</include>
</schemaIncludes>
<generatePackage>schema1.package</generatePackage>
</configuration>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/resources/dir2</schemaDirectory>
<schemaIncludes>
<include>schema2.xsd</include>
</schemaIncludes>
<generatePackage>schema2.package</generatePackage>
</configuration>
</plugin>
</plugins>
What happened: Maven executes the the first plugin. Then deletes the target folder and creates the second package, which then is visible.
发生了什么:Maven 执行第一个插件。然后删除目标文件夹并创建第二个包,然后可见。
I tried to set target/somedir1 for the first configuration and target/somedir2 for the second configuration. But the behavior does not not change? Any ideas? I do not want to generate the packages directly in the src/main/java folder, because these packages are genereated and should not be mixed with manual created classes.
我尝试为第一个配置设置 target/somedir1,为第二个配置设置 target/somedir2。但行为不会改变?有任何想法吗?我不想直接在 src/main/java 文件夹中生成包,因为这些包是生成的,不应该与手动创建的类混合。
采纳答案by Pascal Thivent
I had to specify different generateDirectory
(without this, the plugin was considering that files were up to date and wasn't generating anything during the second execution). And I recommend to follow the target/generated-sources/<tool>
convention for generated sources so that they will be imported in your favorite IDE automatically. I also recommend to declare several execution
instead of declaring the plugin twice (and to move the configuration
inside each execution
element):
我必须指定不同的generateDirectory
(没有这个,插件会考虑文件是最新的并且在第二次执行期间没有生成任何东西)。我建议遵循target/generated-sources/<tool>
生成源的约定,以便它们将自动导入到您喜欢的 IDE 中。我还建议声明几个execution
而不是两次声明插件(并移动configuration
每个execution
元素的内部):
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.1</version>
<executions>
<execution>
<id>schema1-generate</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/dir1</schemaDirectory>
<schemaIncludes>
<include>shiporder.xsd</include>
</schemaIncludes>
<generatePackage>com.stackoverflow.package1</generatePackage>
<generateDirectory>${project.build.directory}/generated-sources/xjc1</generateDirectory>
</configuration>
</execution>
<execution>
<id>schema2-generate</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/dir2</schemaDirectory>
<schemaIncludes>
<include>books.xsd</include>
</schemaIncludes>
<generatePackage>com.stackoverflow.package2</generatePackage>
<generateDirectory>${project.build.directory}/generated-sources/xjc2</generateDirectory>
</configuration>
</execution>
</executions>
</plugin>
With this setup, I get the following result after a mvn clean compile
使用此设置,我得到以下结果 mvn clean compile
$ tree target/ target/ ├── classes │?? ├── com │?? │?? └── stackoverflow │?? │?? ├── App.class │?? │?? ├── package1 │?? │?? │?? ├── ObjectFactory.class │?? │?? │?? ├── Shiporder.class │?? │?? │?? ├── Shiporder$Item.class │?? │?? │?? └── Shiporder$Shipto.class │?? │?? └── package2 │?? │?? ├── BookForm.class │?? │?? ├── BooksForm.class │?? │?? ├── ObjectFactory.class │?? │?? └── package-info.class │?? ├── dir1 │?? │?? └── shiporder.xsd │?? └── dir2 │?? └── books.xsd └── generated-sources ├── xjc │?? └── META-INF │?? └── sun-jaxb.episode ├── xjc1 │?? └── com │?? └── stackoverflow │?? └── package1 │?? ├── ObjectFactory.java │?? └── Shiporder.java └── xjc2 └── com └── stackoverflow └── package2 ├── BookForm.java ├── BooksForm.java ├── ObjectFactory.java └── package-info.java
Which seems to be the expected result.
这似乎是预期的结果。
回答by khmarbaise
you should change that to define the plugin only once and do twice execution areas...like the following...and the generateDirectory should be set (based on the docs)..
您应该将其更改为仅定义一次插件并执行两次执行区域......如下所示......并且应该设置 generateDirectory (基于文档)。
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.1</version>
<executions>
<execution>
<id>firstrun</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generateDirectory>target/gen1</generateDirectory>
<schemaDirectory>src/main/resources/dir1</schemaDirectory>
<schemaIncludes>
<include>schema1.xsd</include>
</schemaIncludes>
<generatePackage>schema1.package</generatePackage>
</configuration>
</execution>
<execution>
<id>secondrun</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generateDirectory>target/gen2</generateDirectory>
<schemaDirectory>src/main/resources/dir2</schemaDirectory>
<schemaIncludes>
<include>schema2.xsd</include>
</schemaIncludes>
<generatePackage>schema2.package</generatePackage>
</configuration>
</execution>
</executions>
</plugin>
It seemed to me that you are fighting against single artifact rule of maven...may be you should think about this.
在我看来,您正在与 maven 的单一神器规则作斗争……也许您应该考虑一下。
回答by Davide Consonni
i have solved with:
我已经解决了:
<removeOldOutput>false</removeOldOutput>
<clearOutputDir>false</clearOutputDir>
<forceRegenerate>true</forceRegenerate>
add this to each configuration ;)
将此添加到每个配置中;)
回答by xmedeko
You can use also JAXB bindings to specify different package for each schema, e.g.
您还可以使用 JAXB 绑定为每个模式指定不同的包,例如
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0" schemaLocation="book.xsd">
<jaxb:globalBindings>
<xjc:serializable uid="1" />
</jaxb:globalBindings>
<jaxb:schemaBindings>
<jaxb:package name="com.stackoverflow.book" />
</jaxb:schemaBindings>
</jaxb:bindings>
Then just use the new maven-jaxb2-plugin 0.8.0 <schemas>
and <bindings>
elements in the pom.xml
. Or specify the top most directory in <schemaDirectory>
and <bindingDirectory>
and by <include>
your schemas and bindings:
然后,只需使用新的maven-JAXB2-0.8.0插件<schemas>
和<bindings>
中的元素pom.xml
。或在指定上最目录<schemaDirectory>
,并<bindingDirectory>
和<include>
你的架构和绑定:
<schemaDirectory>src/main/resources/xsd</schemaDirectory>
<schemaIncludes>
<include>book/*.xsd</include>
<include>person/*.xsd</include>
</schemaIncludes>
<bindingDirectory>src/main/resources</bindingDirectory>
<bindingIncludes>
<include>book/*.xjb</include>
<include>person/*.xjb</include>
</bindingIncludes>
I think this is more convenient solution, because when you add a new XSD you do not need to change Maven pom.xml
, just add a new XJB binding file to the same directory.
我认为这是更方便的解决方案,因为当您添加新的 XSD 时,您不需要更改 Maven pom.xml
,只需将新的 XJB 绑定文件添加到同一目录即可。
回答by Prashant C Chaturvedi
This can also be achieved by specifying stale file name for schemas and not clearing output directory. The default out put directory is automatically included in classpath which is little convenient. If we specify different output directory one has to take care of classpath to use this code in IDE. For example -
这也可以通过为模式指定陈旧文件名而不清除输出目录来实现。默认输出目录自动包含在类路径中,这不太方便。如果我们指定不同的输出目录,则必须注意类路径才能在 IDE 中使用此代码。例如 -
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.3.1</version>
<configuration>
<quiet>true</quiet>
<verbose>false</verbose>
<clearOutputDir>false</clearOutputDir>
<readOnly>true</readOnly>
<arguments>-mark-generated</arguments>
</configuration>
<executions>
<execution>
<id>reportingSchema</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/schema/r17/schemaReporting</schemaDirectory>
<schemaIncludes>
<include>OCISchemaReporting.xsd</include>
</schemaIncludes>
<packageName>com.broadsoft.oci.r17.reporting</packageName>
<staleFile>${build.directory}/generated-sources/.jaxb-staleFlag-reporting</staleFile>
</configuration>
</execution>
<execution>
<id>schemaAS</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/schema/r17/schemaAS</schemaDirectory>
<schemaIncludes>
<include>OCISchemaAS.xsd</include>
</schemaIncludes>
<packageName>com.broadsoft.oci.r17.as</packageName>
<staleFile>${build.directory}/generated-sources/.jaxb-staleFlag-as</staleFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
回答by eugen-fried
There is another, a clear one (IMO) solution to this There is a parameter called "staleFile"that uses as a flag to not generate stuff again. Simply alter it in each execution.
还有另一个,一个明确的(IMO)解决方案有一个名为“staleFile”的参数,它用作不再生成东西的标志。只需在每次执行时更改它。
回答by Chris Hinshaw
This is fixed in version 1.6 of the plugin.
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.6</version>
Quick note though, I noticed that the first iteration output was being deleted. I fixed it by adding the following to each of the executions.
不过请注意,我注意到第一个迭代输出被删除了。我通过在每个执行中添加以下内容来修复它。
<removeOldOutput>false</removeOldOutput>
<clearOutputDir>false</clearOutputDir>
Here is my full working example with each iteration outputting correctly. BTW I had to do this due to a duplicate namespace problem with the xsd's I was given. This seems to resolve my problem.
这是我的完整工作示例,每次迭代都正确输出。顺便说一句,由于给定的 xsd 存在重复的命名空间问题,我不得不这样做。这似乎解决了我的问题。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>submitOrderRequest</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<extension>true</extension>
<schemaDirectory>src/main/resources/xsd/</schemaDirectory>
<!-- <schemaFiles>getOrderStatusResponse.xsd,quoteShippingRequest.xsd,quoteShippingResponse.xsd,submitOrderRequest.xsd,submitOrderResponse.xsd</schemaFiles> -->
<schemaFiles>submitOrderRequest.xsd</schemaFiles>
<bindingDirectory>${project.basedir}/src/main/resources/xjb</bindingDirectory>
<bindingFiles>submitOrderRequest.xjb</bindingFiles>
<removeOldOutput>false</removeOldOutput>
<clearOutputDir>false</clearOutputDir>
</configuration>
</execution>
<execution>
<id>submitOrderResponse</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<extension>true</extension>
<schemaDirectory>src/main/resources/xsd/</schemaDirectory>
<!-- <schemaFiles>getOrderStatusResponse.xsd,quoteShippingRequest.xsd,quoteShippingResponse.xsd,submitOrderRequest.xsd,submitOrderResponse.xsd</schemaFiles> -->
<schemaFiles>submitOrderResponse.xsd</schemaFiles>
<bindingDirectory>${project.basedir}/src/main/resources/xjb</bindingDirectory>
<bindingFiles>submitOrderResponse.xjb</bindingFiles>
<removeOldOutput>false</removeOldOutput>
<clearOutputDir>false</clearOutputDir>
</configuration>
</execution>
</executions>
</plugin>
回答by Brian teggart
The following works for me, after much trial
经过多次试验,以下对我有用
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>xjc1</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<packageName>com.mycompany.clientSummary</packageName>
<sourceType>wsdl</sourceType>
<sources>
<source>src/main/resources/wsdl/GetClientSummary.wsdl</source>
</sources>
<outputDirectory>target/generated-sources/xjb</outputDirectory>
<clearOutputDir>false</clearOutputDir>
</configuration>
</execution>
<execution>
<id>xjc2</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<packageName>com.mycompany.wsclient.employerProfile</packageName>
<sourceType>wsdl</sourceType>
<sources>
<source>src/main/resources/wsdl/GetEmployerProfile.wsdl</source>
</sources>
<outputDirectory>target/generated-sources/xjb</outputDirectory>
<clearOutputDir>false</clearOutputDir>
</configuration>
</execution>
<execution>
<id>xjc3</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<packageName>com.mycompany.wsclient.producersLicenseData</packageName>
<sourceType>wsdl</sourceType>
<sources>
<source>src/main/resources/wsdl/GetProducersLicenseData.wsdl</source>
</sources>
<outputDirectory>target/generated-sources/xjb</outputDirectory>
<clearOutputDir>false</clearOutputDir>
</configuration>
</execution>
</executions>
</plugin>
回答by Glenn Van Schil
I encountered a lot of problems when using jaxb in Maven but i managed to solve your problem by doing the following
我在 Maven 中使用 jaxb 时遇到了很多问题,但我通过执行以下操作设法解决了您的问题
First create a schema.xjc file
首先创建一个schema.xjc文件
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
jaxb:version="2.0">
<jaxb:bindings schemaLocation="YOUR_URL?wsdl#types?schema1">
<jaxb:schemaBindings>
<jaxb:package name="your.package.name.schema1"/>
</jaxb:schemaBindings>
</jaxb:bindings>
<jaxb:bindings schemaLocation="YOUR_URL??wsdl#types?schema2">
<jaxb:schemaBindings>
<jaxb:package name="your.package.name.schema2"/>
</jaxb:schemaBindings>
</jaxb:bindings>
</jaxb:bindings>
The package name can be anything you want it to be, as long as it doesn't contain any reserved keywords in Java
包名可以是任何你想要的名字,只要它不包含任何 Java 中的保留关键字
Next you have to create the wsimport.bat script to generate your packaged and code at the preferred location.
接下来,您必须创建 wsimport.bat 脚本以在首选位置生成打包好的代码。
cd C:\YOUR\PATH\TO\PLACE\THE\PACKAGES
wsimport -keep -verbose -b "C:\YOUR\PATH\TO\schema.xjb" YOUR_URL?wsdl
pause
If you do not want to use cd, you can put the wsimport.bat in "C:\YOUR\PATH\TO\PLACE\THE\PACKAGES"
如果不想用cd,可以把wsimport.bat放在"C:\YOUR\PATH\TO\PLACE\THE\PACKAGES"
If you run it without -keep -verbose it will only generate the packages but not the .java files.
如果你在没有 -keep -verbose 的情况下运行它,它只会生成包而不是 .java 文件。
The -b will make sure the schema.xjc is used when generating
-b 将确保在生成时使用 schema.xjc