Any idea how to use Proguard with Kotlin/JVM (non Android project)?

This question might be marked as duplicated but I spent days searching all over the internet and I couldn’t understand how I can use it to reduce the jar file size and I already saw many questions like this (the issue from my side)

Let’s say you want to make a very lightweight script in Kotlin/JVM and ship it as jar, and you want to use some dependencies so you will want to use something like Shadow jar Gradle plugin to include the dependencies sinde the default jar task wouldn’t, shadow jar already have minimize option but it doesn’t do much as it’s not designed for that,1.6MB for a hello world program that use zero imports is a little bit overkill

All I know proguard is a tool designed primarily for reducing the jar and do other similar tasks

Adding proguard gradle task along with the plugin as build task, defining in and out jar

But when running the proguard task it says I should solve the warrnings but doesn’t provide any warrings, running the task with --info will make the log very long and still can’t understand what’s wrong, searching on Stackoverflow answers says I should add ignore warrnings in the proguard-rules.pro which doesn’t sound like a solution to me but I tried anyway

After that I get different error says I should define steps for what to keep

I don’t understand this, Proguard is designed for detecting what is used and what is not automatically but sometimes you should define what to keep and what to not because of reflection for example

But shouldn’t choosing what to keep and what to not is optional??

I didn’t quite understand how it work and searched from many places and used the rules template and doesn’t seems to work regarding of what I do, one template worked but I’m getting error says ClassNotFound Exception for MainKt

On Android projects we rarely have to deal with this file, I just want to get started and using proguard on hello world in Kotlin to reduce the 1.6MB with no imports but still include many things like kotlin collections

There are other tools like shakyboi and did just that with minimal configurations but is more experimental and unfinished and doesn’t reduce much as the project grow but did incredible jar file size reduce for hello world program from 1.6MB to about kilobytes

I appreciate your work and help on proguard but I really want to try it out correctly, and I just want to get started with minimal configurations in Kotlin/JVM for hello world program

Then I would start adding dependencies and more code and functionalities

Thank you

Hi @AhHne1,

Regarding Integration;
To integrate ProGuard with non-android Java/Kotlin projects, you can follow these steps:

Next, you need to pass in a proguard configuration file.

Something like this:

proguard {
configuration ‘proguard-rules.pro’
injars ‘build/path/to/your-app.jar’
outjars ‘build/path/to/your-app-proguarded.jar’
}

Once complete, you can rebuild and PG will shrink/optimize your JAR file.

You can also post-process your JAR file with ProGuard as explained here:

Regarding Configuration;
ProGuard may provide some default configuration as you mentioned. However, during the shrinking and optimization step, it may remove aspects of your application that are required. In this case, you need to provide a -keep rule to preserve that portion of code.

You can read more Keep Options here

(Scroll down to ‘Keep Options’ and ‘Overview of Keep Options’ sections)

Regarding Errors;
ClassNotFoundException: This indicates a class was removed during shrinking or optimization.

If you’re getting a ClassNotFoundException for Main.kt, the class was most likely removed during the shrinking or optimization step. ProGuard does this in good faith to make your project smaller and faster. But sometimes you will need to provide additional -keep options (in your proguard configuration file) to retain necessary classes and make sure elements of your code are not removed to aggressively by ProGuard.

For example:
-keep class com.example.Main {*;}

This will keep the class so it’s not removed and it’s name not obfuscated.

Once complete, you can re-build your project and test again to confirm the error is gone.

This is an iterative process which you need to repeat to solve new errors.

Regarding Notes/Warnings:
Notes and Warnings are not fatal. As long as you test your application and it works as expected after providing the necessary -keep options, you can safely suppress them with the -dontnote or -dontwarn option:

ProGuard Playground;
To make things easier, we introduced the ProGuard Playground.

You can upload your JAR file and input -keep rules. Then, it will show you the impact so you can see what classes will be kept as a result of that -keep option without needed to rebuild. This can save you time and help you get familiar with construction -keep options quicker.

Please let me know if anything is not clear.
Kind Regards,
Jack

1 Like

I was already able to solve this (didn’t a notification to the message), thank you for the detailed answer though, The answer is clear and helpful.

Unrelated to this question:

Is there a way to exclude a specific library/dependency completely from the minimization? using -keep class com.example.library.** { *; } didn’t fix the issue in my case, I have different versions of the JAR,

Fat JAR, and the other two versions, one minimized by Proguard and the other by Shadow JAR Plugin, I use a library that heavily depends on reflections and one way to fix the runtime issues is to exclude it from minimization/shrinking completely, Shadow JAR has a exclude function to exclude from minimization, Progaurd has the -keep class which will keep it without removing it, however, I’m not sure if it will modify it in any way, I tried with different ways to get it working but wasn’t able to fix the runtime error, even after using the -keep class for the library I’m still getting a different error, I’m wondering if there is an issue to exclude it from minimizations and modifications by Progaurd. Thank you once again.

Edit: It appears I didn’t include java.desktop.jmod which is why this issue happened. Fixed.