 ------
 EAR Modules
 ------
 Edwin Punzalan
 ------
 2006-07-31
 ------

~~ Copyright 2006 The Apache Software Foundation.
~~
~~ Licensed under the Apache License, Version 2.0 (the "License");
~~ you may not use this file except in compliance with the License.
~~ You may obtain a copy of the License at
~~
~~      http://www.apache.org/licenses/LICENSE-2.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.

~~ NOTE: For help with the syntax of this file, see:
~~ http://maven.apache.org/doxia/references/apt-format.html


EAR Modules

  The EAR Plugin supports additional configurations of the following modules:

  * {{{ejbClientModule}ejbClientModule}}

  * {{{ejbModule}ejbModule}}

  * {{{jarModule}jarModule}}

  * {{{parModule}parModule}}

  * {{{rarModule}rarModule}}

  * {{{sarModule}sarModule}}

  * {{{webModule}webModule}}

  * {{{wsrModule}wsrModule}}

  * {{{harModule}harModule}}

  * {{{appClientModule}appClientModule}}

  []

  If the artifact you want to configure is not listed above, you can create your
  own custom artifact configuration by following the
  {{{Custom_Artifact_Types}adding custom artifact types}} guide below this page.

  These module names go into the <<<modules>>> parameter of the EAR Plugin. For
  example, to configure the properties of an EjbModule, the EAR Plugin
  configuration for <<<modules>>> would look like:

+-----
<project>
  [...]
  <build>
    [...]
    <plugins>
      [...]
      <plugin>
        <artifactId>maven-ear-plugin</artifactId>
        <version>${project.version}</version>
        <configuration>
          <modules>
            <ejbModule>
              <!-- property configurations goes here -->
            </ejbModule>
          </modules>
        </configuration>
      </plugin>
      [...]
</project>
+-----


* {ejbClientModule} Properties

  The following configuration options are available for EjbClientModule:

  * <<groupId>> - sets the groupId of the artifact you want to configure.

  * <<artifactId>> - sets the artifactId of the artifact you want to configure.

  * <<type>> - sets the type of the artifact you want to configure.
  Default is 'ejb-client'.

  * <<classifier>> - sets the classifier of the artifact you want to
  configure if multiple artifacts matches the groupId/artifactId/type. Use
  the mainArtifactId ('none' by default) to define the main artifact (e.g.
  the artifact without a classifier).

  * <<bundleDir>> - sets the location of this artifact inside the ear archive.
  If not set, this artifact will be packaged in the root of the archive.

  * <<bundleFileName>> - sets the new name of this artifact inside the ear
  archive. If not set, the artifact's filename in the repository is used.

  * <<excluded>> - set to true to exclude this artifact from being packaged into
  the ear archive. Default is false.

  * <<uri>> - sets the URI path of this artifact within the ear archive.
  Automatically determined when not set.

  * <<unpack>> - set to true to unpack this artifact into the ear archive according
  to its uri. Default is false.

  * <<altDeploymentDescriptor>> - sets the alternative deployment descriptor for
  this module.

  * <<moduleId>> - sets the id of the module in the generated application.xml.

  * <<libDirectory>> - sets archive directory which contains Java libraries (JARs)
  packaged into archive. Default is <<<null>>> meaning that archive doesn't
  contain packaged libraries.
  If libraries are located at the root of archive then use single slash ('/')
  to configure that.
  If <<<libDirectory>>> is <<<null>>> then <<<Class-Path>>> setting of module
  <<<MANIFEST.MF>>> is modified to reference libraries which are packaged in EAR.
  Modification here means:

    * If <<<MANIFEST.MF>>> has no <<<Class-Path>>> setting then it is added.

    * Existing elements of <<<Class-Path>>> setting which match libraries packaged
    in EAR are replaced with references to the matching libraries in EAR.

    * Other libraries packaged in EAR are appended to <<<Class-Path>>> setting in order
    of EAR dependency on library if
    {{{./ear-mojo.html#skipClassPathModification}skipClassPathModification}} parameter
    is false.

  If <<<libDirectory>>> is not <<<null>>> and if
  {{{./examples/skinny-modules.html}skinny modules}} are used then <<<Class-Path>>>
  setting in module <<<MANIFEST.MF>>> is modified and libraries of module located in
  <<<libDirectory>>> and matching libraries of EAR are removed from module.

  * <<classPathItem>> - defines if the module is an element of the <<<Class-Path>>> setting
  of <<<MANIFEST.MF>>> of other modules. Default is true. Refer to the <<<classPathItem>>>
  property of {{{jarModule}jarModule}} for the cases when the module is removed from
  the <<<Class-Path>>> setting or added into the <<<Class-Path>>> setting or existing
  reference to the module is updated in the <<<Class-Path>>> setting of <<<MANIFEST.MF>>>
  of other modules.


* {ejbModule} Properties

  The following configuration options are available for EjbModule:

  * <<groupId>> - sets the groupId of the artifact you want to configure.

  * <<artifactId>> - sets the artifactId of the artifact you want to configure.

  * <<type>> - sets the type of the artifact you want to configure.
  Default is 'ejb'.

  * <<classifier>> - sets the classifier of the artifact you want to
  configure if multiple artifacts matches the groupId/artifactId/type. Use
  the mainArtifactId ('none' by default) to define the main artifact (e.g.
  the artifact without a classifier).

  * <<bundleDir>> - sets the location of this artifact inside the ear archive.
  If not set, this artifact will be packaged in the root of the archive.

  * <<bundleFileName>> - sets the new name of this artifact inside the ear
  archive. If not set, the artifact's filename in the repository is used.

  * <<excluded>> - set to true to exclude this artifact from being packaged into
  the ear archive. Default is false.

  * <<uri>> - sets the uri path of this artifact within the ear archive.
  Automatically determined when not set.

  * <<unpack>> - set to true to unpack this artifact into the ear archive according
  to its uri. Default is false.

  * <<altDeploymentDescriptor>> - sets the alternative deployment descriptor for
  this module.

  * <<moduleId>> - sets the id of the module in the generated application.xml.

  * <<libDirectory>> - refer to the same name property of {{{ejbClientModule}ejbClientModule}}.

  * <<classPathItem>> - defines if the module is an element of the <<<Class-Path>>> setting
  of <<<MANIFEST.MF>>> of other modules. Default is false. Refer to the <<<classPathItem>>>
  property of {{{jarModule}jarModule}} for the cases when the module is removed from
  the <<<Class-Path>>> setting or added into the <<<Class-Path>>> setting or existing
  reference to the module is updated in the <<<Class-Path>>> setting of <<<MANIFEST.MF>>>
  of other modules.


* {jarModule} Properties

  The following configuration options are available for JarModule:

  * <<groupId>> - sets the groupId of the artifact you want to configure.

  * <<artifactId>> - sets the artifactId of the artifact you want to configure.

  * <<type>> - sets the type of the artifact you want to configure.
  Default is 'jar'. Use 'test-jar' if the artifact of the module is test JAR.

  * <<classifier>> - sets the classifier of the artifact you want to
  configure if multiple artifacts matches the groupId/artifactId/type. Use
  the mainArtifactId ('none' by default) to define the main artifact (e.g.
  the artifact without a classifier).

  * <<bundleDir>> - sets the location of this artifact inside the ear archive.
  If not set, this artifact will be packaged in the root of the archive.

  * <<bundleFileName>> - sets the new name of this artifact inside the ear
  archive. If not set, the artifact's filename in the repository is used.

  * <<excluded>> - set to true to exclude this artifact from being packaged into
  the ear archive. Default is false.

  * <<uri>> - sets the uri path of this artifact within the ear archive.
  Automatically determined when not set.

  * <<unpack>> - set to true to unpack this artifact into the ear archive according
  to its uri. Default is false.

  * <<altDeploymentDescriptor>> - sets the alternative deployment descriptor for
  this module.

  * <<moduleId>> - sets the id of the module in the generated application.xml.

  * <<includeInApplicationXml>> - set to true to if you want to generate an entry
  of this module in <<<application.xml>>>. Default is false.

  * <<classPathItem>> - defines if the module is an element of the <<<Class-Path>>> setting
  of <<<MANIFEST.MF>>> of other modules. Default is true.

  The module is removed from the <<<Class-Path>>> setting of <<<MANIFEST.MF>>> of another module
  if the <<<classPathItem>>> property is false and one of the following conditions is met:

    * Another module doesn't contain all of its dependencies (refer to the <<<libDirectory>>>
    property of particular module type).

    * {{{./ear-mojo.html#skinnyWars}skinnyWars}} parameter is true and another module is
    a {{{webModule}webModule}}.

    * {{{./ear-mojo.html#skinnyModules}skinnyModules}} parameter is true.

  Existing reference to the module in the <<<Class-Path>>> setting of <<<MANIFEST.MF>>>
  of another module is updated to match location of the module in EAR if
  the <<<classPathItem>>> property is true and one of the following conditions is met:

    * Another module doesn't contain all of its dependencies (refer to the <<<libDirectory>>>
    property of particular module type).

    * {{{./ear-mojo.html#skinnyWars}skinnyWars}} parameter is true and another module is
    a {{{webModule}webModule}}.

    * {{{./ear-mojo.html#skinnyModules}skinnyModules}} parameter is true.

  The module is added into the <<<Class-Path>>> setting of another module
  if the <<<classPathItem>>> is true, there is no existing reference to the module
  in the <<<Class-Path>>> setting and one of the following conditions is met:

    * {{{./ear-mojo.html#skinnyWars}skinnyWars}} parameter is true, another module is
    a {{{webModule}webModule}} and one of the following conditions is met:

      * {{{./ear-mojo.html#skipClassPathModification}skipClassPathModification}} parameter is false.

      * {{{./ear-mojo.html#version}version}} parameter is less than 5.

    * {{{./ear-mojo.html#skinnyModules}skinnyModules}} parameter is true and
    one of the following conditions is met:

      * {{{./ear-mojo.html#skipClassPathModification}skipClassPathModification}} parameter is false.

      * {{{./ear-mojo.html#version}version}} parameter is less than 5.


* {parModule} Properties

  The following configuration options are available for ParModule:

  * <<groupId>> - sets the groupId of the artifact you want to configure.

  * <<artifactId>> - sets the artifactId of the artifact you want to configure.

  * <<type>> - sets the type of the artifact you want to configure.
  Default is 'par'. If the artifact you want to configure is built with
  {{{https://github.com/mojohaus/jboss-packaging-maven-plugin}JBoss Packaging Maven Plugin}}
  and has 'jboss-par' type, then that type should be specified explicitly.

  * <<classifier>> - sets the classifier of the artifact you want to
  configure if multiple artifacts matches the groupId/artifactId/type. Use
  the mainArtifactId ('none' by default) to define the main artifact (e.g.
  the artifact without a classifier).

  * <<bundleDir>> - sets the location of this artifact inside the ear archive.
  If not set, this artifact will be packaged in the root of the archive.

  * <<bundleFileName>> - sets the new name of this artifact inside the ear
  archive. If not set, the artifact's filename in the repository is used.

  * <<excluded>> - set to true to exclude this artifact from being packaged into
  the ear archive. Default is false.

  * <<uri>> - sets the uri path of this artifact within the ear archive.
  Automatically determined when not set.

  * <<unpack>> - set to true to unpack this artifact into the ear archive according
  to its uri. Default is false.

  * <<altDeploymentDescriptor>> - sets the alternative deployment descriptor for
  this module.

  * <<moduleId>> - sets the id of the module in the generated application.xml.

  * <<libDirectory>> - refer to the same name property of {{{ejbClientModule}ejbClientModule}}.

  * <<classPathItem>> - defines if the module is an element of the <<<Class-Path>>> setting
  of <<<MANIFEST.MF>>> of other modules. Default is false. Refer to the <<<classPathItem>>>
  property of {{{jarModule}jarModule}} for the cases when the module is removed from
  the <<<Class-Path>>> setting or added into the <<<Class-Path>>> setting or existing
  reference to the module is updated in the <<<Class-Path>>> setting of <<<MANIFEST.MF>>>
  of other modules.


* {rarModule} Properties

  The following configuration options are available for RarModule:

  * <<groupId>> - sets the groupId of the artifact you want to configure.

  * <<artifactId>> - sets the artifactId of the artifact you want to configure.

  * <<type>> - sets the type of the artifact you want to configure.
  Default is 'rar'.

  * <<classifier>> - sets the classifier of the artifact you want to
  configure if multiple artifacts matches the groupId/artifactId/type. Use
  the mainArtifactId ('none' by default) to define the main artifact (e.g.
  the artifact without a classifier).

  * <<bundleDir>> - sets the location of this artifact inside the ear archive.
  If not set, this artifact will be packaged in the root of the archive.

  * <<bundleFileName>> - sets the new name of this artifact inside the ear
  archive. If not set, the artifact's filename in the repository is used.

  * <<excluded>> - set to true to exclude this artifact from being packaged into
  the ear archive. Default is false.

  * <<uri>> - sets the uri path of this artifact within the ear archive.
  Automatically determined when not set.

  * <<unpack>> - set to true to unpack this artifact into the ear archive according
  to its uri. Default is false.

  * <<altDeploymentDescriptor>> - sets the alternative deployment descriptor for
  this module.

  * <<moduleId>> - sets the id of the module in the generated application.xml.

  * <<libDirectory>> - sets archive directory which contains Java libraries
  packaged into archive. Default is '/' meaning that libraries are located
  at the root of archive. Refer to the same name property of
  {{{ejbClientModule}ejbClientModule}} for details.

  * <<classPathItem>> - defines if the module is an element of the <<<Class-Path>>> setting
  of <<<MANIFEST.MF>>> of other modules. Default is false. Refer to the <<<classPathItem>>>
  property of {{{jarModule}jarModule}} for the cases when the module is removed from
  the <<<Class-Path>>> setting or added into the <<<Class-Path>>> setting or existing
  reference to the module is updated in the <<<Class-Path>>> setting of <<<MANIFEST.MF>>>
  of other modules.


* {sarModule} Properties

  The following configuration options are available for SarModule:

  * <<groupId>> - sets the groupId of the artifact you want to configure.

  * <<artifactId>> - sets the artifactId of the artifact you want to configure.

  * <<type>> - sets the type of the artifact you want to configure.
  Default is 'sar'. If the artifact you want to configure is built with
  {{{https://github.com/mojohaus/jboss-packaging-maven-plugin}JBoss Packaging Maven Plugin}}
  and has 'jboss-sar' type, then that type should be specified explicitly.

  * <<classifier>> - sets the classifier of the artifact you want to
  configure if multiple artifacts matches the groupId/artifactId/type. Use
  the mainArtifactId ('none' by default) to define the main artifact (e.g.
  the artifact without a classifier).

  * <<bundleDir>> - sets the location of this artifact inside the ear archive.
  If not set, this artifact will be packaged in the root of the archive.

  * <<bundleFileName>> - sets the new name of this artifact inside the ear
  archive. If not set, the artifact's filename in the repository is used.

  * <<excluded>> - set to true to exclude this artifact from being packaged into
  the ear archive. Default is false.

  * <<uri>> - sets the uri path of this artifact within the ear archive.
  Automatically determined when not set.

  * <<unpack>> - set to true to unpack this artifact into the ear archive according
  to its uri. Default is false.

  * <<moduleId>> - sets the id of the module in the generated application.xml.

  * <<libDirectory>> - sets archive directory which contains Java libraries
  packaged into archive. Default is 'lib'. Refer to the same name property of
  {{{ejbClientModule}ejbClientModule}} for details.

  * <<classPathItem>> - defines if the module is an element of the <<<Class-Path>>> setting
  of <<<MANIFEST.MF>>> of other modules. Default is false. Refer to the <<<classPathItem>>>
  property of {{{jarModule}jarModule}} for the cases when the module is removed from
  the <<<Class-Path>>> setting or added into the <<<Class-Path>>> setting or existing
  reference to the module is updated in the <<<Class-Path>>> setting of <<<MANIFEST.MF>>>
  of other modules.


* {webModule} Properties

  The following configuration options are available for WebModule:

  * <<groupId>> - sets the groupId of the artifact you want to configure.

  * <<artifactId>> - sets the artifactId of the artifact you want to configure.

  * <<type>> - sets the type of the artifact you want to configure.
  Default is 'war'.

  * <<classifier>> - sets the classifier of the artifact you want to
  configure if multiple artifacts matches the groupId/artifactId/type. Use
  the mainArtifactId ('none' by default) to define the main artifact (e.g.
  the artifact without a classifier).

  * <<bundleDir>> - sets the location of this artifact inside the ear archive.
  If not set, this artifact will be packaged in the root of the archive.

  * <<bundleFileName>> - sets the new name of this artifact inside the ear
  archive. If not set, the artifact's filename in the repository is used.

  * <<excluded>> - set to true to exclude this artifact from being packaged into
  the ear archive. Default is false.

  * <<uri>> - sets the uri path of this artifact within the ear archive.
  Automatically determined when not set.

  * <<unpack>> - set to true to unpack this artifact into the ear archive according
  to its uri. Default is false.

  * <<altDeploymentDescriptor>> - sets the alternative deployment descriptor for
  this module.

  * <<moduleId>> - sets the id of the module in the generated application.xml.

  * <<contextRoot>> - sets the context root of this web artifact.

  * <<libDirectory>> - sets archive directory which contains Java libraries
  packaged into archive. Default is 'WEB-INF/lib'. Refer to the same name property
  of {{{ejbClientModule}ejbClientModule}} for details.
  If <<<libDirectory>>> is not <<<null>>> and if
  {{{./examples/skinny-wars.html}skinny WARs}} or
  {{{./examples/skinny-modules.html}skinny modules}} are used then <<<Class-Path>>>
  setting in module <<<MANIFEST.MF>>> is modified and libraries of module located in
  <<<libDirectory>>> and matching libraries of EAR are removed from module.

  * <<classPathItem>> - defines if the module is an element of the <<<Class-Path>>> setting
  of <<<MANIFEST.MF>>> of other modules. Default is false. Refer to the <<<classPathItem>>>
  property of {{{jarModule}jarModule}} for the cases when the module is removed from
  the <<<Class-Path>>> setting or added into the <<<Class-Path>>> setting or existing
  reference to the module is updated in the <<<Class-Path>>> setting of <<<MANIFEST.MF>>>
  of other modules.


* {wsrModule} Properties

  The following configuration options are available for WsrModule:

  * <<groupId>> - sets the groupId of the artifact you want to configure.

  * <<artifactId>> - sets the artifactId of the artifact you want to configure.

  * <<type>> - sets the type of the artifact you want to configure.
  Default is 'wsr'.

  * <<classifier>> - sets the classifier of the artifact you want to
  configure if multiple artifacts matches the groupId/artifactId/type. Use
  the mainArtifactId ('none' by default) to define the main artifact (e.g.
  the artifact without a classifier).

  * <<bundleDir>> - sets the location of this artifact inside the ear archive.
  If not set, this artifact will be packaged in the root of the archive.

  * <<bundleFileName>> - sets the new name of this artifact inside the ear
  archive. If not set, the artifact's filename in the repository is used.

  * <<excluded>> - set to true to exclude this artifact from being packaged into
  the ear archive. Default is false.

  * <<uri>> - sets the uri path of this artifact within the ear archive.
  Automatically determined when not set.

  * <<unpack>> - set to true to unpack this artifact into the ear archive according
  to its uri. Default is false.

  * <<altDeploymentDescriptor>> - sets the alternative deployment descriptor for
  this module.

  * <<moduleId>> - sets the id of the module in the generated application.xml.

  * <<libDirectory>> - sets archive directory which contains Java libraries
  packaged into archive. Default is 'lib'. Refer to the same name property of
  {{{ejbClientModule}ejbClientModule}} for details.

  * <<classPathItem>> - defines if the module is an element of the <<<Class-Path>>> setting
  of <<<MANIFEST.MF>>> of other modules. Default is false. Refer to the <<<classPathItem>>>
  property of {{{jarModule}jarModule}} for the cases when the module is removed from
  the <<<Class-Path>>> setting or added into the <<<Class-Path>>> setting or existing
  reference to the module is updated in the <<<Class-Path>>> setting of <<<MANIFEST.MF>>>
  of other modules.


* {harModule} Properties

  The following configuration options are available for HarModule:

  * <<groupId>> - sets the groupId of the artifact you want to configure.

  * <<artifactId>> - sets the artifactId of artifact you want to configure.

  * <<type>> - sets the type of the artifact you want to configure.
  Default is 'har'. If the artifact you want to configure is built with
  {{{https://github.com/mojohaus/jboss-packaging-maven-plugin}JBoss Packaging Maven Plugin}}
  and has 'jboss-har' type, then that type should be specified explicitly.

  * <<classifier>> - sets the classifier of the artifact you want to
  configure if multiple artifacts matches the groupId/artifactId/type. Use
  the mainArtifactId ('none' by default) to define the main artifact (e.g.
  the artifact without a classifier).

  * <<bundleDir>> - sets the location of this artifact inside the ear archive.
  If not set, this artifact will be packaged in the root of the archive.

  * <<bundleFileName>> - sets the new name of this artifact inside the ear
  archive. If not set, the artifact's filename in the repository is used.

  * <<excluded>> - set to true to exclude this artifact from being packaged into
  the ear archive. Default is false.

  * <<uri>> - sets the uri path of this artifact within the ear archive.
  Automatically determined when not set.

  * <<unpack>> - set to true to unpack this artifact into the ear archive according
  to its uri. Default is false.

  * <<libDirectory>> - sets archive directory which contains Java libraries
  packaged into archive. Default is 'lib'. Refer to the same name property of
  {{{ejbClientModule}ejbClientModule}} for details.

  * <<classPathItem>> - defines if the module is an element of the <<<Class-Path>>> setting
  of <<<MANIFEST.MF>>> of other modules. Default is false. Refer to the <<<classPathItem>>>
  property of {{{jarModule}jarModule}} for the cases when the module is removed from
  the <<<Class-Path>>> setting or added into the <<<Class-Path>>> setting or existing
  reference to the module is updated in the <<<Class-Path>>> setting of <<<MANIFEST.MF>>>
  of other modules.


* {appClientModule} Properties

  The following configuration options are available for AppClientModule:

  * <<groupId>> - sets the groupId of the artifact you want to configure.

  * <<artifactId>> - sets the artifactId of the artifact you want to configure.

  * <<type>> - sets the type of the artifact you want to configure.
  Default is 'app-client'.

  * <<classifier>> - sets the classifier of the artifact you want to
  configure if multiple artifacts matches the groupId/artifactId/type. Use
  the mainArtifactId ('none' by default) to define the main artifact (e.g.
  the artifact without a classifier).

  * <<bundleDir>> - sets the location of this artifact inside the ear archive.
  If not set, this artifact will be packaged in the root of the archive.

  * <<bundleFileName>> - sets the new name of this artifact inside the ear
  archive. If not set, the artifact's filename in the repository is used.

  * <<excluded>> - set to true to exclude this artifact from being packaged into
  the ear archive. Default is false.

  * <<uri>> - sets the uri path of this artifact within the ear archive.
  Automatically determined when not set.

  * <<unpack>> - set to true to unpack this artifact into the ear archive according
  to its uri. Default is false.

  * <<altDeploymentDescriptor>> - sets the alternative deployment descriptor for
  this module.

  * <<moduleId>> - sets the id of the module in the generated application.xml.

  * <<classPathItem>> - defines if the module is an element of the <<<Class-Path>>> setting
  of <<<MANIFEST.MF>>> of other modules. Default is false. Refer to the <<<classPathItem>>>
  property of {{{jarModule}jarModule}} for the cases when the module is removed from
  the <<<Class-Path>>> setting or added into the <<<Class-Path>>> setting or existing
  reference to the module is updated in the <<<Class-Path>>> setting of <<<MANIFEST.MF>>>
  of other modules.


* Adding {Custom Artifact Types}

  If you need to map a custom artifact type to one of those types, use the
  <<<customArtifactTypeMappings>>>.

  For instance, to map a custom 'my-rar' to the 'rar' standard artifact's type,
  add the following to the pom's configuration:

+--------
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-ear-plugin</artifactId>
        <version>${project.version}</version>
        <configuration>
          <artifactTypeMappings>
            <artifactTypeMapping type="my-rar" mapping="rar"/>
          </artifactTypeMappings>
        </configuration>
      </plugin>
    </plugins>
  </build>
+---------
