Search code examples
grailsflying-saucer

Third party libraries conflict in my Grails 2.5.5 application


I have a problem and my ideas how to solve it has just finished. Maybe you can help me. In my project I'm using 'org.xhtmlrenderer:flying-saucer-pdf:9.1.7' this library used depend on com.lowagie:itext:2.1.7. Unfortunately I should import com.lowagie:itext:2.1.7 too. So I have something like this:

grails.project.dependency.resolution = {
    dependencies {
        build ('com.lowagie:itext:2.1.7') {
            excludes 'bctsp-jdk14'
            excludes 'bcmail-jdk14'
            excludes 'bcprov-jdk14'
        }
        compile 'org.xhtmlrenderer:flying-saucer-pdf:9.1.6'
     }
}

The problem occurs when I'm trying to use flying-saucer library. I've got an exception: com.lowagie.text.pdf.BaseFont.getCharBBox(C)[Ijava.lang.NoSuchMethodError: com.lowagie.text.pdf.BaseFont.getCharBBox(C)

The question is how can I fix something like that since both library and I are using only com.lowagie:itext:2.1.7

Thanks.


Solution

  • That Grails project of yours is suffering in the so called JAR Hell. Your Grails app dependencies and the transitive dependencies (the ones your dependencies & Grails plugins use) are creating a conflict. In your case multiple versions of a class on your classpath.

    All you can do is to analyze your WARs classpath and try identify the conflicting classes and their JARs.

    After that try one of the following resolutions:

    • find a common version of iText that works for your Grails app and its plugins
    • fork the conflicting Grails plugin and try to clean up the dependencies of that plugin. Then use the fork.

    While searching for some other solutions I have found a promising software project called jHades. Maybe you might want to take a look at this one too.

    jHades allows you to analyze your WAR file by simply execute the following command

    java -jar jhades-standalone-report.jar path/to/war/webapp.war
    

    Additionally you can troubleshoot your web application by adding jHades to your classpath (as a dependency) and add a jHades servlet listener to your web.xml.

    <listener>
            <listener-class> org.jhades.JHadesServletListener</listener-class>
    </listener>