【发布时间】:2018-09-20 15:59:23
【问题描述】:
简而言之:我无法使用 Proguard 缩减更复杂的 scala 程序。我想我忽略了一些东西,但目前我不知道它可能是什么。
我当前的设置依赖于 build.gradle 文件来缩小我编译的 fat-jar。
import proguard.gradle.ProGuardTask
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'net.sf.proguard:proguard-gradle:5.2.1'
}
}
plugins {
id 'application'
id 'java'
id 'scala'
}
mainClassName = 'app.Main'
sourceCompatibility = 1.8
repositories {
...
}
dependencies {
...
}
jar {
manifest {
attributes(
'Class-Path': configurations.compileClasspath.files.collect {"$it.name"}.join(' '),
'Main-Class': 'app.Main'
)
}
from {
configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
task proguarding(type: ProGuardTask, dependsOn: jar) {
configuration 'proguard-rules.pro'
libraryjars files(configurations.compileClasspath.collect { it })
injars "$buildDir/libs/Main.jar"
outjars "$buildDir/libs/Shrunk.jar"
}
这些是我在 proguard-rules.pro 文件中的 proguard 规则
-keep class testing.** { *; }
-dontoptimize
-dontobfuscate
#-dontpreverify
#-dontnote
-ignorewarnings
-forceprocessing
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-dontwarn scala.**
-keep class !scala*.** { *; }
-dontwarn **$$anonfun$*
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-keep class ... # imagine like 5-thousend different keep-rules I tried
-keepclassmembers class * {
** MODULE$;
}
到目前为止我尝试收缩的所有程序/库在收缩后都不起作用。
除了最基本的scala程序:
package main
import java.io._
object Main extends App {
val pw = new PrintWriter(new File("hello.txt" ))
pw.write("Hello, world")
pw.close()
}
这个我可以从 5.5mb 缩小到 432kb,但其他一切都不起作用,而是抛出运行时错误,如 NullPointerExceptions 或有关堆栈图的东西。
Exception in thread "main" java.lang.VerifyError: Expecting a stackmap frame at branch target 14
Exception Details:
Location:
generator/Main$.parameters()Lscalafx/application/JFXApp$Parameters; @4: ifne
Reason:
Expected stackmap frame at this location.
Bytecode:
0x0000000: 2ab4 0010 9a00 0a2a b700 1ca7 0007 2ab4
0x0000010: 0011 b0
at generator.Main.main(Main.scala)
我发现,这些问题是通过 dontpreverify-option 引起的,但是如果我不使用“-dontpreverify”,它甚至不会编译。
如果没有该选项,ProGuard 将无法找到超类(就像 this guy)
所以我尝试了所有我能找到的保留选项。 我发现的任何解决方案都没有任何帮助。如果有人知道出了什么问题,请帮帮我。
如果有人知道另一个实际上易于使用的 jar 文件压缩器,请告诉我。
顺便说一句,GUI 比 gradle 插件更令人困惑,所以我放弃了这种方法
【问题讨论】:
-
“而是向我抛出运行时错误,例如 NullPointerExceptions 或有关堆栈映射的某些内容”——在询问编程问题时,您基本上总是希望包含准确和完整的错误文本,而不是释义或摘要
-
我知道,但我无法在发布时重新创建这些特定错误。另外,我已经知道这是因为“-dontpreverify”-选项。因此,该语句之后的句子。我将编辑帖子以使其更清晰