I'm struggling with obfuscation of JavaFX application. Using this project as a base:
https://github.com/openjfx/samples/tree/master/IDE/IntelliJ/Non-Modular/Gradle
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 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 *;
}
Anybody have experience with JavaFX obfuscation?
To get Proguard working with Java 11 we need:
The latest Proguard beta version, for Gradle in this case.
Modify the build gradle file to include the proguard task.
Add a proguard config file including the required changes for Java 11.
Build.gradle
Starting from the HelloFX sample, the build will be modified to:
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.
Finally, add a task to run the application with the proguarded classes.
proguard.conf
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.
Checking
applications.pro
, you can read:So that's it!
This is the config file I've used with the HelloFX sample (of course it could be extended with other many options):
Result
If you run
./gradlew proguard
, you will get theoutput.jar
.If you run
./gradlew unpackProguardOutput
, you can see the result inbuild/classes
:In this case,
b.class
is the main class, so this is why in therunProguard
task I've setmain = 'a.a.b'
. This will depend on each case, obviously.Also, you can check the out.map:
Finally,
./gradlew runProguard
will successfully run the application.