Java Applet中的Apache FOP - 没有为数据找到ImagePreloader

Jos*_*ris 2 java applet apache-fop

我正在研究一个成熟商业产品的问题.

简而言之,我们使用Apache POI库的一部分来读取Word .DOC或.DOCX文件,并将其转换为XSL-FO,以便我们可以进行令牌替换.然后,我们使用FOP(嵌入到Java程序中)将FO数据转换为PDF以进行打印.问题是,所有这些都是在Internet Explorer中运行的Java applet内的客户端上完成的.

最初我们使用的FOP为0.93,效果相当不错.但是,在生成PDF时无法利用DOC文件中的字体,并将所有内容映射到Times,其中一个客户不喜欢.理论上可以通过添加某种字体度量数据来使其工作,但这可能需要对它可能遇到的每种字体进行相对复杂的定义,并且我们无法预测客户端在MS之外可能使用的字体.核心字体集.

为了解决这个问题,FOP升级到1.0,这增加了对从操作系统自动检测字体的支持.这很有效,但我们注意到图像处理已停止工作,信头已消失.似乎发生的事情是FOP内的图像加载器在0.93和0.95之间的某个时刻被重写,因此它不使用Jimi和JAI,而是使用ImageIO.早期的实现工作正常,但新代码不喜欢作为applet运行.

图像嵌入在FO数据的URI中,因此我们得到如下错误:2014-09-30 17:00:10,607 ERROR [org.apache.fop.apps.FOUserAgent]图像不可用.URI:data:image/jpeg; base64,iVBORw0KGgoAAAANSUhEUgAAALQAAABSCAIAAABysmn6AAA ...... ggg ==.原因:org.apache.xmlgraphics.image.loader.ImageException:不支持文件格式.找不到数据的ImagePreloader:image/jpeg; base64,iVBORw0KGgoAAAANSUhEUgAAALQAAABSCAIAAABysmn6AAAA ...

当通过测试工具运行时,会生成正确的输出,但是当在浏览器中作为applet运行时,我们会收到上述错误,这使我怀疑浏览器applet安全性会以某种方式阻塞ImageIO插件加载程序.

FOP转换的内容,即触发错误的位是:

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

transformer.transform(src, res);
Run Code Online (Sandbox Code Playgroud)

...所有都在PrivilegedAction块中运行,因为在FOP 1.0中它需要文件I/O访问来管理字体缓存.

在linux下运行独立的FOP 0.93和1.0程序并使用strace显示它正在为图像数据写出临时文件,但是0.93和1.0都做类似的事情,所以它本身不应该是这样,特别是因为它应该有已经创建临时文件的权限.

我尝试过不同版本的JRE,因为几年前有些版本显然存在ImageIO库的安全问题,但无济于事.

有任何想法吗?

谢谢,

Jos*_*ris 16

如果其他人有类似的东西,结果是由于在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也有一组冲突的默认值,由于一些奇怪的原因,禁用所有的图像解码器,并且一个优先.

为了解决这个问题,我确保我的maven pom.xml文件 FOP 之前导入了xml-graphics-common ,因此它的默认值优先,并且在那时一切都栩栩如生.

我仍然不确定为什么代码作为一个独立的测试程序正常工作,但我怀疑这是处理类路径与插件模式下运行的方式不同的方式.

  • 谢谢。我们正在使用Maven阴影插件,而对我来说,解决方案是向阴影插件配置`<transformer Implementation =“ org.apache.maven.plugins.shade.resource.AppendingTransformer”> <resource> META-INF / services添加一个转换器。 /org.apache.xmlgraphics.image.loader.spi.ImagePreloader </ resource> </ transformer>` (2认同)