Gradle, copy and rename file - gradle

I'm trying to in my gradle script, after creating the bootJar for a spring app, copy and rename the jar that was created to a new name (which will be used in a Dockerfile). I'm missing how to rename the file (I don't want to have the version in docker version of the output file).
bootJar {
baseName = 'kcentral-app'
version = version
}
task buildForDocker(type: Copy){
from bootJar
into 'build/libs/docker'
}

You could directly generate the jar with your expected name, instead of renaming it after it has been generated, using archiveName property from bootJar extension:
bootJar {
archiveName "kcentral-app.jar" // <- this overrides the generated jar filename
baseName = 'kcentral-app'
version = version
}
EDIT
If you need to keep the origin jar filename (containing version), then you can update your buildForDocker task definition as follows:
task buildForDocker(type: Copy){
from bootJar
into 'build/libs/docker'
rename { String fileName ->
// a simple way is to remove the "-$version" from the jar filename
// but you can customize the filename replacement rule as you wish.
fileName.replace("-$project.version", "")
}
}
For more information, see Gradle Copy Task DSL

You can also do something like this:
task copyLogConfDebug(type: Copy){
group = 'local'
description = 'copy logging conf at level debug to WEB-INF/classes'
from "www/WEB-INF/conf/log4j2.debug.xml"
into "www/WEB-INF/classes/"
rename ('log4j2.debug.xml','log4j2.xml')

Related

Delete directory content from Gradle

I use this Gradle configuration to copy generated asciidoc files.
But I need to delete old outdated files also.
task copyDocument(type: Copy) {
dependsOn bootJar
from file("build/docs/asciidoc/")
into file("src/main/resources/static/")
}
How I can delete the content of directory src/main/resources/static/ before I paste the new generated files?
task copyDocument(type: Copy) {
dependsOn bootJar
from file("build/docs/asciidoc/")
into file("src/main/resources/static/")
doFirst {
delete "build/folder"
}
}

How to deal with relative paths in Gradle composite builds?

I have a Gradle composite build with the following directory structure:
compositebuildroot/
build.gradle
settings.gradle
componentbuild/
build.gradle
settings.gradle
testfile.txt
with compositebuildroot/build.gradle containing
task runComponentBuildSampleTask {
dependsOn gradle.includedBuild('componentbuild').task(':sampleTask')
}
, compositebuildroot/settings.gradle containing
rootProject.name = 'compositebuildroot'
includeBuild 'componentbuild'
, compositebuildroot/componentbuild/build.gradle containing
task sampleTask {
doLast {
println "System.getProperty(\"user.dir\"): " + System.getProperty("user.dir")
println new File("testfile.txt").text
}
}
, and compositebuildroot/componentbuild/settings.gradle containing
rootProject.name = 'componentbuild'
.
When I execute gradle sampleTask from the componentbuild directory, I get the absolute path of the componentbuild directory printed out, followed by the contents of testfile.txt (which is what I want/expect). However, when I execute gradle runComponentBuildSampleTask from the compositebuildroot directory, I get the absolute path of the compositebuildroot directory followed by a java.io.FileNotFoundException for the testfile.txt file.
How can I make gradle runComponentBuildSampleTask from compositebuildroot produce whatever output gradle sampleTask from componentbuild does? Is there some way to tell gradle to run component build tasks as if the current directory is that of the component build's settings.gradle file?
Never use new File(...)
Always use file(...)
See Project.file(Object)

Gradle JAR files in a folder recursively

How can I JAR a folder and all of it's sub directories and files in a simple JAR?
I tried something like this and it does not work.
task jarVrCore(type: Jar, description: 'JARs core part of the project') {
doLast {
archiveName = "vasasdasasdasd"
from "${projectDir}"
println "${vrCoreSourceDir}"
destinationDir = file("${dirTmpLibsVr4}")
}
}
I always get an empty JAR with only the manifest.
The problem is that all of your task configurations are applied too late. You are using a doLast closure, which is executed after the actual task action (for a Jar task: the creation of the .jar file).
Normally, all task configuration is done directly inside the task configuration closure:
task jarVrCore(type: Jar, description: 'JARs core part of the project') {
archiveName = "vasasdasasdasd"
from "${projectDir}"
println "${vrCoreSourceDir}"
destinationDir = file("${dirTmpLibsVr4}")
}
If you need to apply configuration after other tasks have been executed, use a doFirst closure.
Please note, that using the example above, the println statement will be executed during configuration phase and therefore on each Gradle invocation, whether the task jarVrCore is executed or not.

Gradle task to compile java files and resources to zip file

I'm new to Gradle and I have no past experience for Gradle builds. What I'm trying to achieve are compile Java classes, copy some files to build dir with some resource files and make a zip file of the whole directory.
Zip file contents
bin
----data
----java
----properties
----resources
----run.sh
----classes <---- Java compiles classes here!
lib
----sqlite-jdbc-3.23.1.jar
properties
----MANIFEST.MF
I tried to Gradle build for Java but it makes too much tasks for this and I think it's overkill for my purposes. I want to write simple compile and copy task for this. Or if I need to use all java build tasks, how can I edit those task operations?
I think you should use both Java and Distribution plugins, that will help you to create a simple build script. Java plugin will bring you some tasks that you might not need in you case, but it still worth using it instead of creating your own task for source compilation.
An example of script you could use as a starter:
plugins {
id 'java'
id 'distribution'
}
// Java plugin configuration
// ---------------------------------------------------
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
jcenter()
}
dependencies {
compile group: 'org.xerial', name: 'sqlite-jdbc', version: '3.23.1'
}
// Distribution plugin configuration
// ------------------------------------------------------
distributions {
main {
baseName = 'myDist'
contents {
// 1. by default, content under /src/main/dist will be automatically included in the target dist zip
// 2. include compiled classes output dir into /bin/classes
from(project.sourceSets.main.output.classesDir) {
into('bin/classes/')
}
// 3. include all dependent jars into /libs
from(configurations.compile) {
into('libs/')
}
// 4. other resources to include in the target zip
// ...
}
}
}
// Make distZip task depend on compileJava task
distZip {
dependsOn compileJava
// EDIT : change target file path
eachFile { file ->
String path = file.relativePath
String newPath = path.substring(path.indexOf("/")+1,path.length())
println "Changed path to file from $path to $newPath"
file.setPath(newPath)
}
}
This script assumes that you follow standard directory layout in your project, for your source code and resources ( src/main/java/ , src/main/dist/ , ..), else you will have to adapt the script.

Unable to run repacked spring boot jar caused by "Unable to open nested entry"

I am setting up a build pipeline for a spring boot project.
It has three stages so far:
build: compile-->unit test-->archive the jar
deploy acceptance test: repack the jar for acc environment (replacing datasource.properties etc)
deploy uat test: repack the jar for uat environment (replacing datasource.properties etc)
I don't want to build the jar from scratch for different environments as it wastes time and potentially has risk of building inconsistent artifacts.
For traditional war project, I just extract the war, replace the config files and repack. But this time with spring boot, somehow it does not work. When I run the repacked jar, it reports
java.lang.IllegalStateException: Unable to open nested entry 'lib/antlr-2.7.7.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file
at org.springframework.boot.loader.jar.JarFile.createJarFileFromFileEntry(JarFile.java:378)
at org.springframework.boot.loader.jar.JarFile.createJarFileFromEntry(JarFile.java:355)
at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:341)
at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:108)
at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchives(JarFileArchive.java:92)
at org.springframework.boot.loader.ExecutableArchiveLauncher.getClassPathArchives(ExecutableArchiveLauncher.java:68)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:60)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:45)
I extracted the origin jar and the repacked jar and don't find differences with lib folder.
task extractArtifact() {
doLast {
def outputDirName = "${buildDir}/tmp/under_config"
def outputDir = file(outputDirName)
assert outputDir.deleteDir() // cleanup workspace
def zipFile = file("${buildDir}/libs/${getArtifactName()}")
copy {
from zipTree(zipFile)
into outputDir
}
copy {
from file("${buildDir}/env")
into file("${buildDir}/tmp/under_config")
}
}
}
task repackConfiguredArtifact(type: Zip, dependsOn: extractArtifact) {
archiveName = "${getArtifactName()}"
destinationDir = file("${buildDir}/libs/${getEnv()}")
from file("${buildDir}/tmp/under_config")
}
Does anyone have an idea?
Or how do you guys config the jar for different environment (without re-compile the binary).
You shoud add -0 to store only; use no ZIP compression
$jar -cvf0m yourproject.jar META-INF/MANIFEST.MF .
There is another soulution:
Set the active Spring profiles
$java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar
You can use application-${profile}.properties to specify profile-specific values.
I have a solution after looking up the spring-boot reference.
turn default spring boot repackage off since I need to repack it anyway.
extract the traditional jar and copy the config files
Use jar type task to repack it
Use BootRepackage type task to assemble a spring-boot jar.
here is the code:
bootRepackage {
enabled = false
}
task extractArtifact() {
doLast {
def outputDirName = "${buildDir}/tmp/under_config"
def outputDir = file(outputDirName)
assert outputDir.deleteDir() // cleanup workspace
def zipFile = file("${buildDir}/libs/${getArtifactName()}")
copy {
from zipTree(zipFile)
into outputDir
}
copy {
from file("${buildDir}/env")
into file("${buildDir}/tmp/under_config")
}
assert zipFile.delete()
}
}
task clientJar(type: Jar, dependsOn: extractArtifact) {
archiveName = "${getArtifactName()}"
from file("${buildDir}/tmp/under_config")
}
task repackConfiguredArtifact(type: BootRepackage, dependsOn: clientJar) {
withJarTask = clientJar
}
I found that if you had a directory called 'resources/lib' the spring-boot executable JAR would assume the contents were zipped and throw the above exception. Renaming to 'resources/static' worked for me.

Resources