Sebastian S.
Sebastian S.

Reputation: 1609

Filtering web.xml when using the jetty-maven-plugin?

Original Post:
I want to filter the web.xml deployment descriptor of a Java 6 web application which is running on the Jetty 8.1 servlet container, but it does not work so far. I want to set a different JSF project stage depending on the active maven profile:

<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>${jsfProjectStage}</param-value>
</context-param>

The profiles section in the pom.xml looks like that:

<profiles>
    <profile>
        <id>development</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <jsfProjectStage>Development</jsfProjectStage>
        </properties>
    </profile>
    <profile>
        <id>production</id>
        <properties>
            <jsfProjectStage>Production</jsfProjectStage>
        </properties>
    </profile>
</profiles>

On the internet you find several ways to accomplish that, e.g. using alternative web.xml files. But to me the most obvious way seems to use the maven-war-plugin:

<build>
    <finalName>...</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <webResources>
                    <webResource>
                        <directory>src/main/webapp/WEB-INF</directory>
                        <filtering>true</filtering>
                        <targetPath>WEB-INF</targetPath>
                        <includes>
                            <include>web.xml</include>
                        </includes>
                    </webResource>
                </webResources>
            </configuration>
        </plugin>

        ...

    </plugins>
</build>

Since you find many answers or articles with this code snippet, I wonder why it is not working for me. I tried to replace <webResource> with <resource> (often found it this way) and I also tried to add <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors> but nothing of that works.

Does anyone have an idea, what is missing here in order to filter the web.xml correctly? Or do I have to explicitly specify <filters>?

Thanks
Sebastian

Update:
Thanks to user944849 I know now that the reason for my not filtered web.xml is not the maven-war-plugin but the jetty-maven-plugin, since I use mvn jetty:run to run the (unassembled) webapp. Does anyone know how to bring the jetty-maven-plugin to filter the web.xml before running the unassembled webapp?

Upvotes: 5

Views: 4149

Answers (3)

bubak
bubak

Reputation: 1674

Just my 2 cents:

Using run-war is a bit worse than using run, as the run-war will require packaging -- not handy for development. Solution that worked for me is to follow those steps (I can imagine a more simple one, but we have several tweeks in maven and project deployment):

  1. Leave default webapp resource filtering as is and add our own, custom filtering
  2. Point jetty config to custom docroot (and alternate web.xml)
  3. Bind jetty to prepare-package (maven 2.2.1+) phase as the last phase before actual packaging
  4. Once done, one can simply run maven and provide the properties at command line, st. like: mvn -Djetty=run -Djetty.webcontext=any-web-context -Djetty.port=8180 prepare-package

Config below is for maven2, but modification for new org.eclipse.jetty & maven3 should be straightforward:

    <!-- jetty:run -->
    <profile>
        <id>jetty-run</id>
        <activation>
            <property>
                <name>jetty</name>
                <value>run</value>
            </property>
        </activation>
        <properties>
            <jetty.docroot>${project.build.directory}/jetty-docroot</jetty.docroot>
        </properties>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>2.4.3</version>
                    <executions>
                        <execution>
                            <id>jetty-docroot</id>
                            <phase>prepare-package</phase>
                            <goals>
                                <goal>copy-resources</goal>
                            </goals>
                            <configuration>
                                <outputDirectory>${jetty.docroot}</outputDirectory>
                                <resources>
                                    <resource>
                                        <directory>${basedir}/src/main/webapp</directory>
                                        <filtering>true</filtering>
                                    </resource>
                                </resources>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <!-- for maven2, use org.eclipse.jetty for maven3 + slightly different configuration  -->
                    <groupId>org.mortbay.jetty</groupId>
                    <artifactId>maven-jetty-plugin</artifactId>
                    <configuration>
                        <connectors>
                            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
                                <port>${jetty.port}</port>
                                <maxIdleTime>60000</maxIdleTime>
                            </connector>
                        </connectors>
                        <scanIntervalSeconds>10</scanIntervalSeconds>
                        <contextPath>/${jetty.webcontext}</contextPath>
                        <webXml>${jetty.docroot}/WEB-INF/web.xml</webXml>
                        <webAppSourceDirectory>${jetty.docroot}</webAppSourceDirectory>
                        <!-- maven3
                        <webApp>
                            <contextPath>/${jetty.webcontext}</contextPath>
                            <descriptor>${jetty.docroot}/WEB-INF/web.xml</descriptor>
                            <baseResource>${jetty.docroot}</baseResource>
                        </webApp>
                        -->
                        <systemProperties>
                            <systemProperty>
                                <name>java.awt.headless</name>
                                <value>true</value>
                            </systemProperty>
                        </systemProperties>
                    </configuration>
                    <executions>
                        <execution>
                            <id>jetty-run</id>
                            <phase>prepare-package</phase>
                            <goals>
                                <goal>run</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>

Upvotes: 0

Sebastian S.
Sebastian S.

Reputation: 1609

After figuring out that the problem was not the maven-war-plugin but the jetty-maven-plugin, I just had to change the maven command from mvn clean jetty:run to mvn clean jetty:run-war in order to run an assembled webapp on the embedded jetty in which the deployment descriptor gets also filtered.

Thanks for your help guys
Sebastian

Upvotes: 6

manub
manub

Reputation: 4100

Your configuration seems correct, but in my experience you may need also <filters> section.

For example, my application has something similar to:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>${maven-war-plugin.version}</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
                <webResources>
                    <resource>
                        <directory>src/main/webapp</directory>
                        <filtering>true</filtering>
                        <includes>
                            <include>**/bm.js</include>
                        </includes>
                    </resource>
                </webResources>
                <warName>${war.name}</warName>
            </configuration>
        </plugin>
    </plugins>
    <filters>
        <filter>src/main/filters/filter-${target.environment}.properties</filter>
    </filters>
</build>

The bm.js file contains a reference to a macro ${my.property}, which value is set in 2 different files, filter-dev.properties and filter-qa.properties. I do have 2 different maven profiles (called dev and qa) in the parent POM in which I define the target.environment property accordingly.

When running mvn package specifying the profile, the macro in bm.js will be replaced with the correct value.

I'm not 100% sure this would necessary work with web.xml, but you can give it a try.

Upvotes: 0

Related Questions