From a0aebcc477d639eb52d1682f398ec60b45ee17f4 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+ellet0@users.noreply.github.com> Date: Tue, 21 May 2024 20:09:29 +0300 Subject: [PATCH 1/4] docs: Include a note for using Proguard/Shadow with FlatLaf in README.md --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 4588d17dc..062114b71 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,24 @@ See also for instructions on how to redistribute FlatLaf native libraries with your application. +Proguard/Shadow JAR +-------- + +If you are using [Gradle Shadow JAR Plugin](https://github.com/johnrengelman/shadow) to build the jar for your application and `minimize()` function to minimize the size in the configurations of `shadowJar` task, then you will get an exception `java.lang.Error: no ComponentUI class for:` when running the jar, that's because Swing and Flatlaf both use Reflection, one way to fix this issue without removing the `minimize()` is to exclude Flatlaf from being minimized by using the following: + +```groovy + +shadowJar { + // Your shadow configurations + minimize { + // Exclude the entire FlatLaf dependency from minimization to fix `no ComponentUI class for: javax.swing.` + exclude(dependency("com.formdev:flatlaf:.*")) + } +} + +``` + +Use a similar solution if you use other tools like Proguard, for [more details](https://github.com/JFormDesigner/FlatLaf/issues/648#issuecomment-1441547550) ### Snapshots From 73aea0f46181844ede3533726ce6d55aac56c931 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+ellet0@users.noreply.github.com> Date: Thu, 6 Jun 2024 10:11:11 +0300 Subject: [PATCH 2/4] docs: add steps for excluding Flatlaf from minimizations when using Proguard --- README.md | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 062114b71..21cdf54e8 100644 --- a/README.md +++ b/README.md @@ -74,21 +74,89 @@ application. Proguard/Shadow JAR -------- -If you are using [Gradle Shadow JAR Plugin](https://github.com/johnrengelman/shadow) to build the jar for your application and `minimize()` function to minimize the size in the configurations of `shadowJar` task, then you will get an exception `java.lang.Error: no ComponentUI class for:` when running the jar, that's because Swing and Flatlaf both use Reflection, one way to fix this issue without removing the `minimize()` is to exclude Flatlaf from being minimized by using the following: +Flatlaf and Swing Desktop both use reflections in the code and other features like dynamic class loading, and +minimization/shrinking tools like Proguard/Shadow JAR won't be able to see these references. Explicit rules are +necessary to retain these classes. + +If you're trying to run the application without excluding Flatlaf from minimization, you will get a runtime error: +``` +java.lang.Error: no ComponentUI class for: javax.swing. +``` + +At the moment, we don't have support for minimization tools; however, the issue can be +solved very easily by excluding FlatLaf from minimization; the steps will depend on the tool you're using. + +The steps are **not guaranteed**, in most cases, it should work. + +
+ Proguard + +1. First of all, make sure you're including `java.desktop.jmod` and `java.base.jmod` by `libraryjars` using Proguard + rules, this is needed so Proguard can have access to the JDK modules that are being used in your application, + this step is not specific to Flatlaf, `java.desktop.jmod` is needed when using Java Swing/Desktop in general. + + An example of using Proguard in Gradle Kotlin DSL: + + ```kotlin + tasks.register("minimizedJar") { + + // Your Proguard configurations + + // Automatically handle the Java version of this build. + val javaHome = System.getProperty("java.home") + if (System.getProperty("java.version").startsWith("1.")) { + // Before Java 9, runtime classes are packaged in a single JAR file. + libraryjars("$javaHome/lib/rt.jar") + } else { + // Starting from Java 9, runtime classes are packaged in modular JMOD files. + libraryjars( + mapOf("jarfilter" to "!**.jar", "filter" to "!module-info.class"), + "$javaHome/jmods/java.base.jmod", + ) + // Needed to support Java Swing/Desktop + libraryjars( + mapOf("jarfilter" to "!**.jar", "filter" to "!module-info.class"), + "$javaHome/jmods/java.desktop.jmod", + ) + } + } + ``` + +2. Include the following in your Proguard configurations/rules, which is usually in `proguard.pro` file: + ``` + # Exclude the FlatLaf dependency from minimization to fix `no ComponentUI class for: javax.swing.` + -keep class com.formdev.flatlaf.** { *; } + -dontwarn com.formdev.flatlaf.** + ``` + +Try to run the application now and test anything that uses Flatlaf. + +
+ +
+ Shadow JAR Minimization + +[Gradle Shadow JAR Plugin](https://github.com/johnrengelman/shadow) is primarily +for building fat JAR for your application, it has a `minimize()` function to minimize the JAR +in the configurations of `shadowJar` task, use the following snippet in your `build.gradle` (or `build.gradle.kts`) ```groovy shadowJar { // Your shadow configurations minimize { - // Exclude the entire FlatLaf dependency from minimization to fix `no ComponentUI class for: javax.swing.` + // Exclude the FlatLaf dependency from minimization to fix `no ComponentUI class for: javax.swing.` exclude(dependency("com.formdev:flatlaf:.*")) } } ``` -Use a similar solution if you use other tools like Proguard, for [more details](https://github.com/JFormDesigner/FlatLaf/issues/648#issuecomment-1441547550) +Try to run the application now and test anything that uses Flatlaf. + +
+ +Use a similar solution for other tools. ### Snapshots From 82bfa1fbf62c7bfad5c3e2d5cba84723e3e34244 Mon Sep 17 00:00:00 2001 From: Ellet <73608287+ellet0@users.noreply.github.com> Date: Sat, 8 Jun 2024 16:26:37 +0300 Subject: [PATCH 3/4] docs: improve the include Java module example for Proguard --- README.md | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 21cdf54e8..55b75ac79 100644 --- a/README.md +++ b/README.md @@ -109,15 +109,25 @@ The steps are **not guaranteed**, in most cases, it should work. libraryjars("$javaHome/lib/rt.jar") } else { // Starting from Java 9, runtime classes are packaged in modular JMOD files. - libraryjars( - mapOf("jarfilter" to "!**.jar", "filter" to "!module-info.class"), - "$javaHome/jmods/java.base.jmod", - ) - // Needed to support Java Swing/Desktop - libraryjars( - mapOf("jarfilter" to "!**.jar", "filter" to "!module-info.class"), - "$javaHome/jmods/java.desktop.jmod", - ) + fun includeJdkModule(jModFileNameWithoutExtension: String) { + val jModFilePath = Paths.get(javaHome, "jmods", "$jModFileNameWithoutExtension.jmod").toString() + val jModFile = File(jModFilePath) + if (!jModFile.exists()) { + throw FileNotFoundException("The '$jModFile' at '$jModFilePath' doesn't exist.") + } + libraryjars( + mapOf("jarfilter" to "!**.jar", "filter" to "!module-info.class"), + jModFilePath, + ) + } + + val javaModules = + listOf( + "java.base", + // Needed to support Java Swing/Desktop + "java.desktop", + ) + javaModules.forEach { includeJdkModule(it) } } } ``` From 95f48b044c9d4d1ead6f3eafa116ec326b6ded71 Mon Sep 17 00:00:00 2001 From: Ellet Date: Tue, 10 Sep 2024 16:55:42 +0300 Subject: [PATCH 4/4] docs: enhance documentation with updates in this PR --- README.md | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 55b75ac79..93c971137 100644 --- a/README.md +++ b/README.md @@ -74,26 +74,33 @@ application. Proguard/Shadow JAR -------- -Flatlaf and Swing Desktop both use reflections in the code and other features like dynamic class loading, and -minimization/shrinking tools like Proguard/Shadow JAR won't be able to see these references. Explicit rules are -necessary to retain these classes. +**FlatLaf** and **Swing Desktop** both use reflections, and dynamic class loading. + +Minimization/Shrinking tools (e.g. **Proguard/Shadow JAR**) are unable to detect these references. +Explicit rules are necessary to retain these classes. If you're trying to run the application without excluding Flatlaf from minimization, you will get a runtime error: -``` + +```console java.lang.Error: no ComponentUI class for: javax.swing. ``` At the moment, we don't have support for minimization tools; however, the issue can be -solved very easily by excluding FlatLaf from minimization; the steps will depend on the tool you're using. +solved by excluding **FlatLaf** from being minimized without disabling code shrinking completely. + +**FlatLaf** adds only a minimal increase to the bundle size. + +The steps will depend on the tool you're using. -The steps are **not guaranteed**, in most cases, it should work. +> [!NOTE] +> The steps are **not guaranteed**, but they should work in most cases.
Proguard -1. First of all, make sure you're including `java.desktop.jmod` and `java.base.jmod` by `libraryjars` using Proguard +1. Include the modules `java.desktop` and `java.base` by `libraryjars` using Proguard rules, this is needed so Proguard can have access to the JDK modules that are being used in your application, - this step is not specific to Flatlaf, `java.desktop.jmod` is needed when using Java Swing/Desktop in general. + this step is not specific to **FlatLaf**, `java.desktop` is needed when using Java Swing/Desktop. An example of using Proguard in Gradle Kotlin DSL: @@ -139,7 +146,7 @@ The steps are **not guaranteed**, in most cases, it should work. -dontwarn com.formdev.flatlaf.** ``` -Try to run the application now and test anything that uses Flatlaf. +Try to run the application now and test all features that use **FlatLaf** in runtime.
@@ -162,7 +169,7 @@ shadowJar { ``` -Try to run the application now and test anything that uses Flatlaf. +Try to run the application now and test all features that use **FlatLaf** in runtime.