I've a Maven webapp project. It has a default directory structure as below -
|-- pom.xml
`-- src
`-- main
|-- java
| `-- com
| `-- example
| `-- projects
| `-- SampleAction.java
|-- resources
| `-- images
| `-- sampleimage.jpg
`-- webapp
|-- WEB-INF
| `-- web.xml
|-- index.jsp
`-- jsp
`-- websource.jsp
The WAR file it generates has the structure as below which is again based on defaults -
|-- META-INF
| |-- MANIFEST.MF
| `-- maven
| `-- com.example.projects
| `-- documentedproject
| |-- pom.properties
| `-- pom.xml
|-- WEB-INF
| |-- classes
| | |-- com
| | | `-- example
| | | `-- projects
| | | `-- SampleAction.class
| | `-- images
| | `-- sampleimage.jpg
| `-- web.xml
|-- index.jsp
`-- jsp
`-- websource.jsp
I want to rename web-prod.xml to web.xml, which reside under webapp directory, before packaging into WAR.
Now the catch is - contents of this directory are copied into target/<finalName>
by the maven-war-plugin
only during the packaging phase and immediately the WAR is generated.
Since webapp contents are copied by default by maven-war-plugin
, other plugins like maven-compiler-plugin
and maven-resources-plugin
which come into picture early, don't have any role in modifying the said file.
pom.xml
<build>
...
<plugins>
...
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>replace-descriptor</id>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<delete file="${project.build.directory}/${project.finalName}/WEB-INF/web.xml" />
<move file="${project.build.directory}/${project.finalName}/WEB-INF/web-prod.xml" tofile="${project.build.directory}/${project.finalName}/WEB-INF/web.xml"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archiveClasses>true</archiveClasses>
<attachClasses>true</attachClasses>
<warSourceIncludes>WEB-INF/**</warSourceIncludes>
<packagingExcludes>WEB-INF/classes</packagingExcludes>
<webResources>
<resource>
<directory>src/main/resources</directory>
<targetPath>WEB-INF/classes</targetPath>
<includes>
...
</includes>
</resource>
<resource>
<directory>${project.build.directory}/classes</directory>
<includes>
...
</includes>
<targetPath>WEB-INF/classes</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
web.xml
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" metadata-complete="true" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>NSWeb</display-name>
...
<filter>
<filter-name>corsFilter</filter-name>
<filter-class>com.example.core.security.filter.CORSFilter</filter-class>
</filter>
...
</web-app>
web-prod.xml
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" metadata-complete="true" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>NSWeb</display-name>
...
<filter>
<filter-name>corsFilter</filter-name>
<filter-class>com.example.core.security.filter.CORSFilter</filter-class>
<init-param>
<description>A comma separated list of allowed origins. Note: An '*' cannot be used for an allowed origin when using credentials.</description>
<param-name>cors.enabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
...
</init-param>
<init-param>
...
</init-param>
<init-param>
...
</init-param>
...
</filter>
...
</web-app>
Thanks eis for pointing me to the filtering feature!
Earlier I maintained two different web.xml files and was trying to replace one with the other since there was a difference of around 40 lines of block between those two files.
I could achieve the end result by modifying the same and NOT by replacing it with the other. Here's the solution explained stepwise:
maven-war-plugin
and use the profiles.web.xml
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" metadata-complete="true" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>NSWeb</display-name>
...
<filter>
<filter-name>corsFilter</filter-name>
<filter-class>com.example.core.security.filter.CORSFilter</filter-class>
@web.xml.cors.config@
</filter>
...
</web-app>
pom.xml
<build>
...
<filters>
<filter>src/main/resources/place-holders-${targetenv}.properties</filter>
</filters>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
...
<webResources>
...
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
<includes>
<include>**/web.xml</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<targetenv>dev</targetenv>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<targetenv>prod</targetenv>
</properties>
</profile>
</profiles>
place-holders-dev.properties [just a blank/empty space for dev]
web.xml.cors.config=
place-holders-prod.properties
web.xml.cors.config=<init-param>\
\n\t\t\t<description>A comma separated list of allowed origins. Note An '*' cannot be used for an allowed origin when using credentials.</description>\
\n\t\t\t<param-name>cors.enabled</param-name>\
\n\t\t\t<param-value>true</param-value>\
\n\t\t</init-param>\
\n\t\t<init-param>\
...
\n\t\t</init-param>\
\n\t\t<init-param>\
...
\n\t\t</init-param>\
...
...