johnrengelman / 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.
http://imperceptiblethoughts.com/shadow/
Apache License 2.0
3.58k stars 386 forks source link

Is it possible to specify the entry points for minimize configuration? #885

Open chorniyn opened 8 months ago

chorniyn commented 8 months ago

Use Case: The final jar contains multiple classes A and B from which the execution can start (these are the AWS lambda handlers).

Question: Is it possible to configure minimizing so that it would clean everything except A, B and their transitive dependencies?

maxlim33 commented 5 months ago

I wonder this as well. It will be extremely helpful for my use case as well, which is similar to yours.

This is possible with Maven Shade's :

By default, all of the target module’s classes are kept and used as entry points for JAR minimization. By explicitly limiting the set of entry points, you can further minimize the set of classes kept in the shaded JAR. This affects both classes in the module itself and dependency classes.

It seems that there is something similar in Gradle Shadow: #273, which is closed. Unfortunately, I am new and I can't understand. Perhaps, you can make sense of it?

maxlim33 commented 5 months ago

I have taken the time to try to understand the commit from superbobry in #273, following snippet will remove unused classes in my own project:

import org.vafer.jdependency.Clazz
import org.vafer.jdependency.Clazzpath

final entryPoint = 'com.example.testgroovy.HelloWorld'

shadowJar {
    doFirst {
        final cp = new Clazzpath()
        for (SourceSet sourceSet in sourceSets) {
            FileCollection sourceSetClassesDirs = sourceSet.output.classesDirs
            sourceSetClassesDirs.each { File classDir ->
                if (classDir.isDirectory()) {
                    cp.addClazzpathUnit(classDir)
                }
            }
        }
        Set<Clazz> unused = cp.clazzes
        Clazz clazz = cp.getClazz(entryPoint)
        if (clazz == null) {
            throw new RuntimeException("Entry point not found: " + entryPoint);
        }

        unused.remove(clazz)
        unused.removeAll(clazz.transitiveDependencies)

        unused.collect { it.name }.toSet()
        exclude(unused.collect { it.name.replaceAll(/\./, '/') + '.class' }.toSet())
    }
    minimize()
}

So far, I have just tested a simple setups for my project. This is still a good starting point.

Vampire commented 5 months ago

I am new and I can't understand. Perhaps, you can make sense of it?

That PR added minimization possibility at all, including entrypoint support. But it was closed without being merged. A different PR (#390) was instead merged which does not have the entrypoint functionality, hence this issue about the missing entrypoint support.

PS: Changing the configuration of a task at execution time like in your snippet is generally a pretty bad idea and if you ever want to use configuration cache, it even is forbidden.