How do I use a maven BOM (bill of materials) to manage my dependencies in SBT?
Asked Answered
W

4

15

I want to use an external BOM to manage dependency versions for my project in SBT.

For example, the AWS Java SDK publishes a bill-of-materials artifact to their maven repository: https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-bom/1.11.86

I can use it to manage versions of dependencies in the AWS SDK. In Maven I can do this by adding the BOM to my <dependencyManagement> section like so:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-java-sdk-bom</artifactId>
      <version>1.11.86</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

Then when I want to use a module that's covered in the BOM I can omit the version and the BOM will resolve it for me:

<dependencies>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-s3</artifactId>
  </dependency>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-sns</artifactId>
  </dependency>
</dependencies>

Similarly in Gradle, I can use the BOM to manage dependencies for me using this plugin, like so:

apply plugin: "io.spring.dependency-management"

dependencyManagement {
    imports {
        mavenBom 'com.amazonaws:aws-java-sdk-bom:1.11.86'
    }
}

dependencies {
    compile 'com.amazonaws:aws-java-sdk-sns'
    compile 'com.amazonaws:aws-java-sdk-s3'
}

Is there a similar plugin for SBT?

Watercool answered 3/2, 2017 at 20:12 Comment(2)
Hi, did you got the sbt to work using inline ivy xml?Oiler
Hello, have you found a solution for BOM in SBT ? Thanks !Oldline
O
3

I'm looking for the same and have searched in a lot of place.

Most interesting thing I found is it looks like there is Open Ticket on SBT Project:

https://github.com/sbt/sbt/issues/4531

Can't wait that it's resolved !

Oldline answered 24/6, 2020 at 11:41 Comment(0)
R
3

As mentioned by @tdebroc sbt does not support importing Maven BOM out of the box.

A plugin to use Maven BOM files from SBT has been implemented and the source code has been released on Github: https://github.com/heremaps/here-sbt-bom

The plugin supports importing BOM files from public repos and from password protected ones.

The instructions for public repo:

First, create a Dependency.scala file:

import sbt._
import com.here.bom.Bom

case class Dependencies(platformBom: Bom) {
    val dependencies: Seq[ModuleID] = Seq(
        "dependency.group.id" % "artifact" % platformBom
    )
}

Second, add the sbt-bom plugin to plugins.sbt file.

addSbtPlugin("com.here.platform" % "sbt-bom" % "1.0.1")

Then, include the BOM file you want in your build.sbt

import Dependencies._
import com.here.bom.Bom

lazy val deps = Bom.read("bom.group.id" % "bom" % "bom.version")(bom => Dependencies(bom))

lazy val `demo` = project
    .in(file("."))
    .settings(scalaVersion := "2.12.15")
    .settings(deps)
    .settings(
        name := "simple-project",
        libraryDependencies ++= deps.key.value.dependencies,
        resolvers := Resolver.DefaultMavenRepository +: resolvers.value
)

For the full example see: https://github.com/heremaps/here-sbt-bom/tree/master/plugin/src/sbt-test/bom/simple_1.6.1

Reserve answered 8/9, 2023 at 10:59 Comment(1)
As of a few days ago, the plugin also support a more intuitive approach without even the need to declare dependencies explicitly, adding all dependencies of a BOM as dependencyOverrides.Elaterite
R
0

Have you tried to use Ivy with sbt? It allows you to specify "get latest" by using rev="+"

<ivy-module version="2.0" xmlns:m="http://ant.apache.org/ivy/maven" xmlns:e="http://ant.apache.org/ivy/extras">
    <dependencies>
        <dependency org="com.amazonaws" name="aws-java-sdk-s3" rev="+" conf="compile->compile(*),master(*);runtime->runtime(*)" />
    </dependencies>
</ivy-module>

See http://www.scala-sbt.org/1.0/docs/Library-Dependencies.html

Raynell answered 3/2, 2017 at 20:31 Comment(4)
I'm not necessarily trying to get the latest, I'm trying to get the version that is compatible with that version of the BOM. The idea of the BOM is that it tells you what versions of a dependency play nicely together. Taking the latest won't necessarily do it.Watercool
You can set properties (e.g. slf4j.version.numer=2.1.3) in a file called ivysettings.xml. Then you use the symbolic version# in your ivy.xml. See ant.apache.org/ivy/history/2.4.0-rc1/tutorial/defaultconf.html, ant.apache.org/ivy/history/2.4.0-rc1/tutorial/multiproject.htmlRaynell
So I'd have to manually (ie: in scala code in my sbt build) download the BOM file I wanted, and then set the different version properties of the project programmatically? That means I have to manage the dependency chain myself...Watercool
@Watercool There is always a certain amount of manual management. I believe that the best automation you can have is given by the symbolic expressions (e.g. [0.12,) for "at least 0.12, and any greater"). I don't think Maven (or any tool) can provide you with dependency resolution that guarantees that you JAR compiles/runs with a certain version of a dependency. That kind of information (AFAIK) is just not available. Curious to know the ultimate solution you find.Raynell
C
0

If I understand you correctly, you can add this to your libraryDependencies:

"com.amazonaws" % "aws-java-sdk-bom" % "1.11.800" pomOnly()

You still have to put that version number in a variable and use it with the SDKs you actually want, unless someone knows the right magic to use to use in the revision field. I know you can go latest.release if you want the latest release version.

Continue answered 15/6, 2020 at 21:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.