sbt update
See library depdency basics in the Getting Started guide to learn about the basics.
Synopsis
sbt --client update
Description
sbt uses Coursier to implement library management, also known as a package manager in other ecosystems. The general idea of library management is that you can specify external libraries you would like to use in your subprojects, and the library management system would:
- Check if such versions exists in the listed repositories
- Look for the transitive dependencies (i.e. the libraries used by the libraries)
- Attempt to resolve version conflicts, if any
- Download the artifacts, such as JAR files, from the repositories
Dependencies
Declaring a dependency looks like:
libraryDependencies += groupID %% artifactID % revision
or
libraryDependencies += groupID %% artifactID % revision % configuration
Also, several dependencies can be declared together:
libraryDependencies ++= Seq(
groupID %% artifactID % revision,
groupID %% otherID % otherRevision
)
If you are using a dependency that was built with sbt, double the first
%
to be %%
:
libraryDependencies += groupID %% artifactID % revision
This will use 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.
versionScheme
and eviction errors
sbt allows library authors to declare the version semantics using the versionScheme
setting:
// Semantic Versioning applied to 0.x, as well as 1.x, 2.x, etc
versionScheme := Some(VersionScheme.EarlySemVer)
When Coursier finds multiple versions of a library, for example Cats Effect 2.x and Cats Effect 3.0.0-M4, it often resolves the conflict by removing the older version from the graph. This process is colloquially called eviction, like "Cats Effect 2.2.0 was evicted."
This would work if the new tenant is binary compatible with Cats Effect 2.2.0.
In this case, the library authors have declared that they are not binary compatible, so the eviction was actually unsafe.
An unsafe eviction would cause runtime issues such as ClassNotFoundException
. Instead Coursier should've failed to resolve.
lazy val use = project
.settings(
name := "use",
libraryDependencies ++= Seq(
"org.http4s" %% "http4s-blaze-server" % "0.21.11",
"org.typelevel" %% "cats-effect" % "3.0.0-M4",
),
)
sbt performs this secondary compatibility check after Coursier returns a candidate:
[error] stack trace is suppressed; run last use / update for the full output
[error] (use / update) found version conflict(s) in library dependencies; some are suspected to be binary incompatible:
[error]
[error] * org.typelevel:cats-effect_2.12:3.0.0-M4 (early-semver) is selected over {2.2.0, 2.0.0, 2.0.0, 2.2.0}
[error] +- use:use_2.12:0.1.0-SNAPSHOT (depends on 3.0.0-M4)
[error] +- org.http4s:http4s-core_2.12:0.21.11 (depends on 2.2.0)
[error] +- io.chrisdavenport:vault_2.12:2.0.0 (depends on 2.0.0)
[error] +- io.chrisdavenport:unique_2.12:2.0.0 (depends on 2.0.0)
[error] +- co.fs2:fs2-core_2.12:2.4.5 (depends on 2.2.0)
[error]
[error]
[error] this can be overridden using libraryDependencySchemes or evictionErrorLevel
This mechanism is called the eviction error.
Opting out of the the eviction error
If the library authors have declared the compatibility breakage, but if you want to ignore
the strict check (often for scala-xml
), you can write this in project/plugins.sbt
and build.sbt
:
libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
To ignore all eviction errors:
evictionErrorLevel := Level.Info
Resolvers
sbt uses the standard Maven Central repository by default. Declare additional repositories with the form:
resolvers += name at location
For example:
libraryDependencies ++= Seq(
"org.apache.derby" % "derby" % "10.4.1.3",
"org.specs" % "specs" % "1.6.1"
)
resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
sbt can search your local Maven repository if you add it as a repository:
resolvers += Resolver.mavenLocal
Override default resolvers
resolvers
configures additional, inline user resolvers. By default,
sbt
combines these resolvers with default repositories (Maven Central
and the local Ivy repository) to form externalResolvers
. To have more
control over repositories, set externalResolvers
directly. To only
specify repositories in addition to the usual defaults, configure
resolvers
.
For example, to use the Sonatype OSS Snapshots repository in addition to the default repositories,
resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
To use the local repository, but not the Maven Central repository:
externalResolvers := Resolver.combineDefaultResolvers(resolvers.value.toVector, mavenCentral = false)
Override all resolvers for all builds
The repositories used to retrieve sbt, Scala, plugins, and application dependencies can be configured globally and declared to override the resolvers configured in a build or plugin definition. There are two parts:
- Define the repositories used by the launcher.
- Specify that these repositories should override those in build definitions.
The repositories used by the launcher can be overridden by defining
~/.sbt/repositories
, which must contain a [repositories]
section
with the same format as the Launcher
configuration file. For example:
[repositories]
local
my-maven-repo: https://example.org/repo
my-ivy-repo: https://example.org/ivy-repo/, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]
A different location for the repositories file may be specified by the
sbt.repository.config
system property in the sbt startup script. The
final step is to set sbt.override.build.repos
to true to use these
repositories for dependency resolution and retrieval.
Exclude Transitive Dependencies
In certain cases a transitive dependency should be excluded from
all dependencies. This can be achieved by setting up ExclusionRules
in excludeDependencies
.
excludeDependencies ++= Seq(
// commons-logging is replaced by jcl-over-slf4j
ExclusionRule("commons-logging", "commons-logging")
)
To exclude certain transitive dependencies of a dependency, use the
excludeAll
or exclude
methods. The exclude
method should be used
when a pom will be published for the project. It requires the
organization and module name to exclude. For example,
libraryDependencies +=
("log4j" % "log4j" % "1.2.15").exclude("javax.jms", "jms")
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:
libraryDependencies += "slinky" % "slinky" % "2.1" from "https://slinky2.googlecode.com/svn/artifacts/2.1/slinky.jar"
The URL is only used as a fallback if the dependency cannot be found through the configured repositories. Also, the explicit URL is not included in published metadata (that is, the pom or ivy.xml).
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:
libraryDependencies += ("org.apache.felix" % "org.apache.felix.framework" % "1.8.0").intransitive()
Classifiers
You can specify the classifier for a dependency using the classifier
method. For example, to get the jdk15 version of TestNG:
libraryDependencies += ("org.testng" % "testng" % "5.7").classifier("jdk15")
For multiple classifiers, use multiple classifier
calls:
libraryDependencies +=
"org.lwjgl.lwjgl" % "lwjgl-platform" % lwjglVersion classifier "natives-windows" classifier "natives-linux" classifier "natives-osx"
To obtain particular classifiers for all dependencies transitively, run
the updateClassifiers
task. By default, this resolves all artifacts
with the sources
or javadoc
classifier. Select the classifiers to
obtain by configuring the transitiveClassifiers
setting. For example,
to only retrieve sources:
transitiveClassifiers := Seq("sources")
Download Sources
Downloading source and API documentation jars is usually handled by an
IDE plugin. These plugins use the updateClassifiers
and
updateSbtClassifiers
tasks, which produce an Update-Report
referencing these jars.
To have sbt download the dependency's sources without using an IDE
plugin, add withSources()
to the dependency definition. For API jars,
add withJavadoc()
. For example:
libraryDependencies +=
("org.apache.felix" % "org.apache.felix.framework" % "1.8.0").withSources().withJavadoc()
Note that this is not transitive. Use the update*Classifiers
tasks
for that.