Gradle badass-runtime-plugin và ProGuard Gradle Plugin


8

Làm thế nào để chạy proguard trước jPackage?

Giới thiệu

Tôi đang phát triển một ứng dụng trong JavaFx bằng cách sử dụng các plugin gradle và đóng gói nó với jPackager, cũng sử dụng các plugin gradle.

Các plugin chính tôi đang sử dụng là:

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"

Phiên bản lớp hiện tại của tôi là: gradle-5.6.2-all

Mô tả vấn đề

Làm cách nào để sử dụng proguard để mã bị xáo trộn và tối ưu hóa trước khi jPackage thực hiện công việc của nó?

Tôi có thể chạy các tác vụ proguard, nhưng khi tôi chạy jPackage, mã không bị xáo trộn!

Ive tìm thấy một hướng dẫn ( Hướng dẫn ) cho phiên bản lớp cũ hơn tuy nhiên tôi không chắc chắn làm thế nào để kết hợp điều này với các plugin hiện tại. Tôi đã thử một vài đoạn mã nhưng tất cả đều thất bại trong việc xây dựng và tôi không muốn làm lộn xộn chủ đề này với một loạt các mã không hoạt động.

Công việc hiện tại của tôi 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
}

Người giới thiệu

Gói một ứng dụng JavaFX không mô-đun

JavaF Proguard Obfuscation


Câu trả lời:


1

Vấn đề

Khi bạn chạy một nhiệm vụ Gradle, bạn phải tính đến các nhiệm vụ sẽ được thực hiện trước đó, dựa trên sự phụ thuộc của chúng.

Trong câu trả lời Obfuscation của JavaFX mà bạn đã liên kết, bạn có thể thấy rằng các tác vụ tùy chỉnh của proguard được nối giữa chúng và khi bạn chạy ./gradlew runProguard, thực sự bạn nhận được thứ tự các nhiệm vụ này:

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

Nếu bạn muốn thêm runtimeplugin ngay bây giờ , cho các tác vụ như runtimehoặc jpackage, bạn sẽ nhận được thứ tự này:

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

Bạn có thấy vấn đề? Không có lời kêu gọi nào đối với các nhiệm vụ của proguard, bởi vì chúng tôi đã không sửa đổi runtimenhiệm vụ để phụ thuộc vào proguard.

Giải pháp

Như bạn có thể thấy, cả hai runtimejpackagephụ thuộc vào bình của dự án. Vì vậy, một sửa chữa dễ dàng sẽ kết nối proguardnhiệm vụ vào jarnhiệm vụ, vì vậy chúng tôi tạo ra một jar từ các lớp được bảo vệ thay vì các lớp ban đầu.

Một cái gì đó như thế này trong bản dựng của bạn sẽ hoạt động:

jar.dependsOn(unpackProguardOutput)

Tuy nhiên, có một vấn đề với các tài nguyên (tệp FXML được bảo vệ sẽ bị ghi đè bởi tài nguyên gốc), vì các tài nguyên ban đầu được sao chép lại vào tệp jar.

Vì vậy, chúng ta có thể sửa đổi tác vụ jar thay thế:

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

Đây sẽ là thứ tự nhiệm vụ bây giờ:

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

Bây giờ chạy ./gradlew clean runtimesẽ tạo ra một hình ảnh thời gian chạy dựa trên một proguarded hellofx.jar. Chạy build/image/bin/hellofxnên làm việc.

Điều tương tự cũng áp dụng cho jpackage:

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

Trong bức ảnh này, bạn thấy rằng cái hũ có trong hellofx.app chỉ chứa các lớp được bảo vệ.


Tuy nhiên, cảm ơn câu trả lời, tôi nghĩ rằng tôi chưa làm việc vì câu trả lời của bạn yêu cầu cái bóng đó. Vì vậy, Jar {} không được sử dụng. . ': jpackageImage', task ': jpackage']
KenobiShan

1
Tại sao bạn cần plugin bóng ở nơi đầu tiên? Bạn đang làm một trình cài đặt. Điều chỉnh bản dựng theo nhu cầu của bạn và loại bỏ những gì không cần thiết.
Jose Pereda

Tôi không biết tại sao tôi lại sử dụng plugin bóng. Tôi đã xóa và nó hoạt động ngay bây giờ: github.com/KenobySky/hellofx
KenobiShan

1
Tuyệt quá. Tốt hơn nếu bạn loại bỏ compileJava, runvà JavaFX phụ thuộc từ việc xây dựng, tất cả điều đó được đưa về chăm sóc bởi các plugin JavaFX.
Jose Pereda

1
Đây là:compile “.org.openjfx:...”
Jose Pereda

0

Xem hướng dẫn , buildscriptkhối cung cấp sự phụ thuộc trông hoàn toàn khác nhau:

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

Trong khi nó phàn nàn, rằng nó unable to resolve class proguard.gradle.ProGuardTaskcó khả năng sẽ không có proguard.gradle.ProGuardTask. Và dependsOn: 'obfuscatedJar'là lạ, bởi vì nhiệm vụ myProguardTaskđược cho là làm xáo trộn nó.

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

Cũng chắc chắn rằng, /usr/local/java/proguard/libthậm chí được cài đặt, ví dụ. với locate proguard, vì đối với Java, nó không được cung cấp bởi SDK Android - và do đó, người ta phải cung cấp nó dưới dạng buildscriptphụ thuộc. Sau đó, bạn sẽ phải viết một tùy chỉnh proguard.txt, dựa trên tất cả các cảnh báo mà nó đưa ra khi che giấu.


Cập nhật proguard-gradleplugin có thể là một tùy chọn có thể khác:

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

Để tham khảo, đây sẽ là ProGuardTask.java .


Bạn đã không giải thích chính xác làm thế nào để viết lên tác vụ cho bản dựng javafx. Cũng lưu ý rằng Jpackage được chạy sau khi xây dựng. Vì vậy, câu trả lời của bạn là không đầy đủ.
KenobiShan

@KenobiShanhow tôi sẽ trả lời hoàn toàn điều này khi không có mã Java? Khi thêm tác vụ proguard, điều này sẽ yêu cầu viết các quy tắc cấu hình, chỉ có thể được viết khi proguard phàn nàn về các lớp bị thiếu và giống nhau.
Martin Zeitler

Build.gradle không yêu cầu "mã java". Lưu ý rằng câu hỏi liên quan đến việc sử dụng proguard với các plugin có liên quan và với proguard liên quan. Việc sử dụng proguard là không đáng kể trong các ứng dụng java phổ biến, tuy nhiên, những hạn chế đó là điều khiến mọi người tò mò về câu hỏi này
KenobiShan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.