I have a Scala 3 project and need to build a binary which runs on machines where installing Java is possible, but I don’t want to install Scala there (because I want to be able to determine Scala versions solely on the dev side).
And I don’t want to build an installer file, because the file will get updated quite often.
I have a /src/main/scala/main.scala
with
@main
def main(): Unit =
etc, and this is my build.sbt
so far:
ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / scalaVersion := "3.3.1"
lazy val root = (project in file("."))
.settings(
name := "foo",
libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "2.2.0",
libraryDependencies += "org.scala-lang.modules" %% "scala-xml" % "2.1.0",
libraryDependencies += "com.lihaoyi" %% "os-lib" % "0.9.1",
libraryDependencies += "com.lihaoyi" %% "requests" % "0.8.0",
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.15" % Test,
)
scalacOptions ++= Seq("-deprecation", "-feature")
Is there an easy way to do this?
In the end, I used sbt-assembly to build a big jar. This way I still need Java at the target machine, but not Scala. At first I was not sure, because I could not find any version for Scala 3, but (as LuisMiguelMejíaSuárez pointed out) sbt plugins work with any (target) Scala version.
I had to add a file project/plugins.sbt
containing:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.5")
And in build.sbt
I configured the main class and target file name/location inside .settings(
like this:
assembly / mainClass := Some("main"),
assembly / assemblyJarName := "../../foo.jar",
I tried to use assemblyOutputPath
instead of adding the path to assemblyJarName
, but that deleted the whole project 😱, so I do not dare to use that again.
sbt assembly
builds the big jar and at the target machines I just do: java -jar foo.jar