Maven assembly plugin produces undeployable war file - deployment

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

Related

How to create muliple war file from one Maven jersey REST API project in eclipse?

How to create multiple war files from one maven eclipse Jersey Rest API project? As i have multiple Rest APIs in this project. I want to have one war file per each Rest API. How to do? As i don't want to use multi module maven project.
I think your best bet is using Maven's executions feature (i.e. "run" any plugin, multiple times, in your case maven-war-plugin).
So basically you "run" maven-war-plugin multiple times, and configure it differently for each war you want to make. Below is an example taken from SO (you need to tailor the configuration section for each execution.
Please be aware, that this is considered "last-resort" build design, and it is still advisable to use multi-module.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>list</id>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
<configuration>
<warName>myProj-list.war</warName>
<webResources>
<resource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</webResources>
<filtering>true</filtering>
<filters>
<filter>src/main/filters/list.properties</filter>
</filters>
</configuration>
</execution>
...
<!-- more executions -->
</execution>
</executions>
</plugin>

Intellij doesn't work well with multi module maven scala project

I have a project with standard multi project maven with mixed scala / java modules.
When I open this project on IntelliJ it fails to recognise scala folders as sources / test-sources root folders.
.
|-- pom.xml
`-- src
|-- it
| |-- resources
| | `-- data.csv
| `-- scala #### TEST SOURCES ###
| `-- com
| `-- my
| `-- example
| `-- jetty
| `-- JettyBasedServerIT.scala
|-- main
| `-- scala #### SOURCES ###
| `-- com
| `-- my
| `-- example
| `-- jetty
| `-- JettyBasedServer.scala
`-- test
`-- scala #### TEST SOURCES ###
`-- com
`-- my
`-- example
`-- jetty
`-- MainArgumentsTest.scala
As a result, interdependencies are not recognized.
I have to go module by module and manually set the the sources folders.
Do you know how to do it automtically?
I got similar issues when I wanted to set maven submodules with scala in intelliJ. I eventually succeed with particular pom.xml. You may investigate this way.
Just for information I'll give you some extracts from my pom.xml that might be useful to you :
Parent pom.xml
<pluginManagement>
<plugins>
<!-- configure scala style -->
<plugin>
<groupId>org.scalastyle</groupId>
<artifactId>scalastyle-maven-plugin</artifactId>
<version>0.8.0</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<verbose>false</verbose>
<failOnViolation>true</failOnViolation>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<failOnWarning>false</failOnWarning>
<sourceDirectory>${basedir}/src/main/scala</sourceDirectory>
<testSourceDirectory>${basedir}/src/test/scala</testSourceDirectory>
<outputFile>${project.basedir}/target/scalastyle-output.xml</outputFile>
<outputEncoding>UTF-8</outputEncoding>
</configuration>
</plugin>
<!-- set scala maven plugin version -->
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<scalaCompatVersion>${scala.binary.version}</scalaCompatVersion>
<scalaVersion>${scala.version}</scalaVersion>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Child pom.xml
<build>
<plugins>
<!-- Scala Compiler -->
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<executions>
<!-- Run scala compiler in the process-resources phase, so that dependencies on
scala classes can be resolved later in the (Java) compile phase -->
<execution>
<id>scala-compile-first</id>
<phase>process-resources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmArgs>
<jvmArg>-Xms128m</jvmArg>
<jvmArg>-Xmx512m</jvmArg>
</jvmArgs>
</configuration>
</plugin>
<!-- Adding scala source directories to build path -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<!-- Add src/main/scala to eclipse build path -->
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/scala</source>
</sources>
</configuration>
</execution>
<!-- Add src/test/scala to eclipse build path -->
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/test/scala</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<!-- Scala Code Style, most of the configuration done via plugin management -->
<plugin>
<groupId>org.scalastyle</groupId>
<artifactId>scalastyle-maven-plugin</artifactId>
<configuration>
<configLocation>${project.basedir}/../../tools/maven/scalastyle-config.xml</configLocation>
</configuration>
</plugin>
Unfortunately I couldn't say exactly which part is fondamental. Hope it could help.
Weird enough the problem was related to maven importer memory issue.
I increased the import memory settings and re-imported the project and it worked like magic.

Using tycho-p2-repository-plugin to create zip with parent directory

I am using the tycho-p2-repository-plugin during the assembly of my target product. The default behavior of its archive-repository goal is to create a zip archive of the aggregated p2 repository.
What I want to know is how to include the parent repository directory in the zip file? By default, only the contents of the repository directory are included. For example, if you have 2 files a.file and b.file in the repository directory, when you open the generated jar, you'd see this
a.file
b.file
However, what I want is the repository directory itself to be the first layer in the zip, and if you drill down into it, you'd see the others, like this:
repository/
-> a.file
-> b.file
How can I get tycho-p2-repository-plugin to do this?
AFAIK the tycho-p2-repository-plugin does not allow to customize the layout of the produced zip file.
We had a similar use case where we had to create a WAR file from the bundles of the p2 repository and used the maven-assembly-plugin therefore.
Here is what we specified in our pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2</version>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<finalName>my-repo</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>verify</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
And here is how the assembly.xml could look like:
<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>com.diwoblood.war</id>
<formats>
<format>war</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${basedir}/target/repository/</directory>
<outputDirectory>/repository</outputDirectory>
</fileSet>
</fileSets>
</assembly>

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

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.

Problem when importing Maven2 project in Eclipse

In my project, I have a resources directory (src/main/resources) that contains properties and XML files.
I want to filter only the properties files, but not any others kind of files (XML for example). Thus, I've set this in my pom.xml:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
</build>
This is working well when I run a Maven 2 package command, i.e. both XML and properties files are included in my final JAR, and only properties files have been filtered.
However, as I want to include this project in Eclipse, when I run the command mvn eclipse:eclipse, and import the project, then I have a problem with the source declared in my project properties.
In the "Java Build Path" option of Eclipse for my project, in tab "Source", I see the src/main/resources directory, but Eclipse also add filters which say to exclude all java files (Excluded: **/*.java) and include only properties files (Included: **/*.properties).
In the .classpath file generated, I get this line:
<classpathentry kind="src" path="src/main/resources" including="**/*.properties" excluding="**/*.java"/>
This way, the JAR built by Eclipse is not correct as all my XML files are not in the JAR.
How can I solve this problem?
Edit, regarding this page, I've added this in my pom.xml:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.6</version>
<configuration>
<sourceIncludes>
<sourceInclude>**/*.xml</sourceInclude>
</sourceIncludes>
</configuration>
</plugin>
</plugins>
However, the .classpath generated is not modified with the adequate information...
Edit again.
The addition in my previous edit works only for version 2.6.1+ of the Eclipse plugin, not for 2.6. So, I've tried with version 2.7. However, I don't know how to force the Eclipse plugin to not define the including attribute:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.7</version>
<configuration>
<sourceIncludes>
<sourceInclude>*</sourceInclude>
</sourceIncludes>
</configuration>
</plugin>
</plugins>
If I run the mvn eclipse:eclipse command, I get the following error:
Request to merge when 'filtering' is not identical. Original=resource src/main/resources: output=target/classes, include=[**/*.properties], exclude=[**/*.java], test=false, filtering=true, merging with=resource src/main/resources: output=target/classes, include=[], exclude=[**/*.properties|**/*.java], test=false, filtering=false
Well maven-eclipse-plugin is very bugy :( and we use version 2.5. The solution we found is copy resources to different folder. For regular maven bulid we use default filtering but for eclipse we have special profile. Here is maven-eclipse=plugin configuration in this profile:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources-step1</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>initialize</phase>
<configuration>
<outputDirectory>${project.build.directory}/for-eclipse/resources</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-resources-step2</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>initialize</phase>
<configuration>
<outputDirectory>${basedir}/src/main/resources</outputDirectory>
<resources>
<resource>
<directory>${project.build.directory}/for-eclipse/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Of course you must modify include/exclude section for your needs.
I did some testing with the maven eclipse plugin 2.6, 2.5.1, 2.7 and 2.8-SNAPSHOT and none of them is indeed producing the expected result.
The only workaround I've been able to find is to use another directory for the resources you don't want to filter. Something like this:
...
<build>
<resources>
<resource>
<directory>src/main/resources1</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources2</directory>
<filtering>false</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.6</version>
</plugin>
</plugins>
</build>
I agree that this is ugly. But at least, it produces a .classpath with the following entries:
<classpathentry kind="src" path="src/main/resources1" including="**/*.properties" excluding="**/*.java"/>
<classpathentry kind="src" path="src/main/resources2" including="**/*.xml" excluding="**/*.java"/>
That should allow you to deploy on Tomcat.
By the way, I wouldn't use the version 2.7 of the plugin because it's not working (see this thread). The version 2.6 may not produce the expected output but at least, it works.
Use properties to have Eclipse and Maven build into different directories. Now you can use Eclipse to quickly develop your code and use Maven to deploy it as a JAR.
I suggest that you either the mvn package goal as an external tool from Eclipse. I don't think that Eclipse can handle complex Maven workflows.
Even the m2eclipse plugin, which I use and highly recommend, has troubles with complex workflows.