How does war plugin decide which jar file should go under WEB-INF/lib directory?

buildship
plugins

(Parth) #1

Hello guys,

I am new to Gradle. Currently involved with an assignment where need to convert Ant build to Gradle build for a multi project gradle build mechansim. Most of projects are already coverted to gradle build. There is one project I am working on which needs to convert from Ant to gradle.

For a web archive I’ve added WAR plugin to gradle file. I am not able to understand which jar files (dependencies) will got to WEB-INF/lib directory.

Below is dependency task for my gradle file:

dependencies {
	compile fileTree(dir: 'lib', include: '*.jar')
}

My intention is to only have jar files which are under {project_dir}/lib directory.

But gradle war ends up with with many additional jar files apart from those under lib directory. So want to understand that how does gradle decide which jar files should go in WEB-INF/lib directory. I’ve read in document that those which are complie and runtime dependencies will go to WEB-INF/lib directory. But here I did not mentioned complie or runtime dependencies.

So, how does it decide which jar file should go under WEB-INF/lib directory ?
Does it have impact of multi project build mechanism on copying jar files for WEB-INF/lib ?


(Parth) #2

Any help on this will be greatful.

Thank you.


(nerro) #3

Can you provide your build.gradle please? It would help to help you :slight_smile:


(Parth) #4

Here is my build file.

apply plugin: 'war'

buildDir = "${rootProject.ext.buildGradle}/${project.name}"
def buildClassesDir = buildDir.getAbsolutePath() + '/classes/main'

task copyNonJava(type: Copy, dependsOn: compileJava) {
	from ('src/main/java') {
		exclude '**/*.java'
		include '**/*.properties'
	}
	from ('resources') {
		include 'default_content.properties'
	}

	into buildClassesDir

	includeEmptyDirs = false
}

task bundleJar (type: Jar, dependsOn: ['compileJava', 'copyNonJava']) {
	baseName archivesBaseName
	from buildClassesDir
}

task bundleWar (type: War, dependsOn: ['bundleJar']) {
	baseName = project.name
	from 'web'
	webXml = file( 'resources/WEB-INF/web.xml' )
	classpath fileTree('lib')
}

dependencies {
    compile group: 'com.system', name: 'core', version: rootProject.version, changing: true
	compile group: 'com.system', name: 'core-ui', version: rootProject.version, changing: true
	compile group: 'com.persistence', name: 'persistence', version: '1.0'
	compile group: 'com.surveys', name: 'survey', version: '1.0'
}

There are around 8-9 jar files under lib directory. I only want those jar files and not any other. But I ended up having approx. 100 jar files.


(nerro) #5

There are your com.system dependencies declared and they are will be included into war file.

I would solve your issue using configuration. E.g.

apply plugin: "war"

repositories {
  jcenter()
}

configurations {
  localLibraries
}

dependencies {
  compile "junit:junit:4.12"
  localLibraries fileTree("lib")
}

war {
  classpath = configurations.localLibraries
}

Most important line is classpath = configurations.localLibraries. So you can override default classpath of war plugin.

If you have any questions, please let me know.


(Parth) #6

Thanks for the reply.

I tried the solution you have shared. Thing is compile dependencies are not been included in war file WEB-INF/lib directory (in my case dependencies com.*). Why it is so?

What I was doing wrong? Can you please explain me why it was wrong or share link to document for the same?

Thank you.


(nerro) #7

If I understood you correctly, you wanted that only jar files from lib directory will be copied into WEB-INF/lib. So I defined custom configuration localLibraries with jars from lib directory. And as classpath I use only localLibraries configuration (that is why only these files are in WEB-INF/lib directory).

Your com.* dependencies have other dependencies too, that is why your initial approach has many files (about 100) in WEB-INF/lib folder. Documentation about WAR plugin -
https://docs.gradle.org/current/userguide/war_plugin.html#sec:war_default_settings.

If you’ll provide more details (what dependencies exactly should be copied into WEB-INF/lib directory), so it will be easier to provide a good solution for you.


P.S. You can exclude transitive dependencies from your com.* libraries using @jar (https://docs.gradle.org/current/userguide/dependency_management.html#ssub:artifact_dependencies). E.g.

...
dependencies {
  compile group: 'com.system', name: 'core', version: rootProject.version, changing: true, ext: jar
}
...

(Parth) #8

Thanks nerro for the reply.

I want jar files from lib directory as well as those defined in compile dependencies. I also want jar file generated from bundleJar task from this project.

Thanks.


(Parth) #9

Hello Nerro,

Any input how can I do that? How can I use jar file generated with jar task defined in the same gradle file and use that jar file to WEB-INF/lib directory of war task?

Thank you.