Please explain the very Intricate philosophy of Gradle!

Over week I’m trying to understand how Gradle works! A lot of solutions in internet and most of them doesn’t work, I cannot repeat them.
I want just to create uber jar. I found plugin
http://imperceptiblethoughts.com/shadow/
I repeated just as written there
put in code

shadowJar {
println '!!! SHADOW JAR’
baseName = ‘shadow’
}

This task is mentioned on configuration stage. But it never called when I run gradle build. Why?
Should I set something like ‘build dependsOn shadowJar’ ? Or what way I have to run this task during build task?
Maybe I have to add something like

shadowJar.execute()

after configuration block?

Thanks in advance!

at command line, simply call gradle shadowJar

don’t forget toapply plugin: 'java' or any other plugin you will use

gradlew task does list all available tasks.

Thanks for answer.
How it will look for complete build (on Jenkins for example)? If I want assemble build completely I should run command like
’gradle shadowJar build’ ?

If you want the shadow jar to be part of the ‘gradle build’, just add build.dependsOn(shadowJar) somewhere in your build script.

So if shadow task even extends Jar task it will not be run on Jar stage without additional command like
build.dependsOn(shadowJar) , correct?

No, it won’t. As you mentioned, on the surface the tasks are much closer to the Ant model (ignoring the notion of actions , up-to-date checking, etc.)

In addition to having fine grain control over the task ordering/lack of imposed structure, you may register multiple instances of the same task, with different parameters and dependencies,

The only hard requirement is that the task graph can not be modified once it starts executing. It is also a bad practice (though convenient at times) to produce different-shaped graph depending on parameters or volatile external conditions.

To create a fat jar, I normally just use this:

task fatJar( type: Jar ) {
    manifest {
        attributes 'Implementation-Title': 'my-project',
                'Implementation-Version': version,
                'Main-Class': 'my.Main'
    }
    baseName = project.name
    classifier = 'fat-jar'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree( it ) } }
    with jar
}

Run with gradlew fatJar.

If you want fatJar to always run when you run gradlew build you can add this line (making fatJar always run after the normal jar task):

jar.finalizedBy fatJar

I advise you start by learning how tasks work in Gradle… then understand configurations (compile, test, runtime etc).

In the example code above, notice how the fatJar is created by just telling Gradle to create a zipTree of configurations.compile i.e. the compile configuration… you could create a jar including the test code and deps as well by using configurations.test instead… really powerful!

Hope this helps you.

1 Like

When I want to have fat jar I just use the “shadow” plugin and a few lines of config if I want anything special. To create executable jar, throw in the “application” plugin too.

Thank you for helping