簡體   English   中英

Java Applet 中的 Apache FOP - 未找到用於數據的 ImagePreloader

[英]Apache FOP in a Java Applet - No ImagePreloader found for data

我正在研究成熟商業產品中的一個問題。

簡而言之,我們使用 Apache POI 庫的一部分來讀取 Word .DOC 或 .DOCX 文件,並將其轉換為 XSL-FO,以便我們可以進行標記替換。 然后我們使用 FOP(嵌入到 Java 程序中)將 FO 數據轉換為 PDF 進行打印。 問題是,所有這些都是在 Internet Explorer 中運行的 Java 小程序中的客戶端上完成的。

最初我們使用 FOP 0.93,它運行得相當好。 但是,它在生成 PDF 時無法利用 DOC 文件中的字體,並將所有內容映射到 Times,這是一位客戶不喜歡的。 從理論上講,它可以通過添加某種字體度量數據來工作,但這需要對可能遇到的每種字體進行相對復雜的定義,而且我們無法預測客戶端可能會在 MS 之外使用什么核心字體集。

為了解決這個問題,FOP 升級到 1.0,增加了對從操作系統自動檢測字體的支持。 這有效,但我們注意到圖像處理停止工作,信頭也消失了。 似乎發生的事情是 FOP 中的圖像加載器在 0.93 和 0.95 之間的某個時間點被重寫,因此現在使用 ImageIO 而不是使用 Jimi 和 JAI。 較早的實現工作正常,但新代碼不喜歡作為小程序運行。

圖像嵌入在 FO 數據的 URI 中,因此我們收到如下錯誤:2014-09-30 17:00:10,607 ERROR [org.apache.fop.apps.FOUserAgent] Image not available。 URI:數據:圖像/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAABSCAIAAABysmn6AAA... ...ggg==。 原因:org.apache.xmlgraphics.image.loader.ImageException:不支持文件格式。 未找到數據的 ImagePreloader:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAABSCAIAAABysmn6AAAA...

當通過測試工具運行時,會生成正確的輸出,但是當在瀏覽器中作為小程序運行時,我們會收到上述錯誤,這讓我懷疑瀏覽器小程序安全以某種方式干擾了 ImageIO 插件加載器。

FOP 轉換的核心,即觸發錯誤的位是這樣的:

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

transformer.transform(src, res);

...這一切都在 PrivilegedAction 塊中運行,因為在 FOP 1.0 中它需要文件 I/O 訪問來管理字體緩存。

在 linux 下運行獨立的 FOP 0.93 和 1.0 程序並使用 strace 顯示它正在為圖像數據寫出臨時文件,但是 0.93 和 1.0 都做類似的事情,所以它本身不應該是這樣,特別是因為它應該有已經創建臨時文件的權限。

我嘗試了不同版本的 JRE,因為幾年前的一些構建顯然存在 ImageIO 庫的安全問題,但無濟於事。

有任何想法嗎?

謝謝,

萬一其他人有類似的情況,這原來是由項目在 Maven 中構建的方式引起的。

Fop 1.0 及以上版本使用 xml-graphics-commons 庫來方便圖像渲染。 正如問題中提到的,這使用了一個插件注冊表,該注冊表是使用 JAR 中的以下文件配置的:

META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImageConverter
META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImageLoaderFactory
META-INF/services/org.apache.xmlgraphics.image.loader.spi.ImagePreloader

...每個都包含將支持的圖像解碼器列表。

問題在於 xml-graphics-common 將這些文件與合理的默認值列表一起發送,而 FOP 也有一組相互沖突的默認值,由於某種奇怪的原因禁用了所有圖像解碼器,而那個優先。

FOP, so that its defaults took precedence, and at that point everything sprang to life.為了解決這個問題,我確保我的 maven pom.xml 文件FOP導入了 xml-graphics-common,所以它的默認值優先,在這一點上一切都變得生動起來。

我仍然不確定為什么代碼作為獨立測試程序可以正常工作,但我懷疑這是處理類路徑的方式與它在插件模式下運行的方式不同。

剛剛在這個問題上掙扎。 如果您使用 maven-shade-plugin 創建 uber jar,請使用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>

在我的例子中,插件注冊表從兩個插件文件中加載了ImagePreloader並將它們混合在一起。 然而錯誤仍然出現。 我正在將一個 SVG 文件插入到一個 PDF 文件中。 根本原因是org.apache.xmlgraphics:batik-svg-dom版本不正確。 org.apache.xmlgraphics:fop:1.1需要1.7版本,但是, 1.8版本在類路徑中。

這兩個版本之間有一個主要區別: org.apache.fop.image.loader.batik.PreloaderSVG類需要org.apache.batik.dom.svg.SAXSVGDocumentFactory來自1.7版的類路徑。 如果它從1.8版本獲取org.apache.batik.anim.dom.SAXSVGDocumentFactory ,則它不會按預期工作。

這個問題: org.apache.batik.dom.svg.SVGDOMImplementation 去哪兒了? 在解決這個問題時對我很有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM