Проблема Java EXIficient с использованием грамматики, основанной на схеме, для XSD на основе JAR
Использовали библиотеку JAXB и EXIficient для сортировки объектов в XML, а затем сжатия XML в EXI. Возможность отправить EXI по сети и восстановить XML. Схемы и файлы привязки находятся в папке моих проектов src/main/resources/xsd . Удалось успешно запустить приложение-прототип из IDE (Gradle, IntelliJ). Упаковали приложение и ресурсы в uber/fat JAR и создали набор сценариев запуска. Запуск приложения через командную строку завершается сбоем при построении грамматики EXI для XSD верхнего уровня.
Мой первоначальный фрагмент заводской настройки EXI выглядел так:
var SCHEMA_PATH = "xsd/my-root.xsd";
var exiFactory = DefaultEXIFactory.newInstance();
URL xsdResource = EXICodec.class.getClassLoader().getResource(SCHEMA_PATH);
checkNotNull(xsdResource);
var xsdAbsPath = xsdResource.getFile();
// Following OK when run from within IDE.
// Following generates exception when trying to locate the XSD in uber JAR.
exiFactory.setGrammars(GrammarFactory.newInstance().createGrammars(xsdAbsPath));
exiFactory.getEncodingOptions().setOption(EncodingOptions.INCLUDE_COOKIE, true);
exiFactory.setCodingMode(CodingMode.COMPRESSION);
Это не удалось следующим образом
com.siemens.ct.exi.core.exceptions.EXIException: XML Schema document (file:/mnt/c/Users/user1/my-project/tmp-install/myapp-0.1/lib/myapp-0.1.jar!/xsd/my-root.xsd) not found.
По сути, XSD нельзя найти в uber/fat JAR. Глядя на содержимое JAR, я увидел ожидаемую запись /xsd/my-root.xsd . Понял, что я не могу получить доступ к схеме как к файлу , так как на самом деле это не файл, а ресурс, упакованный в банку.
Изменил заводскую настройку EXI следующим образом.
exiFactory = DefaultEXIFactory.newInstance();
var xsdInputStream = ClassLoader.getSystemResourceAsStream(SCHEMA_PATH);
// Seeing exceptions as XSDs referenced from top-level XSD can't be located within JAR
exiFactory.setGrammars(GrammarFactory.newInstance().createGrammars(xsdInputStream));
exiFactory.getEncodingOptions().setOption(EncodingOptions.INCLUDE_COOKIE, true);
exiFactory.setCodingMode(CodingMode.COMPRESSION);
Продвинулись немного дальше, но столкнулись с проблемами при поиске XSD, на которые ссылается мой XSD верхнего уровня. Например, такие записи, как следующие, в XSD верхнего уровня
<xs:import namespace="http://someURL/someVersion/" schemaLocation="../other/common.xsd"/>
привело к ошибкам, подобным следующим, при создании грамматики
com.siemens.ct.exi.core.exceptions.EXIException: Problem occured while building XML Schema Model (XSModel)!
. [xs-warning] schema_reference.4: Failed to read schema document '../other/common.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.