The place where random ideas get written down and lost in time.
2021-08-28 - Train Motion: FatJar vs ClassPath?
Category DEVIn the Train-Motion project, I have a fat jar gradle rule to package all the dependencies in a single jar.
To make it work, I had to create a “configuration” in gradle:
configurations {
runtimeCompile {
canBeResolved = true
canBeConsumed = true
}
compileClasspath.extendsFrom(runtimeCompile)
runtimeClasspath.extendsFrom(runtimeCompile)
testCompileClasspath.extendsFrom(runtimeCompile)
testRuntimeClasspath.extendsFrom(runtimeCompile)
}
Then I use this configuration to include the dependencies:
dependencies {
runtimeCompile project(":LibUtilsJava")
runtimeCompile "commons-cli:commons-cli:1.4"
runtimeCompile "org.bytedeco:javacv-platform:1.5.3"
runtimeCompile "org.bytedeco:javacpp-platform:1.5.3"
runtimeCompile "uk.co.caprica:vlcj:4.7.1"
runtimeCompile "com.fasterxml.jackson.core:jackson-databind:2.10.2"
runtimeCompile "com.squareup.okhttp3:okhttp:3.10.0"
runtimeCompile "org.eclipse.jetty:jetty-server:9.4.29.v20200521"
runtimeCompile "com.google.dagger:dagger:2.28"
runtimeCompile "com.google.auto.factory:auto-factory:1.0.1"
}
And finally a fatJar task collects these specific dependencies and packages them together:
task fatJar(type: Jar) {
manifest.from jar.manifest
classifier = "all"
from {
configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
} {
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}
with jar
}
Note that “runtimeCompile” is a superset of the “compile” configuration, and the artifacts can be found using configurations.compileClasspath.
That’s neat to create the needed single JAR. That jar is ~760 MB with all the OpenCV deps. And it takes an interminable 4 minutes to create the jar itself.
So now the question is whether I can avoid that. I don’t need to distribute the jar, so I'd be fine with crafting a specific command line with the needed classpath. Or even having a “gradle run” task that does not need the fat jar first.