Home > front end >  How to sbt publish multi module project
How to sbt publish multi module project

Time:02-19

I'm a complete beginner in sbt/scala. I have a multi module sbt project that I build with sbt assembly, which creates jar files of my modules. When I tried sbt module2/publish I noticed the output jar file in my directory is super slim compared to the jar files created by sbt-assembly and its throwing error when I tried to run:

Error: Unable to initialize main class 
com.example.module2.service.Server
Caused by: java.lang.NoClassDefFoundError: scala/Function0

What do I need to include in my build.sbt file to make sbt publishing possible?

my-proj
├── Build.scala
├── common
│   ├── build.sbt
│   └── src
├── module1
│   ├── build.sbt
│   └── src
├── module2
│   ├── build.sbt
│   └── src
└── project
    ├── build.properties
    └── plugins.sbt

Build.scala

lazy val my_proj = (project in file("."))
  .aggregate(common, module1, module2)

lazy val common = project

lazy val common = (project in file("commons"))

lazy val module1 = (project in file("module1"))
  .dependsOn(common, module2)

lazy val module1 = (project in file("module1"))
  .dependsOn(common)

module1/build.sbt

name := "module1"
version := "0.1"
organization := "com.example"
scalaVersion := "2.11.12"
val akkaVersion = "2.5.16"

scalacOptions   = Seq("-unchecked", "-deprecation", "-Xcheckinit", "-encoding", "utf8")
fork := true

/** Dependencies */
resolvers   = Seq("Akka Repository" at "http://repo.akka.io/releases/",
  "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"
)

publishTo := Some(Resolver.file("file", new File("/tmp/my/artifactory")))

libraryDependencies   = Seq(
  "org.scala-lang" % "scala-library"    % scalaVersion
  , "org.scala-lang" % "scala-compiler" % scalaVersion
  , "org.scala-lang" % "scala-reflect"  % scalaVersion
  , "com.typesafe.akka" %% "akka-actor" % akkaVersion
  
)
assemblyMergeStrategy in assembly := {
  case "META-INF\\io.netty.versions.properties"             => MergeStrategy.first
  case m if m.toLowerCase.endsWith("manifest.mf")           => MergeStrategy.discard
  case m if m.toLowerCase.matches("meta-inf.*\\.sf$")       => MergeStrategy.discard
  case m if m.toLowerCase.startsWith("meta-inf/services/")  => MergeStrategy.filterDistinctLines
  case "reference.conf"                                     => MergeStrategy.concat
  case _                                                    => MergeStrategy.first
}

CodePudding user response:

To publish a "fat" jar to a repository, you have to add the following to build.sbt of each sub-project you want to publish.

Compile / assembly / artifact ~= { art =>
  art.withClassifier(Some("fat"))
}

addArtifact(Compile / assembly / artifact, assembly).settings
  • Related