Gradle badass-runtime-plugin e ProGuard Gradle Plugin

8

Como executar o programa antes do jPackage?

Introdução

Estou desenvolvendo um aplicativo em JavaFx usando plugins gradle e empacotando-o com o jPackager, também usando os plugins gradle.

Os principais plugins que estou usando são:

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"

Minha versão atual do gradle é: gradle-5.6.2-all

Descrição do Problema

Como uso o proguard para que o código seja ofuscado e otimizado antes do jPackage fazer seu trabalho?

Posso executar as tarefas proguard, mas quando executo o jPackage, o código não fica ofuscado!

Eu encontrei um tutorial ( Tutorial ) para uma versão gradle mais antiga, no entanto, não tenho certeza de como misturar isso com os plugins atuais. Eu tentei alguns trechos de código, mas todos eles falharam ao criar e não quero desordenar este tópico com um monte de código não funcional.

Meu build.gradle de trabalho atual

// 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
}

Referências

Empacote um aplicativo JavaFX não modular

Ofuscação do programa JavaFX


KenobiShan
fonte

Respostas:

1

Problema

Ao executar uma tarefa Gradle, é necessário levar em consideração as tarefas que serão executadas anteriormente, com base em suas dependências.

Na resposta JavaFX Proguard Obfuscation que você vinculou, é possível ver que as tarefas personalizadas proguard são concatenadas entre elas e, quando você executa ./gradlew runProguard, na verdade, você recebe esta ordem de tarefas:

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

Se você deseja adicionar o runtimeplugin now there , para tarefas como runtimeou jpackage, você receberá esta ordem:

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

Você vê o problema? Não há chamada para as tarefas proguard, porque não modificamos a runtimetarefa para depender do proguard.

Solução

Como você pode ver, ambos runtimee jpackagedependem do jarro do projeto. Portanto, uma solução fácil será conectar a proguardtarefa à jartarefa; portanto, criamos um jarro das classes programadas em vez das originais.

Algo assim em sua compilação deve funcionar:

jar.dependsOn(unpackProguardOutput)

No entanto, há um problema com os recursos (o arquivo FXML programado será substituído pelo original), porque os recursos originais são copiados novamente para o jar.

Portanto, podemos modificar a tarefa jar:

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

Esta será a ordem das tarefas agora:

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

Agora, a execução ./gradlew clean runtimegerará uma imagem de tempo de execução com base em um programa hellofx.jar. Correr build/image/bin/hellofxdeve funcionar.

O mesmo se aplica a jpackage:

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

Nesta foto, você vê que o jar incluído no hellofx.app contém apenas classes programadas.

José Pereda
fonte
Obrigado pela resposta, no entanto, acho que a minha ainda não está funcionando porque Sua resposta exige esse dep de shadowjar. Portanto, o Jar {} não é usado. [tarefa ': cleanClasses', tarefa ': compileJava', tarefa ': processResources', tarefa ': classes', tarefa ': shadowJar', tarefa ': startShadowScripts', tarefa ': installShadowDist', tarefa ': jre', task ': jpackageImage', task ': jpackage']
KenobiShan
1
Por que você precisa do plugin shadow em primeiro lugar? Você está fazendo um instalador. Adapte a construção às suas necessidades e remova o que não é necessário.
José Pereda
Não sei por que estava usando o plugin de sombra. I removido e seu trabalho agora: github.com/KenobySky/hellofx
KenobiShan
1
Ótimo. Melhor se você remover compileJava, rune o JavaFX dependências da compilação, tudo isso é tomado cuidado de pelo plugin JavaFX.
José Pereda
1
Estes:compile “.org.openjfx:...”
José Pereda
0

Veja o manual , o buildscriptbloco que fornece a dependência parece totalmente diferente:

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

Enquanto reclama, é verdade unable to resolve class proguard.gradle.ProGuardTask, provavelmente não haverá proguard.gradle.ProGuardTask. E dependsOn: 'obfuscatedJar'é estranho, porque a tarefa myProguardTaskdeve ofuscá-la.

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

Verifique também se /usr/local/java/proguard/libestá instalado, por exemplo. com locate proguard, porque para Java não está sendo fornecido pelo Android SDK - e, portanto, é preciso fornecê-lo como buildscriptdependência. Então você terá que escrever um costume proguard.txt, com base em todos os avisos que lança ao ofuscar.


A atualização do proguard-gradleplug - in pode ser outra opção possível:

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

Para referência, seria o ProGuardTask.java .

Martin Zeitler
fonte
Você não explicou corretamente como escrever a tarefa para a compilação javafx. Observe também que o Jpackage é executado após a compilação. Portanto, sua resposta está incompleta.
KenobiShan
@KenobiShanhow devo responder isso completamente, quando não tiver o código Java? Quando adicionada a tarefa proguard, isso exigirá a criação de regras de configuração, que só podem ser escritas quando o proguard estiver reclamando da falta de classes e similares.
Martin Zeitler
O build.gradle não requer o "código java". Observe que a pergunta é sobre o uso de proguard com os plugins envolvidos e com o proguard envolvido. O uso de proguard é trivial em aplicações Java comum, no entanto, essas restrições é o que está fazendo as pessoas curiosas sobre esta questão
KenobiShan