【问题标题】:Shrinking Scala with ProGuard使用 ProGuard 缩小 Scala
【发布时间】: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”-选项。因此,该语句之后的句子。我将编辑帖子以使其更清晰

标签: scala gradle proguard


【解决方案1】:

我犯的错误是没有包含 jdk 中的 java 运行时 jar

这是带有proguarding任务的gradle

import proguard.gradle.ProGuardTask

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'net.sf.proguard:proguard-gradle:6.0.3'
    }
}

plugins { ... }

version '1.0'

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\\" + project.name + "-" +  version + ".jar"
    outjars "$buildDir\\libs\\" + project.name + "-" +  version + "_shrunk" + ".jar"
}

这里是 proguard-rules.pro 中的 pro-guard 规则

-keep class app.** { *; }

#-dontoptimize
-dontobfuscate
#-dontnote
#-dontusemixedcaseclassnames
-ignorewarnings
-forceprocessing

-libraryjars  C:/Program Files/Java/jdk1.8.0_181/jre/lib/rt.jar
-libraryjars  C:/Program Files/Java/jdk1.8.0_181/jre/lib/ext/jfxrt.jar

现在我没有收到任何警告,一切都编译得很好。

【讨论】:

    猜你喜欢
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 1970-01-01
    • 2015-02-25
    相关资源
    最近更新 更多