Craig Otis
Craig Otis

Reputation: 32054

Include Source JAR (of web application) in lib directory of WAR file

We're using Cobertura to generate test coverage for our deployed web application. It needs to find the source JARs on the classpath of the application in order to produce our HTML reports.

Our Maven build produces:

target/our-webapp-sources.jar (about 40k)
target/our-webapp.war (about 20MB)

And when deployed in Tomcat, we have (under WEB-INF)

classes/... (the .class files) ...
lib/our-service-library.jar
lib/our-service-library-sources.jar
lib/our-core-library.jar
lib/our-core-library-sources.jar

So we are able to instrument, but only display the source files for our profiled Service and Core projects. What we want is for our -sources JAR for the webapp itself to be deployed as a dependency under the lib directory. So we want:

classes/... (the .class files) ...
lib/our-webapp-sources.jar
lib/our-service-library.jar
lib/our-service-library-sources.jar
...

We can manually specify (to the Cobertura command-line script) a directory to look for source files (thinking we could just give it the sources JAR separately), but doing so overrides the other sources. So we can get the web service sources included, but when we do so, we lose the source files for the Core and Service.

We're using Maven profiles - so this will only be an instrumentation-specific deployment, but we would like to tweak the maven-war-plugin or similar to include the -sources JAR in the lib folder, of the webapp itself.

Upvotes: 1

Views: 1500

Answers (1)

tmarwen
tmarwen

Reputation: 16354

First you have to configure your war project descriptor to include the sources jar of your web application, it can be simply made as follows:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <!-- other components configuration -->

  <build>
    <finalName>war-with-sources</finalName>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <executions>
          <execution>
            <id>package-and-attach-sources</id>
            <phase>package</phase>
          </execution>
        </executions>
        <configuration>
          <webResources>
            <resource>
              <directory>${project.build.directory}</directory>
              <includes>
                <include>${project.build.finalName}-sources.jar</include>
              </includes>
              <targetPath>WEB-INF/lib</targetPath>
            </resource>
          </webResources>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

The relevant part here is the <webResources> element which instructs maven to include additional resources into your archive determined by:

  • directory including the archive to add, which should be your build directory since the build *-sources.jar file will go there.
  • includes element that specifies artifacts to include i.e. the sources jar assuming here that it won't be nothing but your web archive name appended with sources suffix (default name pattern).
  • targePath that defines the target inside the war archive where configured includes will be copied.

To have you sources jar file copied using the aforementioned configuration, you have to tell maven to generate project sources which is not done by default.

This can be seamlessly done using the maven-sources-plugin using a necessary trick by mentioning a maven <phase> (in which sources will be generated) that must come before the package phase (default phase for the maven-war-plugin) e.g. the prepare-package phase, otherwise you won't get those sources included in your war file. Here down the additional maven-sources-plugin configuration that should be appended to the above pom.xml descriptor:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <build>
    <finalName>war-with-sources</finalName>
    <plugins>
      <!-- other plugins configuration -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <executions>
          <execution>
            <id>attach-sources</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Here you can find a working sample from which you can copy/use the project descriptor configuration.

Upvotes: 2

Related Questions