Scala的Proguard - 错误4

时间:2014-12-31 16:30:11

标签: scala proguard

Proguard 5.1在缩小阶段失败,出现“错误:4” proguard配置文件如下:

-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$;
}

这主要是文档中给出的默认Scala配置 正在复制的jar文件的下载链接:download

什么是“错误:4”,如何修复或避免?

3 个答案:

答案 0 :(得分: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 :(得分:1)

虽然prosseek的答案很有帮助,但我能够在不必诉诸类文件的情况下使用简单的Hello-World proguard配置。 (与prosseek不同,我没有尝试过Uberjar)。

the Scala example in the Proguard manual改编,我得到一个简单的send_data看起来像:

return

从Scala库中过滤掉清单。

当我传递给*.pro的Scala库的版本与我编译它的Scala版本不同(补丁)版本时,我也得到了错误4.

答案 2 :(得分:0)

当我的injar jar文件是来自插件程序集的胖jar通过sbt assembly命令时,我也遇到了同样的问题。 解决这个问题的方法不是使用胖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")
}

您可以使用scalac src/hello.scala -d classes获取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

中上传了该示例