我该如何告诉jaxb/Maven生成多个模式包?

94

示例:

</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>

发生了什么: Maven 执行了第一个插件。然后删除目标文件夹并创建第二个包,随后可见。

我尝试为第一个配置设置 target/somedir1,为第二个配置设置 target/somedir2。但是行为没有改变?有什么想法吗?我不想直接在 src/main/java 文件夹中生成这些包,因为这些包是自动生成的,不应与手动创建的类混合在一起。


是的,在这里遇到了相同的问题,不过 Pascal 的解决方案几乎完美。现在我所需要的就是让 IDE 能够与生成的代码良好地配合,否则就是我想要的。 - Newtopian
9个回答

144

我不得不指定不同的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>

дҪҝз”ЁжӯӨи®ҫзҪ®еҗҺпјҢеңЁжү§иЎҢ 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

иҝҷдјјд№ҺжҳҜйў„жңҹзҡ„з»“жһңгҖӮ


2
Eclipse插件m2eclipse确实会更新构建路径。在使用mvc clean assembly:assembly生成bean之后,我只需右键单击项目,然后选择[Maven] > [Update Project Configuration],它就会更新构建路径。 - M.R.
嗯,好的,那么事实证明要做的事情与我手动做的一样,只是现在只需要点击一两下。看到目标文件夹在源文件夹中仍然感觉有些奇怪,但现在几乎是免费的,所以我会保留它 :-) - Newtopian
必须为两个配置添加staleFile <staleFile>${project.build.directory}/jaxb2/.xjcStaleFlag_1</staleFile> - Rakesh
1
我知道这是一个老问题,但我希望有人能回答我。我使用了那段代码,它可以工作。但是当我想要设置相同的包时,它总是只生成一个模式。例如,在第一次执行中,我设置了com.myproject.answer,在第二次执行中设置了com.myproject.request...在源代码生成后,我只有*answer包,而request则丢失了...有什么办法可以解决吗?我也设置了相同的生成目录。 - Denis Stephanov
1
谢谢,我有同样的问题,这个方法对我非常有效 :) - MattWeiler
显示剩余5条评论

15

你也可以使用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>

那么只需使用新的 maven-jaxb2-plugin 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>

我认为这是更为方便的解决方案,因为当您添加新的XSD时,无需更改Mavenpom.xml,只需要将新的XJB绑定文件添加到同一目录即可。


虽然提供语法高亮提示的编辑看似微不足道,但确实提高了帖子的可读性。 - Kev
好的,谢谢解释。我没有注意到编辑添加了语法高亮。 - xmedeko
2
这对我来说是最好的答案,因为我不想每次添加新模式时都更改pom。 - Ben Thurley
这里唯一的问题是如果书籍和人在xsd中处于相同的目标命名空间中。假设他们有书籍、期刊、报纸等,所有这些都包括publishable.xsd。它们必须与publishable处于相同的命名空间中,因此彼此之间也是如此,现在这就会出现问题,因为每个命名空间只能有一个schemaBindings。我同意这是理想的,我希望它适用于上面的例子,但JAXB并不够灵活。 - TurnipEntropy

9

您应该将其更改为仅定义插件一次,并执行两个执行区域...如下所示...并且应设置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>

我觉得你在与Maven的单一构件规则作斗争……也许你应该考虑一下这个问题。


1
每个模块只有一个工件的规则确实存在,但是...... 该 OP 并没有生成两个工件。 - Pascal Thivent

5
这也可以通过为模式指定陈旧的文件名而不清除输出目录来实现。默认的输出目录自动包含在类路径中,这有点方便。如果我们指定了不同的输出目录,则必须注意类路径以在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>

来源:使用JAXB插件生成代码


5

我已经解决了以下问题:

                        <removeOldOutput>false</removeOldOutput>
                        <clearOutputDir>false</clearOutputDir>
                        <forceRegenerate>true</forceRegenerate>

将此内容添加到每个配置文件中 ;)


2
你也可以将它添加到<executions>标签中。这就足够了。<removeOldOutput>默认设置为false。但我在http://static.highsource.org/mjiip/maven-jaxb2-plugin/generate-mojo.html上找不到`<clearOutputDir>`。 - user321068
对我来说,真正的解决方案是因为你可以在同一个文件夹中生成所有内容。 - MilacH
在我的情况下,<clearOutputDir>false</clearOutputDir> 就足够了。 - Ruwanka De Silva

3
以下是我经过多次尝试后的做法,可以正常工作。
<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>

3
我在使用Maven的时候,使用jaxb遇到了很多问题,但是通过以下方式成功解决了这个问题: 首先,创建一个名为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>

软件包名称可以是任何你想要的名称,只要它不包含Java中的任何保留关键字。

接下来,您需要创建wsimport.bat脚本,在首选位置生成您的打包和代码。

cd C:\YOUR\PATH\TO\PLACE\THE\PACKAGES
wsimport -keep -verbose -b "C:\YOUR\PATH\TO\schema.xjb" YOUR_URL?wsdl
pause

如果您不想使用cd命令,可以将wsimport.bat放在“C:\ YOUR \ PATH \ TO \ PLACE \ THE \ PACKAGES”中。

如果您不加-keep -verbose运行它,它只会生成包,而不是.java文件。

-b参数将确保在生成时使用schema.xjc。


3

该问题在插件的1.6版本中已得到解决

            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <version>1.6</version>

需要注意的是,我发现第一次迭代的输出被删除了。我通过在每个执行中添加以下内容来修复它。

                        <removeOldOutput>false</removeOldOutput>
                        <clearOutputDir>false</clearOutputDir>

这里是我的完整工作示例,每次迭代都可以正确输出。顺便说一句,我不得不这样做是因为我收到的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>

0

对于这个问题,我认为还有另一个比较明显的解决方案。有一个名为"staleFile"的参数,可以用作标志以避免再次生成内容。只需在每次执行时进行修改即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接