JavaFX Proguard混淆 [英] JavaFX Proguard Obfuscation

查看:198
本文介绍了JavaFX Proguard混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力处理JavaFX应用程序的混淆问题.以此项目为基础:

I'm struggling with obfuscation of JavaFX application. Using this project as a base:

https://github.com/openjfx/样本/树/母版/IDE/IntelliJ/非模块化/Gradle

Proguard抛出此错误:

Proguard throws this error:

java.io.IOException: Can't write [Path\infile.jar] (Can't read [Path\outfile.jar] (Duplicate jar entry [a.class]))

Proguard配置文件: -dontoptimize -dontshrink

Proguard config file: -dontoptimize -dontshrink

-libraryjars 'E:\Prog\jdk-11.0.2\jmods'
-libraryjars 'E:\Prog\javafx-sdk\lib'

# Save meta-data for stack traces
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable

# Rename FXML files together with related views
-adaptresourcefilenames **.fxml,**.png,**.css
-adaptresourcefilecontents **.fxml
-adaptclassstrings

# Keep all annotations and meta-data
-keepattributes *Annotation*,Signature,EnclosingMethod

# Keep entry-point class
-keep classpackage.App {
    public static void main(java.lang.String[]);
}

# Keep all classes inside application
-keep,allowobfuscation class package.** {
}

# Keep names of fields marked with @FXML attribute
-keepclassmembers class * {
    @javafx.fxml.FXML *;
}

有人对JavaFX混淆有经验吗?

Anybody have experience with JavaFX obfuscation?

推荐答案

要使Proguard使用Java 11,我们需要:

To get Proguard working with Java 11 we need:

  • 最新的Proguard 测试版,在这种情况下适用于Gradle.

  • The latest Proguard beta version, for Gradle in this case.

修改构建gradle文件以包含proguard任务.

Modify the build gradle file to include the proguard task.

添加一个proguard配置文件,其中包括Java 11所需的更改.

Add a proguard config file including the required changes for Java 11.

Build.gradle

从HelloFX 示例开始,该版本将修改为:

Starting from the HelloFX sample, the build will be modified to:

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

plugins {
  id 'application'
  id 'org.openjfx.javafxplugin' version '0.0.7'
}

repositories {
    mavenCentral()
}

dependencies {
}

javafx {
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

mainClassName = 'org.openjfx.MainApp'

我将添加一些其他任务,而不是仅添加proguard任务,以默认的构建/类替换受保护的任务.这有助于检查结果.

Instead of just adding the proguard task, I'll add a few more tasks to replace the default build/classes with the proguarded ones. This helps inspecting the result.

// 2. Add tasks

// 2.1 Clean buildDir before running proguard
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")
}

最后,添加一个任务以使用受保护的类运行应用程序.

Finally, add a task to run the application with the proguarded classes.

// 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 = 'a.a.b' // <-- this name will depend on the proguard result
}

proguard.conf

有关如何使其与Java 9+一起使用的密钥,可以在以下

The key on how to get it working with Java 9+ can be found in this comment. If you download the source code, and check the examples folder, there are different configuration files.

检查applications.pro,您可以阅读:

# Before Java 9, the runtime classes were packaged in a single jar file.
#-libraryjars <java.home>/lib/rt.jar

# As of Java 9, the runtime classes are packaged in modular jmod files.
-libraryjars <java.home>/jmods/java.base.jmod(!**.jar;!module-info.class)

就这样!

这是我与HelloFX示例一起使用的配置文件(当然,可以使用其他许多选项对其进行扩展):

This is the config file I've used with the HelloFX sample (of course it could be extended with other many options):

-dontoptimize
-dontshrink

#Java 9+
-libraryjars <java.home>/jmods/java.base.jmod(!**.jar;!module-info.class)

# Save meta-data for stack traces
-printmapping out.map
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable

# Rename FXML files together with related views
-adaptresourcefilenames **.fxml,**.png,**.css,**.properties
-adaptresourcefilecontents **.fxml
-adaptclassstrings

# Keep all annotations and meta-data
-keepattributes *Annotation*,Signature,EnclosingMethod

# Keep entry-point class
-keep class org.openfjx.MainApp {
  public static void main(java.lang.String[]);
}

# Keep names of fields marked with @FXML, @Inject and @PostConstruct attributes
-keepclassmembers class * {
  @javafx.fxml.FXML *;
  @javax.inject.Inject *;
  @javax.annotation.PostConstruct *;
}

结果

如果运行./gradlew proguard,将得到output.jar.

如果运行./gradlew unpackProguardOutput,则可以在build/classes中查看结果:

If you run ./gradlew unpackProguardOutput, you can see the result in build/classes:

main
|____a
| |____a
| | |____styles.css
| | |____scene.fxml
| | |____b.class
| | |____a.class

在这种情况下,b.class是主要类,所以这就是为什么在runProguard任务中我设置了main = 'a.a.b'的原因.显然,这取决于每种情况.

In this case, b.class is the main class, so this is why in the runProguard task I've set main = 'a.a.b'. This will depend on each case, obviously.

此外,您还可以查看out.map:

Also, you can check the out.map:

org.openjfx.FXMLController -> a.a.a:
    javafx.scene.control.Label label -> label
    10:10:void <init>() -> <init>
    17:20:void initialize(java.net.URL,java.util.ResourceBundle) -> initialize
org.openjfx.MainApp -> a.a.b:
    11:11:void <init>() -> <init>
    15:23:void start(javafx.stage.Stage) -> start
    26:27:void main(java.lang.String[]) -> a

最后,./gradlew runProguard将成功运行该应用程序.

Finally, ./gradlew runProguard will successfully run the application.

这篇关于JavaFX Proguard混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆