// Copyright (C) 2024 Gradle, Inc.
//
// Licensed under the Creative Commons Attribution-Noncommercial-ShareAlike 4.0 International License.;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://creativecommons.org/licenses/by-nc-sa/4.0/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

[[war_plugin]]
= The War Plugin

The War plugin extends the <<java_plugin.adoc#java_plugin,Java plugin>> to add support for assembling web application WAR files.
It adds a default `war` task that assembles the WAR archive, and a `web` software component for <<#sec:war_plugin_publishing,publishing>> it.

[[sec:war_usage]]
== Usage

To use the War plugin, include the following in your build script:

====
include::sample[dir="snippets/reference/core-plugins/webApplication/kotlin",files="build.gradle.kts[tags=use-war-plugin]"]
include::sample[dir="snippets/reference/core-plugins/webApplication/groovy",files="build.gradle[tags=use-war-plugin]"]
====

[[sec:war_project_layout]]
== Project layout

In addition to the <<java_plugin.adoc#sec:java_project_layout,standard Java project layout>>, the War Plugin adds:

`src/main/webapp`::
Web application sources

[[sec:war_tasks]]
== Tasks

The War plugin adds and modifies the following tasks:

`war` — link:{groovyDslPath}/org.gradle.api.tasks.bundling.War.html[War]::
_Depends on_: `classes`
+
Assembles the WAR archive containing the compiled classes, the web application content, and the runtime libraries.

`assemble` - _lifecycle task_::
_Depends on_: `war`

The War plugin adds the following dependencies to tasks added by the Java plugin;

.War plugin - tasks
image::warPluginTasks.png[]

[[sec:war_dependency_management]]
== Dependency management

The War plugin adds two dependency configurations:

`providedCompile`::
This configuration should be used for dependencies required at compilation but which are provided by the environment in which the WAR is deployed.
Dependencies declared here are visible to the `main` and `test` compile and runtime classpaths, but are excluded from the WAR archive.

`providedRuntime`::
This configuration should be used for dependencies required at runtime but which are provided by the environment in which the WAR is deployed.
Dependencies declared here are visible to the `main` and `test` runtime classpaths, but are excluded from the WAR archive.

[NOTE]
====
It is important to note that these `provided` configurations work transitively.

Let's say you add `commons-httpclient:commons-httpclient:3.0` to any of the provided configurations.
This dependency has a dependency on `commons-codec`.
Because this is a "provided" configuration, this means that neither of these dependencies will be added to your WAR, even if the `commons-codec` library is an explicit dependency of your `implementation` configuration.

If you don't want this transitive behavior, simply declare your `provided` dependencies like `commons-httpclient:commons-httpclient:3.0@jar`.
====

[[sec:war_plugin_publishing]]
== Publishing

`components.web`::
A link:{javadocPath}/org/gradle/api/component/SoftwareComponent.html[SoftwareComponent] for <<publishing_setup.adoc#publishing_overview,publishing>> the production WAR created by the `war` task.

[[sec:war_default_settings]]
== War

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 a `web.xml` file. Your compiled classes are copied to `WEB-INF/classes`. The libraries on the `runtimeClasspath` configuration, minus those declared in the `providedRuntime` configuration, are copied to `WEB-INF/lib`.

The link:{groovyDslPath}/org.gradle.api.tasks.bundling.War.html[War] class in the API documentation has additional useful information.

The most commonly configured properties of the `War` task are:

`webAppDirectory` — link:{javadocPath}/org/gradle/api/file/DirectoryProperty.html[DirectoryProperty]::
The directory whose contents are copied to the root of the archive.
The `war` plugin sets the default value to `src/main/webapp`.

`classpath` — link:{javadocPath}/org/gradle/api/file/FileCollection.html[FileCollection]::
The classpath to include in the archive.
Directories on the classpath are added to `WEB-INF/classes` and JAR or ZIP files are added to `WEB-INF/lib`.
The `war` plugin sets the default value to `sourceSets.main.runtimeClasspath` minus the `providedRuntime` configuration.

`webXml` — `File`::
The `web.xml` file to copy to `WEB-INF/web.xml`.
When not set, no `web.xml` file is included in the archive.
+
[NOTE]
====
An incubating replacement, `webXmlFile` (a link:{javadocPath}/org/gradle/api/file/RegularFileProperty.html[RegularFileProperty]), was introduced in Gradle 9.7.0.
====

`webInf`::
Adds a nested link:{groovyDslPath}/org.gradle.api.file.CopySpec.html[CopySpec] whose contents are copied into the `WEB-INF` directory of the archive.

[[sec:war_customizing]]
== Customizing

Here is an example with the most important customization options:

====
include::sample[dir="snippets/reference/core-plugins/customized/kotlin",files="build.gradle.kts[tags=customization]"]
include::sample[dir="snippets/reference/core-plugins/customized/groovy",files="build.gradle[tags=customization]"]
====

Of course one can configure the different file-sets with a closure to define excludes and includes.
