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

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

简而言之,我们使用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); 

…所有都在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 /服务/ org.apache.xmlgraphics.image.loader.spi.ImageConverter
META-INF /服务/ org.apache.xmlgraphics.image.loader.spi.ImageLoaderFactory
META-INF /服务/ org.apache.xmlgraphics.image.loader.spi.ImagePreloader

…这些中的每一个都包含将支持的图像解码器列表。

问题是xml-graphics-common将这些文件与一组合理的默认值一起发布,而FOP也有一组冲突的默认值,由于一些奇怪的原因,禁用了所有的图像解码器,而且这个默认值是优先考虑的。

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

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

刚刚和这个人挣扎。 如果您使用maven-shade-plugin创建超级jar,请使用ServicesResourceTransformer合并所有服务配置:

  org.apache.maven.plugins maven-shade-plugin 2.2