2014-10-01 5 views
2

Я рассматриваю проблему в зрелом коммерческом продукте.Apache FOP в Java Applet - нет ImagePreloader для данных

Вкратце, мы используем часть библиотеки POI Apache для чтения в Word .DOC или .DOCX-файле и конвертируем ее в XSL-FO, чтобы мы могли делать замены токенов. Затем мы используем FOP - встроенную в программу Java - для преобразования данных FO в PDF для печати. Уловка все это делается на клиенте внутри апплета Java, работающего внутри Internet Explorer.

Первоначально мы использовали FOP 0.93, который работал достаточно хорошо. Тем не менее, он не смог использовать шрифты внутри DOC-файла при создании PDF-файла и отобразил бы все в Times, чего не понравилось одному из клиентов. Теоретически это можно было бы сделать, добавив какие-то данные метрик шрифтов, но для этого потребуется довольно сложное определение для каждого шрифта, с которым он может столкнуться, и мы не можем предсказать, что клиент может использовать за пределами MS набор основных шрифтов.

Чтобы исправить это, FOP был обновлен до 1.0, что добавило поддержку автоматического определения шрифтов из операционной системы. Это сработало, но мы заметили, что обработка изображений перестала работать, а бланки исчезли. Похоже, что загрузчик изображений внутри FOP был переписан в какой-то точке между 0,93 и 0,95, так что вместо использования Jimi и JAI теперь он использует ImageIO. Ранняя реализация работала нормально, но новый код не нравится запускаться как апплет.

Изображения встроены в URI в данных FO, поэтому мы получаем ошибку: 2014-09-30 17: 00: 10,607 ERROR [org.apache.fop.apps.FOUserAgent] Изображение недоступно. URI: данные: image/jpeg; base64, iVBORw0KGgoAAAANSUhEUgAAALQAAABSCAIAAABysmn6AAA ... ... ggg ==. Причина: org.apache.xmlgraphics.image.loader.ImageException: формат файла не поддерживается. Нет ImagePreloader найдено для данных: изображение/JPEG; base64, iVBORw0KGgoAAAANSUhEUgAAALQAAABSCAIAAABysmn6AAAA ...

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

Внутренность трансформации ФОПА, то есть бит, который инициирующая ошибка заключается в следующем:

// Step 4: Setup JAXP using identity transformer 
TransformerFactory factory = TransformerFactory.newInstance(); 
Transformer transformer = factory.newTransformer(); // identity transformer 

transformer.transform(src, res); 

... который все запускаются внутри PrivilegedAction блока, так как в ФОПЕ 1.0 он нужен файл I/Вывода для управления кешем шрифтов.

Запуск автономных программ FOP 0.93 и 1.0 под Linux и использование strace показывает, что он записывает временные файлы для данных изображения, но обе версии 0.93 и 1.0 выполняют аналогичные вещи, поэтому это не должно быть само по себе, особенно так как он должен иметь разрешение на создание временных файлов.

Я пробовал разные версии JRE, так как некоторые сборки за несколько лет назад, очевидно, имели проблемы с безопасностью в библиотеке ImageIO, но безрезультатно.

Любые идеи?

Спасибо,

ответ

13

В случае, если кто-то имеет что-то подобное, это оказалось, вызвано тем, как проект строится в Maven.

Fop 1.0 и выше используют библиотеку xml-graphics-commons для облегчения рендеринга изображений.Как уже упоминалось в вопросе, это использует плагин реестра, который выполнен с использованием следующих файлов внутри JAR:

META-INF/услуги/org.apache.xmlgraphics.image.loader.spi.ImageConverter
META-INF /services/org.apache.xmlgraphics.image.loader.spi.ImageLoaderFactory
META-INF/услуги/org.apache.xmlgraphics.image.loader.spi.ImagePreloader

... каждый из них содержит список декодеров изображений, которые будут поддерживаться.

Проблема в том, что xml-graphics-common передает эти файлы с разумным списком значений по умолчанию, в то время как FOP также имеет конфликтующий набор значений по умолчанию, которые по какой-то странной причине отключают все декодеры изображений, приоритет.

Чтобы решить эту проблему, я убедился, что мой файл pom.xml Maven импортирован XML-график-общего перед тем ФОПА, так что его значение по умолчанию имеет приоритет, и в этот момент все ожили.

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

+0

Спасибо, решение решить мою проблему. – Amogh

+0

Рад !!! Он работает, почему вы не принимаете его правильно –

+1

Спасибо. Мы используем Maven плагин оттенок и решение для меня, чтобы добавить трансформатор для конфигурации тени плагина <реализации трансформатора = «org.apache.maven.plugins.shade.resource.AppendingTransformer»> ' \t \t \t \t \t \t \t \t \t META-INF/услуги/org.apache.xmlgraphics.image.loader.spi.ImagePreloader \t \t \t \t \t \t \t \t ' – DominikM

1

Просто борется с этим. Если вы используете Maven-тень-плагин для создания убера банки, используйте ServicesResourceTransformer слить всю конфигурацию служб:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-shade-plugin</artifactId> 
    <version>2.2</version> 
    <executions> 
    <execution> 
     <!-- snip --> 
     <configuration> 
     <transformers> 
      <!-- snip --> 
      <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> 
     </transformers> 
     </configuration> 
    </execution> 
    </executions> 
</plugin>