J'essaye de convertir un projet Scala en un gros pot déployable en utilisant sbt-Assembly . Lorsque j'exécute ma tâche d'assemblage dans sbt, l'erreur suivante apparaît:
Merging 'org/Apache/commons/logging/impl/SimpleLog.class' with strategy 'deduplicate'
:Assembly: deduplicate: different file contents found in the following:
[error] /Users/home/.ivy2/cache/commons-logging/commons-logging/jars/commons-logging-1.1.1.jar:org/Apache/commons/logging/impl/SimpleLog.class
[error] /Users/home/.ivy2/cache/org.slf4j/jcl-over-slf4j/jars/jcl-over-slf4j-1.6.4.jar:org/Apache/commons/logging/impl/SimpleLog.class
Maintenant de la documentation sbt-Assembly:
Si plusieurs fichiers partagent le même chemin relatif (une ressource nommée Application.conf dans plusieurs fichiers JAR de dépendance, par exemple), la stratégie par défaut est vérifier que tous les candidats ont le même contenu et la même erreur de sortie autrement. Ce comportement peut être configuré chemin par chemin à l’aide de soit l'une des stratégies intégrées suivantes, soit une stratégie personnalisée:
MergeStrategy.deduplicate
est la valeur par défaut décrite ci-dessusMergeStrategy.first
choisit le premier des fichiers correspondants dans l'ordre des classpathMergeStrategy.last
choisit le dernierMergeStrategy.singleOrError
abandonne avec un message d'erreur sur le conflitMergeStrategy.concat
concatène simplement tous les fichiers correspondants et inclut le résultatMergeStrategy.filterDistinctLines
concatène également, mais omet les doublons en cours de routeMergeStrategy.rename
renomme les fichiers provenant des fichiers jarMergeStrategy.discard
supprime simplement les fichiers correspondants
En passant par ceci j'ai configuré mon build.sbt comme suit:
import sbt._
import Keys._
import sbtassembly.Plugin._
import AssemblyKeys._
name := "my-project"
version := "0.1"
scalaVersion := "2.9.2"
crossScalaVersions := Seq("2.9.1","2.9.2")
//assemblySettings
seq(assemblySettings: _*)
resolvers ++= Seq(
"Typesafe Releases Repository" at "http://repo.typesafe.com/typesafe/releases/",
"Typesafe Snapshots Repository" at "http://repo.typesafe.com/typesafe/snapshots/",
"Sonatype Repository" at "http://oss.sonatype.org/content/repositories/releases/"
)
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "1.6.1" % "test",
"org.clapper" %% "grizzled-slf4j" % "0.6.10",
"org.scalaz" % "scalaz-core_2.9.2" % "7.0.0-M7",
"net.databinder.dispatch" %% "dispatch-core" % "0.9.5"
)
scalacOptions += "-deprecation"
mainClass in Assembly := Some("com.my.main.class")
test in Assembly := {}
mergeStrategy in Assembly := mergeStrategy.first
Dans la dernière ligne du build.sbt, j'ai:
mergeStrategy in Assembly := mergeStrategy.first
Maintenant, quand j'exécute SBT, j'obtiens l'erreur suivante:
error: value first is not a member of sbt.SettingKey[String => sbtassembly.Plugin.MergeStrategy]
mergeStrategy in Assembly := mergeStrategy.first
Quelqu'un peut-il indiquer ce que je pourrais faire de mal ici?
Merci
Je pense que cela devrait être MergeStrategy.first
avec une majuscule M
, donc mergeStrategy in Assembly := MergeStrategy.first
.
En ce qui concerne la version actuelle 0.11.2 (2014-03-25), la façon de définir la stratégie de fusion est différente.
Ceci est documenté ici , la partie pertinente est:
REMARQUE: mergeStrategy dans Assembly attend une fonction, vous ne pouvez pas le faire
mergeStrategy in Assembly := MergeStrategy.first
La nouvelle manière est (copiée à partir de la même source):
mergeStrategy in Assembly <<= (mergeStrategy in Assembly) { (old) =>
{
case PathList("javax", "servlet", xs @ _*) => MergeStrategy.first
case PathList(ps @ _*) if ps.last endsWith ".html" => MergeStrategy.first
case "application.conf" => MergeStrategy.concat
case "unwanted.txt" => MergeStrategy.discard
case x => old(x)
}
}
Cela s’applique peut-être aussi aux versions précédentes, je ne sais pas exactement quand cela a changé.
Je viens de configurer un petit projet sbt qui doit modifier certaines stratégies de fusion et trouve la réponse un peu dépassée. Laissez-moi ajouter mon code de travail pour les versions (à partir du 4-7-2015).
Assemblée 0.13.0
mergeStrategy in Assembly := {
case x if x.startsWith("META-INF") => MergeStrategy.discard // Bumf
case x if x.endsWith(".html") => MergeStrategy.discard // More bumf
case x if x.contains("slf4j-api") => MergeStrategy.last
case x if x.contains("org/cyberneko/html") => MergeStrategy.first
case PathList("com", "esotericsoftware", xs@_ *) => MergeStrategy.last // For Log$Logger.class
case x =>
val oldStrategy = (mergeStrategy in Assembly).value
oldStrategy(x)
}
Pour la nouvelle version de sbt (sbt-version: 0.13.11), je rencontrais l’erreur pour slf4j; pour le moment, prenez la solution de facilité: vérifiez également la réponse ici Scala SBT Assembly ne peut pas fusionner en raison d’une erreur de déduplication dans StaticLoggerBinder.class où sbt-dependency-graph est mentionné plutôt cool de le faire manuellement
assemblyMergeStrategy in Assembly <<= (assemblyMergeStrategy in Assembly) {
(old) => {
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
}
Mise à jour rapide: mergeStrategy est obsolète. Utilisez assemblyMergeStrategy. En dehors de cela, les réponses précédentes sont encore solides
c’est le bon moyen de fusionner la plupart des projets Java/scala courants . Il s’occupe de META-INF et des classes.
l'enregistrement des services dans META-INF est également pris en charge.
assemblyMergeStrategy in Assembly := {
case x if Assembly.isConfigFile(x) =>
MergeStrategy.concat
case PathList(ps @ _*) if Assembly.isReadme(ps.last) || Assembly.isLicenseFile(ps.last) =>
MergeStrategy.rename
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}