2012-05-26 47 views
1

我使用的是xsbt-proguard-plugin,這是一款與Proguard一起使用的SBT插件。如何使用xsbt-proguard-plugin排除/包含特定的軟件包?

我試圖想出一個Hive Deserializer一個Proguard的配置我寫的,它具有以下依存關係:

// project/Dependencies.scala 
val hadoop  = "org.apache.hadoop"   % "hadoop-core"   % V.hadoop 
val hive  = "org.apache.hive"   % "hive-common"   % V.hive 
val serde  = "org.apache.hive"   % "hive-serde"   % V.hive 
val httpClient = "org.apache.httpcomponents" % "httpclient"   % V.http 
val logging  = "commons-logging"   % "commons-logging"  % V.logging 
val specs2  = "org.specs2"     %% "specs2"    % V.specs2  % "test" 

加上非託管依賴:

// lib/UserAgentUtils-1.6.jar 

因爲大多數這些都是爲本地單元測試或在Hadoop/Hive環境中提供,無論如何,我希望我的縮小jarfile只包括:

  • Java類SnowPlowEventDeserializer.class和SnowPlowEventStruct.class
  • org.apache.httpcomponents.httpclient
  • commons-logging
  • lib/UserAgentUtils-1.6.jar

但我真的努力讓語法正確。我應該從我想保留的類的白名單開始,還是明確地過濾掉Hadoop/Hive/Serde/Specs2庫?我知道this SO question,但似乎並不適用於此。

如果我最初嘗試的白名單方式:

// Should be equivalent to sbt> package 
import ProguardPlugin._ 
lazy val proguard = proguardSettings ++ Seq(
    proguardLibraryJars := Nil, 
    proguardOptions := Seq(
    "-keepattributes *Annotation*,EnclosingMethod", 
    "-dontskipnonpubliclibraryclassmembers", 
    "-dontoptimize", 
    "-dontshrink", 
    "-keep class com.snowplowanalytics.snowplow.hadoop.hive.SnowPlowEventDeserializer", 
    "-keep class com.snowplowanalytics.snowplow.hadoop.hive.SnowPlowEventStruct" 
) 
) 

然後我得到一個Hadoop的處理錯誤,這麼清楚Proguard的仍試圖捆綁Hadoop的:

proguard: java.lang.IllegalArgumentException: Can't find common super class of [[Lorg/apache/hadoop/fs/FileStatus;] and [[Lorg/apache/hadoop/fs/s3/Block;] 

同時,如果我嘗試Proguard's filtering syntax到建立我不想包括的圖書館黑名單:

import ProguardPlugin._ 
lazy val proguard = proguardSettings ++ Seq(
    proguardLibraryJars := Nil, 
    proguardOptions := Seq(
    "-keepattributes *Annotation*,EnclosingMethod", 
    "-dontskipnonpubliclibraryclassmembers", 
    "-dontoptimize", 
    "-dontshrink", 
    "-injars !*hadoop*.jar" 
) 
) 

然後這似乎並不工作:

proguard: java.io.IOException: Can't read [/home/dev/snowplow-log-deserializers/!*hadoop*.jar] (No such file or directory) 

任何幫助非常感謝!

回答

0

最後,我無法使用ProGuard闖過重複類錯誤,更不用說如何找出如何篩選出相關的罐子,所以最後切換到更清潔sbt-assembly方法:

-1 。根據README

-2將我的項目添加了sbt-assembly插件。更新與"provided"標誌相應的項目依賴阻止他們被添加到我的脂肪罐子:

val hadoop  = "org.apache.hadoop"   % "hadoop-core"   % V.hadoop  % "provided" 
val hive  = "org.apache.hive"   % "hive-common"   % V.hive  % "provided" 
val serde  = "org.apache.hive"   % "hive-serde"   % V.hive  % "provided" 
val httpClient = "org.apache.httpcomponents" % "httpclient"   % V.http 
val httpCore = "org.apache.httpcomponents" % "httpcore"    % V.http 
val logging  = "commons-logging"   % "commons-logging"  % V.logging  % "provided" 
val specs2  = "org.specs2"     %% "specs2"    % V.specs2  % "test" 

-3。加入SBT-組件構造像這樣:

import sbtassembly.Plugin._ 
import AssemblyKeys._ 
lazy val sbtAssemblySettings = assemblySettings ++ Seq(
    assembleArtifact in packageScala := false, 
    jarName in assembly <<= (name, version) { (name, version) => name + "-" + version + ".jar" }, 
    mergeStrategy in assembly <<= (mergeStrategy in assembly) { 
    (old) => { 
     case "META-INF/NOTICE.txt" => MergeStrategy.discard 
     case "META-INF/LICENSE.txt" => MergeStrategy.discard 
     case x => old(x) 
    } 
    } 
) 

然後鍵入assembly產生了「脂肪罐子」與我只需要在它的包,包括非託管依賴性和不包括的Hadoop /蜂房等

1

白名單是正確的方法:ProGuard應該得到一個完整的上下文,因此它可以適當地調出不需要的類,字段和方法。

錯誤「無法找到常見的超類」表明某些庫仍然從輸入中丟失。 ProGuard可能會對此提出警告,但配置似乎包含選項-ignorewarnings或-dontwarn(應避免)。您應該使用-injars或-libraryjars添加庫。

如果ProGuard包含了一些您不希望輸出的類,可以使用「-whyareyoukeeping類somepackage.SomeUnexpectedClass」來獲得解釋。

從工作配置開始,您仍然可以嘗試從輸入中過濾出類或整個罐子。雖然過濾器不是自己添加到類路徑中的項目,例如, 「-injars some.jar(!somepackage/**。class)」 - cfr。手冊。如果輸入包含可拖動其他不需要的類的測試類,這可能很有用。

+0

由於埃裏克,我感謝幫助。最後,我無法超越重複的類錯誤,更不用說排除特定的jar。當我在SBT中有一個簡單的依賴關係列表時,排除特定的瓶子似乎有點笨拙,我寧願使用/註釋來包含/排除。最後,我採用了sbt-assembly的方法,見下文。 –

相關問題