Maven plugin maven-antrun-plugin copy option does not overwrite - maven

I have a problem with this maven plugin and I don't really know how to solve it.
I am trying to copy some resources to "${basedir}/../server/a/base-store" to "${basedir}/../resources/store/base_certificate_store_prod/base-store"
However I use "overwrite" on copy. But at the final end under "${basedir}/../server/a/base-store" the files are added and the others which were before still exist.
I would like the hole "base-store" directory to be replaced.
<profile>
<id>PROD</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>copy-prod-base-store</id>
<phase>compile</phase>
<configuration>
<target>
<copy todir="${basedir}/../server/a" overwrite="true">
<fileset dir="${basedir}/../resources/store/base_certificate_store_prod" includes="**/*"/>
</copy>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

Just delete the directory first and then copy.

Related

How to set a property based on environment value?

I try to create a maven script which takes care of my packaging for different environments dev, test and production.
I'd like to make some kind of template which copies certain files into a specific directory. Something like this:
<profile>
<id>default-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>prepare-package</id>
<phase>prepare-package</phase>
<configuration>
<target>
<echo message="Copying configuraiton files .."/>
<copy file="${package-mode.config-directory}/x.xml" todir="src/main/webapp/WEB-INF/config" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
My current problem is that I need ${package-mode.config-directory} to be set according to the environment which I want to build for.
I am currently using the maven-enforcer-plugin in order to require an environment variable to be set:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce-property</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireProperty>
<property>package-mode</property>
<message>You must set a "package-mode" property!</message>
<regex>(test|dev|deploy)</regex>
<regexMessage>
[ ########### ] "package-mode"" must be either "test", "dev" or "deploy".
</regexMessage>
</requireProperty>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
But I'm now facing the problem that I need some kind of conditional build for ${package-mode.config-directory}. I would need something like this:
<plugin>
<!-- ... -->
<property>package-mode</property>
<condition>
<equals>test</equals>
<package-mode.config-directory>src/main/assembly/test</package-mode.config-directory>
</condition>
<condition>
<equals>dev</equals>
<package-mode.config-directory>src/main/assembly/dev</package-mode.config-directory>
</condition>
<condition>
<equals>deploy</equals>
<package-mode.config-directory>src/main/assembly/deploy</package-mode.config-directory>
</condition>
</plugin>
Is it possible to do that?
Turns out I could simply use the already enforced environment variable package-mode and just name the directories to its valid values. One can argue about whether this is "nice" or not but it works and it builds my war file:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>prepare-package</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>src/main/webapp/WEB-INF/config</outputDirectory>
<resources>
<resource>
<directory>src/main/assembly/${package-mode}/config</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>

Ignore maven plugin during a build

How can I ignore my plugin (maven-antrun-plugin) during a build or deploy?
I am generating source files from a IDL tool (written in C). I used the maven-antrun-plugin to do the source generation and applied it to the generate-sources phase. Along with the build-helper-maven-plugin, the java source generated by the IDL tool is deposited in a generated sources folder and, ultimately, included in the jar packaging as source. Perfect!
Here's what I use in my maven build:
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<tasks>
<mkdir dir="target/generated-sources/" />
<!-- other task stuff here -->
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>target/generated-sources/gen-java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
However, now the problem is that our team is directed to not use the IDL tool in our Continuous Integration (CI) environment; the plugin will fail in CI because the IDL tool is not installed. As a result, I must check in the generated source (with the other code under src/main/java) to our GIT repo.
I would like to be able to still run the maven-antrun-plugin, but, decouple it from the generated-sources phase or any lifecycle so that the CI environment can run my build. I will run the plugin manually/locally when I make a change so that the source will be generated and then checked in to the GIT repo.
Is this even possible? How can I ignore maven-antrun-plugin during an build or deploy?
As suggested by a commenter (Jarrod Roberson), maven profiles can be used to ignore the generation of sources in the maven-antrun-plugin plugin.
Specifically, adding the profiles block shown below addresses the issue. The default-profile profile is activated by default; it does not contain the maven-antrun-plugin block.
However, the generate-source-profile does contain the maven-antrun-plugin that will initiate the sources generation.
<profiles>
<profile>
<id>default-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>generate-sources-profile</id>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<tasks>
<mkdir dir="target/generated-sources/" />
<!-- other task stuff here -->
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Thus, the Continuous Integration (CI) tool will do a normal build and deploy (mvn deploy). When I want to generate sources then I will run the generate sources profile by doing, for example, mvn clean install -P generate-sources-profile.
You can use profiles or simply skip maven-antrun-plugin execution
skip - Specifies whether the Antrun execution should be skipped.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<skip>${skipAntRunForMe}</skip>
<tasks>
<mkdir dir="target/generated-sources/"/>
<!-- other task stuff here -->
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
And inovke goal with param -DskipAntRunForMe

Maven rename a file after everything else finishes

I have a project which I need to rename the final output file generated by the Maven Assembly Plugin after everything else finishes (in the compiling/building/assembly process).
The Maven Assembly Plugin is generating a final .zip file, based on the project's name, and I need to rename this completely to final-version.oxt. I'm trying to use the maven-antrun-plugin to rename it, as pointed by other similar questions here, but no luck (I've never used Maven or Ant before, so maybe I'm missing something).
This is the <build> section of the project's pom.xml. The rename part seems to be completely ignored, since no file is generated in my home folder.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>assembly</id>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
<configuration>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
</archive>
<descriptors>
<descriptor>src/main/assembly/ooo-jar.xml</descriptor>
<descriptor>src/main/assembly/ooo.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>deploy</phase>
<configuration>
<tasks>
<copy file="${project.build.directory}/target/libreofficeplugin-ooo.zip"
tofile="/home/brunofinger/final-version.oxt" />
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
A few modifications made it work, probably the phase was wrong, but using <phase>install</phase> seems to make it work:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>install</phase>
<configuration>
<target>
<copy file="${project.build.directory}/libreofficeplugin-ooo.zip" tofile="${project.build.directory}/final-version.oxt" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
This question is nearly an year old, but in case anyone else is facing similar issue, here is an alternate solution.
If you are looking for a more mavenish way of doing it,you can use
<plugin>
<groupId>com.coderplus.maven.plugins</groupId>
<artifactId>copy-rename-maven-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<id>rename-file</id>
<phase>install</phase>
<goals>
<goal>rename</goal>
</goals>
<configuration>
<sourceFile>${project.build.outputDirectory}/libreofficeplugin-ooo.zip</sourceFile>
<destinationFile>${project.build.outputDirectory}/final-version.oxt</destinationFile>
</configuration>
</execution>
</executions>
</plugin>
and in case you want to copy instead of rename, use the copy goal instead of the rename goal.
You don't need to use antrun to rename the output file. Just use the tag finalName of the assembly plugin to rename the output file.
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>assembly</id>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
<configuration>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
</archive>
<descriptors>
<descriptor>src/main/assembly/ooo-jar.xml</descriptor>
<descriptor>src/main/assembly/ooo.xml</descriptor>
</descriptors>
<finalName>final-version.oxt</finalName>
</configuration>
</execution>
</executions>
</plugin>

How do I include test classes and configuration in my war for integration testing using maven?

I currently have a maven web project that I am attempting to write integration tests for. For the structure of the project, I've defined test stubs under src/test/java, whilst the spring bean definitions for these stubs sit under src/test/resources.
What I would like to do, is that when I build my war artifact I'd like all of the test stub classes to be compiled and included in the war along with the spring bean definition files. I've tried to do it with the maven war plugin but the only things I've been able to copy are the resources. Simply put, I'd like to make use of the test class path and include all these classes in my war file.
It seems the useTestClassPath option with the maven jetty plugin would solve my problem but the current project I'm working on is currently using Tomcat 6.0. Is there another maven plugin or a way I can configure the maven war plugin to achieve my objective?
You can also do it straightforwardly. This will add both test classes and test resources to the WEB-INF/classes:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>process-test-classes</phase>
<configuration>
<target>
<copy todir="${basedir}/target/classes">
<fileset dir="${basedir}/target/test-classes" includes="**/*" />
</copy>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
I also recommend you place it into separate profile like "integration" and also to override the package name in that profile to not be able to confuse normal war without tests packaged in and the testing war.
The full example with profile is here. You may run mvn clean package to have a war war-it-test.war without tests included, or you may run mvn clean package -Pintegration to have a war war-it-test-integration.war for the war with tests included.
I believe the following configuration for the maven war plugin would do what you want. You copy your test-classes to your WEB-INF/classes folder. You can even filter those resources.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<id>generate-test-war</id>
<phase>pre-integration-test</phase>
<goals>
<goal>war</goal>
</goals>
</execution>
</executions>
<configuration>
<warSourceDirectory>${basedir}/src/test/webapp</warSourceDirectory>
<warName>${project.artifactId}-test</warName>
<webappDirectory>${basedir}/target/${project.artifactId}-test</webappDirectory>
<primaryArtifact>false</primaryArtifact>
<webResources>
<resource>
<directory>${basedir}/target/test-classes</directory>
<targetPath>WEB-INF/classes</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
See http://maven.apache.org/plugins/maven-war-plugin/examples/adding-filtering-webresources.html
You can use the maven build helper plugin to add additional folders to the "normal" class path.
But I would recommend to create an new folder for your integration test (for example src/it/java), and add this folder, but not the "normal" test folder (src/test/java) -- the same for the resources folder.
Instead of using the maven antrun plugin, you could instead use the maven resources plugin and configure it like this:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>process-test-classes</phase>
<id>test-classes</id>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<overwrite>false</overwrite>
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
<resources>
<resource>
<directory>${project.build.directory}/test-classes</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Use Tomcat 7 plugin with additional classpath directories configuration.
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<additionalClasspathDirs>
<additionalClasspathDir>${build.testOutputDirectory}</additionalClasspathDir>
</additionalClasspathDirs>
</configuration>
<executions>
<execution>
<id>start-tomcat</id>
<goals>
<goal>run</goal>
</goals>
<configuration>
<fork>true</fork>
</configuration>
</execution>
</executions>
</plugin>
You can do this Configuration in pom.xml file you don't get any errors in pom.xml and adding test classes to our jar or war file.
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<versionRange>[1.7,)</versionRange>
<goals>
<goal>run</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>process-test-classes</phase>
<configuration>
<target>
<copy todir="${basedir}/target/classes">
<fileset dir="${basedir}/target/test-classes" includes="**/*" />
</copy>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
We need to add the below plugin to the pom.xml in order to add the test cases to jar. Thanks to #IvonSopov
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-test-classes</phase>
<configuration>
<target>
<copy todir="${basedir}/target/classes">
<fileset dir="${basedir}/target/test-classes" includes="**/*" />
</copy>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
But after adding this line we got the build succeeded and also able to add the test case classes into the jar.. but the problem is in pom.xml it is showing as error like
Plugin execution not covered by lifecycle configuration:
org.apache.maven.plugins:maven-antrun-plugin:1.8:run
(execution:default, phase: process-test-classes)
In order to remove this error we need to include the below plugin as a separate tag within the build tag. (not inside the plugins which we added earlier.)
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<versionRange>[1.7,)</versionRange>
<goals>
<goal>run</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Now we can create the jar which includes the test classes without any errors.

How to stop Maven from overwriting if the destination exists

I have a directory in a dependency, that I want copied in src/main/webapp/mypath during the initialize phase.
But I want it to be copied exactly and only once, meaning that:
if src/main/webapp/mypath doesn't exist, then copy from dependency
if src/main/webapp/mypath exists, then never ever copy from dependency even if the one in the dependency is newer. If exists, don't overwrite it. Never.
I tried a couple of approaches with copy-resources and dependency:unpack but maven will always overwrite if mypath coming from the dependency is newer / updated even if I set to false every possible overwrite* configuration I'm aware of.
Any advice or RTFM + link to a manual I didn't read so far?
You can use profiles:
<profiles>
<profile>
<activation>
<file>
<missing>src/main/webapp/mypath</missing>
</file>
</activation>
... copy ...
</profile>
</profiles>
As described by #William, you can use ant plugin, export the property to maven context and skip the task if "true".
Here is the code:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<exportAntProperties>true</exportAntProperties>
<target>
<available file="src/main/resources/my-data" type="dir"
property="dir-exits"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-zip-dependencies</id>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<skip>${dir-exists}</skip>
<artifactItems>
<artifactItem>
<groupId>com.mygroup</groupId>
<artifactId>myartifactid</artifactId>
<includes>**/*.json</includes> <outputDirectory>src/main/resources/</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>

Resources