2011-10-19 110 views
12

我正在將一個遺留的jar項目轉換爲SBT,並且出於難以解決的奇怪原因,此項目在其中包含「javax/servlet/Servlet.class」。所以我需要以某種方式從由package-bin生成的jar文件中排除此類。我該怎麼做到這一點?最好我想排除使用通配符(即javax。*)。SBT:從Jar中排除類

的SBT組件插件看起來像它的功能,將做到這一點,但我擔心的是依靠SBT裝配意味着我的JAR項目將無法在船型多模塊項目(即工作,如果我把它作爲戰爭文件中的依賴關係,那麼需要告知戰爭項目在依賴jar項目上運行程序集而不是程序包bin - 但我可能會在這裏弄錯)。

回答

13

每個任務都聲明其使用的其他任務和設置。您可以使用inspect來確定這些輸入,如Inspecting Settings和最近的教程式樣blog post by John Cheng中所述。

在這種情況下,packageBin使用的相關任務是mappingsmappings任務收集要包含在jar中的文件並將它們映射到jar中的路徑。在Mapping Files上解釋了一些背景,但結果是mappings產生了Seq[(File, String)]類型的值。這裏,File是提供內容的輸入文件,String是jar中的路徑。

因此,修改爲packageBin任務的映射,過濾掉從默認映射的路徑,你不想包括:

mappings in (Compile,packageBin) ~= { (ms: Seq[(File, String)]) => 
    ms filter { case (file, toPath) => 
    toPath != "javax/servlet/Servlet.class" 
    } 
} 

mappings in (Compile,packageBin)選擇主包任務的映射(如與測試資源或packageSrc任務相對)。

x ~= f表示「將x設置爲將函數f應用於x的先前值的結果」。 (有關詳細信息,請參見More About Settings。)

過濾器將刪除所有路徑對應於Servlet類的對。

+0

這是一個比我自己的更好的解決方案,也是一個很好的答案,因爲它還設法澄清了一些核心SBT概念。 –

+0

請注意,〜=沒有記錄在0.13頁面上,解釋存在於0.12文檔中http://www.scala-sbt.org/0.12.4/docs/Getting-Started/More-About-Settings.html –

+0

語法爲0.13 (編譯,packageBin):= { (映射到(Compile,packageBin))。value.filter {case(file,toPath)=> toPath!=「javax/servlet/Servlet.class 「 } }''' –

2

我想出了這個解決方案,它定義了依賴於以前的編譯任務新的編譯任務(從而有效地讓我的右鉤源編譯後,它的包裝前)

def mySettings = { 
    // add functionality to the standard compile task 
    inConfig(Compile)(Seq(compile in Compile <<= (target,streams,compile in Compile) map{ 
    (targetDirectory, taskStream, analysis) => 
     import taskStream.log 
     // this runs after compile but before package-bin 
     recursiveListFiles(targetDirectory, ".*javax.*".r) foreach { 
     file => 
      log.warn("deleting matched resource: " + file.getAbsolutePath()) 
      IO.delete(file) 
     } 
     analysis 
    })) ++ 
    Seq(name := "MyProject", version := "1.0", exportJars := true) 
} 

def recursiveListFiles(f: File, r: Regex): Array[File] = { 
    val these = f.listFiles 
    val good = these.filter(f => r.findFirstIn(f.getName).isDefined) 
    good ++ these.filter(_.isDirectory).flatMap(recursiveListFiles(_, r)) 
} 

它比我希望的複雜一點,但它允許我在打包之前進行各種修改(在這種情況下,搜索目標文件夾刪除與正則表達式匹配的所有類文件)。此外,它還實現了堅持默認SBT生命週期的第二個目標。