Як я можу сказати jaxb / Maven генерувати кілька пакетів схем?


80

Приклад:

</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, оскільки ці пакети генеруються і не повинні змішуватися з класами, створеними вручну.


так, отримав ту саму проблему тут, хоча рішення Паскаля працює майже ідеально. Все, що мені зараз потрібно, - це змусити IDE добре грати з генерованим кодом, інакше саме те, що я хотів.
Ньютопіан,

Відповіді:


119

Мені довелося вказати інше 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

$ дерево цільової /
ціль /
├── заняття
│ ├── ком
│ │ └── потік стоків
│ │ ├── App.class
Package │ ├── пакет1
│ │ │ ├── ObjectFactory.class
│ │ │ ├── Шипордер.клас
│ │ │ ├── Шипордер $ Пункт. Клас
│ │ │ └── Shiporder $ Shipto.class
Package │ └── пакет2
│ │ ├── BookForm.class
│ │ ├── BooksForm.class
│ │ ├── ObjectFactory.class
│ │ └── package-info.class
│ ├── реж.1
│ │ └── shiporder.xsd
│ └── реж.2
│ └── книги.xsd
└── генеровані джерела
    ├── xjc
    │ └── МЕТА-ІНФ
    │ └── sun-jaxb.episode
    ├── xjc1
    │ └── ком
    │ └── потік стоків
    │ └── пакет1
    │ ├── ObjectFactory.java
    │ └── Shiporder.java
    └── xjc2
        └── ком
            └── сток-потік
                └── пакет2
                    ├── BookForm.java
                    ├── BooksForm.java
                    ├── ObjectFactory.java
                    └── package-info.java

Що здається очікуваним результатом.


дякую, у мене насправді була та сама проблема вчора, але на мить я дала відповідь на неї. Ваше рішення працює майже ідеально, моя єдина проблема зараз полягає в тому, що я не можу змусити Eclipse скомпілювати без помилок. У командному рядку все добре. Моє поточне обхідне рішення полягає в тому, що я оголошую ці папки в target як вихідні папки, і все добре .. хоча я не впевнений, що мені це дуже подобається, я б скоріше створив банку із згенерованим кодом і просто використав би її безпосередньо
Newtopian

1
Плагін eclipse m2eclipse оновлює шлях збірки. Після генерації компонентів за допомогою чистої збірки mvc: Assembly я просто запускаю [клацніть правою кнопкою миші на проекті]> [Maven]> [Оновити конфігурацію проекту], і він оновлює шлях збірки.
MR

@Newtopian See коментар @ MR, m2eclipse зробить це за вас, якщо ви будете дотримуватись згаданої мною конвенції.
Паскаль Тивент,

хм, добре, тоді, виявляється, робив те саме, що я робив вручну, тільки зараз потрібно лише один або два клацання. Все ще дивно бачити ціль у вихідних папках, але зараз це майже безкоштовно, тому я її
збережу

1
Я знаю, що це старе запитання, але сподіваюся, щось мені відповість. Я використовую цей код, і він працює. Але коли я хочу встановити той самий пакет, він завжди генерує лише одну схему. Наприклад, при першому виконанні я встановлюю com.myproject.answer, а при другому виконанні com.myproject.request .., а після генерації джерела у мене відсутній лише * пакет відповідей і запит відсутній ... будь-яка ідея, як це виправити? Створити каталог, який я також встановив, те саме.
Денис Стефанов

14

Ви також можете використовувати прив'язки 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-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, вам не потрібно змінювати Maven pom.xml, просто додайте новий файл прив'язки XJB до того самого каталогу.


Хоча тривіальне редагування, щоб надати підказку для висвітлення синтаксису, покращує розбірливість повідомлення
Кев,

Добре, дякую за пояснення. Я не розумію, що редагування додало підсвічування синтаксису.
xmedeko

2
Це найкраща відповідь для мене, оскільки я не хотів би продовжувати змінювати пом кожен раз, коли додається нова схема.
Бен Турлі,

Одне питання полягає в тому, якщо книга та особа знаходяться в одному цільовому просторі імен у xsd. Скажімо, натомість у них була книга, журнал, газета тощо, до яких входило publishable.xsd. Вони повинні знаходитись у тому самому просторі імен, що і для публікації, і, отже, один одного, і тепер це ламається, оскільки ви можете мати лише одне schemaBindings на простір імен. Я погоджуюсь, що це ідеально, і хотів би, щоб це працювало для прикладу вище, але JAXB просто недостатньо гнучкий.
TurnipEntropy

8

ви повинні змінити це, щоб визначити плагін лише один раз і виконати двічі області виконання ... як наведено нижче ... і createDirectory повинен бути встановлений (на основі документів) ..

<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 ... можливо, вам слід подумати про це.


Правило одного артефакту на модуль відповідає дійсності, але ... OP не генерує двох артефактів.
Паскаль Тивент,

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. Але я не можу знайти <clearOutputDir>на static.highsource.org/mjiip/maven-jaxb2-plugin/…

Для мене справжнє рішення, адже ти можеш генерувати всі файли в одній папці
MilacH

<clearOutputDir>false</clearOutputDir>мені було достатньо у моєму випадку.
Ruwanka Madhushan

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>

2

Наступне працює для мене після довгих випробувань

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

2

Я зіткнувся з багатьма проблемами під час використання jaxb у Maven, але мені вдалося вирішити вашу проблему, виконавши наступне

Спочатку створіть файл 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

Якщо ви не хочете використовувати компакт-диск, ви можете помістити wsimport.bat у "C: \ YOUR \ PATH \ TO \ PLACE \ THE \ PACKAGES"

Якщо запустити його без -keep -verbose, він буде генерувати лише пакети, але не файли .java.

Значок -b переконається, що schema.xjc використовується під час генерації


0

Існує інше, чітке (IMO) рішення цього питання. Існує параметр, який називається "staleFile", який використовується як прапор, щоб не генерувати речі знову. Просто змініть його в кожному виконанні.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.