// 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.

[[ear_plugin]]
= The Ear Plugin

The Ear plugin adds support for assembling web application EAR files.
It adds a default EAR archive task.
It doesn't require the <<java_plugin.adoc#java_plugin,Java plugin>>, but for projects that also use the Java plugin it disables the default JAR archive generation.

[[sec:ear_usage]]
== Usage

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

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

[[sec:ear_tasks]]
== Tasks

The Ear plugin adds the following tasks to the project.

`ear` — link:{groovyDslPath}/org.gradle.plugins.ear.Ear.html[Ear]::
_Depends on_: `compile` (only if the Java plugin is also applied)
+
Assembles the application EAR file.

[[sec:ear_dependencies_added_to_other_tasks]]
=== Dependencies added to other tasks

The Ear plugin adds the following dependencies to tasks added by the <<base_plugin.adoc#base_plugin,Base Plugin>>.

`assemble`::
_Depends on_: `ear`.


[[sec:ear_project_layout]]
== Project layout

[source,text]
----
.
└── src
    └── main
        └── application // <1>
----
<1> Ear resources, such as a META-INF directory


[[sec:ear_dependency_management]]
== Dependency management

The Ear plugin adds two dependency configurations: `deploy` and `earlib`. All dependencies in the `deploy` configuration are placed in the root of the EAR archive, and are _not_ transitive. All dependencies in the `earlib` configuration are placed in the 'lib' directory in the EAR archive and _are_ transitive.

[[sec:ear_default_settings]]
== Ear

The default behavior of the Ear task is to copy the content of `src/main/application` to the root of the archive. If your `application` directory doesn't contain a `META-INF/application.xml` deployment descriptor then one will be generated for you.

The link:{groovyDslPath}/org.gradle.plugins.ear.Ear.html[Ear] class in the API documentation has additional useful information.

[[sec:ear_customizing]]
== Customizing

Here is an example with the most important customization options:

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

You can also use customization options that the link:{groovyDslPath}/org.gradle.plugins.ear.Ear.html[Ear] task provides, such as `from` and `metaInf`.

[[sec:skinny_war_pattern]]
== Skinny WAR Pattern

The Ear plugin supports the Skinny WAR deployment pattern, where shared libraries are placed in the EAR's `lib` directory rather than being packaged within individual WAR files.

=== Basic Skinny WAR Setup

To implement the Skinny WAR pattern, configure your multi-module project with separate `war` and `ear` modules:

.Project structure
----
.
├── settings.gradle.kts
├── war/ // <1>
│   └── src/main/
│       ├── java/
│       └── webapp/
└── ear/ // <2>
    └── src/main/application/
        └── META-INF/
            └── application.xml
----
<1> Contains web application code and resources, produces skinny WAR with compileOnly dependencies
<2> Assembles complete enterprise application, packages WAR and shared libraries in lib directory

=== WAR Module Configuration

Configure the WAR module to use `compileOnly` dependencies for libraries that will be provided by the EAR:

.WAR module build script
====
include::sample[dir="snippets/ear/skinnyWar/kotlin/war",files="build.gradle.kts[]"]
include::sample[dir="snippets/ear/skinnyWar/groovy/war",files="build.gradle[]"]
====

=== EAR Module Configuration

Configure the EAR module to include the WAR and place shared libraries in the `lib` directory:

.EAR module build script
====
include::sample[dir="snippets/ear/skinnyWar/kotlin/ear",files="build.gradle.kts[]"]
include::sample[dir="snippets/ear/skinnyWar/groovy/ear",files="build.gradle[]"]
====

=== Runtime Library Resolution

In the Skinny WAR pattern, shared dependencies are centralized in the EAR's `lib` directory instead of being duplicated in each WAR file. The generated EAR file structure demonstrates this dependency organization:

----
ear.ear
├── META-INF/
│   ├── MANIFEST.MF
│   └── application.xml
├── lib/
│   └── commons-lang3-3.14.0.jar
└── war.war (skinny WAR - no shared libraries)
----

[[sec:using_custom_app_xml]]
== Using custom descriptor file

You may already have appropriate settings in a `application.xml` file and want to use that instead of configuring the `ear.deploymentDescriptor` section of the build script. To accommodate that goal, place the `META-INF/application.xml` in the right place inside your source folders (see the `appDirName` property). The file contents will be used and the explicit configuration in the `ear.deploymentDescriptor` will be ignored.
