Wie kann ich jaxb / Maven anweisen, mehrere Schemapakete zu generieren?

80

Beispiel:

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

Was ist passiert: Maven führt das erste Plugin aus. Löscht dann den Zielordner und erstellt das zweite Paket, das dann sichtbar ist.

Ich habe versucht, target / somedir1 für die erste Konfiguration und target / somedir2 für die zweite Konfiguration festzulegen. Aber das Verhalten ändert sich nicht? Irgendwelche Ideen? Ich möchte die Pakete nicht direkt im Ordner src / main / java generieren, da diese Pakete generiert werden und nicht mit manuell erstellten Klassen gemischt werden sollten.

HERR
quelle
Ja, ich habe hier das gleiche Problem, obwohl Pascals Lösung nahezu perfekt funktioniert. Jetzt muss ich nur noch die IDE dazu bringen, mit dem generierten Code gut zu spielen, sonst ist es genau das, was ich wollte.
Newtopian

Antworten:

118

Ich musste anders angeben generateDirectory(ohne dies berücksichtigte das Plugin, dass die Dateien auf dem neuesten Stand waren und während der zweiten Ausführung nichts generierten). Ich empfehle, die target/generated-sources/<tool>Konvention für generierte Quellen zu befolgen , damit diese automatisch in Ihre bevorzugte IDE importiert werden. Ich empfehle auch, mehrere zu deklarieren, executionanstatt das Plugin zweimal zu deklarieren (und das configurationInnere jedes executionElements zu verschieben):

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

Mit diesem Setup erhalte ich nach a das folgende Ergebnis mvn clean compile

$ tree target /
Ziel/
├── Klassen
│ ├ com
│ │ └ Stapelüberlauf
│ │ ├ App.Klasse
│ │ ├ Paket1
F │ │ ├ ObjectFactory.class
Order │ │ ├ Shiporder.class
Order │ │ ├ Versandauftrag $ Item.class
Order │ │ └ Versandauftrag $ Shipto.class
│ │ └ Paket2
│ │ ├ BookForm.class
│ │ ├ BooksForm.class
│ │ ├ ObjectFactory.class
│ │ └ package-info.class
│ ├ dir1
│ │ └── shiporder.xsd
│ └ dir2
│ └ books.xsd
└── generierte Quellen
    ├── xjc
    │ └ META-INF
    │ └── sun-jaxb.episode
    ├── xjc1
    │ └ com
    │ └ Stapelüberlauf
    │ └ Paket1
    │ ├ ObjectFactory.java
    │ └ Shiporder.java
    └── xjc2
        └── com
            └── Stapelüberlauf
                └── Paket2
                    ├── BookForm.java
                    ├── BooksForm.java
                    ├── ObjectFactory.java
                    └── package-info.java

Welches scheint das erwartete Ergebnis zu sein.

Pascal Thivent
quelle
danke, ich hatte gestern tatsächlich das gleiche problem, gab es aber momentan auf. Ihre Lösung funktioniert fast perfekt. Mein einziges Problem ist jetzt, dass ich Eclipse nicht ohne Fehler zum Kompilieren bringen kann. In der Kommandozeile ist jedoch alles in Ordnung. Meine aktuelle Problemumgehung besteht darin, dass ich diese Ordner im Ziel als Quellordner deklariere und alles in Ordnung ist. Obwohl ich nicht sicher bin, ob es mir sehr gefällt, würde ich lieber ein Glas mit dem generierten Code erstellen und es direkt verwenden
Newtopian
1
Das Eclipse-Plugin m2eclipse aktualisiert den Build-Pfad. Nach dem Generieren der Beans mit mvc clean Assembly: Assembly führe ich einfach [Rechtsklick auf Projekt]> [Maven]> [Projektkonfiguration aktualisieren] aus und es aktualisiert den Erstellungspfad.
MR
@Newtopian Siehe @ MRs Kommentar, m2eclipse erledigt das für Sie, wenn Sie die von mir erwähnte Konvention befolgen.
Pascal Thivent
hmm ok dann stellt sich heraus, dass ich das gleiche mache, was ich manuell gemacht habe, nur dass es jetzt nur ein oder zwei Klicks dauert. Es ist immer noch seltsam, das Ziel in den Quellordnern zu sehen, aber jetzt ist es fast kostenlos, ich werde es behalten :-)
Newtopian
1
Ich weiß, dass es eine alte Frage ist, aber ich hoffe, dass mir etwas antwortet. Ich benutze diesen Code und es funktioniert. Wenn ich jedoch dasselbe Paket einrichten möchte, wird immer nur ein Schema generiert. Zum Beispiel setze ich in der ersten Ausführung com.myproject.answer und in der zweiten Ausführung com.myproject.request .. und nach der Generierung der Quelle habe ich nur * Antwortpaket und Anfrage fehlt ... eine Idee, wie man das behebt? Verzeichnis generieren habe ich auch gleich eingestellt.
Denis Stephanov
14

Sie können auch JAXB-Bindungen verwenden, um für jedes Schema ein anderes Paket anzugeben, z

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

Dann benutze einfach das neue maven-jaxb2-Plugin 0.8.0 <schemas>und <bindings>Elemente in der pom.xml. Oder geben Sie das oberste Verzeichnis in <schemaDirectory>und <bindingDirectory>und nach <include>Ihren Schemas und Bindungen an:

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

Ich denke, dies ist eine bequemere Lösung , denn wenn Sie eine neue XSD hinzufügen, müssen Sie Maven nicht ändern pom.xml, sondern fügen einfach eine neue XJB-Bindungsdatei zum selben Verzeichnis hinzu.

xmedeko
quelle
Die Bearbeitung zur Bereitstellung eines Hinweises zur Syntaxhervorhebung ist zwar trivial, verbessert jedoch die Lesbarkeit des Beitrags
Kev
OK, danke für die Erklärung. Ich habe nicht verstanden, dass die Bearbeitung Syntax Hervorhebung hinzugefügt.
Xmedeko
2
Dies ist die beste Antwort für mich, da ich den POM nicht jedes Mal ändern möchte, wenn ein neues Schema hinzugefügt wird.
Ben Thurley
Das einzige Problem hierbei ist, ob sich Buch und Person im xsd im selben Ziel-Namespace befinden. Nehmen wir stattdessen an, sie hatten ein Buch, ein Tagebuch, eine Zeitung usw., die alle publishable.xsd enthielten. Sie müssten sich im selben Namespace wie publizierbar und damit untereinander befinden, und dies bricht jetzt ab, da Sie nur ein SchemaBindings pro Namespace haben können. Ich bin damit einverstanden, dass es ideal ist, und ich wünschte, es würde für das obige Beispiel funktionieren, aber JAXB ist einfach nicht flexibel genug.
TurnipEntropy
8

Sie sollten dies ändern, um das Plugin nur einmal zu definieren und zweimal Ausführungsbereiche auszuführen ... wie im Folgenden ... und das generateDirectory sollte festgelegt werden (basierend auf den Dokumenten).

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

Es schien mir, dass Sie gegen die Regel eines einzelnen Artefakts von Maven kämpfen ... Vielleicht sollten Sie darüber nachdenken.

khmarbaise
quelle
Die Regel für ein Artefakt pro Modul ist wahr, aber ... das OP generiert keine zwei Artefakte.
Pascal Thivent
5

Dies kann auch erreicht werden, indem ein veralteter Dateiname für Schemas angegeben und das Ausgabeverzeichnis nicht gelöscht wird. Das Standardausgabeverzeichnis wird automatisch in den Klassenpfad aufgenommen, was wenig praktisch ist. Wenn wir ein anderes Ausgabeverzeichnis angeben, muss man sich um den Klassenpfad kümmern, um diesen Code in der IDE zu verwenden. Zum Beispiel -

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

Quelle: Generieren von Code mit dem JAXB-Plugin

Prashant C Chaturvedi
quelle
5

Ich habe gelöst mit:

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

füge dies jeder Konfiguration hinzu;)

Davide Consonni
quelle
2
Sie können es auch nur zum <executions>Tag hinzufügen . Das reicht aus. <removeOldOutput>ist standardmäßig auf false gesetzt. Aber ich kann nicht <clearOutputDir>bei static.highsource.org/mjiip/maven-jaxb2-plugin/…
Für mich die wirkliche Lösung, weil Sie alles in demselben Ordner generieren können
MilacH
<clearOutputDir>false</clearOutputDir>war genug für mich in meinem Fall.
Ruwanka Madhushan
3

Dies ist in Version 1.6 des Plugins behoben .

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

Kurzer Hinweis: Ich bemerkte, dass die erste Iterationsausgabe gelöscht wurde. Ich habe es behoben, indem ich jeder der Ausführungen Folgendes hinzugefügt habe.

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

Hier ist mein vollständiges Arbeitsbeispiel, bei dem jede Iteration korrekt ausgegeben wird. Übrigens musste ich dies aufgrund eines doppelten Namespace-Problems mit den XSDs tun, die mir gegeben wurden. Dies scheint mein Problem zu lösen.

        <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>
Chris Hinshaw
quelle
2

Das Folgende funktioniert für mich nach langem Ausprobieren

<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>
Brian Teggart
quelle
2

Bei der Verwendung von jaxb in Maven sind viele Probleme aufgetreten, aber ich habe es geschafft, Ihr Problem folgendermaßen zu lösen

Erstellen Sie zuerst eine schema.xjc-Datei

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

Der Paketname kann beliebig sein, solange er in Java keine reservierten Schlüsselwörter enthält

Als nächstes müssen Sie das Skript wsimport.bat erstellen, um Ihr Paket und Ihren Code am bevorzugten Speicherort zu generieren.

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

Wenn Sie keine CD verwenden möchten, können Sie die Datei wsimport.bat in "C: \ IHR \ PFAD \ TO \ PLACE \ THE \ PACKAGES" einfügen.

Wenn Sie es ohne -keep -verbose ausführen, werden nur die Pakete generiert, nicht jedoch die Java-Dateien.

Das -b stellt sicher, dass beim Generieren die Datei schema.xjc verwendet wird

Glenn Van Schil
quelle
0

Es gibt eine andere, eindeutige (IMO) Lösung dafür. Es gibt einen Parameter namens "staleFile" , der als Flag verwendet, um keine Daten erneut zu generieren. Ändern Sie es einfach bei jeder Ausführung.

Eugen gebraten
quelle