Как я могу генерировать классы из внешнего файла XSD, используя JAXB XJC

У меня есть два проекта:

/src/main/resources/schema.xsd pom.xml

B /src/main/gen pom.xml

Я хочу, чтобы в проекте B генерировались классы из XSD, которые существуют в проекте A.

В pom.xml проекта B у меня есть:

<dependencies>
    <dependency>
        <groupId>test</groupId>
        <artifactId>A</artifactId>
        <version>${project.version}</version>
    </dependency>
</dependencies>
<build>
    <plugins>
       <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>jaxb2-maven-plugin</artifactId>
        <executions>
            <execution>
                <id>xjc</id>
                <goals>
                    <goal>xjc</goal>
                </goals>
            </execution>
            </executions>
            <configuration>
                <schemaDirectory>src/main/resources</schemaDirectory>
                <outputDirectory>src/main/gen</outputDirectory>
            </configuration>
        </plugin>
    </plugins>

</build>

Но файл xsd не найден в пути к классам:

Не удалось выполнить цель org.codehaus.mojo:jaxb2-maven-plugin:1.5:xjc (xjc) в проекте B: схемы не найдены

Как я могу использовать xsd из другого проекта?


person wajs    schedule 10.10.2014    source источник


Ответы (3)


Проблема с этой конфигурацией заключается в том, что <schemaDirectory> ожидает имя/путь File. Дело в том, что File ищет файлы в файловой системе в текущем рабочем каталоге. В этом случае корень проекта. Но ресурс из проекта A не находится в src/main/resources проекта B. Это ресурс пути к классам, из которых (при сборке в maven) src/main/resources больше не существует.

Я никогда не пытался работать с jaxb2- maven-plugin, поэтому я не уверен, что это возможно.

Но с помощью maven-jaxb2-plugin это позволяет компилировать схему из артефакта Maven. Вы могли бы так что-то вроде

<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>0.9.0</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <schemas>
            <schema>
                <dependencyResource>
                    <groupId>projecta.groupid</groupId>
                    <artifactId>project-a</artifactId>
                    <version>${project.version}</version>
                    <resource>/schema.xsd</resource>
                </dependencyResource>
            </schema>
        </schemas>
        <generateDirectory>src/main/gen/</generateDirectory>
        <generatePackage>mypackage</generatePackage> 
    </configuration>
</plugin>

В этом случае его ресурс (schema.xsd) находится в src/main/resources проекта A. Плагин сгенерирует файлы классов в пакет mypackage и получит src/main/gen

person Paul Samsotha    schedule 10.10.2014
comment
Великолепно, но я хочу знать, возможно ли это с jaxb2-maven-plugin. - person wajs; 10.10.2014
comment
Я никогда не пробовал, но просматривая параметры конфигурации, Я не вижу ничего, что заставило бы меня поверить, что это возможно. Это только из-за того, что я бегло просмотрел руководство. Насколько я знаю, это может быть возможным. Я имею в виду, что теоретически вы могли бы использовать абсолютный путь из проекта A, но я думаю, что это противоречит цели того, что вы пытаетесь выполнить. - person Paul Samsotha; 10.10.2014
comment
@peeskillet Автор maven-jaxb2-plugin здесь. Пожалуйста, посмотрите мой ответ, я думаю, есть несколько функций, которые могут вам пригодиться. :) - person lexicore; 10.10.2014

Мой maven-jaxb2-plugin поддерживает компиляция отдельной схемы.

Как это сделать:

  • Добавьте свой артефакт a в качестве эпизода.
  • If a.xsd is imported into b.xsd, you have to make this schema available to JAXB when compiling b:
    • One way to do this is to extract a.xsd from the artifact a using Maven dependency plugin, for instance.
    • Другой способ — использовать файл каталога, чтобы переписать местоположение a.xsd в артефакт a.

См., например, этот тестовый проект.

Проект a совершенно не впечатляет. Просто компилирует схему a.xsd.

Проект b интереснее. Давайте взглянем.

pom.xml:

        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <configuration>
                <catalog>src/main/resources/catalog.cat</catalog>
                <episodes>
                    <episode>
                        <groupId>org.jvnet.jaxb2.maven2</groupId>
                        <artifactId>maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a</artifactId>
                    </episode>
                </episodes>
            </configuration>
        </plugin>

Конфигурация говорит использовать артефакт a как эпизод. Поэтому, когда JAXB/XJC встречает классы, скомпилированные в a, он будет повторно использовать их вместо создания новых.

Кстати, вместо настройки отдельных эпизоды. В этом случае все зависимости будут рассматриваться как эпизоды, что очень удобно (меньше конфигурации).

В конфигурации также указано использовать файл каталога:

REWRITE_SYSTEM "http://www.ab.org" "maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!"

Это указывает JAXB/XJC переписать все URL-адреса схемы, начинающиеся с http://www.ab.org, чтобы вместо этого начинаться с maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!. Последний будет обработан maven-jaxb2-plugin и, наконец, преобразован в ресурс в a.

Давайте посмотрим поближе. Схема b.xsd импортирует http://www.ab.org/a.xsd:

<import namespace="urn:a" schemaLocation="http://www.ab.org/a.xsd"/>

Это будет переписано в maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!/a.xsd, которое будет преобразовано в a.xsd внутри JAR проекта a. Итак, наконец, JAXB/XJC сможет прочитать эту схему из артефакта JAR a.

Вы также можете использовать PUBLIC вместо REWRITE_SYSTEM для ссылки на a.xsd для каждого URI пространства имен вместо местоположения схемы (что логически лучше):

PUBLIC "urn:a" "maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!/a.xsd"

Однако есть ошибка в JAXB/XJC, это не работает, если у вас есть schemaLocation в вашем xs:import .

Это будет работать на данный момент:

<xsd:import namespace="urn:a"/>

Это не будет работать в данный момент:

<xsd:import namespace="urn:a" schemaLocation="a.xsd"/>

Я отправил Oracle запрос на вытягивание, который исправляет это, но он еще не применен.

Объяснение выше относится к maven-jaxb2-plugin и работает в версиях 0.10.0 и выше.

Ваш исходный вопрос касается jaxb2-maven-plugin от Codehaus, который является другим плагином Maven. Этот плагин не имеет всех функций, которые я описал выше, но по крайней мере эпизоды должны работать через аргументы. Каталоги также должны работать, но я считаю, что jaxb2-maven-plugin работает не поддерживает разрешающие схемы в артефактах Maven. Вместо этого вы можете использовать maven-dependency-plugin для извлечения a.xsd из артефакта a.

Отказ от ответственности SO: я являюсь автором файла maven-jaxb2-plugin.

Примечание для рецензентов: я НЕ намерен продвигать/рекламировать свой плагин, я просто хочу предоставить решение заданного вопроса. И похоже, что мой проект предлагает лучшее/самое элегантное и полное решение.

person lexicore    schedule 10.10.2014

Мы также можем использовать, как показано ниже, в файле pom.xml

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <version>1.5</version>
            <executions>
                <execution>
                    <id>id1</id>
                    <goals>
                        <goal>xjc</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>src/main/java</outputDirectory>
                        <clearOutputDir>false</clearOutputDir>
                        <packageName>com.subu.xsd.model</packageName>
                        <schemaDirectory>src/main/java/schemadir</schemaDirectory>
                        <schemaFiles>XYZ.xsd</schemaFiles>
                    </configuration>
                </execution>
            </executions>
        </plugin>
person Subhasish Sahu    schedule 12.01.2017