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

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

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.

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

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?

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

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.

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