Avoidable mistakes while Working with Gradle

Deleting a Single Directory with Directory Name matching a pattern

Resource : https://stackoverflow.com/a/35635432

As per the given resource the below solution works.

import groovy.io.FileType

class DeleteDir extends DefaultTask {
   def baseDir = "."
   def deleteMe(Object... targets) {
       def directoryList = []
       def baseDirectory = new File(baseDir).eachFileRecurse(FileType.DIRECTORIES) {
           if ( targets.contains(it.name) ) {
               directoryList << it
       directoryList.each { dirObj -> 
           if ( dirObj.exists() ) {
               println "Removing directory: $dirObj"

task hello( type: DeleteDir) {
    baseDir = '.'
    deleteMe 'obj', 'gen', 'jniLibs'

The above solution works with a small change

Object… targets > Object target

targets.contains(it.name) > it.name.contains(target)

Avoid using of Thick(Fat) JAR

#Depends Up-On the Project type

#Before Starting check if creating a Fat jar would be a good approach for your Project.

Method to create a Thick(Fat) JAR 

The maven-shade-plugin can be used to create a fat JAR. This takes the app and all its dependencies and piles it into one big JAR. This JAR is immutable and has no external dependencies, making it easy to supply and operate.


The Java Plugin Jar task can be used to create a fat JAR.


from {
        configurations.implementation.filter{ it.exists() }.collect {
         it.isDirectory() ? it : zipTree(it)
duplicatesStrategy = 'exclude'

But it comes with some serious drawbacks.

  1. JARs are not supposed to be aggregated in this way. There may be files with the same path present in several JARs and automatically the shadow plugin merges the first file into the fat JAR and discards the rest. This might cause some really frustrating bugs.

  2. The process is slow and inefficient.

  3. For Obfuscation, we now have to pass the fat JAR which comes with added challenges which could be completely avoided.

  4. Your business logic and application container are all in one file. Yes, the pro is a con sometimes and not an insignificant one. When your business logic changes, you will need to send another copy of the application container(which has not changed) with it.

  5. Spin-up times are higher compared to the deployment of a thin war to a running application container.

Local External Jar Files should be verified before use

The external Jar files added in the project should be verified after decompiling, external Jar files with Similar names might have a different version.

Eg : derby.jar might have a version 10.14 or 10.12 with a same name might throw an exception

[getDatabaseConnection::::: Message: Failed to start database] in case of a downgrade 

The Below resource can be used for decompile 


Converting Multiple Single Unit operations to Single batch operations

Single Unit operations like permission change using a commandLine can be converted to batch operations using predefined tasks like ant.chmod 

Also it supports including patterns


task permission1(type: Exec) {
    commandLine 'chmod', '444', "${releaseFolder}/testproject/app/*.jar"

task permission2(type: Exec) {
    commandLine 'chmod', '444', "${releaseFolder}/testproject/app/lib/*.jar"


task permissionChange {
	ant.chmod(dir: "${releaseFolder}/testproject/app/", perm: "444", includes: "*.jar")
	ant.chmod(dir: "${releaseFolder}/testproject/app/lib/", perm: "444", includes: "*.jar")

Important tasks can be repeated in every Build irrespective of their UP-TO-DATE Status

By setting outputs.upToDateWhen { false }

Use Proguard terminal commands

Proguard terminal commands can be used to debug the proguard configuration properly 

Proguard Manual


Sample commands

java -jar proguard.jar @proguard_conf.cfg -injars InJar.jar -outjars OutJar.jar -printmapping mapping_file.txt >> command_output.txt

Leave A Comment

Your email address will not be published. Required fields are marked *