javasvgdependenciesjavax.imageiobatik

dependency conflicts with batik-transcoder and java 17


I'm trying to use the twelvemonkeys and batik to process svg files in java.

  <!-- https://mvnrepository.com/artifact/com.twelvemonkeys.imageio/imageio-batik -->
        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-batik</artifactId>
            <version>3.9.4</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.xmlgraphics/batik-transcoder -->
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-transcoder</artifactId>
            <version>1.16</version>
        </dependency>
        

The problem is that the inclusion of this library in my pom results in the following errors:

The package org.w3c.dom is accessible from more than one module: <unnamed>, java.xml
SAXException cannot be resolved to a type

I've tried the following exclusions which fixes the above errors but at runtime I now get a classnotfound error:

 <!-- https://mvnrepository.com/artifact/org.apache.xmlgraphics/batik-transcoder -->
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-transcoder</artifactId>
            <version>1.16</version>
            <exclusions>
                <exclusion>
                    <groupId>xml-apis</groupId>
                    <artifactId>xml-apis-ext</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>xml-apis</groupId>
                    <artifactId>xml-apis</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
[m java.lang.ClassNotFoundException: org.w3c.dom.svg.SVGDocument
    at jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[?:?]
    at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[?:?]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[?:?]
    at java.lang.ClassLoader.defineClass1(Native Method) ~[?:?]
    at java.lang.ClassLoader.defineClass(ClassLoader.java:1012) ~[?:?]
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150) ~[?:?]
    at jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862) ~[?:?]
    at jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760) ~[?:?]
    at jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681) ~[?:?]
    at jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639) ~[?:?]
    at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[?:?]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[?:?]
    at org.apache.batik.anim.dom.SVGDOMImplementation.createDocument(SVGDOMImplementation.java:140) ~[batik-anim-1.16.jar:?]
    at org.apache.batik.dom.util.SAXDocumentFactory.startElement(SAXDocumentFactory.java:641) ~[batik-dom-1.16.jar:?]

Solution

  • Same probelm with Gradle in a Java Modularity project:

    implementation 'org.apache.xmlgraphics:batik-transcoder:1.17'
    

    Results in

    the unnamed module reads package javax.xml from both xml.apis and java.xml
    

    Which is correct, because the pom file in the batik-transcoder jar declares a dependency on xml-apis which then leads to the conflict.

    Fortunately, we can tell the dependency resolver to not include xml-apis:

    implementation 'org.apache.xmlgraphics:batik-transcoder:1.17', {
        exclude group: "xml-apis", module: "xml-apis"
    }
    

    But then we hit a runtime problem when we try to parse an SVG image:

    Caused by: java.lang.ClassNotFoundException: org.w3c.dom.css.DOMImplementationCSS
    

    Again, this is correct because we haven't declared that we would like to use code from the jdk.xml.dom module. This is fixed by declaring it in module-info.java:

    requires jdk.xml.dom;