21

I have a multi-project Gradle build structure, where child project depends on a JAR, which I don't want to be in WAR file. I tried "exclude" but it does not work.

The main project script:

apply plugin: 'war'
war {
    dependencies {
        runtime (project(':childProject')) {
            exclude group: 'javax.servlet.jsp', module: 'jsp-api'
        }
    }
}

The childProject script:

apply plugin: 'java'
dependencies {
    compile 'javax.servlet.jsp:jsp-api'
}
isobretatel
  • 3,812
  • 7
  • 34
  • 49
  • I don't think that excludes are supported for project dependencies. (See John's answer for a working solution.) The `dependencies` block is a top-level element, and should not be nested inside `war`. – Peter Niederwieser Dec 20 '13 at 16:11

5 Answers5

28

I'm doing it this way.

war {   
    rootSpec.exclude("**/some-*.jar")
}
d-sauer
  • 1,485
  • 1
  • 15
  • 20
26

From the Gradle documentation

The War plugin adds two dependency configurations: providedCompile and providedRuntime. Those configurations have the same scope as the respective compile and runtime configurations, except that they are not added to the WAR archive.

So, in other words, adding an entry to providedCompile or providedRuntime will cause that dependency to be excluded from the war file.

  • use providedCompile if you have source that relies on some classes for compiling
  • use providedRuntime if you use it for testing and not compiling.

http://www.gradle.org/docs/current/userguide/war_plugin.html

Example

providedCompile "javax.servlet:servlet-api:2.5"

GreenGiant
  • 4,930
  • 1
  • 46
  • 76
John Vint
  • 39,695
  • 7
  • 78
  • 108
  • 3
    Works: apply plugin: 'war' dependencies { runtime (project(':childProject')) { } providedCompile "javax.servlet.jsp:jsp-api" } – isobretatel Dec 20 '13 at 16:41
  • 2
    I want to exclude a jar from the war due to file size reasons. SpringBoot (which I'm using) unfortunately moves the jars to `WEB-INF/lib-provided` for the case of using an embedded server. – HankCa Jul 19 '15 at 22:07
  • 1
    This didn't work for me, but when I changed the scope to "provided" instead of "providedComile/Runtime", then it worked. – GreenGiant Aug 19 '16 at 21:30
7

I realised that providedCompile sometimes introduced dependencies issues for me, e.g. some classes are not found. I then figured out a more flexible solution.

We can just configure required dependencies as 'compile' and then exclude specific jars from the war file by using the following war configuration:

war {
    classpath = classpath.filter { file ->
        println file.name
        (
            !file.name.startsWith('gwt-dev') &&
            !file.name.startsWith('gwt-user') &&
            !file.name.startsWith('guava-gwt') &&
            !file.name.startsWith('gwtbootstrap3') &&
            !file.name.startsWith('gwtbootstrap3-extras') &&
            !file.name.startsWith('servlet-api')
        )
    }
}

So far, I found this is the cleanest solution for me. I hope it helps.

Rick-777
  • 9,714
  • 5
  • 34
  • 50
Jake W
  • 2,788
  • 34
  • 39
  • I liked, this but this to me filtered out all values of that jar - i only wanted to remove duplicates. https://issues.gradle.org/browse/GRADLE-1454 provided a solution similar that only excludes duplicates – VeenarM Mar 17 '16 at 00:32
  • I guess you will need to write some custom logic in it to remove duplicates. As you can see, we can print all file names – Jake W Mar 17 '16 at 04:26
  • Yup, got it done and working as I wished, but yours put me on the right track to solve it, it's an odd case and it's only a problem temporarily until the other artifacts are put into maven and not just dropped into a lib dir. – VeenarM Mar 19 '16 at 10:45
3

I had the same problem but i found a generic solution based on the one of Jake W.

In your child-project, without the war plugin, you add your own providedCompile and providedRuntime like this:

configurations {
  providedCompile
  providedRuntime.extendsFrom providedCompile
}

plugins.withId('java') {
  configurations {
    compile.extendsFrom providedCompile
    runtime.extendsFrom providedRuntime
  }
}

In the project with your war file you copy this anywhere you want:

configurations.runtime.allDependencies.withType(ProjectDependency) { ProjectDependency dep ->
  Project proj = dep.dependencyProject
  evaluationDependsOn(proj.path)
  Configuration cfg = proj.configurations.findByName('providedRuntime')
  if (cfg != null){
    war {
      classpath -= cfg
    }
  }
}
Adrodoc
  • 673
  • 10
  • 19
0

The default behavior of the War task is to copy the content of src/main/webapp to the root of the archive. Your webapp directory may of course contain a WEB-INF sub-directory, which may contain all the dependencies of the runtime [1] configuration to WEB-INF/lib.

So to avoid load of other jar files or to decrease war file size, you may have to exclude jars during packaging. So, try adding rootSpec.exclude("/*.jar")** to exclude jars in war file like below.

war {
    archiveName = "newproject.war"
    rootSpec.exclude("**/*.jar")
    destinationDir = buildDir
}
Supritha
  • 1
  • 4