War plugin: war task is always executed if I am using a dynamic value in the manifest file

(Jefferson Magno Solfarello) #1

Hi all,

I am building a Web app using the War plugin.

I would like to run the War task only if:

processResources task did work OR compileJava tasks did work OR contents inside directory webAppDirName changed

The problem I am facing here is that I’m creating a manifest file based on a dynamic value (to have a dynamic implementation version).

When I do that the temporary manifest file (created by Gradle) always changes and, as a result, the war task is always executed.

I would like to intercept the process just before the manifest file is generated in order to decide if I need a manifest file.

That way, if nothing else changed, I don’t need to generate a new implementation version and I don’t need to regenerate my War file.

Thanks for any help

(Peter Niederwieser) #2

Are you saying that the manifest content changes but you nevertheless want the ‘war’ task to be up-to-date? The straightforward solution would be to prevent the manifest content from changing during that time.

(Jefferson Magno Solfarello) #3

Hi Peter,

the content of the manifest file is supposed to change every build because it’s implementation version is generated based on a date pattern: manifest {

attributes(“Implementation-Title”: “Gradle”, “Implementation-Version”: “$bdImplementationVersion”) }

I had to do the following to check if the contents of webAppdir changed: onlyIf {

def targetFile = new File("$buildDir/libs/${project.name}")

def webAppDirFile = new File("${project.projectDir.getAbsolutePath()}/$webAppDirName")

def isWarUpToDate = true

webAppDirFile.eachFileRecurse {

if (it.lastModified() > targetFile.lastModified()) {

isWarUpToDate = false



return !isWarUpToDate || compileJava.didWork || processResources.didWork || classes.didWork


I think it should more elegant to create a separate task for the checking, what do you think?

Thanks, Jefferson

(Peter Niederwieser) #4

A task isn’t a good fit for such a check. As long as you don’t want the War to be recreated, why not prevent the implementation version from changing?

(Jefferson Magno Solfarello) #5

So, I am not building a single application, but a multiproject build (many Jar, War and Ear projects). The “full build” is triggered (and a version number is generated) when a developer commits a change into the source control. Our approach is to build only the components / projects that changed in order to reduce the deploy time. The problem is that the war task is never UP-TO-DATE if I use the following: manifest {

attributes(“Implementation-Title”: “Gradle”, “Implementation-Version”: “$bdImplementationVersion”) } Looking at the Gradle logs, I have noticed that it generates a temporary file to represent the manifest file.

I think generating a temp file means that the task is not UP-TO-DATE. Is there another way to achieve my goals? Thanks , Jefferson

(Peter Niederwieser) #6

It’s correct for Gradle to rerun the War task whenever the content of the manifest changes - after all, I assume we are talking about a manifest that will go into the War. (I don’t understand why you think that the temp file plays into this.) If you need a different behavior, you have to implement it yourself via ‘onlyIf {}’ (like you already did). I don’t know of an easy way to keep Gradle’s behavior except disregarding manifest changes.

(Jefferson Magno Solfarello) #7

Peter, thanks for the clarification. The onlyIf code is working fine for now! Gradle is great!