使用 Scala 的 Proguard - 错误 4
Posted
技术标签:
【中文标题】使用 Scala 的 Proguard - 错误 4【英文标题】:Proguard with Scala - Error 4 【发布时间】:2015-02-27 16:41:43 【问题描述】: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”是什么,如何解决或避免?
【问题讨论】:
我也遇到了这个问题。我是 Proguard 的新手 【参考方案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
【讨论】:
【参考方案2】:虽然 prosseek 的回答很有帮助,但我能够获得一个简单的 Hello-World 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。
【讨论】:
【参考方案3】:当我的 injar jar 文件是通过 sbt assembly
命令从插件程序集中获得的胖 jar 时,我也遇到了同样的问题。
解决这个问题的方法不是使用 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")
您可以使用scalac src/hello.scala -d classes
获取classes 目录中的类文件。应添加 MANIFEST 文件以区分哪个是主类。小心最后一个空行。
Manifest-Version: 1.0
Main-Class: HelloWorld
... blank line should be here ...
类文件是从 scala 生成的。
使用proguard @your.pro
,我可以获得工作 jar 文件。
我在https://dl.dropboxusercontent.com/u/10773282/share/2015/scala_class.zip上传了示例
【讨论】:
以上是关于使用 Scala 的 Proguard - 错误 4的主要内容,如果未能解决你的问题,请参考以下文章
为 Scala AWS Lambda 使用 Proguard
使用 Scala 编写的库在 Android 应用上运行 Proguard