tkhm
tkhm

Reputation: 880

Make NON-FAT jar in Gradle on-demand

I'm using Gradle. Usually I'm build the FAT jar. There was no problem, but at this time, I also need to make NON-FAT jar. I mean I want to exclude all depended library and run jar with -cp option like the following:

java -cp "/sample1/lib/myjar.jar:/sample2/lib/depended.jar" com.example.main.Runner

(In FAT jar, java -jar myjar.jar is the same thing and its contains depended.jar)

Here is my build.gradle.

apply plugin: 'java'
apply plugin: 'application'

jar.baseName = 'myjar'
version = ''
def mainClass = 'com.example.main.Runner'
mainClassName =  mainClass

def defaultEncoding = 'UTF-8'

repositories {
  flatDir dirs: "${projectDir}/libs"
}

dependencies {
  compile ':commons-chain:1.2'
  compile ':commons-io:2.4'

  testCompile ':junit:4.12'
  testCompile ':hamcrest-core:1.3'
}
jar {
  manifest {
      attributes 'Implementation-Version': version,
                 'Main-Class': mainClass
  }
  from {configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }}
}

I still want to keep this for usual FAT jar creation. So, I tried to append a task like the following:

TRY #1

task makeSlimJar {
  jar.baseName = 'myjar.slim'
  jar {
  manifest {
      // remove main class
      attributes 'Implementation-Version': version
  }
  from {configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }}
}

TRY #2

task makeSlimJar {
  jar.baseName = 'myjar.slim'  
  jar {
  manifest {
      // remove main class
      attributes 'Implementation-Version': version
  }
  from {configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }}

  tasks.Jar.execute()
}

TRY #3

task makeSlimJar {
  jar.baseName = 'myjar.slim'
  jar {
  manifest {
      // remove main class
      attributes 'Implementation-Version': version
  }
  from {configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }}
  dependsOn Jar 
}

After appended it, I ran the gradle makeSlimJar. All of the above my tries were failed(programmatically, it were succeeded) and just created FAT jar with name myjar.slim.jar.

Is there way to live together FAT and NON-FAT jar on the same build.gradle file? ... Or am I something wrong?

I consider that removing apply plugin: 'application' for NON-FAT jar is my last resort.

Please help me, if you could.

Thanks,

Upvotes: 3

Views: 4493

Answers (1)

robjwilkins
robjwilkins

Reputation: 5652

the code which is actually adding the dependencies to your jar is this line:

from {configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }}

your build script will normally build a 'slim jar' by default, except that you have added code to override this behaviour:

jar {
  manifest {
  attributes 'Implementation-Version': version,
             'Main-Class': mainClass
  }
  from {configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }}
}

I would recommend removing these lines. When you run gradle clean build this will then build a normal jar (with no dependencies).

You could then add an additional task to create your 'fatjar' like this:

task fatjar << {
    jar.doFirst {
       println "creating fatjar"
       jar {
         from {configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }}
       }
    }
}

You can use this task to build the fatjar by running gradle clean fatjar build.

Alternatively you could try looking at a framework such as springboot, which would do all this for you.

Upvotes: 2

Related Questions