xjc или jaxb2-maven-plugin или maven: странное поведение при компиляции XSD, обработка файлов дважды, но с измененными именами?

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

Я компилирую папку XSD, и кажется, что каждый файл обрабатывается дважды, один раз с фактическим именем файла и один раз с немного измененным именем файла. [Кстати, это на OSX, но я не думаю, что это прямая проблема файловой системы с учетом регистра (как вы увидите позже).]

Вот соответствующая часть pom.xml:

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>1.6</version>
    <executions>
      <execution>
        <id>xjc</id>
        <goals>
          <goal>xjc</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <schemaDirectory>src/main/resources</schemaDirectory>
    </configuration>
  </plugin>

src/main/resources содержит следующие XSD:

ATIS_03_00_74_Local.xsd     ITIS_Final_3_0_0.xsd        LRMS_Final_09_07.xsd        TCIP_4_0_0_Final.xsd
ATIS_Partial_03_00_74.xsd   ITIS_Final_3_0_0_for_atis.xsd   LRMS_Final_09_07_for_atis.xsd   TCIP_4_0_0_Local.xsd
IM_03_00_38_Local.xsd       ITIS_Local_for_atis.xsd     LRMS_Final_09_07_for_im.xsd TMDD_Partial_0_0_0.xsd
IM_Partial_03_00_38.xsd     ITIS_Local_for_im.xsd       LRMS_Local_for_atis.xsd
ITIS_3_0_0_Local.xsd        LRMS_09_07_Local.xsd        LRMS_Local_for_im.xsd

когда я запускаю maven, он терпит неудачу в одном файле с чем-то вроде:

[ERROR] file:/Users/dhaskin/clients/cs/onebusaway-nyc/onebusaway-nyc-tcip-api/src/main/resources/atis_Partial_03_00_74.xsd[35,50]
org.xml.sax.SAXParseException: 'RouteRequest' is already defined
...
[ERROR] file:/Users/dhaskin/clients/cs/onebusaway-nyc/onebusaway-nyc-tcip-api/src/main/resources/ATIS_Partial_03_00_74.xsd[22,38]
org.xml.sax.SAXParseException: (related to above error) the first definition appears here
...

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

Глядя на вывод maven -X, я почти уверен, что это делает сам XJC, но я пока не смог определить, как это исправить.

Обратите внимание, что этот проект является подпроектом более крупного проекта maven, но я не думаю, что это имеет значение. Что бы это ни стоило, моя командная строка maven в родительском проекте: mvn -X -U install -pl onebusaway-nyc-tcip-api. (onebusaway-nyc-tcip-api это подпроект.)


person denishaskin    schedule 13.11.2014    source источник
comment
Можете ли вы добавить другие сведения о вашем XSD? Возможно, что XSD будет обработан дважды, потому что его импортирует какой-то другой XSD.   -  person Xstian    schedule 14.11.2014
comment
Это общедоступные схемы? Я мог бы попробовать их скомпилировать.   -  person lexicore    schedule 14.11.2014


Ответы (3)


Хорошо, я проверил ваши схемы.

Ваша исходная проблема связана с неправильным импортом. Например, схема TCIP*.xsd0_0_Final.xsd имеет следующие импорты:

<xs:import namespace="http://www.im-partial-03-00-38" schemaLocation="im_Partial_03_00_38.xsd"/>
<xs:import namespace="http://www.itis-final-3-0-0" schemaLocation="itis_Final
IM_Partial_03_00_38.xsd
ITIS_Final_3_0_0.xsd
LRMS_Final_09_07.xsd
TCIP*.xsd0_0_Local.xsd
0_0.xsd"/> <xs:import namespace="http://www.lrms-final-09-07" schemaLocation="lrms_Final_09_07.xsd"/> <xs:import namespace="http://www.tcip-4-0-0-local" schemaLocation="tcip*.xsd0_0_local.xsd"/>

Принимая во внимание, что файлы названы в другом регистре:

IM_Partial_03_00_38.xsd
ITIS_Final_3_0_0.xsd
LRMS_Final_09_07.xsd
TCIP*.xsd0_0_Local.xsd

На самом деле это неверно, поскольку URL-адреса фактически чувствительны к регистру. Поэтому я бы сказал, что структура импорта этих схем недействительна.

Когда вы компилируете схемы, XJC создает и поддерживает URL-адрес хэш-карты -> документ схемы, который он использует, чтобы избежать повторной загрузки одной и той же схемы. URL-адреса (или, в частности, "системные идентификаторы") обрабатываются с учетом регистра.

Если компилировать все схемы (*.xsd), то некоторые схемы включаются в компилируемый набор (как минимум) дважды: первый раз напрямую, а второй раз через прямой или косвенный импорт. Таким образом, вы получаете IM_Partial_03_00_38.xsd два раза. А поскольку XJC использует системные идентификаторы с учетом регистра для кэша схемы, он думает, что это два разных документа, пытается дважды скомпилировать один и тот же файл — что приводит к коллизиям. (Ошибки, которые вы получаете.)

Если вы просто скомпилируете TCIP_4_0_0_Final.xsd, то доступ к каждой схеме будет только один раз. Операционная система радостно игнорирует регистр при доступе к файлам и все работает.

Я экспериментировал с вашими схемами в следующем демонстрационный проект. (Схемы ZIP загружаются во время сборки, поэтому с юридической точки зрения это не проблематично). Мне пришлось добавить файл привязки, но он заработал довольно быстро. Это работает на моей машине (Windows), но я думаю, что это может не работать на * nix. Хотя не уверен.

Затем я подумал, что могу использовать файл каталога, чтобы исправить проблему регистра в URL-адресах схемы.

К моему сожалению, это не сработало легко.

Во-первых, я обнаружил, что нецелесообразно переписывать системные идентификаторы при компиляции локальных файлов. URL-адреса, подлежащие перезаписи, задаются как полные абсолютные file://.../schema.xsd URL-адреса, поэтому включение таких правил перезаписи в файл каталога сделает файл каталога специфичным для каталога/машины, что нецелесообразно. На самом деле это проблема преобразователя каталога XJC, но я постараюсь решить ее.

Затем я подумал, что если URL-адреса локальных файлов не работают, то подойдут абсолютные URL-адреса. Давайте представим, что мы хотим скомпилировать схемы из ZIP-файла из исходного URL:

<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <executions>
        <execution>
            <id>generate</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <schemaIncludes/>
                <catalog>src/main/resources/catalog.cat</catalog>
                <schemas>
                    <schema>
                        <url>http://www.aptatcip.com/APTA-TCIP-S-01%204.0_files/Schema%20Set.zip!/Schema%20Set/TCIP_4_0_0_Final.xsd</url>
                    </schema>
                </schemas>
            </configuration>
        </execution>
    </executions>
</plugin>

URL http://www.aptatcip.com/APTA-TCIP-S-01%204.0_files/Schema%20Set.zip!/Schema%20Set/TCIP_4_0_0_Final.xsd не работает, конечно. (Помните, мы просто притворяемся.) Но он дает абсолютный URL, который не зависит от конкретной машины.

Чтобы разрешить XJC разрешать схемы из этого URL-адреса, нам понадобится файл каталога. Если мы сделали локальные копии схем в src/main/resources, то файл каталога src/main/resource/catalog.cat должен разрешить схемы от http://www.aptatcip.com/APTA-TCIP-S-01%204.0_files/Schema%20Set.zip!/Schema%20Set до src/main/resources:

REWRITE_SYSTEM "http://www.aptatcip.com/APTA-TCIP-S-01%204.0_files/Schema%20Set.zip!/Schema%20Set/" "./"

Я подумал, тогда мы могли бы переписать недопустимые URL-адреса в нижнем регистре, и все были бы довольны.

Это сработало, но только для абсолютного URL http://www.aptatcip.com/APTA-TCIP-S-01%204.0_files/Schema%20Set.zip!/Schema%20Set/TCIP_4_0_0_Final.xsd. XJC пытался разрешить относительный импорт как относительные URL-адреса, такие как lrms_Final_09_07.xsd, а не (как я ожидал) как абсолютные URL-адреса, такие как http://www.aptatcip.com/APTA-TCIP-S-01%204.0_files/Schema%20Set.zip!/Schema%20Set/lrms_Final_09_07.xsd.

На секунду, когда я компилировал локальные файлы, они были сначала разрешены как абсолютные URL-адреса. И когда я попытался скомпилировать схему с помощью абсолютных URL-адресов, относительный импорт был разрешен как относительный URL-адреса.

Тем не менее в итоге я пришел к следующему файлу каталога:

REWRITE_SYSTEM "http://www.aptatcip.com/APTA-TCIP-S-01%204.0_files/Schema%20Set.zip!/Schema%20Set/" "./"
REWRITE_SYSTEM "tmdd_Partial_0_0_0.xsd" "TMDD_Partial_0_0_0.xsd"
REWRITE_SYSTEM "lrms_Final_09_07.xsd" "LRMS_Final_09_07.xsd"
REWRITE_SYSTEM "atis_Partial_03_00_74.xsd" "ATIS_Partial_03_00_74.xsd"
REWRITE_SYSTEM "im_Partial_03_00_38.xsd" "IM_Partial_03_00_38.xsd"
REWRITE_SYSTEM "itis_Final_3_0_0.xsd" "ITIS_Final_3_0_0.xsd"
REWRITE_SYSTEM "tcip_4_0_0_local.xsd" "TCIP_4_0_0_Local.xsd"

REWRITE_SYSTEM "TCIP_4_0_0_Final.xsd" "TCIP_4_0_0_Final.xsd"
REWRITE_SYSTEM "atis_Partial_03_00_74.xsd" "atis_Partial_03_00_74.xsd"
REWRITE_SYSTEM "ITIS_Final_3_0_0_for_atis.xsd" "ITIS_Final_3_0_0_for_atis.xsd"
REWRITE_SYSTEM "ITIS_Local_for_atis.xsd" "ITIS_Local_for_atis.xsd"
REWRITE_SYSTEM "LRMS_Final_09_07_for_atis.xsd" "LRMS_Final_09_07_for_atis.xsd"
REWRITE_SYSTEM "LRMS_Local_for_atis.xsd" "LRMS_Local_for_atis.xsd"
REWRITE_SYSTEM "ATIS_03_00_74_Local.xsd" "ATIS_03_00_74_Local.xsd"
REWRITE_SYSTEM "TMDD_Partial_0_0_0.xsd" "TMDD_Partial_0_0_0.xsd"
REWRITE_SYSTEM "ITIS_Local_for_im.xsd" "ITIS_Local_for_im.xsd"
REWRITE_SYSTEM "LRMS_Final_09_07_for_im.xsd" "LRMS_Final_09_07_for_im.xsd"
REWRITE_SYSTEM "LRMS_Local_for_im.xsd" "LRMS_Local_for_im.xsd"
REWRITE_SYSTEM "IM_03_00_38_Local.xsd" "IM_03_00_38_Local.xsd"
REWRITE_SYSTEM "ITIS_3_0_0_Local.xsd" "ITIS_3_0_0_Local.xsd"
REWRITE_SYSTEM "LRMS_09_07_Local.xsd" "LRMS_09_07_Local.xsd"

Переписывание имен файлов из нижнего регистра в верхний было именно тем, что я хотел сделать. Но почему я должен был переписать все остальные имена файлов в идентичные имена файлов, выше моего понимания.

Тем не менее файл каталога выше раза в 3 больше, чем должен был быть, но работает. Вот еще один демонстрационный проект который теперь тоже строит без ошибок.

К сожалению, я должен сказать, что каталоги до сих пор не работают удовлетворительно. Я подал следующие вопросы в maven-jaxb2-плагин:

Чтобы было ясно, с моей точки зрения, ни одна из этих проблем не является ошибкой в ​​моем maven-jaxb2-plugin. Это то, что я «унаследовал» от XJC и используемого там преобразователя каталогов.

Но я постараюсь решить это в своем плагине.

person lexicore    schedule 15.11.2014
comment
Спасибо за подробное расследование и отчет. Я дам знать людям в APTA; они должны по крайней мере исправить несоответствие между imports и фактическими именами файлов. - person denishaskin; 15.11.2014
comment
@denishaskin Добро пожаловать. Также есть немного нестандартные URI пространства имён и почему-то дублирование схем ..._for_atis или ..._for_im — это приведёт к почти идентичным пакетам классов (не очень хорошо для разработки). В остальном эти схемы весьма хороши. - person lexicore; 16.11.2014

Это может быть много много вещей.

  • Прежде всего, проверьте свои import и include, очень вероятно, что неправильное имя происходит от одного из них. (Кредит принадлежит Xstian).
  • Если это так, попробуйте использовать файл каталога, чтобы исправить это.
  • Далее, поскольку ошибка указывает на два разных места в файле схемы, я бы также рассмотрел возможность ошибки в схеме. Что у вас там? Можете ли вы показать соответствующие фрагменты схемы? Это какая-то общедоступная схема, которую мы могли бы проверить.
  • Это может быть важной проблемой.

Хорошо, как бы мне решить эту проблему.

Отказ от ответственности: я являюсь автором maven-jaxb2-plugin, а также автор/ведущий разработчик Проект OGC Schemas, в котором собран огромный набор схем ГИС.

  • I'd use my own plugin as it
    • fixes a number of XJC issues
    • выводит отладочную информацию о разрешении схемы
  • Поместите все схемы в src/main/resources
  • Проверьте все import и include, если все правильно
  • В случае проблем с расположением схемы в imports и includes я бы написал файл каталога, который исправляет/переписывает недопустимые ссылки.
  • Я бы запустил компиляцию с помощью mvn -X clean install и проверил журнал, особенно часть разрешения схемы.
  • В случае проблем я бы либо редактировал файл каталога, либо, в крайнем случае, патчил схемы (иногда это действительно нужно сделать)
  • Для исправления я бы создал отдельную «исходную» копию схем и применил патч с помощью плагина Maven patch во время сборки. (Не просто редактировать локальные копии.)

Все это я сделал в упомянутом проекте OGC Schemas.

Пример того, как может выглядеть журнал разрешения схемы:

REWRITE_SYSTEM: http://www.w3.org
    maven:org.hisrc.w3c:w3c-schemas:jar::!/w3c
resolveSystem(http://schemas.opengis.net/gml/3.2.1/gml.xsd)
Resolved system: http://schemas.opengis.net/gml/3.2.1/gml.xsd
    maven:org.jvnet.ogc:ogc-schemas:jar::!/ogc/gml/3.2.1/gml.xsd
[DEBUG] Resolved dependency resource [Dependency {groupId=org.jvnet.ogc, artifactId=ogc-schemas, version=2.0.1-SNAPSHOT, type=jar, classifier=null, resource=ogc/gml/3.2.1/gml.xsd}] to resource URL [jar:file:/C:/Repository/org/jvnet/ogc/ogc-schemas/2.0.1-SNAPSHOT/ogc-schemas-2.0.1-SNAPSHOT.jar!/ogc/gml/3.2.1/gml.xsd].

Обычно это проливает свет на то, что происходит и какие схемы загружаются.

Большинство советов применимы к jaxb2-maven-plugin.

person lexicore    schedule 14.11.2014
comment
Схема общедоступна, ее можно найти по адресу aptatcip. .com/APTA-TCIP-S-01%204.0_files/Schema%20Set.zip - person denishaskin; 14.11.2014
comment
@denishaskin Хорошо, я попробую. Это то, что может заинтересовать многих людей, или это более нишевая вещь? т.е. имеет ли смысл проект с открытым исходным кодом на GitHub? - person lexicore; 14.11.2014
comment
следующий вопрос здесь: stackoverflow.com/questions/26936271/ - person denishaskin; 14.11.2014
comment
re: GitHub, ну, это схема из органа по стандартизации, и вы знаете, какими они могут быть... но публикация ее на GitHub имела бы большой смысл. - person denishaskin; 14.11.2014

У @Xstian был ответ (хотя я нашел его до того, как прочитал комментарий).

Я работал с pom.xml, который, как я предполагал, успешно использовался раньше, но теперь я не верю, что это так.

Проблема заключалась в том, что мне нужно было скомпилировать только основной XSD, который включал другие XSD через import. Поскольку я заставлял XJC компилировать все XSD в папке, некоторые из них компилировались дважды и, следовательно, дублировались определения.

Изменив соответствующую часть pom.xml, как показано ниже, у меня больше нет этой проблемы (хотя у меня есть другая, которую я опубликую отдельно):

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>1.6</version>
    <executions>
      <execution>
        <id>xjc</id>
        <goals>
          <goal>xjc</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <schemaDirectory>src/main/resources</schemaDirectory>
      <schemaFiles>TCIP_4_0_0_Final.xsd</schemaFiles>
    </configuration>
  </plugin>
person denishaskin    schedule 14.11.2014