Maven Resources Not Copying Files - maven-2

I want to use maven for replacing some of my *.properties files in my war file.
Therefore I created folders dev, test and prod in my resources folder. Now I only want to have one of these folders used in the resources folder path in my war file when executing the corresponding profile. The result is that maven is copying all other folders as well so those are double in the classpath. Here is my configuration:
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>copy-dev-resources</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<overwrite>true</overwrite>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<resources>
<resource>
<!-- source -->
<directory>src/main/resources/dev</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
How do I configure Maven now that its only copying the contents of folder src/main/resources/dev to target/classes?
Thank you for you help

Maven by default copies all files in "src/main/resources" to the output folder, so in your current configuration it would probably create "dev", "test" and "prod" folders with their contents and then additionally copy the development resources without a "dev" prefix.
I would suggest to leave the default resources folder as it is and use it only for profile-independent resources. In your profile you can then configure additional resource folders:
<profile>
<id>dev</id>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources-dev</directory>
</resource>
</resources>
</build>
</profile>
It should also be possible to configure this in the common build section using properties defined in the profiles:
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources-${projectStage}</directory>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>dev</id>
<properties>
<projectStage>dev</projectStage>
</properties>
</profile>
</profiles>
If you for some reason can't change your current directory structure then you would have to configure exclusions for the default resource folder to not copy the nested profile-dependant folders:
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<excludes>
<exclude>dev/**</exclude>
<exclude>test/**</exclude>
<exclude>prod/**</exclude>
</excludes>
</resource>
</resources>
</build>

The "main" part in the maven directory structure exists for this purpose.
Instead of creating directories inside the resource dir, you should create more dirs in your src directory.
This is the default behavior, and it's already implemented by letting test resources override main resources during the test phases of the maven lifecycle.
Your structure should look like this:
src
main
resources
a.properties
b.properties
c.properties
test
resources
b.properties
c.properties
dev
resources
b.properties
With this structure, your "main" target will have the default property files, the test phases would temporarily overwrite b and c, and the dev profile will only overwrite b with yet another custom version, in the final deployable.
In order to achieve this, you'd have to configure the maven-resources-plugin the way you already do in our question, for a dev profile.
And when you do, also consider: what version of property files should you use when running unit tests while building using the dev profile?

I was using the assembly.xml file in maven and used this set of code to make sure that my resources file was at the root directory of the app...
<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>distribution</id>
<formats>
<format>tar.gz</format>
</formats>
<fileSets>
<fileSet>
<directory>${basedir}</directory>
<includes>
<include>bin/**</include>
<include>webapps/**</include>
<include>data/**</include>
</includes>
</fileSet>
<fileSet>
<directory>${basedir}/target</directory>
<includes>
<include>*.jar</include>
</includes>
<outputDirectory>lib</outputDirectory>
</fileSet>
<fileSet>
<directory>${basedir}/src/main/</directory>
<includes>
<include>resources/**</include>
</includes>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
</dependencySet>
</dependencySets>
</assembly>
Don't know if this is the best way, but it was one I could visualize.

Adding to the earlier answers, you can also copy file from custom path to specific directory with maven copy-resources.(though its not suggested, ideally the)
<configuration>
<!-- Destination target path -->
<outputDirectory>${basedir}/target/classes/com/db/abc/util/</outputDirectory>
<resources>
<resource>
<!-- source file path -->
<directory>C:/Users/abc/Work/filepath</directory>
</resource>
</resources>
</configuration>

Related

Create a simple app with user-accessible config files using Maven

I need to produce a simple app for my customer configure and run at their site. I am using the Spring framework, so I have a number of config files that must be on the class path. I am using Maven2 with Netbeans as my IDE.
I am able to create and run my app using Netbeans/Maven and I am using the Application Assembler Maven plugin to generate the runnable application. All this works fine except that my Spring config files have to be placed in src/main/resources which means that they get packaged into the resulting JAR file.
I need my customer to be able to modify the config files to do their testing, but it's not reasonable to ask them to modify the copies that are packaged in the JAR.
There are perhaps a number of solutions, but it seems to me that the simplest would be to get Maven to not package the app and the config files into a JAR at all, just leaving them in something like a classes directory from which they can be run. This would allow the user to modify the config files easily. Unfortunately I can't figure out how to get Maven to "package" the app in this manner, or how to get the AppAssembler to generate the resulting runnable.
Here is an extract of my pom.xml that may help illustrate what I am trying to do:
...
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
... stuff deleted ...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<!-- Set the target configuration directory to be used in the bin scripts -->
<configurationDirectory>conf</configurationDirectory>
<!-- Copy the contents from "/src/main/config" to the target
configuration directory in the assembled application -->
<copyConfigurationDirectory>true</copyConfigurationDirectory>
<!-- Include the target configuration directory in the beginning of
the classpath declaration in the bin scripts -->
<includeConfigurationDirectoryInClasspath>
true
</includeConfigurationDirectoryInClasspath>
<platforms>
<platform>windows</platform>
</platforms>
<programs>
<program>
<mainClass>org.my.path.App</mainClass>
<name>app</name>
</program>
</programs>
</configuration>
</plugin>
</plugins>
</build>
...
Neither single packed jar file or bunch of unpacked classes files are good format for professional client delivery. Look at those brilliant apache apps like tomcat, ant and maven, they are shipped as a tar.gz or zip file, after download, simply extract them and you will get a nice and clean directory structure:
conf --> put config file like *.properties, logback.xml here
doc --> readme.txt, userguide.doc etc
lib --> put you core.jar with dependency jar file here
run.bat --> run script for Windows
run.sh --> run script for Unix
We can do these kinds of stuff with Maven as well. Note that you should design and implement your core jar to read *.properties from the conf directory properly. then use maven-assembly-plugin pack you app into this classical directory structure.
Sample pom.xml for a command-line app:
<!-- Pack executable jar, dependencies and other resource into tar.gz -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>attached</goal></goals>
</execution>
</executions>
<configuration>
<descriptors>
<descriptor>src/main/assembly/binary-deployment.xml</descriptor>
</descriptors>
</configuration>
</plugin>
Sample binary-deployment.xml for a command-line app:
<!--
release package directory structure:
*.tar.gz
conf
*.xml
*.properties
lib
application jar
third party jar dependencies
run.sh
run.bat
-->
<assembly>
<id>bin</id>
<formats>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>src/main/java</directory>
<outputDirectory>conf</outputDirectory>
<includes>
<include>*.xml</include>
<include>*.properties</include>
</includes>
</fileSet>
<fileSet>
<directory>src/main/bin</directory>
<outputDirectory></outputDirectory>
<filtered>true</filtered>
<fileMode>755</fileMode>
</fileSet>
<fileSet>
<directory>src/main/doc</directory>
<outputDirectory>doc</outputDirectory>
<filtered>true</filtered>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
</assembly>
If not misleading, I think you want to let the jar and config to be separated, with jar exposed for client's testing.
The following can do this for you using copy-maven-plugin, it can accomplish almost tasks what assembly-plugin would do ,ex: copy, dependency and much more - download, upload ,move ,... .
<plugin>
<groupId>com.github.goldin</groupId>
<artifactId>copy-maven-plugin</artifactId>
<version>0.2.5</version>
<executions>
<execution>
<id>create-archive</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
</execution>
</executions>
<configuration>
<resources>
<!--copy your scripts to ${myOutPutPath}/bin-->
<resource>
<targetPath>${myOutPutPath}/bin</targetPath>
<directory>${project.basedir}/src/main/scripts</directory>
<includes>
<include>*</include>
</includes>
</resource>
<resource>
<!--copy your configs-->
<targetPath>${myOutPutPath}/conf</targetPath>
<directory>${project.basedir}/src/main/config</directory>
<include>*</include>
</resource>
</resources>
</configuration>
</plugin>
Package main jar and put to your ${myOutPutPath}
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<!-- The configuration of the plugin -->
<configuration>
<outputDirectory>${myOutPutPath}</outputDirectory>
<!-- Configuration of the archiver -->
<archive>
<!-- Manifest specific configuration -->
<manifest>
<!-- Classpath is added to the manifest of the created jar file. -->
<addClasspath>true</addClasspath>
<!--
Configures the classpath prefix. This configuration option is
used to specify that all needed libraries are found under lib/
directory.
-->
<classpathPrefix>lib/</classpathPrefix>
<!-- Specifies the main class of the application -->
<mainClass>com.xinguard.snmp.SNMP_ETL</mainClass>
</manifest>
<!-- you need to add some classpath by yourself, like conf here for client to use-->
<manifestEntries>
<Class-Path>conf/</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
then package the lib jar to lib directory under jar directory.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${myOutPutPath}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

Maven: clean the webapp directory before war:exploded?

quoting from maven war plugin usage page :
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webappDirectory>/sample/servlet/container/deploy/directory</webappDirectory>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
How do i clean the content of the directory defined in the <webappDirectory>/sample/servlet/container/deploy/directory</webappDirectory> before exploding the war file ?
In my experience, the folder defined as the webappDirectory wont get cleaned, and so will have nonrelated files that was part of the webapp.
It'll be cool if i can add something to the current command im currently using to clean the webappDirectory, which is something like this :
mvn -o clean <cleanWebappDirectory here?> install war:exploded
Thank you !
You may want to look at adding the maven clean plugin, specifying the requisite folder to be cleaned. Something like below... Note that the directory should be relative.
<build>
[...]
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<filesets>
<fileset>
<directory>sample/servlet/container/deploy/directory</directory>
<includes>
<include>*</include>
</includes>
</fileset>
</filesets>
</configuration>
</plugin>
[...]
</build>

Maven, filtering NON-resource file

I share a config file between several modules and I don't want the config file to be baked into any of the JARs.
How can i make Maven do (resource) filtering on the file which is not specified as a resource but is in a config folder on the same level as the root POM?
You could use the Maven Resources Plugin and its resources:copy-resources mojo. From the Examples:
Copy Resources
You can use the mojo copy-resources to
copy resources which are not in the
default maven layout or not declared
in the build/resources element and
attach it to a phase
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/extra-resources</outputDirectory>
<resources>
<resource>
<directory>src/non-packaged-resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
...
</project>
Another option would be to use the Maven AntRun Plugin and Ant filtering capabilities (e.g. with the Filter and/or the Copy tasks) but the above looks just fine.

Exclude property files from resources

How to exclude files from src/main/resources, for ex : I have a folder named "map" in there, which I wanna keep and I want to delete everything from war(or not to package it inside at firstplace).
Or alternative but same result, exclude all *.resources files from src/main/resources and put in war everything else?
Thank you
You may configure your resources like this:
<build>
<resources>
<resource>
<directory>src/main/resources/map</directory>
</resource>
</resources>
</build>
or this:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.log</exclude>
</excludes>
</resource>
</resources>
</build>
For more details, click here.
If you don't want some resources to be copied into target/classes, you can define includes or excludes in the resource element as documented in Including and excluding files and directories. For example:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/map/*.*</exclude>
</excludes>
</resource>
</resources>
</build>
If you want resources to be still copied into target/classes but for some reason don't want them to be packaged in the final artifact, then configure the maven war plugin to use packagingExcludes.
The official documentation for the maven resources plugin describes how you can perform includes and excludes.
http://maven.apache.org/plugins/maven-resources-plugin/examples/include-exclude.html

How do I exclude files/directories from the target directory using the maven war plugin?

I followed the instructions here, and it worked but only if it was mapped to a directory other than the default.
Here's a sample that I tried:
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<!-- the below works when uncommented and does exclude *.tmp -->
<!-- <targetPath>test/WEB-INF</targetPath> -->
<!-- the below does not -->
<targetPath>WEB-INF</targetPath>
<excludes>
<exclude>*.tmp</exclude>
</excludes>
</resource>
</webResources>
</configuration>
So my assumptions is that I have something else overriding the configuration. However, this is my first project using maven, so I'm not sure what to test or investigate next.
change your exclusion to
**/*.tmp
You could also leave off the WEB-INF from the directory and remove the targetDirectory altogether. For instance, here's one that would include all xml, xhtml, x*ml etc. and excludes all *.tmp in any directory
<webResources>
<resource>
<directory>${basedir}/src/main/webapp</directory>
<includes>
<include>**/*.x*ml</include>
</includes>
<excludes>
<exclude>**/*.tmp</exclude>
</excludes>
</resource>
</webResources>