title: Obfuscation for Compose Desktop application. Probably with ProGuard
body: <p>Our main task is to  make a GUI application on Windows (and preferably on Mac too) so it would be impossible/extremely difficult to find out the source code (Kotlin). Question is = how to do it?</p>
  <p>Ideally, I would like to know:</p>
  <p>.1. Tools to get the source code from our executable/files executable depends on.</p>
  <p>.2. Tools for code obfuscation to the level where the tools of the previous point won't work.</p>
  <p>.3. Next section is about what I did in Compose Desktop, but I do not limit myself to it. If you, for example, know how to make a working project with encrypted Kotlin code in JavaFx or something else, please let me know.</p>
  <p>What has been done so far:
  In Compose Desktop generated a <code>.msi</code> file, which on Windows creates files, and among them there are <code>.jar</code> files.
  I opened one of the <code>.jar</code> in <a href="http://java-decompiler.github.io/" rel="nofollow noreferrer">here</a> and there was it = my beautiful source code, although in Java, but even the variables were not renamed!</p>
  <p>Next I changed <code>build.gradle.kts</code> according to <a href="https://gist.github.com/mcpiroman/cf511c5f9312a59e8f821706738eeab3" rel="nofollow noreferrer">template</a></p>
  <p>Important note = I do not understand this template. Perhaps I did something wrong.
  I'll added the code, take a look.
  But at least <code>.msi</code> got built and it installed the rest as previously. And again the same story = I open the <code>.jar</code> and see the source code in Java with variables not renamed!
  But again = not even sure if this template is supposed to make the code in <code>.jar</code> unreadable.</p>
  <p>Note = never done/learned custom obfuscation before. I work mainly with Kotlin and Android Studio. For Compose Desktop installed IntelliJ Idea.</p>
  <p>Code:</p>
  <p>build.gradle.kts</p>
  <pre><code>import org.jetbrains.compose.compose
  import org.jetbrains.compose.desktop.application.dsl.TargetFormat
  
  buildscript {
      dependencies {
          classpath(&quot;com.guardsquare:proguard-gradle:7.2.1&quot;)
      }
  }
  
  repositories {
      google()
      mavenCentral()
      maven(&quot;https://maven.pkg.jetbrains.space/public/p/compose/dev&quot;)
  }
  
  plugins {
      kotlin(&quot;jvm&quot;) version &quot;1.6.10&quot;
      id(&quot;org.jetbrains.compose&quot;) version &quot;1.1.1&quot;
  }
  
  dependencies {
      implementation(compose.desktop.currentOs)
  }
  val obfuscate by tasks.registering(proguard.gradle.ProGuardTask::class)
  
  fun mapObfuscatedJarFile(file: File) =
      File(&quot;${project.buildDir}/tmp/obfuscated/${file.nameWithoutExtension}.min.jar&quot;)
  
  compose.desktop {
      application {
          mainClass = &quot;MainKt&quot;
          nativeDistributions {
              targetFormats(TargetFormat.Exe, TargetFormat.Msi, TargetFormat.Deb)
              packageName = &quot;untitled_04&quot;
              packageVersion = &quot;1.0.0&quot;
          }
      }
  }
  
  
  obfuscate.configure {
      dependsOn(tasks.jar.get())
  
      val allJars = tasks.jar.get().outputs.files + sourceSets.main.get().runtimeClasspath.filter { it.path.endsWith(&quot;.jar&quot;) }
          .filterNot { it.name.startsWith(&quot;skiko-awt-&quot;) &amp;&amp; !it.name.startsWith(&quot;skiko-awt-runtime-&quot;) } // walkaround https://github.com/JetBrains/compose-jb/issues/1971
  
      for (file in allJars) {
          injars(file)
          outjars(mapObfuscatedJarFile(file))
      }
  
      libraryjars(&quot;${compose.desktop.application.javaHome ?: System.getProperty(&quot;java.home&quot;)}/jmods&quot;)
  
      configuration(&quot;proguard-rules.pro&quot;)
  }
  </code></pre>
  <p>proguard-rules.pro</p>
  <pre><code>-keepclasseswithmembers public class MainKt {
      public static void main(java.lang.String[]);
  }
  
  -dontwarn kotlinx.coroutines.debug.*
  
  -keep class kotlin.** { *; }
  -keep class kotlinx.coroutines.** { *; }
  -keep class org.jetbrains.skia.** { *; }
  -keep class org.jetbrains.skiko.** { *; }
  
  -assumenosideeffects public class androidx.compose.runtime.ComposerKt {
      void sourceInformation(androidx.compose.runtime.Composer,java.lang.String);
      void sourceInformationMarkerStart(androidx.compose.runtime.Composer,int,java.lang.String);
      void sourceInformationMarkerEnd(androidx.compose.runtime.Composer);
  }
  </code></pre>