1

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>
alfan
  • 81
  • 1
  • 6
  • You want to look at the Maven EAR plugin, since you want to create an EAR. It has support for skiny wars, and it rewrites correctly the manifest of each WARs http://maven.apache.org/plugins/maven-ear-plugin/examples/skinny-wars.html – Tunaki Nov 09 '16 at 14:12
  • But otherwise, you need to pass `true` for your `` configuration to work, see the linked question. – Tunaki Nov 09 '16 at 14:52

1 Answers1

0

@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>
nandsito
  • 3,782
  • 2
  • 19
  • 26
  • It's not the "holistic manner", it's the only way that really works. This has a lot of side effects: it only works for 1 WAR, it packages all the classes in the root directory of the WAR, you need to write every dependency yourself... All of this is probably not wanted. – Tunaki Nov 09 '16 at 14:44
  • @Tunaki i actually mentioned your suggestion as the better one in a holistic manner. Mine is just a local WAR fix. Maybe the OP can tell us what he or she wants – nandsito Nov 09 '16 at 14:49
  • There are better local WAR fix than this... See the linked question, you can customize the Manifest directly with the WAR plugin. – Tunaki Nov 09 '16 at 14:53