2013-02-09 38 views
23

Tôi đang cố gắng chuyển đổi dự án scala thành lọ chứa chất béo có thể triển khai sử dụng sbt-assembly. Khi tôi chạy nhiệm vụ lắp ráp của tôi trong SBT Tôi nhận được lỗi sau:vấn đề lắp ráp-hợp nhất-chiến lược bằng cách sử dụng sbt-assembly

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 

Bây giờ từ tài liệu SBT-lắp ráp:

If multiple files share the same relative path (e.g. a resource named application.conf in multiple dependency JARs), the default strategy is to verify that all candidates have the same contents and error out otherwise. This behavior can be configured on a per-path basis using either one of the following built-in strategies or writing a custom one:

  • MergeStrategy.deduplicate is the default described above
  • MergeStrategy.first picks the first of the matching files in classpath order
  • MergeStrategy.last picks the last one
  • MergeStrategy.singleOrError bails out with an error message on conflict
  • MergeStrategy.concat simply concatenates all matching files and includes the result
  • MergeStrategy.filterDistinctLines also concatenates, but leaves out duplicates along the way
  • MergeStrategy.rename renames the files originating from jar files
  • MergeStrategy.discard simply discards matching files

Đi theo thiết lập tôi này build.sbt của tôi như sau:

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 

trong dòng cuối cùng của build.sbt, tôi có:

mergeStrategy in assembly := mergeStrategy.first 

Bây giờ, khi tôi chạy SBT, tôi nhận được lỗi sau:

error: value first is not a member of sbt.SettingKey[String => sbtassembly.Plugin.MergeStrategy] 
    mergeStrategy in assembly := mergeStrategy.first 

Ai đó có thể chỉ ra những gì tôi có thể làm sai ở đây?

Cảm ơn

Trả lời

7

Tôi nghĩ rằng nó phải được MergeStrategy.first với số vốn M, vì vậy mergeStrategy in assembly := MergeStrategy.first.

+0

Tát đầu tôi. Đó là một sự giám sát như vậy. Cảm ơn đã chỉ ra điều đó. –

+1

không hoạt động đối với tôi, nó cho biết: build.sbt: 27: lỗi: không tìm thấy: giá trị mergeStrategy hợp nhấtChiến lược trong assembly: = MergeStrategy.first ^ [lỗi] Gõ lỗi trong biểu thức – stantonk

+0

@stantonk: Bạn có thể để giải quyết nó? – gjain

11

Đối với phiên bản hiện tại 0.11.2 (2014-03-25), cách xác định chiến lược hợp nhất là khác nhau.

Đây là tài liệu here, phần có liên quan là:

NOTE: mergeStrategy in assembly expects a function, you can't do

mergeStrategy in assembly := MergeStrategy.first 

Cách mới (sao chép từ cùng một nguồn):

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) 
    } 
} 

Đây có thể áp dụng đối với các phiên bản trước là tốt, Tôi không biết chính xác khi nào nó đã thay đổi.

+2

Ví dụ cuối cùng (chính thức) không hoạt động trên scala 10, hiển thị Loại không phù hợp – tribbloid

+0

@tribbloid Tôi đã thử nghiệm đoạn mã trong một 'assembly.sbt', và nó hoạt động (Scala 2.10.3, sbt 0.13.2). – Beryllium

8

Tôi vừa thiết lập một dự án SBT ít mà cần phải ReWire một số mergeStrategies, và tìm thấy câu trả lời một chút lỗi thời, cho tôi thêm mã làm việc tôi cho các phiên bản (tính đến 4-7-2015)

  • SBT 0.13.8
  • scala 2.11.6
  • lắp ráp 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", [email protected]_ *) => MergeStrategy.last // For Log$Logger.class 
        case x => 
        val oldStrategy = (mergeStrategy in assembly).value 
        oldStrategy(x) 
    } 
    
+8

'mergeStrategy' không được dùng nữa, thay vào đó hãy sử dụng' assemblyMergeStrategy'. –

3

Đối với phiên bản sbt mới (sbt-phiên bản: 0.13.11), tôi đã nhận được lỗi cho slf4j; cho thời gian được lấy lối thoát dễ dàng: Cũng vui lòng kiểm tra các câu trả lời ở đây Scala SBT Assembly cannot merge due to de-duplication error in StaticLoggerBinder.class nơi sbt-dependency-graph công cụ được đề cập đó là khá mát mẻ để làm điều này bằng tay

assemblyMergeStrategy in assembly <<= (assemblyMergeStrategy in assembly) { 
    (old) => { 
    case PathList("META-INF", xs @ _*) => MergeStrategy.discard 
    case x => MergeStrategy.first 
    } 
} 
0

đây là cách thích hợp để kết hợp hầu hết các java common/dự án scala. nó sẽ chăm sóc META-INF và các lớp học.

cũng đăng ký dịch vụ tại META-INF được thực hiện.

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}