Reputation: 820
I have this setup currently:
Project A outputs a war file - has a configuration file (WEB-INF/web.xml). We've been delivering this with a commented out section of configuration which gets uncommented manually when the project is deployed in a particular environment.
Needs of the project have changed - and I need Project A to be built without that section of configuration entirely; and I need another project (Project B) to be built WITH that section of configuration (enabled, not commented out).
Rather than having the file exist in both projects (dual maintenance), I had hoped I could have Project B depend on Project A (via war overlay), and then use the maven-config-processor-plugin to add my special config to WEB-INF/web.xml, then re-package the war file.
This doesn't seem to work - though - the config modification can work if the target already exists (i.e. after the previous run), but when I run everything together, the overlay and repackaging into the new war happens together - and I can't figure out any way to make the config-processor plugin operate in the middle. Basically, the default order ends up being "config-processor" (which fails because the overlay hasn't happened yet), then "war" (all as one unit). I can't make the config-processor happen after the overlay but before the war is fully packaged.
Multiple people on the internets have asked over the last few years if there is a way to inject a plugin in between the "unpack the overlay" and "repack the war file" steps, but nobody has seemingly answered this definitively either way. Any ideas?
Upvotes: 9
Views: 8396
Reputation: 31795
You can use unpack goal of maven-dependency-plugin to fetch Project A to get web.xml locally, then transform it and point maven-war-plugin to transformed web.xml.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>unpack</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.test</groupId>
<artifactId>test-war1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>war</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/wars</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.code.maven-config-processor-plugin</groupId>
<artifactId>maven-config-processor-plugin</artifactId>
<version>2.0</version>
<configuration>
<!--
configure to transform file
${project.build.directory}/wars/WEB-INF/web.xml
into
${project.build.directory}/transformed/web.xml
-->
</configuration>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<webXml>${project.build.directory}/transformed/web.xml</webXml>
</configuration>
</plugin>
</plugins>
</build>
Upvotes: 4
Reputation: 6897
Since war overlays and war packaging all seems to happen as part of a single goal, I don't think there's a way to get in the middle of it. As a workaround, you could extract web.xml
in an earlier phase and process it. The maven-dependency-plugin can be used in Project B to extract web.xml
from Project A into a work directory, then run maven-config-processor-plugin on web.xml
and place the result somewhere else, then instruct maven-war-plugin to include that processed web.xml
before overlays. In Project B's POM:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<!-- Extract web.xml from Project A -->
<execution>
<id>unpack-webxml</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>your.group</groupId>
<artifactId>project.a</artifactId>
<version>...</version>
<type>war</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/myconfig/work</outputDirectory>
<includes>WEB-INF/web.xml</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.code.maven-config-processor-plugin</groupId>
<artifactId>maven-config-processor-plugin</artifactId>
<version>2.0</version>
<executions>
<!-- Process extracted web.xml and place in temp build directory -->
<execution>
<id>process-webxml</id>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/myconfig/build</outputDirectory>
<transformations>
<transformation>
<input>${project.build.directory}/myconfig/work/WEB-INF/web.xml</input>
<output>WEB-INF/web.xml</output>
<!-- your transformation config -->
</transformation>
</transformations>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<!-- Instruct war plugin to include temp build directory in webapp -->
<resource>
<directory>${project.build.directory}/myconfig/build</directory>
<includes>
<include>**</include>
</includes>
</resource>
</webResources>
<overlays>
<!-- Overlay customization if needed -->
</overlays>
</configuration>
</plugin>
</plugins>
As far as I can tell, the war plugin includes webResources
first, followed by src/main/webapp
, followed by overlays.
I'm not familiar with maven-config-processor-plugin, so I apologize if my configuration there is not correct.
Upvotes: 6