29
Add a Play module from your own Nexus Repository
Those days I'm mainly working with the Play! Framework for Java. We are in a microservices setup and thus we end up having some common code between the different services. We decided to make Play Modules that we would import in the different projects.
In order to do so, we created a project with a few utility classes that we published using SBT and our own Nexus respository. The final configuration ended up being something like this:
name := "some-module"
organization := "my.organization"
version := "1.0.0-SNAPSHOT"
scalaVersion := "2.12.2"
lazy val root = (project in file(".")).enablePlugins(PlayJava)
libraryDependencies ++= Seq(
guice,
"com.rabbitmq" % "amqp-client" % "4.2.0",
"org.mockito" % "mockito-core" % "2.10.0" % "test"
)
val nexusHost = System.getenv("NEXUS_HOST")
val nexusUser = System.getenv("NEXUS_USER")
val nexusPassword = System.getenv("NEXUS_PASSWORD")
publishTo := {
val httpNexus = "http://" + nexusHost
if (version.value.trim.endsWith("SNAPSHOT"))
Some("snapshots" at httpNexus + "/repository/maven-snapshots")
else
Some("releases" at httpNexus + "/repository/maven-releases")
}
credentials += Credentials("Sonatype Nexus Repository Manager", nexusHost, nexusUser, nexusPassword)
And, then publishing becomes super easy, we only need to run sbt publish
and voilà! The module is published inside our own repository.
Now comes the second part, actually using your module in your project. For this, theoretically, all you need is to add a Library Dependency:
libraryDependencies ++= Seq(
"my.organization" % "some-module" % "1.0.0-SNAPSHOT",
"com.rabbitmq" % "amqp-client" % "4.2.0"
)
But this won't be enough.
First of all, you need to add a resolver to specify the new repository for your module:
resolvers += "My Snapshots" at "https://my.url/repository/maven-snapshots/"
You will also need your credentials to access it:
credentials += Credentials("Sonatype Nexus Repository Manager", "my.url", nexusUser, nexusPassword)
And now you are all excited and you type in sbt clean update
... And it fails miserably.
Now, the thing is, SBT is gonna try to find your module at https://my.url/repository/maven-snapshots/my/organization/some-module/1.0.0-SNAPSHOT/...
. But if you look carefully in your Nexus the module is actually at /my/organization/some-module_2.12/1.0.0-SNAPSHOT/...
. Notice this 2.12
? This is your Scala version, and this is actually quite important. So now, you're left with 3 choices.
- Remove the cross path by doing
crossPaths := false
(highly NOT RECOMMENDED ) - Specify the Scala version by depending on
some-module_2.12
instead of justsome-module
- Using the
%%
syntax to let SBT append this Scala version, which is the solution we chose
So here is now our final Library Dependencies declaration:
libraryDependencies ++= Seq(
"my.organization" %% "some-module" % "1.0.0-SNAPSHOT",
"com.rabbitmq" % "amqp-client" % "4.2.0"
)
And the complete file for science:
name := """my_service"""
organization := "my.organization"
version := "1.0"
packageName in Universal := "my_service"
lazy val root = (project in file(".")).enablePlugins(PlayJava)
scalaVersion := "2.12.2"
val nexusUser = System.getenv("NEXUS_USER")
val nexusPassword = System.getenv("NEXUS_PASSWORD")
resolvers += "My Snapshots" at "https://my.url/repository/maven-snapshots/"
credentials += Credentials("Sonatype Nexus Repository Manager", "my.url", nexusUser, nexusPassword)
libraryDependencies ++= Seq(
guice,
"my.organization" %% "some-module" % "1.0.0-SNAPSHOT",
"com.rabbitmq" % "amqp-client" % "4.0.2"
)
Please note that the Scala version that is going to be appended is the one minor one of your scalaVersion
declaration, so here 2.12
.
You're now good to go, you can get back to your fun with Play!.
29