Working Around Bad Dependency Declarations with sbt

When I noticed the Apache team had released a 1.1 version of FOP, I was excited to try it out. In a Play 2 application that already uses FOP 1.0, bringing in the update should’ve been an easy change: in the application’s Build.scala, simply locate FOP in the appDependencies

"org.apache.xmlgraphics" % "fop" % "1.0"

…and update the version number. But doing so leads to strange sbt errors:

::::::::::::::::::::::::::::::::::::::::::::::                       
::          UNRESOLVED DEPENDENCIES         ::
::::::::::::::::::::::::::::::::::::::::::::::
:: org.apache.avalon.framework#avalon-framework-api;4.2.0: not found
:: org.apache.avalon.framework#avalon-framework-impl;4.2.0: not found
::::::::::::::::::::::::::::::::::::::::::::::

What’s going on?

A Bad Dependency Declaration

One of FOP’s dependencies is Avalon Framework. The version used by FOP 1.0 had a group ID of org.apache.avalon.framework, while version 4.2, used by FOP 1.1, has a group ID of avalon-framework. Per Apache issue FOP-2151, though, the pom.xml for FOP 1.1 still references org.apache.avalon.framework. This bad dependency declaration prevents sbt from finding Avalon Framework and leads to the errors above.

The Workaround

My first thought was to add FOP 1.1 to my local repository and correct its pom.xml. But that solution would not have been portable: anybody with whom I would want to share the application would need to make the same addition.

A better solution lies in sbt’s “explicit URLs” feature (official documentation; Stack Overflow question). It’s intended for dependencies not available in any repository, but we can also use it to map a bad dependency declaration to the correct repository URL. We simply add addDependencies lines for Avalon Framework, placing them before the one for FOP:

"org.apache.avalon.framework" % "avalon-framework-api" % "4.2.0" from "http://repo1.maven.org/maven2/avalon-framework/avalon-framework-api/4.2.0/avalon-framework-api-4.2.0.jar",
"org.apache.avalon.framework" % "avalon-framework-impl" % "4.2.0" from "http://repo1.maven.org/maven2/avalon-framework/avalon-framework-impl/4.2.0/avalon-framework-impl-4.2.0.jar",
"org.apache.xmlgraphics" % "fop" % "1.1"

With that change in place, sbt can find Avalon Framework 4.2, and we’re in business with PDF generation via FOP 1.1!

Advertisements

4 thoughts on “Working Around Bad Dependency Declarations with sbt

  1. Note that the trick above cannot be used if you intend to publish a project depending on Apache FOP, since the “explicit URLs” are not included in POMs or Ivy files. The following alternative solution also works for a published project as it will generate the required exlusion tags in the POM or Ivy files:

    libraryDependencies += “avalon-framework” % “avalon-framework-api” % “4.2.0”

    libraryDependencies += “avalon-framework” % “avalon-framework-impl” % “4.2.0”

    libraryDependencies += “org.apache.xmlgraphics” % “fop” % “1.1” exclude(“org.apache.avalon.framework”, “avalon-framework-api”) exclude(“org.apache.avalon.framework”, “avalon-framework-impl”)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s