java - Gradle badass-runtime-plugin 和 ProGuard Gradle 插件

标签 java gradle build.gradle proguard upgrade

如何在 jPackage 之前运行 proguard?

简介

我正在使用 gradle 插件在 JavaFx 中开发一个应用程序,并使用 jPackager 打包它,也使用 gradle 插件。

我使用的主要插件是:

id 'org.openjfx.javafxplugin' version '0.0.8'
id 'org.beryx.runtime' version '1.7.0'
id "com.github.johnrengelman.shadow" version "5.1.0"

我当前的gradle版本是:gradle-5.6.2-all

问题描述

如何使用 proguard 以便在 jPackage 完成其工作之前对代码进行混淆和优化?

我可以运行 proguard 任务,但是当我运行 jPackage 时,代码不会被混淆!

我找到了一个旧版 gradle 版本的教程( Tutorial ),但是我不确定如何将其与当前插件混合使用。我尝试了一些代码片段,但它们都无法构建,我不想用一堆不起作用的代码来混淆这个主题。

我当前工作的build.gradle

// 1. Include proguard dependency
buildscript {
    repositories {
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath 'net.sf.proguard:proguard-gradle:6.2.0'
    }
}

plugins {
    id 'java'
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.8'
    id 'org.beryx.runtime' version '1.7.0'
    id "com.github.johnrengelman.shadow" version "5.1.0"

}


dependencies {
    compile "org.controlsfx:controlsfx:11.0.0"
    compile "eu.hansolo:tilesfx:11.13"
    compile "com.jfoenix:jfoenix:9.0.9"
    compile "org.apache.httpcomponents:httpclient:4.5.9"
    compile "org.json:json:20180813"
    compile "mysql:mysql-connector-java:8.0.17"
    compile "org.jasypt:jasypt:1.9.3"
    compile "com.mchange:c3p0:0.9.5.4"
    compile "com.sun.mail:javax.mail:1.6.2"
    compile "commons-validator:commons-validator:1.6"
    compile 'org.openjfx:javafx-base:11:win'
    compile 'org.openjfx:javafx-controls:11:win'
    compile 'org.openjfx:javafx-fxml:11:win'
    compile 'org.openjfx:javafx-graphics:11:win'

}

repositories {
    mavenCentral()
}

javafx {
    version = "13"
    modules = [ 'javafx.controls','javafx.graphics','javafx.fxml'  ]
}

mainClassName = 'Main'

runtime {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']

   jpackage {
        jpackageHome = 'C:/Program Files/Java/openjdk-14-jpackage+1-49_windows-x64_bin/'



        if(org.gradle.internal.os.OperatingSystem.current().windows) {
            installerType = 'msi'
            imageOptions = []
            installerOptions = ['--win-per-user-install',
                '--win-dir-chooser',
                '--win-menu',
                '--win-shortcut',
                '--verbose',
                '--description','Test of proguard with jPackage',
                '--name', 'Test-ProguardJPackage',
                '--vendor','DoesItMatter']
        }
    }

}

compileJava {
    doFirst {
        options.compilerArgs = [
                '--module-path', classpath.asPath,
                 '--add-modules', 'javafx.controls,javafx.fxml'
        ]
    }
}

run {
    doFirst {
        jvmArgs = [
                '--module-path', classpath.asPath,
                 '--add-modules', 'javafx.controls,javafx.fxml'
        ]
    }
}




task cleanClasses(type: Delete) {
    delete "${buildDir}/classes/java/main"
    delete "${buildDir}/resources/java/main"
}

classes.dependsOn(cleanClasses)

// 2.2 Add proguard task
task proguard(type: proguard.gradle.ProGuardTask, dependsOn: classes) {
    injars project.sourceSets.main.output
    outjars "${buildDir}/proguard/output.jar"

    libraryjars project.sourceSets.main.compileClasspath

    configuration 'proguard.conf'
}

// 2.3 Clean after proguard task
task cleanAfterProguard(type: Delete, dependsOn: proguard) {
    delete "${buildDir}/classes/java/main"
    delete "${buildDir}/resources/java/main"
}

// 2.4 Extract output jar to buildDir 
task unpackProguardOutput (type: Copy, dependsOn: cleanAfterProguard) {
    from zipTree("${buildDir}/proguard/output.jar")
    into file("${buildDir}/classes/java/main")
}


// 3. Create a task to run the app with the proguarded buildDir
task runProguard(type: JavaExec, dependsOn: unpackProguardOutput) {
    classpath = sourceSets.main.runtimeClasspath
    jvmArgs = ['--module-path', classpath.asPath,
               '--add-modules', 'javafx.controls,javafx.fxml' ]
    main = 'Main' // <-- this name will depend on the proguard result
}
<小时/>

引用文献

Package a non-modular JavaFX application

JavaFX Proguard Obfuscation

<小时/>

最佳答案

问题

当您运行 Gradle 任务时,您必须根据任务的依赖关系考虑之前将执行的任务。

JavaFX Proguard Obfuscation您链接的答案,您可以看到 proguard 自定义任务在它们之间串联,当您运行 ./gradlew runProguard 时,实际上您会得到以下任务顺序:

:cleanClasses
:compileJava
:processResources
:classes
:proguard
:cleanAfterProguard
:unpackProguardOutput
:runProguard

如果您现在想添加 runtime 插件,对于 runtimejpackage 等任务,您将得到以下命令:

:cleanClasses
:compileJava
:processResources
:classes
:jar
:startScripts
:installDist
:jre
:runtime

你看到问题了吗?根本没有调用 proguard 任务,因为我们没有修改 runtime 任务来依赖 proguard。

解决方案

如您所见,runtimejpackage 都依赖于项目的 jar。因此,一个简单的修复方法是将 proguard 任务连接到 jar 任务中,这样我们就可以从 proguarded 类而不是原始类中创建一个 jar。

您的构建中类似的东西应该可以工作:

jar.dependsOn(unpackProguardOutput)

但是资源存在问题(受混淆的 FXML 文件将被原始文件覆盖),因为原始资源会再次复制到 jar 中。

因此我们可以修改 jar 任务:

jar {
    dependsOn 'cleanAfterProguard'
    manifest {
        attributes(
                'Main-Class': 'org.openjfx.Launcher'
        )
    }
    from zipTree("${buildDir}/proguard/output.jar")
}

这将是现在的任务顺序:

:cleanClasses
:compileJava
:processResources
:classes
:proguard
:cleanAfterProguard
:jar
:startScripts
:installDist
:jre
:runtime

现在运行./gradlew clean runtime将生成基于proguarded hellofx.jar的运行时镜像。运行 build/image/bin/hellofx 应该可以工作。

这同样适用于jpackage:

:cleanClasses
:compileJava
:processResources
:classes
:proguard
:cleanAfterProguard
:jar
:startScripts
:installDist
:jre
:jpackageImage
:jpackage

在这张图片中,您可以看到 hellofx.app 中包含的 jar 仅包含 proguarded 类。

关于java - Gradle badass-runtime-plugin 和 ProGuard Gradle 插件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58344590/

相关文章:

gradle - Gradle中的并行复制任务

java - 重命名预编译类文件的导入 (Java)

java - 集成 Spark 和 Spring Boot

java - 没有这样的属性: stopPort for class: org. gradle.api.internal.project.Default Project_Decolated

android - 错误 : Failed to resolve: com. afollestad :material-dialogs:2. 0.0

gradle - 如何将 junit 测试套件结果汇总到由 gradle 运行的单个报告中?

java - 扩展可序列化的类时要小心

java - 通过 Java 进行 Hibernate-SQLite 转储和导入

java - 应用程序从 Eclipse 导入 Android Studio,gradle 错误

java - Android Studio androidx.coordinatorlayout 错误以及如何设置 3Dot Menu?