views:

517

answers:

1

I am using Maven2 to build a WAR project. Some properties files are dependent on the environment targeted for a release.

I want to deliver, in addition of the WAR, a file called datasource.xml. This file already exists in my project directory, but contains properties that will be filtered during the build (i.e. some ${foo.bar}).

In others words, after running the command mvn clean install, I want to see in my target/ directory two files, my-webapp.war and datasource.xml.

Note that datasource.xml must not be included in the my-webapp.war artifact!

How can I do this?

+2  A: 

You can attach additional artifacts using the build-helper-maven-plugin. The configuration below would attach datasource.xml as an additional artifact during the package phase. If that artifact is defined outside of src/main/resources and src/main/webapp it will not be included in the war.

Update: to ensure resource filtering is applied per your comment, you can specify an execution of the resource-plugin's copy-resources goal, specifying filtering to be applied. You can then still attach that filtered artifact using the build-helper-maven-plugin by referencing the corresponding target directory. I've updated the example below to show this usage.

<plugin>
  <artifactId>maven-resources-plugin</artifactId>
  <version>2.4</version>
  <executions>
    <execution>
      <id>copy-resources</id>
      <phase>validate</phase>
      <goals>
        <goal>copy-resources</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.build.outputDirectory}/datasource</outputDirectory>
        <resources>          
          <resource>
            <directory>src/main/datasource</directory>
            <filtering>true</filtering>
          </resource>
        </resources>              
      </configuration>            
    </execution>
  </executions>
</plugin>
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>build-helper-maven-plugin</artifactId>
  <version>1.3</version>
  <executions>
    <execution>
      <id>attach-artifacts</id>
      <phase>package</phase>
      <goals>
        <goal>attach-artifact</goal>
      </goals>
      <configuration>
        <artifacts>
          <artifact>
            <file>${project.build.outputDirectory}/datasource/datasource.xml</file>
            <type>xml </type>
            <classifier>datasource</classifier>
          </artifact>
        </artifacts>
      </configuration>
    </execution>
  </executions>
</plugin>

This won't appear in the target folder, but it will be deployed/installed to the repository alongside the war.

The attached artifact can be referenced by defining a dependency with the classifier "datasource". For example:

<dependency>
  <groupId>my.group.id</groupId>
  <artifactId>my-artifact-id/artifactId>
  <version>1.0.0</version>
  <classifier>datasource</classifier>
  <type>xml</type>
</dependency>

You could use the the dependency plugin's copy goal to retrieve the artifact and put it wherever it is required as part of your deployment process.

Rich Seller
This is not exaclty what I am looking for (I only need the datasource.xml to be located in the target/ dir, not installed in the repository), but this solution is quite interesting however.
romaintaz
This solution does not fit my need also because the XML file copied in the repository is *not* filtered (i.e. I still have ${foo.bar} in it).
romaintaz
so to be clear, you want resource filtering to be applied, but the artifact to not be included in the war?
Rich Seller
maven-resources-plugin will filter the output. you might want to check that the filter is defined under build and not under the war-plugin. filters defined under the war-plugin will only be applied to web-resources.
sal