How to exclude src/main/resources files from the final WAR?

I have seen several inquiries about this problem, but none work for me. In fact, none seem to work for those who asked before me.

I am using Gradle 2.7.

I have two XML files in src/main/resources/manual. Both files are DOCBOOK structured and are processed with XSLT to produce on online manuals and context sensitive help for the webapp. The static resources for the manual–mostly images and a stylesheet–are located in src/main/webapp/manual.

I do not want these XML files in the final WAR. In build.gradle I define:

war {
  doFirst {
    manifest = warManifest
    makeDocs.execute()
    
    // Grr... Why won't exclude work?
    delete 'build/resources/main/manual'
  }
  from 'war'
  exclude("**/WEB-INF/deploy")
  exclude("**/WEB-INF/jetty-web.xml")
  archiveName "${contextName}.war"
}

Note the comment. The two excludes in this task work, but the only way I have found to keep the two XML files from the WAR is to delete them from the build directory before the WAR is built. I have tried

exclude("**/WEB-INF/classes/manual/*")
exclude("**/WEB-INF/classes/manual")
exclude("build/resources/main/manual")
rootSpec.exclude("manual/*.xml")
rootSpec.exclude("desktopmanual.xml") // and
rootSpec.exclude("mobilemanual.xml")

And probably others that I cannot recall. None work.

As I said, I have a workaround (after a lot of work), but why won’t exclude() exclude?

It looks like there’s a few different things going on here, although one of your solutions does actually work.

First, we can eliminate the ones that absolutely will not work:

The first few that use exclude(...) alter the mainSpec, but the classpath resources that are by default added to the War file are added to a different copySpec. Additionally, we don’t want to consider the into location. Your excludes that do work look like files that are actually in a WEB-INF folder in src/main/webapp. The last couple specify the rootSpec, so will have an effect on the spec that contain the resources, but without a **/ in front of the file name, it will only exclude those files if they are at the root path of the copy location not under /manual.

That leaves the one that does work:

This one affects the rootSpec and specifies a path that matches where you said the DOCBOOK XML files are located.

However, if you are just making changes to the excludes and running a task to create a new war, Gradle is considering that things are UP-TO-DATE, so that may be the reason that this particular attempt didn’t appear to work for you. After running clean, this should work as expected.

You also have the option that if you don’t care for these XML files to be copied from the src/main/resources to the build/resources/main folder (not just excluded when build/resources/main is copied to the War), you could use:

processResources {
    exclude('manual/*.xml')
}
1 Like

I think you are making life difficult for yourself. Gradle (and maven) by convention use src/main/resources for resources which ultimately end up in the jar/war file.

But these xml files are different and are not intended to be in the war. If I were you I’d put them in another directory (eg src/documentation/resources). You could then create a custom configuration for your documentation task which includes this location.

Thank you both. Both suggestions work. James, I probably had not run ./gradlew clean before that test. Lance, I’ve gone with your suggestion. Very clean, and no manual directory in WEB-INF/classes.

1 Like