Gradle badass-runtime-plugin и ProGuard Gradle Plugin - PullRequest
8 голосов
/ 11 октября 2019

Как запустить proguard перед jPackage?

Введение

Я занимаюсь разработкой приложения в 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код не запутывается!

Я нашел учебное пособие ( Tutorial ) для более старой версии Gradle, однако я не уверен, как смешать это с текущими плагинами. Я попробовал несколько фрагментов кода, но все они не удалось собрать, и я не хочу загромождать эту тему кучей нерабочего кода.

Мой текущий рабочий 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
}

Ссылки

Пакет немодульного приложения JavaFX

JavaFX Proguard Obfuscation


Ответы [ 2 ]

1 голос
/ 30 октября 2019

Проблема

При запуске задачи Gradle необходимо учитывать задачи, которые будут выполнены ранее, исходя из их зависимостей.

В JavaFX Proguard Obfuscation ответ, который вы связали, вы можете видеть, что пользовательские задачи proguard объединяются между ними, и когда вы запускаете ./gradlew runProguard, фактически вы получаете такой порядок задач:

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

Если вы хотите добавить плагин runtime, для таких задач, как runtime или jpackage, вы получите следующий заказ:

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

Вы видите проблему? Нет никакого вызова к задачам proguard, потому что мы не изменили задачу runtime, чтобы она зависела от proguard.

Решение

Как вы можете видетьи runtime, и jpackage зависят от фляги проекта. Поэтому одним простым исправлением будет подключение задачи proguard к задаче jar, поэтому мы создаем банку из защищенных классов вместо исходных.

Что-то подобное в вашей сборке должно работать:

jar.dependsOn(unpackProguardOutput)

Однако существует проблема с ресурсами (защищенный файл FXML будет перезаписан исходным), поскольку исходные ресурсы снова копируются в банку.

Итаквместо этого мы можем изменить задачу 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 будет генерироваться образ времени выполнения на основе защищенной hellofx.jar. Запуск build/image/bin/hellofx должен работать.

То же самое относится к jpackage:

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

На этом рисунке вы видите, что jar, включенный в hellofx.app, содержит только защищенные классы.

image

0 голосов
/ 20 октября 2019

См. руководство , блок buildscript, который обеспечивает зависимость, выглядит совершенно по-другому:

buildscript {
    repositories {
        flatDir dirs: '/usr/local/java/proguard/lib'
    }
    dependencies {
        classpath ':proguard:'
    }
}

Хотя он жалуется, что это unable to resolve class proguard.gradle.ProGuardTask, там, вероятно, победил 'быть любым proguard.gradle.ProGuardTask. И dependsOn: 'obfuscatedJar' странно, потому что задача myProguardTask должна его скрыть.

task myProguardTask(type: proguard.gradle.ProGuardTask) {
    ...
}

Также убедитесь, что /usr/local/java/proguard/lib даже установлен, например. с locate proguard, потому что для Java он не предоставляется Android SDK - и поэтому нужно предоставить его как buildscript зависимость. Затем вам нужно написать пользовательский proguard.txt, основанный на всех предупреждениях, которые он выдает при запутывании.


Обновление плагина proguard-gradle может быть другой возможной опцией:

dependencies {
    classpath 'net.sf.proguard:proguard-gradle:6.2.0'
}

Для справки это будет ProGuardTask.java .

...