GradleUp / shadow

Gradle plugin to create fat/uber JARs, apply file transforms, and relocate packages for applications and libraries. Gradle version of Maven's Shade plugin.
https://www.gradleup.com/shadow/
Apache License 2.0
3.72k stars 392 forks source link

Does minimize() work for Kotlin projects? #688

Open autonomousapps opened 3 years ago

autonomousapps commented 3 years ago

Please check the User Guide before submitting "how do I do 'x'?" questions!

Shadow Version

7.0.0

Gradle Version

7.1.1

Expected Behavior

shadowJar.minimize() should work for Kotlin projects.

Actual Behavior

I don't think it is.

Gradle Build Script(s)

plugins {
  id 'org.jetbrains.kotlin.jvm'
  id 'application'
  id 'com.github.johnrengelman.shadow'
}

tasks.named('shadowJar', ShadowJar) {
  group = 'Build'
  description = 'Produces a fat jar'
  archiveFileName = "$archivesBaseName-${version}-all.jar"
  reproducibleFileOrder = true

  from sourceSets.main.output
  from project.configurations.runtimeClasspath

  manifest.attributes('Main-Class': 'AppKt')

  minimize()
}
$ ./gradlew app:shadowJar -i
...
> Task :app:shadowJar
file or directory '/Users/trobalik/Development/personal/blog/shaded-distributions/app/build/classes/java/main', not found
Caching disabled for task ':app:shadowJar' because:
  Build cache is disabled
Task ':app:shadowJar' is not up-to-date because:
  Value of input property 'minimize' has changed for task ':app:shadowJar'
file or directory 'shaded-distributions/app/build/classes/java/main', not found
file or directory 'shaded-distributions/app/build/resources/main', not found
file or directory 'shaded-distributions/app/build/classes/java/main', not found
file or directory 'blog/shaded-distributions/app/build/resources/main', not found

And when I inspect the jar with jar tf app/build/libs/app-1.0-all.jar, I see files that I would not expect to be there if minification had taken place. In this case, I'd expect practically nothing to be there since what I have is a basically empty project: a simple main() method that prints hello world.

Content of Shadow JAR (jar tf <jar file> - post link to GIST if too long)

Output of jar tf...: https://gist.github.com/autonomousapps/615d7660479a34b31e2bfef1c0114861

StefanLobbenmeier commented 3 years ago

I had the same question, but I came to a different conclusion. I compared the minimized .jar file to the unminimized .jar file and while a lot of the classes have been removed, there are also a lot of classes still in there:

image

StefanLobbenmeier commented 3 years ago

You can use IntelliJs feature "Show Kotlin Bytecode" and then click Decompile to see the "resulting" Java class. I would expect this plugin to behave exactly as if this Java class would have been in the source code.

From what I can see it is mostly:

so I could not trace where all these class files are being referenced. Maybe there is some way to show the tree of transitive classes being referenced? That would really help pin down why so many classes are still there.

StefanLobbenmeier commented 3 years ago

https://github.com/johnrengelman/shadow/commit/a71f84bf67a1bb007bf150b36472267bf5d6aac9 I guess this is the commit to check if we want to understand how the process actually works

Especially relevant: https://github.com/johnrengelman/shadow/blob/455d2346a23537817a156065ad868ec317cffb73/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/internal/UnusedTracker.groovy#L26

StefanLobbenmeier commented 3 years ago

I just noticed, this is a possible duplicate of https://github.com/johnrengelman/shadow/issues/565 right?

gildor commented 2 years ago

It's not related on #565 and not duplicate

Support of R8 (requested in 565) is another issue, R8 does some things related to Kotlin, but those are just additional optimizations, it works for any JVM bytecode

Though, both issues related on minification, I don't think that improvement of existing minimize() should be mixed with proposed integration with R8