How to overwrite files in the WAR file during maven build? - eclipse

I have a Java webapp project that I develop in Eclipse (more precisely MyEclipse 10) and build using Maven 3.
I have the following layout (including only the files relevant to my problem :
project root
|-- src
| |-- main
| | |-- java
| | |-- resources
| | | |-- log4j.xml
| | | +-- struts.properties
| | |-- webapp
| | | |-- META-INF
| | | | +--context.xml
| | |-- config
| | | |-- test
| | | | |--log4j.xml
| | | | |--struts.properties
| | | | +--context.xml
| | | +-- prod
| | | | |--log4j.xml
| | | | |--struts.properties
| | | | +--context.xml
| +--test
+--pom.xml
As you can see, I included a number of configuration files. The one who are at their proper location within the project struture, i.e. inside src/main/resources and src/main/webapp are the ones that I routinely use when I work in MyEclipse. I can use MyEclipse connectors to automatically update a deployment to e.g. a Tomcat instance on my dev machine. I just click "run server" and I can debug. No need to use Maven at all in this context actually.
Then, when I want to build a release for another environment such as testing or production, I run mvn -P test clean install and it builds a nice WAR.
My goal is to replace the configuration files inside the final WAR by those in src/config/{environment}/.
I have set profiles in my pom.xml:
<profiles>
<profile>
<id>test</id>
<properties>
<environment>test</environment>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<environment>prod</environment>
</properties>
</profile>
</profiles>
Then, I try to copy these resources from the specified profile (using the environment variable) to the correct location inside the WAR (or the temporary folder that will be zipped into a WAR) :
<webResources>
<resource>
<directory>/src/main/config/${environment}</directory>
<targetPath>META-INF/</targetPath>
<includes>
<include>context.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/config/${environment}</directory>
<targetPath>WEB-INF/classes/</targetPath>
<includes>
<include>
struts.properties
</include>
<include>
log4j.xml
</include>
</includes>
</resource>
</webResources>
Now this seems to work, except that the "standard" resources are copied to the directory AFTER this, so they overwrite these files. So I always end up with e.g. the log4j.xml from src/main/resources instead of the one from say src/main/configuration/prod/
Extract from the Maven output :
[INFO] Processing war project
[INFO] Copying webapp webResources [D:\workspace\MyProject/src/main/config/prod] to [D:\workspaces\SITEL\Webfauna\target\Webfauna]
[INFO] Copying webapp webResources [D:\workspace\MyProject\src/main/config/prod] to [D:\workspaces\SITEL\Webfauna\target\Webfauna]
[INFO] Copying webapp resources [D:\workspace\MyProject\src\main\webapp]
As you can see on the last line, stuff from src/main/webapp is copied AFTER, thus overwriting my custom files :(
My question : How to force Maven to use the files "from the activated profile" and somehow OVERWRITE the "natural" files ?

As pointed in the second Q/A given by user944849, the simplest solution was to filter out the original files so that they can be replaced by the files from the profile's folder.
So I have added filtering to standard resources :
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<!-- Exclude those since they are copied from the profile folder for the build -->
<exclude>log4j.xml</exclude>
<exclude>struts.properties</exclude>
</excludes>
<filtering>false</filtering>
</resource>
</resources>
And to the web resources :
<warSourceExcludes>**/context.xml</warSourceExcludes>
So now the 3 files are not copied into the WAR folder. In the next step (webResources) they are copied from the active profile's folder.
I also added a default folder containing the 3 files with common values. The files from this default folder are also copied, but only after the profile's folder ones. As the resources are not overwritten, they will be copied only if they don't already exist. This is useful if you build without a profile activated, or if you can define sensible default values, no each profile needs to replicate the file if it is identical.
Structure of the config folder:
-- config
|-- test
| |--log4j.xml
| | |--struts.properties
| | +--context.xml
| +-- prod
| | |--log4j.xml
| | +--context.xml
| +-- default
| |--log4j.xml
| |--struts.properties
| +--context.xml
...
And the webResources section of my pom.xml:
<webResources>
<!-- Resources from the activated profile folder -->
<resource>
<directory>/src/main/config/${environment}</directory>
<targetPath>META-INF/</targetPath>
<includes>
<include>context.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/config/${environment}</directory>
<targetPath>WEB-INF/classes/</targetPath>
<includes>
<include>
struts.properties
</include>
<include>
log4j.xml
</include>
</includes>
</resource>
<!-- Default resources in case some file was not defined in the profile folder -->
<!-- Files are not overwritten so default files will be copied only if it does not exist already -->
<resource>
<directory>/src/main/config/default</directory>
<targetPath>META-INF/</targetPath>
<includes>
<include>context.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/config/default</directory>
<targetPath>WEB-INF/classes/</targetPath>
<includes>
<include>
struts.properties
</include>
<include>
log4j.xml
</include>
</includes>
</resource>
</webResources>

Take a look at either of these questions/answers. One may work for you.
Run an ant task in maven build phase before war is packaged?
Files got overwritten in maven project when building a war

another attempt :)
I've played around with the overlay parameter. I think that only replaces files within webapp folder you have in another war file inside the webapp folder. So that is not the perfect thing for your setup.
Yet the above mentioned webResource parameter can do this:
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.mimacom.maven.examples</groupId>
<artifactId>mimacom-war-overlays</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>${project.artifactId}</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.compiler.version>1.6</project.build.compiler.version>
<junit.version>4.9</junit.version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>${project.build.compiler.version}</source>
<target>${project.build.compiler.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>prod</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webResources>
<resource>
<directory>src/main/config/prod</directory>
</resource>
</webResources>
<!--<includes>-->
<!--<include>${basedir}/environments/overlay-1/css/styles.css</include>-->
<!--</includes>-->
<!--<overlays>-->
<!--<overlay>-->
<!--<includes>-->
<!--../environments/overlay-1/css/**-->
<!--</includes>-->
<!--</overlay>-->
<!--</overlays>-->
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>test</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webResources>
<resource>
<directory>src/main/config/test</directory>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
The activated profiles will add additional folders to the war file. So that should do the trick!

I see that you would use the same resources but with different configuration in each profile (test and prod).
So, I suggest you to use a configuration like this:
<profiles>
<profile>
<id>test</id>
<activation>
<activeByDefault>true</activeByDefault>
<property>
<name>env</name>
<name>test</name>
</property>
</activation>
<build>
<filters>
<filter>test.properties</filter>
</filters>
</build>
</profile>
<profile>
<id>prod</id>
<activation>
<property>
<name>env</name>
<value>prod</value>
</property>
</activation>
<build>
<filters>
<filter>prod.properties</filter>
</filters>
</build>
</profile>
</profiles>
In this scenario, I have two profiles, each one is activated using "env" parameter.
Each profile has a file to filter your resources, put your log4j.xml, struts.properties, context.xml files in src/main/resources and use variables to use right configuration in each profile.
Hope that helps.

I think you need to overlay the war files. Either creating a dependency in every profile of type war instead of jar, that will overlay the files in your current war file.
Another possibility might be the overlay configuration of the maven-war-plugin.
so the profile would activate the files you want to have copied over the current ones. There is quite some documentation on the plugin site as well with some examples
Hope that works!

Here is a simpler version of the solutions above that relies only on a simple snippet inserted into pom.xml.
Build the default (local workstation) webapp with:
mvn war:exploded
Add an environment command line parameter to copy files from an environment-specific directory like resources-prod to the target WEB-INF/classes directory:
mvn war:exploded -Denvironment=prod
Add this inside the project element of pom.xml:
<!-- this profile will allow files in environment-specific folders like resources-prod or resources-test
to be added to the resulting war's classpath under WEB-INF/classes
to activate the profile, simply add '-Denvironment=prod' to your maven build command
this also works fine with war:inplace and war:exploded
-->
<profile>
<id>environment-specific</id>
<activation>
<property>
<name>environment</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webResources>
<!-- note the order of the following resource elements are important.
if there are duplicate files, the first file copied will win
-->
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>resources-${environment}</directory>
<!-- override default destination at root of war -->
<targetPath>WEB-INF/classes</targetPath>
</resource>
<resource>
<directory>src/main/resources</directory>
<targetPath>WEB-INF/classes</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</profile>
More info and link to working example.

Related

.jar missing in deployed JBoss .war

I know this has been asked a few times in the past, but I'm unable to find a solution (except for the "add the .jar to your project manually in Eclipse"..)
What I have:
A Maven project
A .jar web-service we've created (let's call it kc.ourwebservice)
After a clean install (in Eclipse or via the command line) and Full Publish in Eclipse (and yes, I have done an Update Maven Project - Force Update of Snapshots/Releases before that), this .jar can be found in:
This kc.ourwebservice.jar is present in our Nexus Repository Manager OSS
This kc.ourwebservice.jar is present in our Eclipse project at the Maven dependencies
This kc.ourwebservice.jar is present when I run mvn dependency:tree -Dverbose
This kc.ourwebservice.jar is present in my .m2 folder
However, it's missing from the deployed JBoss .war's lib folder, which is what my question is about.
I know I could manually add the .jar in Eclipse' Deployment Assembly (or org.eclipse.wst.common.component file), but every time I switch git branches or do an "Update Maven Project", it's gone again. And I also don't want to manually add this .jar when the project is put on a server.
I need a permanent solution so the .jar is correctly added to the deployed JBoss .war, using the Maven plugins that were designed for it.
One thing to add. This webservice has both an .aar and .jar. Both of them are necessary. The .jar when we're starting the application, so I gave it a <scope>compile</scope>, and all the .aar we use are only needed at runtime, so I gave it that scope (<scope>runtime</scope>).
Here is the relevant pom.xml code (lots of more dependencies, plugins and code at the ...'s, but those are irrelevant for this problem):
<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>
<parent>
...
</parent>
<artifactId>...</artifactId>
<packaging>war</packaging>
...
<properties>
...
<ourwebservice.version>1.0.0</ourwebservice.version>
...
</properties>
...
<plugins>
...
<!-- Takes care of copying the aar services to the WEB-INF/services -->
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-repo-maven-plugin</artifactId>
<version>1.7.3</version>
<configuration>
<outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
<stripServiceVersion>false</stripServiceVersion>
<services>...,ourwebservice</services>
</configuration>
<executions>
<execution>
<phase>generate-resources</phase>
<id>deploy webservices</id>
<goals>
<goal>create-repository</goal>
</goals>
</execution>
</executions>
</plugin>
...
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>${maven.war.plugin.version}</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<outputDirectory>${warOutputDir}</outputDirectory>
<webappDirectory>${webappDirectory}</webappDirectory>
<warName>${project.artifactId}</warName>
<!-- Tell the maven war plugin to use the merged web.xml -->
<webXml>${warOutputDir}/web.xml</webXml>
<warSourceExcludes>.gwt-tmp/**</warSourceExcludes>
<webResources>
<resource>
<directory>${basedir}/src</directory>
<targetPath>WEB-INF/classes</targetPath>
<excludes>
<exclude>**/*.java</exclude>
<exclude>sample-properties.properties</exclude>
<exclude>sample-log4j.properties</exclude>
</excludes>
</resource>
<!-- Copy the generated services that were extracted from the dependencies to the WEB-INF/services folder of the war archive. -->
<resource>
<directory>${project.build.directory}/generated-resources/services</directory>
<targetPath>/WEB-INF/services</targetPath>
<includes>
<include>**/*.aar</include>
</includes>
</resource>
...
</webResources>
<!-- The axis2 services should not be stored in the WEB-INF/lib -->
<packagingExcludes>WEB-INF/lib/*.aar</packagingExcludes>
</configuration>
</plugin>
<!-- JBoss plugin used to deploy war file - http://mojo.codehaus.org/jboss-maven-plugin/ -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jboss-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<hostName>${deploymentHostName}</hostName>
<port>${deploymentPort}</port>
<fileName>${deploymentFileName}</fileName>
<serverName>default</serverName>
<jbossHome>
//${deploymentHostName}/${jbossHome}
</jbossHome>
</configuration>
</plugin>
</plugins>
...
<dependencies>
...
<dependency>
<groupId>kc</groupId>
<artifactId>ourwebservice</artifactId>
<version>${ourwebservice.version}</version>
<type>aar</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>kc</groupId>
<artifactId>ourwebservice</artifactId>
<version>${ourwebservice.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
...
</dependencies>
...
</project>
Does anyone has any idea why the .jar isn't deployed to the .war? Or better yet, does anyone know a solution so the .jar is always deployed to this .war when doing a clean install and publish?
All other .jar files are present in the .war, this webservice is the only one missing.

Maven: exclude resource from war

I am currently trying to exclude some resource from my built war.
I have read the documentation and the forums, and found a lot of informations.
Unfortunately nothing worked in my case...
I have an Eclipse Maven project, and if I'm right, maven-war-plugin is the default "war builder", so I have to override it in my pom.xml in order to exclude the resource from the buildt war.
I tried warSourceExcludes, packagingExcludes and webResources/excludes :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven.war.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warSourceExcludes>src/main/webapp/frontEndWorkspace</warSourceExcludes>
<packagingExcludes>src/main/webapp/frontEndWorkspace
</packagingExcludes>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>src/main/webapp</directory>
<!-- the list has a default value of ** -->
<excludes>
<exclude>**/frontEndWorkspace</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
Despite this configuration, I still have the frontEndWorkspace directory pushed in my Tomcat...
I wonder if it comes from the fact that I use it in my Eclipse environment?
Thanks in advance!
The parameters that you can use are packagingExcludes which is more generic (applies on the complete war structure) or warSourceExcludes if the files you want to exclude are specifically in the folder defined by the parameter warSourceDirectory (default being ${basedir}/src/main/webapp) (see here). It works easily when you know that it starts considering the folder structure of the war.
Example :
This will exclude all the files finishing by *.jsp contained in the folder WEB-INF of the folder defined by the parameter warSourceDirectory (default being ${basedir}/src/main/webapp) :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceExcludes>WEB-INF/**/*.jsp</warSourceExcludes>
</configuration>
</plugin>
This will exclude all the files contained in all the folders pouet contained in the war (but not the folder structure) :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<packagingExcludes>**/pouet/**/*.*</packagingExcludes>
</configuration>
</plugin>
The problem of your configuration <warSourceExcludes>src/main/webapp/frontEndWorkspace</warSourceExcludes> is that you start from the source folder which is wrong. You just have to remove src/main/webapp and add /** after frontEndWorkspace to have <warSourceExcludes>/frontEndWorkspace/**</warSourceExcludes> working (or <warSourceExcludes>frontEndWorkspace/**</warSourceExcludes>).
I am finding the same issue within Intellij IDEA which is using Maven 3.
The war file it generates contains the directory I am excluding.
UPD
Solution is to use syntax as below to eliminate the myFolder directory
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>src/main/resources</directory>
<excludes>
<exclude>**/myFolder/**</exclude>
</excludes>
</resource>
</webResources>

Deploying Sources.jar Archive to Artifactory through UI

We are using a third party library that doesn't exist in Maven Central Repository and we wan't to deploy this archive as an artifact to Artifactory. We are trying to do that via Artifactory UI and we successfully deployed both archive.jar and archive-sources.jar. The problem occurs when we add this dependency through Gradle to our build.gradle script. Archive.jar is fetched from our repository but archive-sources.jar is not fetched. We are developing with Eclipse and you can see the problem through screenshot.
We tried several things including defining classifier in Artifactory UI, editing pom with Artifactory POM Editor, publishing pom file manually and nothing worked. Whatever we do we couldn't get the source of this archive. Any kind of help would save a lot of time and effort. Thanks!
Screenshot of Artifactory UI:
We have solved the issue but it was a little bit complicated. There are many steps to apply the solution:
In the case of jain-sdp archive, here are the steps:
1- Deploy jain-sdp sources artifact with classifier "sources" as it is shown in the screenshot.
2- Manually upload jain-sdp.pom file with including the "sourceDirectory" tag:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>javax.sip</groupId>
<version>1.2</version>
<artifactId>jain-sip</artifactId>
</parent>
<groupId>javax.sdp</groupId>
<artifactId>jain-sdp</artifactId>
<version>1.0.1111</version>
<packaging>jar</packaging>
<name>jain-sdp</name>
<url>http://jain-sip.dev.java.net</url>
<build>
<sourceDirectory>../../src/javax/</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<includes>
<include>**/sdp/**</include>
</includes>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>target/javax/</directory>
<includes>
<include>sdp/**</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
</build>
</project>
3- Manually create the below files.
pom.xml:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>javax.sip</groupId>
<version>1.2</version>
<artifactId>jain-sip</artifactId>
</parent>
<groupId>javax.sdp</groupId>
<artifactId>jain-sdp</artifactId>
<version>1.0.1111</version>
<packaging>jar</packaging>
<name>jain-sdp</name>
<url>http://jain-sip.dev.java.net</url>
<build>
<sourceDirectory>../../src/javax/</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<includes>
<include>**/sdp/**</include>
</includes>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>target/javax/</directory>
<includes>
<include>sdp/**</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
</build>
</project>
pom.properties:
#Generated by Maven
#Tue Feb 05 21:33:14 CET 2008
version=1.2
groupId=javax.sdp
artifactId=jain-sdp
4- Include the files that have been created in Step 3 to the below path in the archive:
META-INF/maven/javax.sdp/jain-sdp/pom.properties
META-INF/maven/javax.sdp/jain-sdp/pom.xml
Note that these files should be added to jain-sdp.jar, not jain-sdp-sources.jar
5- Upload jain-sdp.jar to the Artifactory through UI
I think that these steps should be done manually. There is no other way to solve this problem that I can think of. sourceDirectories should be included manually to pom files and archives manually.
Add your Source files into your jar, observing the same directory structure as for the class file contents.
This means you don't need to manage another artifact and don't need to update your pom.xml
Simplest steps to perform this addition is on the CLI: change into your source directory and "update" the jar. Doing it with this specific current working directory which will preserve the correct relative filenames.
For example, I have directory structure:
~/project/src/com/mycompany
~/project/target
and have built a jar into ~/project/target named existing.jar
$ cd ~/project/src; jar uvf ../target/existing.jar com
$ jar tvf ~/project/target/existing.jar
should show class files and source files in the same tree.
...
6923 Sun Sep 18 23:19:36 PDT 2016 org/spacehq/reddit/util/http/ResponseType.class
4676 Sun Sep 18 22:30:38 PDT 2016 org/spacehq/reddit/util/http/ResponseType.groovy
...
IntelliJ IDEA detects these source files in the jar and presents them when opening the related class file. I'd assume other full featured IDEs would also.
You should of course be able to automate this somehow with Maven, to take out the human step, but this is good for a one-off.

How to set property into gwt.xml file via maven properties?

I have a property in root pom.xml file: gecko1_8. I want to place this to gwt.xml file.
So I put this property to gwt.xml:
I added the following to build section:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>VAADIN.themes/*</exclude>
</excludes>
</resource>
</resources>
But at the end build failed with the error:
ERROR: Invalid property value '${gwt.user.agents}'
ERROR: Failure while parsing XML
How to place values from pom.xml to gwt.xml file via properties?
UPDATED
Interesting thing. When I use "mvn resources:resources", property's value writes correctly to gwt.xml file, but if I run "mvn clean install -pl com.myproject.module:submodule" it failes with "invalid property value".
You have to define a maven profile (better to define a specific profile for each cases) in your pom like this:
<profile>
<id>gecko</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<user.agent.gecko>
<![CDATA[<set-property name="user.agent" value="gecko,gecko1_8" />]]>
</user.agent.gecko>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*YourGWTModule.gwt.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<defaultGoal>process-resources</defaultGoal>
</build>
</profile>
<properties>
<!--<user.agent>ie6,ie8,gecko,gecko1_8,opera,safari</user.agent>-->
<user.agent.all> </user.agent.all>
<user.agent.ie6> </user.agent.ie6>
<user.agent.ie8> </user.agent.ie8>
<user.agent.gecko> </user.agent.gecko>
<user.agent.opera> </user.agent.opera>
<user.agent.safari> </user.agent.safari>
</properties>
Then set it in your YourGWTModule.gwt.xml like this:
<set-property name="locale" value="default" />
<!-- Specified through pom.xml profiles -->
${user.agent.all}
${user.agent.ie6}
${user.agent.ie8}
${user.agent.gecko}
${user.agent.safari}
${user.agent.opera}
</module>
Finally run maven with profile:
mvn -P gecko install
There's one thing that I didn't mention but it appeared to be too important. Plugins that are used during build can have their own goals. And one of these goals can "redo" what maven-resource-plugin did.
So I had a plugin vaadin-maven-plugin:
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<version>${vaadin.plugin.version}</version>
<configuration>
...
</configuration>
<executions>
<execution>
<goals>
<goal>resources</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
And removal of a <goal>resources</goal> fixed the issue. And now mvn clean install filters properties in my gwt.xml correctly.
Hope this solution help those who will run at such an issue.

Maven assembly plugin produces undeployable war file

I'm working on a multi module project using Spring, Hibernate, GWT and Maven 3 and try to deploy a war-file distribution to a servlet container (preferably Tomcat 7 or Jetty 8). I create the war-file using maven-assembly-plugin 2.2.1 (I'm running maven 3). During the maven build everything works perfectly and the distribution archive is created.
But when I try to deploy the war file, I get ClassNotFound-Exceptions (e.g. Spring ContextLoaderListener and the like) although everything is in place (Web-inf/lib etc. pp.). So, the webapp isn't starting. Then I unpack the war-file into the servlet containers webapp directory and everything is working fine... ??
After further investigation I came across the following thing:
If I take an arbitrary war file A' created by maven-war-plugin (!), replace its content with the unpacked content from the war file I created using maven-assembly-plugin (let me call it
A.) I can see two things happen:
the resulting war file A' is a few bytes smaller than my original file A although their content is identical
the deployment of A' suddenly works like a charm
This is weird and I have absolutely no idea what's happening. Maybe there is an issue and maven-war-plugin and maven-assembly-plugin handle war file packaging differently?! I mean, a war is only a renamed zip file with some predefined structure... Maybe it has absolutely nothing to do with maven but with file encoding or other things? Any ideas on this? I appreciate any hint, that could help me in investigating this...
This is my assembly descriptor
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>dist</id>
<formats>
<format>war</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
<includes>
<include>mypackage.client:parametermgmt:*</include>
<include>mypackage.static:client:*</include>
</includes>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>/</outputDirectory>
</dependencySet>
<dependencySet>
<unpack>false</unpack>
<includes>
<include>mypackage.server.database:domain:*</include>
<include>mypackage.server.businessobjects:BOdomain:*</include>
<include>mypackage.server.security:security:*</include>
<include>mypackage.server.services:paramgmt:*</include>
</includes>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>Web-inf/lib</outputDirectory>
</dependencySet>
<dependencySet>
<unpack>true</unpack>
<includes>
<include>mypackage.static:server:*</include>
</includes>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>/</outputDirectory>
</dependencySet>
<dependencySet>
<unpack>false</unpack>
<includes>
<include>*</include>
</includes>
<excludes>
<exclude>mypackage.*</exclude>
</excludes>
<scope>runtime</scope>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>Web-inf/lib</outputDirectory>
</dependencySet>
</dependencySets>
The maven-assembly-plugin is not intended to create a war. For this purpose use the maven-war-plugin instead.
If you need to create war files for different environments like test,qa, production. This can be used as well a base for different app servers. But if we are talking about a application server this means we should create ear files instead of war files (This means to use maven-ear-plugin instead of maven-war-plugin).
|-- pom.xml
`-- src
|-- main
| |-- java
| |-- resources
| |-- environment
| | |-- test
| | | `-- database.properties
| | |-- qa
| | | `-- database.properties
| | `-- production
| | `-- database.properties
| `-- webapp
You need the following assembly for that (for every environment) which can be created based on this as a template:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>test</id>
<formats>
<format>war</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
<useProjectArtifact>true</useProjectArtifact>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<outputDirectory>WEB-INF</outputDirectory>
<directory>${basedir}/src/main/environment/test/</directory>
<includes>
<include>**</include>
</includes>
</fileSet>
</fileSets>
</assembly>
To support different artifacts for different environments this is the time for the maven-assembly-plugin like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>test</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${project.basedir}/src/main/assembly/test.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>qa</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${project.basedir}/src/main/assembly/qa.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>production</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${project.basedir}/src/main/assembly/production.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
The result is creating three different war files which can be distinguished by their appropriate classifier with a single call (detailed description can be read here):
mvn clean package