title: Duplicate files in Gradle-built .war file
body: <p>I'm having a duplicate files issue with my Gradle build script.</p>
  
  <p>My directory structure is the maven standard, plus some extra directories for various build configurations:</p>
  
  <pre><code>/src/main/java
  /src/main/resources
  /src/main/dev/resources
  /src/main/prod/resources
  </code></pre>
  
  <p>The files from <code>/src/main/resources</code> and <code>/src/main/dev/resources</code> are apparently handled by both the <code>processResources</code> and the <code>war</code> task, and end up in the .war file twice. <strong>How can I prevent that from happening without manually excluding each single file in the war configuration?</strong></p>
  
  <p>My entire build.gradle is included below; note <code>buildEnvironment</code> is set to <code>dev</code> by default, but could also be <code>prod</code>.</p>
  
  <pre><code>apply plugin: "sonar"
  apply plugin: "war"
  apply plugin: "eclipse-wtp"
  
  // ************************************************************************************************
  // GENERAL CONFIGURATION
  // ************************************************************************************************
  
  sourceCompatibility = 1.6
  group = "com.foo"
  archivesBaseName = "security"
  version = "0.1-SNAPSHOT"
  
  // versions of various components where we need more than one and may want to update often
  def springVersion = "3.1.1.RELEASE"
  def tomcatVersion = "7.0.25"
  def jasperVersion = "4.5.0"
  
  // buildEnvironment is set in gradle.properties and can be overridden with -PbuildEnvironment=... on the command line
  println "running in $buildEnvironment mode..."
  
  // set classes output directory to WEB-INF/classes
  eclipse.classpath.defaultOutputDir = new File(project.getWebAppDir().getAbsolutePath(), "/WEB-INF/classes")
  
  // ************************************************************************************************
  // SOURCE SETS
  // ************************************************************************************************
  
  sourceSets {
    // add the resources specific to the build environment
    main.resources.srcDirs += "src/main/$buildEnvironment/resources"
    // add source set for jasper reports
    jasperreports {
      srcDir = file(relativePath('src/main/jasperreports'))
      output.classesDir = file(relativePath('src/main/java/com/foo/bar/security/statistics'))
    }
  }
  
  // ************************************************************************************************
  // PLUGINS
  // ************************************************************************************************
  
  buildscript {
    repositories {
      add(new org.apache.ivy.plugins.resolver.URLResolver()) {
        name = 'GitHub'
        addArtifactPattern 'http://cloud.github.com/downloads/[organisation]/[module]/[module]-[revision].[ext]'
      }
    }
  
    dependencies { classpath 'bmuschko:gradle-tomcat-plugin:0.9' }
  }
  
  apply plugin: "tomcat"
  
  // ************************************************************************************************
  // PLUGIN CONFIGURATION
  // ************************************************************************************************
  
  // configure eclipse .project/.classpath generator
  eclipse {
    project { natures 'com.springsource.sts.gradle.core.nature' }
    wtp { component { contextPath = "/security" } }
  }
  
  configurations {
    // make sure we don't get dependencies we don't want
    all*.exclude group: "net.sf.ehcache", module: "ehcache-terracotta"
    all*.exclude group: "bouncycastle", module: "bcmail-jdk14"
    all*.exclude group: "bouncycastle", module: "bcprov-jdk14"
    all*.exclude group: "bouncycastle", module: "bctsp-jdk14"
  
    // wtp needs a special invitation for some reason
    eclipseWtpComponent {
      exclude group: "net.sf.ehcache", module: "ehcache-terracotta"
    }
  
    jasperreports { transitive = true }
  }
  
  // maven repositories
  repositories {
    maven { url "http://maven.springframework.org/milestone/" }
    mavenCentral()
  }
  
  // sonar configuration
  sonar {
    server { url = "http://xxx" }
    database {
      url = "jdbc:mysql://xxx"
      driverClassName = "com.mysql.jdbc.Driver"
      username = "xxx"
      password = "xxx"
    }
    project { key = "foo.bar:security" }
  }
  
  war {
    // set war output file name
    archiveName = "security.war"
    // make sure no duplicate processing of files takes place
    excludes += [
      "**/database.properties",
      "**/logback.xml",
      "**/rebel.xml",
      "**/upload.properties",
      "**/ValidationMessages.properties"
    ]
  }
  
  tomcatRun { contextPath = "/security" }
  
  // ************************************************************************************************
  // DEPENDENCIES
  // ************************************************************************************************
  
  dependencies {
  
    // exclusions for jasperreports, which tries to load old versions of stuff
    compile("net.sf.jasperreports:jasperreports:$jasperVersion") {
      exclude module: "jfreechart"
      exclude module: "jcommon"
    }
  
    // exclusions for ehcache, we don't want their enterprise cache
    compile("net.sf.ehcache:ehcache:2.5.1") {
      exclude group: "net.sf.ehcache", module: "ehcache-terracotta"
    }
  
    // compile and runtime dependencies
    compile   "org.springframework:spring-webmvc:$springVersion",
        "org.springframework:spring-orm:$springVersion",
        "org.springframework:spring-aspects:$springVersion",
        "org.springframework.mobile:spring-mobile-device:1.0.0.RC1",
        "org.jfree:jfreechart:1.0.14",
        "org.apache.tiles:tiles-jsp:2.2.2",
        "c3p0:c3p0-oracle-thin-extras:0.9.1.2",
        "org.mybatis:mybatis-spring:1.0.2",
        "org.aspectj:aspectjrt:1.6.12",
        "org.aspectj:aspectjweaver:1.6.12",
        "org.codehaus.jackson:jackson-mapper-asl:1.9.4",
        "ch.qos.logback:logback-classic:1.0.0",
        "org.slf4j:jcl-over-slf4j:1.6.4",
        "org.slf4j:log4j-over-slf4j:1.6.4",
        "org.slf4j:jul-to-slf4j:1.6.4",
        "org.hibernate:hibernate-validator:4.2.0.Final",
        "com.google.guava:guava:11.0.1",
        "commons-dbutils:commons-dbutils:1.4",
        "commons-fileupload:commons-fileupload:1.2.2",
        "commons-io:commons-io:2.1",
        "commons-lang:commons-lang:2.6",
        "org.bouncycastle:bcprov-jdk16:1.46",
        "org.quartz-scheduler:quartz:2.1.3",
        "jdom:jdom:1.1",
        "cglib:cglib:2.2.2",
        "org.jasypt:jasypt:1.9.0",
        "com.sun.mail:smtp:1.4.4",
        "com.sun.mail:mailapi:1.4.4",
        "xalan:xalan:2.7.1",
        "org.jdom:saxpath:1.0-FCS"
  
    runtime "javax.servlet:jstl:1.2"
  
    // for compiling jasper reports
    jasperreports "net.sf.jasperreports:jasperreports:$jasperVersion",
        "org.codehaus.groovy:groovy-all:1.8.6"
  
  }
  
  // dependencies for each tomcat version, which are in different packages for 6.x and 7.x, sigh
  println "adding dependencies for Tomcat $tomcatVersion"
  if (tomcatVersion.startsWith("6")) {
    dependencies.add("providedCompile", "org.apache.tomcat:catalina:$tomcatVersion")
    dependencies.add("tomcat", "org.apache.tomcat:catalina:$tomcatVersion")
    dependencies.add("tomcat", "org.apache.tomcat:coyote:$tomcatVersion")
    dependencies.add("tomcat", "org.apache.tomcat:jasper:$tomcatVersion")
  } else if (tomcatVersion.startsWith("7")) {
    dependencies.add("providedCompile", "org.apache.tomcat:tomcat-catalina:$tomcatVersion")
    dependencies.add("tomcat", "org.apache.tomcat:tomcat-catalina:$tomcatVersion")
    dependencies.add("tomcat", "org.apache.tomcat:tomcat-coyote:$tomcatVersion")
    dependencies.add("tomcat", "org.apache.tomcat:tomcat-jasper:$tomcatVersion")
  }
  
  // ************************************************************************************************
  // JASPER REPORTS
  // ************************************************************************************************
  
  task jasperReports(overwrite: true) &lt;&lt; {
    ant {
      taskdef(name: 'jrc',
          classname: 'net.sf.jasperreports.ant.JRAntCompileTask',
          classpath: configurations.jasperreports.asPath)
      mkdir(dir:sourceSets.jasperreports.output.classesDir)
      jrc(srcdir: sourceSets.jasperreports.srcDir, destdir: sourceSets.jasperreports.output.classesDir) {
        include(name:'**/*.jrxml')
        classpath {
          pathElement(path: configurations.jasperreports.asPath)
        }
      }
    }
  }
  
  task cleanJasperReports(overwrite: true) &lt;&lt; {
    ant.delete() {
      fileset(dir:sourceSets.jasperreports.output.classesDir, includes: "*.jasper")
    }
  }
  
  compileJava.dependsOn jasperReports
  </code></pre>