I have found the solution to this problem. As it turns out, I was indeed on the correct track. If like me, your programming efforts are being bottlenecked by a huge jar size, then keep reading.
Once again, to clarify, the approach here is to first create an empty uber jar with no code that contains all your libraries and dependencies. Then, you use that uber jar as a weightless runtime library from a "thin" jar.
Here is a step by step on how to do this:
- Use shadowJar on gradle to create an uber jar. Use the "api" scope using gradle's "java-library" plugin. This will make sure that when you use this uber jar as a dependency, you will be able to access all the libraries the uber jar is implementing. Here is an example build.gradle:
plugins {
id "java"
id "java-library"
id "com.github.johnrengelman.shadow"
}
group 'my.company'
version '1.0.0'
repositories {
maven {
url 'https://jitpack.io'
}
maven {
url 'https://jcenter.bintray.com'
}
}
dependencies {
api 'com.fasterxml.jackson.core:jackson-core:2.10.0'
api 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.9.8'
api 'com.fasterxml.jackson.core:jackson-databind:2.10.0'
api 'org.apache.httpcomponents:httpclient:4.5.6'
api 'org.apache.httpcomponents:httpmime:4.5.6'
api 'com.zaxxer:HikariCP:2.6.0'
api 'mysql:mysql-connector-java:5.1.36'
}
shadowJar {
archiveFileName = "Uber.jar"
destinationDirectory = file("build")
}
// Force character encoding in case the workspace was not set up correctly
tasks.withType(Javadoc) {
options.encoding = 'UTF-8'
}
- Now upload this uber jar to maven, or where ever you want in order to add the uber jar as a dependency in your main project. Make sure you add this uber jar as a "compileOnly" dependency. Here is the modified build.gradle on my main project.
plugins {
id "java"
id "com.github.johnrengelman.shadow" }
group 'my.company' version '2.0'
repositories {
maven {
url 'https://jitpack.io'
}
maven {
url 'https://jcenter.bintray.com'
} }
dependencies {
compileOnly 'my.company:uberjar:1.0.0' }
shadowJar {
archiveFileName = project.name + ".jar"
destinationDirectory = file("build") }
jar {
manifest {
attributes 'Main-Class': 'Main' // your main class
attributes 'Class-Path': 'Uber.jar' // path to the uber jar - in this case its in the same directory as the main jar.
} }
// Force character encoding in case the workspace was not set up
correctly tasks.withType(Javadoc) {
options.encoding = 'UTF-8' }
As shown above in my build.gradle, the real magic happens by configuring the path to the uber jar in the "Class-Path" option.
Compile.
Now you can leave your uber jar with its libraries in place and have fun debugging the short and sweet "thin" jar thats just your own code :D!