Gradle ShadowJar with Other SourceSet Resources - gradle

I am using the ShadowJar Gradle plugin to build a Jar containing all of the source files in the src/main/java directory and other Jar files in a lib directory and it is working fine. What I need is another ShadowJar task, a devShadowJar task, that will instead of pulling in a JSON file in the src/main/resources folder, it will pull in a JSON file in the src/dev/resources folder.
I added this to the build.gradle file to define the dev source set:
sourceSets {
dev
}
But now I am not sure how to create a devShadowJar task to use the dev JSON resource instead of the JSON resource file located in src/main/resources.

try playing around this:
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
task devShadowJar(type: ShadowJar) {
zip64 true
from './build/classes/java/main'
from project.configurations.compile
from './src/dev/resources' // or wherever the resources and up under ./build
}

Related

Gradle Ear plugin should not copy resources into .ear root

I have the following folder structure of my gradle module:
src
main
application
META-INF
application.xml
was.policy
was.webmodule
java
resources
image.bmp
logback.xml
... other files, properties
webapp
My goal is to build an ear archive, which will contain only Tclient.war and META-INF. However, gradle copies all resource files to the ear root.
Gradle documentation about Ear Plugin says that:
The default behavior of the Ear task is to copy the content of
src/main/application to the root of the archive. If your application
directory doesn’t contain a META-INF/application.xml deployment
descriptor then one will be generated for you.
So, It's not really clear why it puts resources into the root. Maybe, it work's like the org.gradle.api.tasks.bundling.Jar task and I should override this behaviour in some way?
Here is my partially build.gradle file:
jar {
description 'Creates tclient.jar'
archiveBaseName = 'tclient'
destinationDirectory = file('src/main/webapp/WEB-INF/lib')
from sourceSets.main.output
include '**/*'
include '**/*.properties'
include '**/*.cmd'
}
ear{
description = "Ear archive for WebSphere server"
archiveBaseName = 'Tclient'
appDirName('src/main/application')
// workaround to exclude classes from ear root
rootSpec.exclude('**/de/**')
rootSpec.exclude('**/org/**')
}
war {
archiveFileName = 'Tclient.war'
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
webInf {
from configurations.natives into 'lib/bin'
}
// do not put compiled classes inside WEB-INF/classes
rootSpec.exclude('**/de/**')
rootSpec.exclude('**/org/**')
rootSpec.exclude('urlrewrite*.dtd')
from(jar) {
into 'WEB-INF/lib'
}
}
dependencies {
// Place .war inside .ear root
deploy files(war)
....
}
The possible workaround is to exclude redundant resources from the rootspec:
ear{
description = "Ear archive for WebSphere server"
archiveBaseName = 'Tclient'
appDirName('src/main/application')
// workaround to exclude classes from ear root
rootSpec.exclude('**/de/**')
rootSpec.exclude('**/org/**')
// workaround
rootSpec.exclude('*.properties')
rootSpec.exclude('*.xml')
rootSpec.exclude('*.dtd')
rootSpec.exclude('*.bmp')
}
However, I'm finding this workaround a little bit ugly and it's a dirty hack.

Gradle: Include dynamically generated file in build?

During my gradle build, I generate a temporary buildinfo.properties file containing things like Git commit info, build time, etc. I would like to include this file in my output *.jar / *.war files as a resource. However, I do not want to put this file in my project src/ folder (this would require fiddling with .gitignore and in general it just seems unnecessary to me). Ideally, the developer shouldn't even see this file at all, it should just be contained in the output archive.
How would you include a dynamically generated text file in a Gradle build?
Add that file in a jar task (Kotin DSL):
tasks {
val jar by getting(Jar::class) {
from("build/buildinfo.properties")
}
}
It will add build/buildinfo.properties file (assuming you generate it there with another taks) to the root of your JAR.
For dynamically generated file, standard gradle way to process resources is the gradle task called processResources. You can do something like this:
processResources {
dependsOn taskThatGeneratesYourBuildinfo
from("build/buildinfo.properties") {
into("desired/path/in/jar")
}
}

gradle main task to zipup sub-projects distribution files

I have a gradle project which at main is using java plugin. At subproj1 - thru subproj4 the build.gradle files are also using application plugin. It works well in sub projects to compile the jars (with a main class) and create a distribution zipfile (using resources and dist files).
Now I want to build a 'main' dist zip file, comprising of the contents of all those subproj contents. I found I can run installDist to unzip to each of the subprojects build/install/subprojN
Now at a loss howto in the main only, have a task and/or dependency to create a "main" dist zip file containing: subproj1/** subproj2/** subproj3/** subproj4/**
My thoughts are to do a copy from('.').include('subproj*/build/install//')
then zip that up. but havent figured out howto add the task only at main level, plus have it not complain: NO SOURCE
thanks in advance
Here's an example that just uses two sub-projects, and does not show the compilation of the main code. That stuff should be easy to add. The key to the solution is the zip and zipfileset via the AntBuilder.
Consider this in the main build.gradle:
task uberBuild(dependsOn: ['subProj1:build',
'subProj2:build']) {
doLast {
ant.mkdir(dir: "${projectDir}/dist")
def PATH = "build/distributions"
ant.zip(destfile: "${projectDir}/dist/uber.zip") {
zipfileset(src: "${projectDir}/subProj1/${PATH}/subProj1.zip")
zipfileset(src: "${projectDir}/subProj2/${PATH}/subProj2.zip")
}
}
}
This will write ~/dist/uber.zip, which has the contents:
$ jar tf dist/uber.zip
subProj1/
subProj1/bin/
subProj1/lib/
subProj1/bin/subProj1
subProj1/bin/subProj1.bat
subProj1/lib/subProj1.jar
subProj2/
subProj2/bin/
subProj2/lib/
subProj2/bin/subProj2
subProj2/bin/subProj2.bat
subProj2/lib/subProj2.jar

How to create directory and move WAR file using Gradle

By default, Gradle puts all WAR files that it creates in build/libs when I run gradle build on a Java project. How do I instruct Gradle to create a directory called dist under build and put all WAR files in that directory (i.e. build/dist)?
I created a new task called moveWar that accomplished what I wanted:
task moveWar(type: Copy) {
from 'build/libs'
into 'build/dist'
}
Then I used build.finalizedBy moveWar to move the WAR file in libs to dist after the build is finished.
Another approach I found:
war.destinationDir = file "$buildDir/dist"

Gradle multi-project with shared logging config

Is there a standard way to share a logging config (for log4j or logback for example) across all sub projects in a gradle project layout?
What I do right now is put a copy of logback.xml (or log4j.properties) in src/main/resources in each sub-project but this results in a lot of unnecessary duplication of this config file
This can be easily overcome using multiple working sets in gradle.
Add a new folder in the root of the project, example "shared-resources" put our configs inside it, and simple add the following line to your build.gradle on the sub-project
sourceSets {
main {
resources {
srcDirs = ["src/main/resource", "../shared-resources"]
}
}
}
This should add both files to your jar file.
An example can be find in github
Create a shared util module containing your Log4j2 configuration in its src/main/resources directory.
Then import the util module into others.
dependencies {
compile project(":util");
}
I also use the util module for re-usable Java code, not just for once-off configuration of Log4j2.

Resources