Dans une construction SBT multi-projets, comment supprimer explicitement l'attribut mainClass dans SBT-assembly ?
J'ai fait de nombreuses recherches mais je n'arrive pas à trouver comment empêcher une classe principale d'être définie dans le jar construit par sbt-assembly dans une construction multi-projets.
Dans le cas d'un projet unique, cela semble fonctionner tant qu'il y a au moins deux classes qui peuvent potentiellement être invoquées par la ligne de commande :
import sbt._
import Keys._
import sbtassembly.Plugin._
import sbtassembly.AssemblyUtils._
import AssemblyKeys._
object TestBuild extends Build {
lazy val buildSettings = Defaults.defaultSettings ++ assemblySettings ++ Seq(
version := "0.1-SNAPSHOT",
organization := "com.organization",
scalaVersion := "2.10.2",
mergeStrategy in assembly := mergeFirst
)
lazy val root = Project(id = "test-assembly",
base = file("."),
settings = buildSettings) settings(
mainClass in assembly := None
)
lazy val mergeFirst: String => MergeStrategy = {
case "reference.conf" | "rootdoc.txt" => MergeStrategy.concat
case PathList("META-INF", xs @ _*) =>
(xs map {_.toLowerCase}) match {
case ("manifest.mf" :: Nil) | ("index.list" :: Nil) | ("dependencies" :: Nil) =>
MergeStrategy.discard
case ps @ (x :: xs) if ps.last.endsWith(".sf") || ps.last.endsWith(".dsa") =>
MergeStrategy.discard
case "plexus" :: xs =>
MergeStrategy.discard
case "services" :: xs =>
MergeStrategy.filterDistinctLines
case ("spring.schemas" :: Nil) | ("spring.handlers" :: Nil) =>
MergeStrategy.filterDistinctLines
case _ => MergeStrategy.first
}
case _ => MergeStrategy.first
}
}
Cependant, il semble que le mainClass := None
n'est même pas nécessaire. En fait, même si elle est laissée là, une classe principale sera toujours définie dans le manifeste s'il n'y a qu'une seule classe candidate.
Malheureusement, dans une construction multi-projets, je n'ai pas pu empêcher une classe principale d'être définie, même en incluant une classe supplémentaire comme point d'entrée fictif.
Après avoir beaucoup bricolé, j'ai découvert que je pouvais empêcher la classe principale d'être définie en définissant le paramètre mainClass
à None
dans plusieurs scopes indépendamment. En particulier, cela fait l'affaire :
mainClass in assembly := None
mainClass in packageBin := None
nainClass in Compile := None
mainClass in run := None
Je n'ai pas trouvé cette exigence dans la documentation et je n'arrive pas à comprendre pourquoi elle est nécessaire. Réglage de mainClass in (Compile, run) := None
ne fonctionne pas. Ils doivent vraiment être évalués séparément.
Est-ce la bonne façon de supprimer manuellement une classe principale ou est-ce que je rate quelque chose ? S'il ne s'agit pas d'un bogue, je pense que cela devrait être documenté quelque part, surtout si l'on considère que le comportement n'est pas cohérent entre les constructions mono et multi-projets.