I have a project where I am trying to create a fat jar using the sbt-assembly plugin. When I attempt to run my main class from the jar using the java -jar
command, I get the error message: Error: Could not find or load main class com.gordon.timeshare.apps.TimeShareLauncher
.
I only have one main class in my project (I use the extends App
syntax to accomplish this), so I do not specify the path to the main class explicitly, although I have tried that and it did not help.
Below are all the settings I have in my build.sbt
file.
ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / organization := "com.gordon.timeshare.apps"
ThisBuild / scalaVersion := "2.13.5"
lazy val app = (project in file("app"))
.settings(
assembly / mainClass := Some("com.gordon.timeshare.apps.TimeShareLauncher"),
assembly / assemblyJarName := "TimeShareLauncher.jar"
)
assemblyMergeStrategy in assembly := {
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
I have also tried other strategies like deduplicate
, but that would give me an error when trying to make the .jar.
Additionally, when making the .jar, I get a warning:
[warn] Could not create directory C:\Users\dgord\workspace\new-timeshare\timeshare\target\streams\_global\assembly\_global\streams\assembly\88fbe735ce5abc6987fbc59b072404628cdc94b4_a99f2fe2a42747ed9809d4f62f51a9e1b336dde8_da39a3ee5e6b4b0d3255bfef95601890afd80709\META-INF\versions\9: java.nio.file.FileAlreadyExistsException: C:\Users\dgord\workspace\new-timeshare\timeshare\target\streams\_global\assembly\_global\streams\assembly\88fbe735ce5abc6987fbc59b072404628cdc94b4_a99f2fe2a42747ed9809d4f62f51a9e1b336dde8_da39a3ee5e6b4b0d3255bfef95601890afd80709\META-INF\versions\9
And in case you want to know what my main class looks like:
package com.gordon.timeshare.apps
object TimeShareLauncher extends App
I have also tried this on WSL and had the same result.
The issue is with lazy val app = (project in file("app"))
. Assuming a single module project with no module named app
, sbt-assembly will create a directory named app
and attempt to stuff the build in there. However, since the main class is not in the app
bundle, the class will not be added to the jar file.
The correct way to do this is:
lazy val app = (project in file("."))
, which specifies the current directory as the one to look for the main class. So this was not really an issue with knowing how to use the sbt-assembly
plugin, but a more general issue with specifying projects in an sbt build.