Jak mogę powiedzieć jaxb / Maven, aby generował wiele pakietów schematu?

80

Przykład:

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

Co się stało: Maven wykonuje pierwszą wtyczkę. Następnie usuwa folder docelowy i tworzy drugi pakiet, który jest wtedy widoczny.

Próbowałem ustawić target / somedir1 dla pierwszej konfiguracji i target / somedir2 dla drugiej konfiguracji. Ale zachowanie się nie zmienia? Jakieś pomysły? Nie chcę generować pakietów bezpośrednio w folderze src / main / java, ponieważ te pakiety są generowane i nie powinny być mieszane z klasami tworzonymi ręcznie.

PAN
źródło
tak, mam ten sam problem, chociaż rozwiązanie Pascala działa prawie idealnie. Wszystko, czego teraz potrzebuję, to sprawić, by IDE dobrze grało z wygenerowanym kodem, w przeciwnym razie właśnie tego chciałem.
Newtopian

Odpowiedzi:

119

Musiałem określić inne generateDirectory(bez tego wtyczka brała pod uwagę, że pliki były aktualne i nie generowały niczego podczas drugiego uruchomienia). I zalecam przestrzeganie target/generated-sources/<tool>konwencji dla wygenerowanych źródeł, aby zostały automatycznie zaimportowane do Twojego ulubionego IDE. Polecam również zadeklarować kilka executionzamiast deklarować wtyczkę dwukrotnie (i przesunąć configurationwewnątrz każdego executionelementu):

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

W tej konfiguracji otrzymuję następujący wynik po pliku mvn clean compile

$ drzewo docelowe /
cel/
├── zajęcia
│ ├── com
│ │ └── stackoverflow
│ │ ├── Klasa aplikacji
│ │ ├── pakiet 1
│ │ │ ├── ObjectFactory.class
│ │ │ ├── Shiporder.class
│ │ │ ├── Zamówienie wysyłkowe $ Item.class
│ │ │ └── Zamówienie wysyłkowe $ Shipto.class
│ │ └── pakiet 2
│ │ ├── BookForm.class
│ │ ├── BooksForm.class
│ │ ├── ObjectFactory.class
│ │ └── pakiet-info.class
│ ├── dir1
│ │ └── shiporder.xsd
│ └── dir2
│ └── books.xsd
└── wygenerowane-źródła
    ├── xjc
    │ └── META-INF
    │ └── sun-jaxb.episode
    ├── xjc1
    │ └── com
    │ └── stackoverflow
    │ └── pakiet 1
    │ ├── ObjectFactory.java
    │ └── Shiporder.java
    └── xjc2
        └── com
            └── stackoverflow
                └── pakiet 2
                    ├── BookForm.java
                    ├── BooksForm.java
                    ├── ObjectFactory.java
                    └── package-info.java

Co wydaje się być oczekiwanym wynikiem.

Pascal Thivent
źródło
dzięki, właściwie miałem wczoraj ten sam problem, ale chwilowo go opuściłem. Twoje rozwiązanie działa prawie idealnie, moim jedynym problemem jest to, że nie mogę skompilować Eclipse bez błędów. Jednak wszystko jest dobre w linii poleceń. Moje obecne obejście polega na tym, że deklaruję te foldery w miejscu docelowym jako foldery źródłowe i wszystko jest w porządku .. chociaż nie jestem pewien, czy bardzo mi się to podoba, wolałbym utworzyć słoik z wygenerowanym kodem i po prostu użyć go bezpośrednio
Newtopian
1
Wtyczka eclipse m2eclipse aktualizuje ścieżkę budowania. Po wygenerowaniu fasoli za pomocą mvc clean assembly: assembler po prostu uruchamiam [kliknij prawym przyciskiem myszy projekt]> [Maven]> [Update Project Configuration] i aktualizuję ścieżkę budowania.
MR
@Newtopian Patrz komentarz @ MR, m2eclipse zrobi to za Ciebie, jeśli będziesz przestrzegać konwencji, o której wspomniałem.
Pascal Thivent
hmm ok wtedy okazuje się, że robię to samo co ręcznie, tyle że teraz wystarczy jedno lub dwa kliknięcia. Wciąż dziwnie widzieć cel w folderach źródłowych, ale teraz jest to prawie darmowe, więc go zatrzymam :-)
Newtopian
1
Wiem, że to stare pytanie, ale mam nadzieję, że coś mi odpowie. Używam tego kodu i działa. Ale kiedy chcę skonfigurować ten sam pakiet, zawsze generuje tylko jeden schemat. Na przykład w pierwszym wykonaniu ustawiam com.myproject.answer, aw drugim com.myproject.request .. a po wygenerowaniu źródła mam już tylko * pakiet odpowiedzi i brakuje żądania ... jakikolwiek pomysł jak to naprawić? Generuj katalog ustawiam też tak samo.
Denis Stephanov
14

Możesz również użyć powiązań JAXB, aby określić inny pakiet dla każdego schematu, np

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

Następnie wystarczy użyć nowej wtyczki maven-jaxb2-plugin 0.8.0 <schemas>i <bindings>elementów w pom.xml. Lub określić górną najwięcej katalogu w <schemaDirectory>i <bindingDirectory>a przez <include>swoich schematów i wiązań:

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

Myślę, że jest to wygodniejsze rozwiązanie , ponieważ dodając nowy XSD nie trzeba zmieniać Mavena pom.xml, wystarczy dodać nowy plik wiązania XJB do tego samego katalogu.

xmedeko
źródło
Chociaż jest to banalne, zmiana wprowadzająca wskazówkę dotyczącą podświetlenia składni poprawia czytelność postu
Kev
OK, dziękuję za wyjaśnienie. Nie rozumiem, że edycja dodała podświetlanie składni.
xmedeko
2
To najlepsza odpowiedź dla mnie, ponieważ nie chciałbym zmieniać pom za każdym razem, gdy dodawany jest nowy schemat.
Ben Thurley
Jedynym problemem jest to, czy książka i osoba znajdują się w tej samej docelowej przestrzeni nazw w xsd. Powiedzmy, że zamiast tego mieli książkę, czasopismo, gazetę itp., Z których wszystkie zawierały publikowalny.xsd. Musiałyby znajdować się w tej samej przestrzeni nazw, w której można je opublikować, a tym samym siebie nawzajem, a teraz to się psuje, ponieważ możesz mieć tylko jedno schemaBindings na przestrzeń nazw. Zgadzam się, że jest idealny i chciałbym, aby działał w powyższym przykładzie, ale JAXB po prostu nie jest wystarczająco elastyczny.
TurnipEntropy
8

powinieneś to zmienić, aby zdefiniować wtyczkę tylko raz i zrobić dwa razy obszary wykonywania ... takie jak poniżej ... i należy ustawić geneDirectory (na podstawie dokumentacji).

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

Wydawało mi się, że walczysz z zasadą jednego artefaktu mavena ... może powinieneś o tym pomyśleć.

khmarbaise
źródło
Zasada jednego artefaktu na moduł jest prawdziwa, ale ... OP nie generuje dwóch artefaktów.
Pascal Thivent
5

Można to również osiągnąć, określając przestarzałą nazwę pliku dla schematów i nie czyszcząc katalogu wyjściowego. Domyślny katalog wyjściowy jest automatycznie dołączany do ścieżki klas, co jest mało wygodne. Jeśli określimy inny katalog wyjściowy, należy zadbać o ścieżkę klasy, aby użyć tego kodu w IDE. Na przykład -

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

Źródło: Generowanie kodu za pomocą wtyczki JAXB

Prashant C Chaturvedi
źródło
5

rozwiązałem z:

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

dodaj to do każdej konfiguracji;)

Davide Consonni
źródło
2
Możesz też dodać go tylko do <executions>tagu. To wystarczy. <removeOldOutput>ma domyślnie wartość false. Ale nie mogę znaleźć <clearOutputDir>na static.highsource.org/mjiip/maven-jaxb2-plugin/ ...
Dla mnie prawdziwe rozwiązanie, ponieważ możesz wygenerować wszystko w tym samym folderze
MilacH
<clearOutputDir>false</clearOutputDir>wystarczyło mi w moim przypadku.
Ruwanka Madhushan
3

Naprawiono to w wersji 1.6 wtyczki .

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

Szybka uwaga jednak, zauważyłem, że pierwsza iteracja została usunięta. Naprawiłem to, dodając następujące elementy do każdej z wykonań.

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

Oto mój pełny przykład roboczy z poprawnym wyjściem każdej iteracji. BTW, musiałem to zrobić z powodu problemu z podwójną przestrzenią nazw z xsd, które otrzymałem. Wydaje się, że to rozwiązuje mój problem.

        <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
źródło
2

Poniższe działa dla mnie po wielu próbach

<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
źródło
2

Napotkałem wiele problemów podczas używania jaxb w Maven, ale udało mi się rozwiązać twój problem, wykonując następujące czynności

Najpierw utwórz plik 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>

Nazwa pakietu może być dowolna, o ile nie zawiera żadnych zastrzeżonych słów kluczowych w Javie

Następnie musisz utworzyć skrypt wsimport.bat, aby wygenerować pakiet i kod w preferowanej lokalizacji.

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

Jeśli nie chcesz używać dysku CD, możesz umieścić wsimport.bat w „C: \ YOUR \ PATH \ TO \ PLACE \ THE \ PACKAGES”

Jeśli uruchomisz go bez -keep -verbose, wygeneruje tylko pakiety, ale nie pliki .java.

Opcja -b zapewni, że podczas generowania zostanie użyty schemat schema.xjc

Glenn Van Schil
źródło
0

Jest jeszcze jedno, jasne (IMO) rozwiązanie tego problemu. Jest parametr o nazwie „staleFile”, który używa jako flagi, aby nie generować ponownie rzeczy. Po prostu zmieniaj to w każdym wykonaniu.

smażony eugen
źródło