LibraryManagement  

Introduction

There are two ways for you to manage libraries with sbt, manually or automatically. These two ways can be mixed as well.

Manual Dependency Management

Manually managing dependencies involves copying any jars that you want to use to the lib directory. sbt will put these jars on the classpath during compilation, testing, running, and when using the interpreter. You are responsible for adding, removing, updating, and otherwise managing the jars in this directory. No modifications to your project definition are required to use this method unless you would like to change the location of the directory you store the jars in.

To change the directory jars are stored in, override dependencyPath in your project definition. For example, to use src/main/webapp/WEB-INF/lib:

override def dependencyPath = webappPath / "WEB-INF" / "lib"

If you want more control and flexibility, override the unmanagedClasspath method, which ultimately provides the manual dependencies to sbt. The default implementation is roughly:

def unmanagedClasspath = descendents(dependencyPath, "*.jar")

If you have multiple directories containing jars, you can add them like:

override def unmanagedClasspath = super.unmanagedClasspath +++ extraJars

where you might build up the extra jars as follows:

def baseDirectories = "libA" +++ ("b" / "lib") +++ "libC"
def extraJars = descendents(baseDirectories, "*.jar") +++ ("d" / "my.jar")

See Paths for more information on building up paths.

Automatic Dependency Management

This method of dependency management involves specifying the direct dependencies of your project and letting sbt handle retrieving and updating your dependencies.

sbt performs this dependency handling when the update action is executed. By default, sbt does not update your dependencies before every compilation, but only does so when you execute update. sbt supports three ways of specifying these dependencies:

  • Declarations in your project definition
  • Maven POM files
  • Ivy configuration and settings files

sbt uses Apache Ivy to implement dependency management in all three cases. If multiple configurations are present, the following precedence is used by default:

  • Inline repositories take precedence over configuration done in ivysettings.xml.
  • Maven and Ivy configurations (pom.xml and ivy.xml) are ignored when inline dependency declarations are present. Note that ivysettings.xml can be used with inline dependencies if no inline repositories are used.
  • A Maven configuration pom.xml is ignored when an Ivy ivy.xml configuration is present. Note that ivysettings.xml can be used with a Maven pom.xml.

The default repositories when ivysettings.xml is not present are the standard Maven2 repository and the Scala Tools Releases (http://scala-tools.org/repo-releases) repository.

The following sections describe how to use each method of automatic dependency management.

Inline Declarations

Inline declarations are a very basic way of specifying the dependencies to be automatically retrieved. They are intended as a lightweight alternative to a full configuration using Ivy. To use inline declarations, do the following:

Basic Dependencies

Declare each dependency in your project definition as a val with the form:

  val dep = groupID % artifactID % revision

or

  val dep = groupID % artifactID % revision % configuration

The actual identifier for the val is currently unimportant. See Configurations for details on configuration mappings. If you are using a dependency that was built with sbt, double the first % to be %%:

  val dep = groupID %% artifactID % revision

This will download the right jar for the dependency built with the version of Scala that you are currently using. If you get an error while resolving this kind of dependency, that dependency probably wasn't published for the version of Scala you are using. See cross-building for details.

Ivy can select the latest revision of a module according to constraints you specify. Instead of a fixed revision like "1.6.1", you specify "latest.integration", "2.9.+", or "[1.0,)". See the Ivy documentation for details.

Additional Repositories

Declare additional repositories besides the default Maven2 and Scala Tools Releases repositories that you want to use with the form:

  val rep = name at location
(The actual identifier for the val is unimportant except for publishing.)

For example:

  val derby = "org.apache.derby" % "derby" % "10.4.1.3"
  val specs = "org.specs" % "specs" % "1.6.1"

  val scalaToolsSnapshots = "Scala-Tools Maven2 Snapshots Repository" at "http://scala-tools.org/repo-snapshots"

sbt can search your local Maven repository if you add it as a repository:

  val mavenLocal = "Local Maven Repository" at "file://"+Path.userHome+"/.m2/repository"

See Resolvers for details on defining other types of repositories.

Explicit URL

If your project requires a dependency that is not present in a repository, a direct URL to its jar can be specified as follows:

  val slinky = "slinky" % "slinky" % "2.1" from "http://slinky2.googlecode.com/svn/artifacts/2.1/slinky.jar"

Disable Transitivity

By default, these declarations fetch all project dependencies, transitively. In some instances, you may find that the dependencies listed for a project aren't necessary for it to build. Projects using the Felix OSGI framework, for instance, only explicitly require its main jar to compile and run. Avoid fetching artifact dependencies with either intransitive() or notTransitive(), as in this example:

  val felix = "org.apache.felix" % "org.apache.felix.framework" % "1.8.0" intransitive()

Classifiers

You can specify the classifer for a dependency using the classifier method. There are some methods for the typical cases of getting sources or API documentation as well. These are withSources, withJavadoc, sources, and javadoc. The withXXX style includes the usual binary jar. Examples:

Get the ScalaCheck binary jar and sources.

  val sc = "org.scalacheck" % "scalacheck" % "1.5" withSources()

Get the jdk15 version of TestNG:

  val testng = "org.testng" % "testng" % "5.7" classifier "jdk15"

Extra Attributes

Extra attributes can be specified by passing key/value pairs to the extra method.

To select dependencies by extra attributes:

  val dep = "org" % "name" % "rev" extra("color" -> "blue")

To define extra attributes on the current project:

  override def projectID =
    super.projectID extra("color" -> "blue", "component" -> "compiler-interface")

Inline Ivy XML

sbt additionally supports directly specifying the configurations or dependencies sections of an Ivy configuration file inline. You can mix this with inline Scala dependency and repository declarations.

For example:

  override def ivyXML =
    <dependencies>
      <dependency org="javax.mail" name="mail" rev="1.4.2">
        <exclude module="activation"/>
      </dependency>
    </dependencies>

Direct Override

Yet another alternative is to declare the Set of all dependencies with the libraryDependencies method:

  override def libraryDependencies =
    Set("org.specs" % "specs" % "1.4.1",
    "org.apache.derby" % "derby" % "10.4.1.3")

If you want to use the val-style definitions as well, use:

  override def libraryDependencies =
    Set("org.specs" % "specs" % "1.4.1",
    "org.apache.derby" % "derby" % "10.4.1.3") ++
    super.libraryDependencies

sbt calls ivyRepositories to get the inline repositories to use. By default, ivyRepositories adds the default repositories (Maven Central and Scala Tools) to the repositories returned by repositories. So, to have complete control over repositories, override ivyRepositories. To specify repositories in addition to the usual defaults, override repositories.

For example, to use the Scala Tools snapshots repository in addition to the default repositories,

  override def repositories = ScalaToolsSnapshots

There are methods defined on sbt.Resolver to assist with default repositories:

	/** Add the local, Maven Central, and Scala Tools releases repositories to the user repositories.  */
	def withDefaultResolvers(userResolvers: Seq[Resolver]): Seq[Resolver]
	/** Add the local Ivy and Maven Central repositories to the user repositories.  If `scalaTools` is true, add the Scala Tools releases repository as well.  */
	def withDefaultResolvers(userResolvers: Seq[Resolver], scalaTools: Boolean): Seq[Resolver]
	/** Add the local Ivy repository to the user repositories.
	* If `scalaTools` is true, add the Scala Tools releases repository.
	* If `mavenCentral` is true, add the Maven Central repository.  */
	def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean, scalaTools: Boolean): Seq[Resolver]

To exclude the default Scala Tools releases repository, but use the local and Maven Central repositories and the ones defined in repositories:

  override def ivyRepositories = Resolver.withDefaultResolvers(repositories, false)

Publishing

Finally, see Publishing for how to publish your project.

Maven/Ivy

For this method, create the configuration files as you would for Maven (pom.xml) or Ivy (ivy.xml and optionally ivysettings.xml). sbt will use these configurations to resolve and retrieve dependencies when you execute update. No modifications to your project definition are necessary.

Maven support is dependent on Ivy's support for Maven POMs. Known issues with this support:

  • Specifying relativePath in the parent section of a POM will produce an error.
  • Ivy ignores repositories specified in the POM. A workaround is to specify repositories inline or in an Ivy ivysettings.xml file.