We have learned how to create ZIP, TAR, and JAR archives with Gradle in this chapter and the previous one. In a Java project we can also package our applications as Web application Archive (WAR) or Enterprise Archive (EAR) files. For a web application we would like to package our application as a WAR file, while a Java Enterprise Edition application can be packaged as an EAR file. Gradle also supports these types of archives with plugins and tasks.
To create a WAR file we can add a new task of type War
to our Java project. The properties and methods of the War
task are the same as for the other archive tasks such as Jar
. In fact, the War
task extends the Jar
task.
The War
task has an extra method, webInf()
, to define a source directory for the WEB-INF
directory in a WAR file. The webXml
property can be used to reference a web.xml
file that needs to be copied into the WAR file. This is just another way to include a web.xml
file; we can also place the web.xml
file in the WEB-INF
directory of the root source directory we defined for the WAR file.
With the classpath()
method, we can define a dependency configuration or directory with libraries or class files we want copied to our WAR file. If the file is a JAR or ZIP file, it is copied to the WEB-INF/lib
directory and other files are copied into the WEB-INF/classes
directory.
In the following sample build file we define a new task war
. We set the root of the WAR file contents to the directory src/main/webapp
. We use the webInf()
and
classpath()
methods to customize the contents of the WEB-INF
, WEB-INF/classes
, and WEB-INF/lib
folders. And, we set a custom web.xml
file with the webXml
property of the task:
apply plugin: 'java' version = '1.0' task war(type: War) { dependsOn classes from 'src/main/webapp' // Files copied to WEB-INF. webInf { from 'src/main/webInf' } // Copied to WEB-INF/classes. classpath sourceSets.main.runtimeClasspath // Copied to WEB-INF/lib. classpath fileTree('libs') // Custom web.xml. webXml = file('src/main/webXml/web-dev.xml') baseName = 'gradle-webapp' } assemble.dependsOn war
To create the WAR file we can execute the war
or assemble
task. The war
task is added to the assemble
task as a task dependency. That is why, if we invoke the assemble
task, Gradle will execute the war
task. Once we have executed the task, the
WAR file gradle-webapp-1.0.war
is created in the directory build/libs
:
$ gradle war :compileJava :processResources :classes :war BUILD SUCCESSFUL Total time: 0.727 secs web mrhaki$ ls build/libs gradle-webapp-1.0.war
Instead of creating a War
task ourselves, we can apply the War plugin in our project. This plugin adds a war
task for us that we can invoke. Also, the default JAR archive is not created for our project any more, as part of the assemble
task.
The plugin also adds two dependency configurations to our project, with the names providedCompile
and providedRuntime
. Any dependencies added to these configurations are not copied to the WEB-INF/lib
directory of our WAR file. If a dependency exists both in the runtime
and providedRuntime
configuration, it is not copied to the WEB-INF/lib
folder. This also works for transitive dependencies.
The default source directory for the contents of the WAR file is src/main/webapp
. We can change this with the property webAppDirName
, if we want to use another directory. This property is a convention property provided by the War plugin.
To customize the added war
task, we still use the same methods and properties we have used for the war
task we created ourselves.
In the sample build file, we now apply the War plugin. We assign some dependencies to the extra dependency configurations and customize the war
task:
apply plugin: 'war' version = '1.0' repositories { mavenCentral() } configurations { extraLibs } dependencies { providedCompile 'javax.servlet:servlet-api:3.0' providedRuntime 'webcontainer:logging:1.0' extraLibs 'sample:lib:2.1' } war { classpath configuration.extraLibs // Custom web.xml. webXml = file('src/main/webXml/web-dev.xml') baseName = 'gradle-webapp' }
To create an EAR file we can create a new task of type Ear
. This task has the same properties and methods as the Jar
task. The Ear
task extends the Jar
task.
With the
lib()
method, we can define which files need to be copied to the lib
directory in the EAR file.
The following build file has a simple ear
task:
import org.gradle.plugins.ear.Ear apply plugin: 'java' version = '1.0' task ear(type: Ear) { from 'src/main/application' lib { from fileTree('earLibs') } baseName = 'gradle-enterprise-app' } assemble.dependsOn ear
We can execute the ear
task and look in the build/libs
directory to see the resulting gradle-enterprise-app-1.0.ear
file:
$gradle ear :ear BUILD SUCCESSFUL Total time: 0.694 secs web mrhaki$ ls build/libs gradle-enterprise-app-1.0.ear
The best way to create an EAR file is by applying the Ear plugin to our project. The plugin adds an ear
task to our project and makes sure the assemble
task will build the EAR file instead of the JAR file of the project.
The plugin also adds two new dependency configurations: deploy
and earlib
. Dependencies assigned to the deploy
configuration are copied to the root of the EAR file. The dependencies are not transitive. The dependencies assigned to the earlib
configuration are transitive and are copied to the lib
directory in the EAR file. We can customize the name of the lib
directory in the EAR file with the project or ear
task property libDirName
.
Any files in the src/main/application
directory are also added to the EAR file. We can change this directory location with the property appDirName
, which is added by the plugin. Here, we can place the file application.xml
in the directory META-INF
, as an EAR descriptor file.
In the sample build file, we apply the Ear plugin and customize the ear
task:
apply plugin: 'java' apply plugin: 'ear' version = '1.0' repositories { flatDir { dirs 'lib' } mavenCentral() } dependencies { deploy 'sample:gradle-web:1.0' earlib 'org.slf4j:slfj4-impl:1.6.2' } ear.baseName = 'gradle-enterprise-app'
We can run the assemble
or ear
task to create the EAR file gradle-enterprise-app-1.0.ear
in the directory build/libs
:
$ gradle clean assemble :clean :compileJava :processResources :classes :ear :assemble BUILD SUCCESSFUL Total time: 0.741 secs web mrhaki$ ls build/libs gradle-enterprise-app-1.0.ear
3.129.42.134