Как я могу указать 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 хорошо работать с сгенерированным кодом, иначе это именно то, что я хотел.
Newtopian

Ответы:

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

$ tree target /
цель /
├── классы
│ ├── com
│ │ └── stackoverflow
│ │ ├── Класс приложения
│ │ ├── 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
└── сгенерированные источники
    ├── xjc
    │ └── МЕТА-ИНФ
    │ └── sun-jaxb.episode
    ├── xjc1
    │ └── com
    │ └── stackoverflow
    │ └── package1
    │ ├── ObjectFactory.java
    │ └── Shiporder.java
    └── xjc2
        └── com
            └── stackoverflow
                └── package2
                    ├── BookForm.java
                    ├── BooksForm.java
                    ├── ObjectFactory.java
                    └── package-info.java

Что кажется ожидаемым результатом.

Паскаль Тивент
источник
спасибо, у меня действительно была такая же проблема вчера, но на мгновение отказался от нее. Ваше решение работает почти идеально, моя единственная проблема сейчас в том, что я не могу заставить Eclipse скомпилировать без ошибок. Хотя в командной строке все хорошо. Мой текущий обходной путь заключается в том, что я объявляю эти папки в target как исходные папки, и все в порядке ... хотя я не уверен, что мне это очень нравится, я бы предпочел создать банку с сгенерированным кодом и просто использовать его напрямую
Newtopian
1
Плагин m2eclipse eclipse обновляет путь сборки. После создания bean-компонентов с помощью mvc clean assembly: assembly я просто запускаю [щелкните правой кнопкой мыши проект]> [Maven]> [Обновить конфигурацию проекта], и он обновит путь сборки.
MR
@Newtopian См. Комментарий @ 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-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 вам не нужно менять Maven pom.xml, просто добавьте новый файл привязки XJB в тот же каталог.

xmedeko
источник
Хотя тривиальное редактирование, обеспечивающее подсказку по синтаксису, действительно улучшает читаемость сообщения
Кев
Хорошо, спасибо за объяснение. Я не понял, что редактирование добавило подсветку синтаксиса.
xmedeko 01
2
Это лучший ответ для меня, так как я бы не хотел постоянно менять pom каждый раз, когда добавляется новая схема.
Бен Терли
Единственная проблема здесь заключается в том, что книга и человек находятся в одном целевом пространстве имен в xsd. Допустим, вместо этого у них была книга, журнал, газета и т. Д., Все из которых содержали publishable.xsd. Они должны быть в том же пространстве имен, что и publishable, и, следовательно, друг друга, и теперь это не работает, потому что вы можете иметь только одну привязку schemaBindings для каждого пространства имен. Я согласен, что это идеальный вариант, и я бы хотел, чтобы он работал в приведенном выше примере, но JAXB недостаточно гибок.
TurnipEntropy
8

вы должны изменить это, чтобы определить плагин только один раз и дважды выполнить области выполнения ... как показано ниже ... и необходимо установить 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 ... может быть, вам стоит подумать об этом.

хмарбайсе
источник
Правило одного артефакта на модуль верно, но ... 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>мне хватило в моем случае.
Руванка Мадхушан
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", который используется в качестве флага, чтобы больше не создавать материал. Просто изменяйте его при каждом выполнении.

жареный
источник