Copy resources from a dependency jar or war file in Gradle

We have multiple war files in different projects, say A and B, sharing common resources like images. The common resources are placed in a war module in a separate project E. And this war file is added as dependency in all the war modules in projects A and B. Currently we are using maven resource plugins to copy these common resources to the root of A and B modules.

How can we do the same action using Gradle?

Rather than a common war, I’d build a common jar (or zip?) for the resources.

You could then either

  1. Add the jar to the runtime classpath and access the images via the classloader
  2. Extract the resources from the jar / zip at build time (using gradle) and add them to the war

Thanks for your quick response. Sure will change it in to jar file.
Currently I am trying this with below configuration, but the files are not copied in to the generated war file. They are only copied to build/libs folder. How to specify the destination correctly?

    configurations {
        commonWebResources
    }
    task extractApi(type: Copy) {
        print 'File : ' + configurations.commonWebResources.singleFile
        from zipTree(configurations.commonWebResources.singleFile)
       into file("${project.buildDir}/libs/")
    }

    compileJava.dependsOn(extractApi)

I’m still not entirely sure where you want these common resources

  1. Unzipped to web-inf/classes
    use war { classpath zipTree ... }

  2. As a jar in web-inf/lib
    use dependencies { runtime ... }

  3. Unzipped as regular files in the war
    use war { from ... } or war { with copySpec ... }

Thank you. I am looking for the 3rd option. The below one seems to be working. The only issue is that I am not able to exclude some files

war {
	from (zipTree(configurations.commonWebResources.singleFile)) {
		exclude '*web.xml'
	}
	into("/")
}

I want to exclude the WEB-INF/web.xml of the common-web.war file while copying contents to my destination web module. But this is being added as duplicate entry.

I think it should be '*/web.xml' rather than '*web.xml' (see AntPathMatcher)

You could also try with(CopySpec) instead of from

war {
   with copySpec {
      from zipTree(...) {
         exclude 'WEB-INF/web.xml' 
      }
   }
} 

It worked. Thanks a lot

I am just adding a generic comment here as @Lance_Java has already answered your question. When people are new to Gradle they tend to look for a UnpackZip task.

The thing to remember is that all copying out of archives can be done via the Copy task. zipTree and tarTree are your friends when using archives as sources. Looking inside archives uses a CopySpec just like a normal copy Copy or project.copy would. LEarn how to use the CopySpec syntax and you’ll be amazed how simple Gradle makes it to copy stuff around.