How to rename an artifact while it's beeing added to an archive

Hi,

I’m just starting using Gradle, and am trying to replace existing production ant scripts (in other words, I have strong constraints)

I am building a war file using the War task.The contents of the WEB-INF/lib folder will contain jar files I declared as a dependencies and that are in a maven repository. I need those jar files to be stripped out of their version number but I haven’t found a simple way to achieve this. I can easily do this when copying artifacts to the file system, thanks to this great thread (http://forums.gradle.org/gradle/topics/copying_dependencies_without_version), but I can’t seem to be able to do it on the fly when building a War.

The classpath property takes a FileCollection, and not an artifact, so there is no notion of artifact name or extension here.

My script looks like this:

dependencies{

main “my.group:my.artifact:” + version

// … many more }

war {

from ‘somewhere’

webInf { from ‘src/additionalWebInf’ }

classpath configurations.main // how can I easily access the FileConfiguration to strip out the artifact version number of the file name? }

Thanks in advance.

Laurent.

In the meantime, I am just copying the dependencies on the file system, renaming them on the fly, and then I war them as a second step, creating a FileCollection out of them. It works in the sense that the jar files no longer have the version number. But for some reason, those files end up in WEB-INF/classes instead of WEB-INF/lib even though they are jar files. I guess I’ll spend more time in the documentation of the WAR task to understand why they end up there.

OK, the second problem was likely due to the way I was building the file collection, and I bet every File object had a path in it, which made the war file determine that those files needed to go to classes. Building the FileCollection using listAll on a different File object worked.

So as a Summary, here is how I resolved the problem so far:

dependencies{

main “my.group:my.artifact:” + version

// … many more }

task renameDependencies {

def lib = ‘./lib’

configurations.main.resolvedConfiguration.resolvedArtifacts.each { artifact ->

project.copy {

from artifact.file

into lib

rename { “${artifact.name}.${artifact.extension}” }

}

} }

war {

dependsOn ‘renameDependencies’

from ‘somewhere’

webInf { from ‘src/additionalWebInf’ }

classpath = file(’./lib’).listFiles() }

I am hoping there is a much simpler, much more elegant way of achieving this. Overall, it seems that some of the problems I have had using Gradle so far come back to the duality File/Artifact. I must be doing something wrong.

To turn ‘renameDependencies’ into a correct task declaration, the whole body needs to be wrapped with ‘doLast { … }’. I think there should be a simpler solution leveraging ‘filesMatching’ and ‘rename’ right inside the ‘war’ task, but I can’t tell offhand.

Tanks Peter. I will take a look at filesMatching and rename and see how I can use them in the context of the War task.

Just curious about the doLast for the renameDependencies task. What part of the code needs to be wrapped in doLast? As a new user, I am still trying to get a better sense of what kind of code is ok to put in the initialization phase, and what needs to be in doLast.

The problem with doLast is that my war task no longer work properly because at the time "classpath = file(’./lib’).listFiles() " is executed (initialization), the lib folder is not populated yet. So I had to wrap the “classpath” line in a doLast, but this didn’t work either because by the time it got executed, the war file was done (I think). I ended up wrapping the “classpath” line in a doFirst and that made everything works. Not sure if this was the right thing to do.

‘task renameDependencies { doLast { … } }’. As it stands now, the code will get executed for every invocation of Gradle (as part of the configuration phase), no matter if the task ‘renameDependencies’ gets executed or not.

Instead of ‘file(’./lib’).listFiles()’, you should use ‘fileTree(‘lib’)’. The latter only scans for files when they are requested, which means that you won’t need a ‘doFirst’.

Thanks Peter. That is great advice. I had read about fileTree some time ago, but I didn’t remember it.