maven-war-plugin how to exclude provided jar from lib directory but include in manifest with prefix folder

1.1k Views Asked by At

I am trying to build a skinny war for later inclusion in a large ear file. The ear build is entirely separate to my war's project and expects me to provide a skinny war, with the correct manifest file, the ear promises to supply provided jars in its root /libs folder.

Problem I am facing is getting the war's manifest.mf file to specify that provided jar's are in the ear's /libs folder, and compile/runtime jars are in the war. i.e. the manifest.mf class-path entry wants to look like this:

Class-Path: libs/commons-lang.jar commons-codec.jar

commons-lang is scoped to provided and expected to be in the ear's libs directory.

commons-codec is compile time and expected to be part of the war.

I've explored maven-war-plugin but can't figure out how to get it to supply the classpathPrefix for just the provided dependencies.

Suggestions please?


The final adopted solution (thanks to all with tips and links) Requires the dependencies provided by ear be scoped to provided and this, noticed the hack: fake-application.xml :

 <plugin>
    <!--required to fix the war's manifest and skinny the war-->
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-ear-plugin</artifactId>
    <version>2.10.1</version>
    <configuration>
        <defaultLibBundleDir>lib/</defaultLibBundleDir>
        <skinnyWars>true</skinnyWars>
        <generateApplicationXml>true</generateApplicationXml>
        <applicationXml>${project.basedir}/src/test/fake-ear/fake-application.xml</applicationXml>
    </configuration>
    <executions>
        <execution>
            <phase>verify</phase>
            <goals><goal>ear</goal></goals>
        </execution>
    </executions>
 </plugin>

I then deploy this new skinny war to the repository and did so using the maven deploy plugin:

<plugin>
    <!--used in release build to deploy skinny war to nexus-->
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-deploy-plugin</artifactId>
    <version>2.8.2</version>
    <executions>
        <execution>
            <id>deploy-file</id>
            <phase>install</phase>
            <goals>
                <goal>deploy-file</goal>
            </goals>
            <configuration>
                <!--location of the skinny war after maven-ear-plugin builds it-->
                <file>${project.build.directory}/${project.artifactId}-${project.version}/${artifactid}-${project.parent.version}.war</file>
                <repositoryId>releases</repositoryId>
                <url>${distributionManagement.repository.url}</url>
                <groupId>${project.parent.groupId}</groupId>
                <artifactId>${artifactid}</artifactId>
                <version>${project.parent.version}</version>
                <packaging>war</packaging>
            </configuration>
        </execution>
    </executions>
</plugin>
1

There are 1 best solutions below

3
On

@Tunaki's maven-ear-plugin suggestion seems better in a holistic manner, but anyway take a look: https://maven.apache.org/plugins/maven-shade-plugin/examples/executable-jar.html

You can modify the manifest this way:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.4.3</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <manifestEntries>
                    <Class-Path>libs/commons-lang.jar commons-codec.jar</Class-Path>
                  </manifestEntries>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>