2014-12-31 157 views
3

Proguard 5.1在「Error:4」的收縮階段失敗。
Proguard的配置文件如下:Scala的Proguard - 錯誤4

-injars  ReversiRaw.jar 
-outjars  Reversi.jar 
-libraryjars <java.home>/lib/rt.jar 
-libraryjars <java.home>/lib/ext/jfxrt.jar 

-dontwarn scala.** 

-dontnote 
-dontwarn 
-ignorewarnings 

-keepclasseswithmembers public class * { 
    public static void main(java.lang.String[]); 
} 

-keepclassmembers class * { 
    ** MODULE$; 
} 

其中大部分是在文檔中給出的默認配置斯卡拉。
正在播放的jar文件的下載鏈接:download

什麼是「錯誤:4」,以及如何修復或避免?

+0

我也碰到過這個問題。我是Proguard的新手 – harschware

回答

0

當我的injar jar文件是來自插件程序集通過sbt assembly命令的胖罐子時,我也有同樣的問題。 此問題的解決方案不是使用fat jar,而是使用從scala和其他java/scala庫生成的類來獲取瘦身jar文件。

在我的Mac(OS X 10.10)上,我有這個proguard文件(名爲your.pro)。

-injar classes 
-injar /usr/local/Cellar/scala/2.11.5/libexec/lib/scala-library.jar(!META-INF/MANIFEST.MF) 
-outjar main.jar 
-libraryjar /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Classes/classes.jar 

-dontwarn 
-dontnote 
-ignorewarnings 

-optimizationpasses 2 
-optimizations !code/allocation/variable 

-keep,allowoptimization,allowshrinking class * { *; } 
-keepattributes SourceFile,LineNumberTable 

-keepclasseswithmembers public class * { public static void main(java.lang.String[]); } 

這是目錄結構。

. 
├── classes 
│   ├── HelloWorld$.class 
│   ├── HelloWorld$delayedInit$body.class 
│   ├── HelloWorld.class 
│   └── META-INF 
│    └── MANIFEST.MF 
├── src 
│   └── hello.scala 
└── your.pro 

hello.scala如下:

object HelloWorld extends App 
{ 
    println("Hello, world") 
} 

你可以在classes目錄中的類文件與scalac src/hello.scala -d classes。應該添加MANIFEST文件來告訴哪個是主類。小心最後的空白行。

Manifest-Version: 1.0 
Main-Class: HelloWorld 
... blank line should be here ... 

這個classes文件是從scala生成的。 與proguard @your.pro,我可以得到工作的jar文件。

我上傳在https://dl.dropboxusercontent.com/u/10773282/share/2015/scala_class.zip

1

另一種解決方案可能使用的gradle的例子。

這是構建gradle源碼,獲取fat文件(shadowJar文件),並用proguard縮小jar文件。

buildscript { 
    repositories { 
     flatDir dirs: '/Users/smcho/Dropbox/smcho/bin/jar/proguard5.2/lib' 
     mavenCentral() 
     jcenter() 
    } 
    dependencies { 
     classpath ':proguard' 
     classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.0' 
    } 
} 

apply plugin: 'scala' 
apply plugin: 'com.github.johnrengelman.shadow' 

repositories{ 
    mavenCentral() 
} 

shadowJar { 
    manifest { 
    attributes 'Main-Class': 'HelloWorld' 
    } 
} 

dependencies{ 
    compile "org.scala-lang:scala-library:2.11.5" 
} 

task proguard(type: proguard.gradle.ProGuardTask) { 
// injars './build/classes' 
    injars './build/libs/scala_all_jar-all.jar' 
    outjars './build/libs/main.jar' 
    libraryjars "${System.getProperty('java.home')}/lib/rt.jar" 

    dontwarn 
    dontnote 
    ignorewarnings 

    keepattributes 'SourceFile,LineNumberTable' 

    keepclasseswithmembers 'public class * { \ 
     public static void main(java.lang.String[]); \ 
    }' 
} 

您需要設置flatDir dirs指向您的proguard文件所在的位置。

gradle build將讓你的編譯類和jar文件,gradle shadowJar將讓你大jar文件,並gradle proguard會給你一個名爲main.jar的瘦身jar文件。

我還上傳來源:https://dl.dropboxusercontent.com/u/10773282/share/2015/scala_all_jar.zip

1

雖然prosseek的答案是有幫助的,我能得到一個簡單的Hello-世界proguard的配置,而不必訴諸類文件。 (不像prosseek,我沒有嘗試Uberjar,但)。

the Scala example in the Proguard manual適應,我有一個簡單的*.pro會看起來像:

-injars  build/install/HelloScala/lib/helloscala-1.0.jar 
-injars  build/install/HelloScala/lib/scala-library-2.11.6.jar(!META-INF/MANIFEST.MF) 
-outjars  helloscalapro.jar 
-libraryjars <java.home>/lib/rt.jar 

-dontwarn scala.** 

//etc. 

過濾出來的清單,從Scala庫。

當我傳遞給injar的Scala庫的版本與我編譯的Scala版本不同(補丁)版本時,我也得到了錯誤4。