views:

113

answers:

2

Hi all,

I have a web application Maven project, and I want to customize the web.xml file depending on the Profile that is running. I am using the Maven-War-plugin, which allows me to define a "resources" directory, where the files may be filtered. However, filtering alone is not sufficient for me.

In more detail, I want to include (or exclude) the whole section on security, depending on the profile I an running. This is the part:

....
....

<security-constraint>

    <web-resource-collection>
        <web-resource-name>protected</web-resource-name>
        <url-pattern>/pages/*.xhtml</url-pattern>
        <url-pattern>/pages/*.jsp</url-pattern>
    </web-resource-collection>

    <auth-constraint>
        <role-name>*</role-name>
    </auth-constraint>

    </security-constraint>
        <login-config>
        <auth-method>${web.modules.auth.type}</auth-method>
        <realm-name>MyRealm</realm-name>
    </login-config>

<security-constraint>

....
....

If this is not done easily, is there a way to have two web.xml files and select the appropriate one depending on the profile?

+2  A: 

is there a way to have two web.xml files and select the appropriate one depending on the profile?

Yes, within each profile you can add a configuration of the maven-war-plugin and configure each to point at a different web.xml.

<profiles>
    <profile>
        <id>profile1</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <configuration>
                        <webXml>/path/to/webXml1</webXml>
                    </configuration>
                </plugin>
                 ...

As an alternative to having to specify the maven-war-plugin configuration in each profile, you can supply a default configuration in the main section of the POM and then just override it for specific profiles.

Or to be even simpler, in the main <build><plugins> of your POM, use a property to refer to the webXml attribute and then just change it's value in different profiles

<properties>
    <webXmlPath>path/to/default/webXml</webXmlPath>
</properties>
<profiles>
    <profile>
        <id>profile1</id>
        <properties>
            <webXmlPath>path/to/custom/webXml</webXmlPath>
        </properties>
    </profile>
</profiles>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <configuration>
                <webXml>${webXmlPath}</webXml>
            </configuration>
        </plugin>
        ...
matt b
Perfect answer, thanks man!
Markos Fragkakis
+3  A: 

"matt b" has already posted the answer that is the most maven way of doing it. It is the way I'd recommend doing it 99% of the time.

However, occasionally, your configuration file might be quite complicated, and it doesn't make much sense to duplicate the whole file for each environment when only one XML stanza differs. In these cases, you can abuse property filtering to accomplish your goal.

Warning, a very duct-tape-y solution follows, and will not be for the faint of heart:

In your pom.xml:

<properties>
    <test.security.config>
        &lt;security-constraint&gt;
            &lt;web-resource-collection&gt;
                &lt;web-resource-name&gt;protected&lt;/web-resource-name&gt;
                &lt;url-pattern&gt;/pages/*.xhtml&lt;/url-pattern&gt;
                &lt;url-pattern&gt;/pages/*.jsp&lt;/url-pattern&gt;
            &lt;/web-resource-collection&gt;

            &lt;auth-constraint&gt;
                &lt;role-name&gt;*&lt;/role-name&gt;
            &lt;/auth-constraint&gt;

            &lt;/security-constraint&gt;
                &lt;login-config&gt;
                &lt;auth-method&gt;${web.modules.auth.type}&lt;/auth-method&gt;
                &lt;realm-name&gt;MyRealm&lt;/realm-name&gt;
            &lt;/login-config&gt;

        &lt;security-constraint&gt;
    </test.security.config>
</properties>

in your web.xml

....
${test.security.config}
....

Because non-existent properties evaluate to an empty string, your configurations which do not have this property set (or the property is an empty xml tag) will evaluate to a blank line here.

It's ugly, and the xml is hard to modify in this form. However, if your web.xml is complex and you pose a greater risk of 4-5 copies of the web.xml getting out of sync, this may be an approach that will work for you.

Brian M. Carr