I\'m looking at an issue in a mature commercial product.
In a nutshell, we are using part of the Apache POI library to read in a Word .DOC or .DOCX file, and convert
Just been struggling with this one. If you're using the maven-shade-plugin to create an uber jar, use the ServicesResourceTransformer
to merge all the services configuration:
<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>
In my case the plugin registry loaded ImagePreloader
s from both the plugin files and mixed them together. Yet the error still appeared. I was inserting an SVG file into a PDF file. The root cause was incorrect version of org.apache.xmlgraphics:batik-svg-dom
. The 1.7
version was required by the org.apache.xmlgraphics:fop:1.1
, however, the 1.8
version was on the classpath.
There is a key difference between the two versions: the org.apache.fop.image.loader.batik.PreloaderSVG
class needs org.apache.batik.dom.svg.SAXSVGDocumentFactory
from the version 1.7
on the classpath. If it gets org.apache.batik.anim.dom.SAXSVGDocumentFactory
from the 1.8
version it does not work as expected.
This SO question: Where has org.apache.batik.dom.svg.SVGDOMImplementation gone? was helpful to me when resolving this issue.
In case anyone else has something similar, this turned out to be caused by the way the project was being built in Maven.
Fop 1.0 and above use the xml-graphics-commons library to facilitate the image rendering. As mentioned in the question, this uses a plugin registry which is configured using the following files inside the 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
...each of these contains a list of the image decoders which will be supported.
The problem is that xml-graphics-common ships these files with a sensible list of defaults, while FOP also has a conflicting set of defaults, which for some weird reason disable all of the image decoders, and that one was taking priority.
To solve the problem, I made sure that my maven pom.xml file imported xml-graphics-common before FOP, so that its defaults took precedence, and at that point everything sprang to life.
I am still not sure why the code was working correctly as a standalone test program, but I suspect it was the way the classpath was being handled being different to it running in plugin mode.