What phase do I use for my task? - maven

I'm using Maven 3.0.3. I want to run a task to copy environment specific properties before I package my WAR file. Below is my task.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<delete file="${project.build.outputDirectory}/environment.properties"/>
<copy file="src/main/resources/${env}_environment.properties"
tofile="${project.build.outputDirectory}/environment.properties" />
<delete file="${project.build.outputDirectory}/${env}_hibernate.cfg.xml"/>
<copy file="src/main/resources/${env}_hibernate.cfg.xml"
tofile="${project.build.outputDirectory}/hibernate.cfg.xml" />
<echo message="Copied ${env}_hibernate.cfg.xml properties. " />
</tasks>
</configuration>
</execution>
</executions>
</plugin>
However, when start up my app, invoking a goal from my Tomcat profile, by running "mvn -P tomcat tomcat:run", the above task doesn't get run. Any ideas how I can correct this? The Tomcat profile I include is below. - Dave
<profile>
<id>tomcat</id>
<activation>
<property>
<name>env</name>
<value>dev</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<charset>UTF-8</charset>
<path>/leadsmonitor</path>
<server>nnadbmon-tomcat</server>
<update>true</update>
<url>http://nnadbmon.mydomain.com:8080/manager</url>
<warFile>target/leadsmonitor.war</warFile>
<systemProperties>
<JAVA_OPTS>-Xms256m -Xmx512m -XX:MaxPermSize=256m -XX:NewRatio=6 -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled -verbose:gc"</JAVA_OPTS>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
</profile>

You should attach it to the compile phase. This will actually get executed after the compilation has finished.

The maven-antrun-plugin runs at prepare-package so you can add that to your command:
mvn -P tomcat tomcat:run prepare-package

From documentation of tomcat:run,
tomcat:run Invokes the execution of the lifecycle phase compile prior to executing itself.
prepare-package phase comes later - before package
Perhaps you should try tomcat:run-war.
tomcat:run-war Invokes the execution of the lifecycle phase package prior to executing itself.

Related

Are parent default plugins being executed when using a child profile in maven?

I get the following error. Is it because the install_path wasn't set? If so, does it mean that when using a profile, the default plugins aren't being executed (the one that sets the install_path)?
Execution:
mvn clean install site -Pfull
Error:
Failed to execute goal
org.apache.maven.plugins:maven-clean-plugin:2.5:clean
(clean-deploy-folder) on project bo-full: Missing base directory for
file set: null (included: [], excluded: [])
Parent:
<project>
<plugins>
<plugin>
<!-- Workaround maven not being able to set a property conditionally based on environment variable -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<exportAntProperties>true</exportAntProperties>
<target>
<property environment="env"/>
<condition property="install.path" value="${env.SERVER_HOME}" else="C:\MY_SERVER">
<isset property="env.SERVER_HOME" />
</condition>
<echo message="${install.path}"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
...
Child:
<project>
<profiles>
<profile>
<id>full</id>
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<executions>
<execution>
<id>clean-deploy-folder</id>
<phase>pre-site</phase>
<goals>
<goal>clean</goal>
</goals>
<configuration>
<excludeDefaultDirectories>true</excludeDefaultDirectories>
<filesets>
<fileset>
<directory>${install.path}</directory>
</fileset>
</filesets>
</configuration>
</execution>
</executions>
</plugin>
...
1) Default plugins should be executed even when using profile. Please verify this is happening by following build log - every plugin execution is logged by maven, even if the plugin itself doesn't log anything.
2) You should keep cleanup execution in the same Maven project/module as the execution that creates the property. One reason is that your child module can then be built separately (it'll use parent pom.xml from local/remote repository, if available). It's also possible that property isn't properly propagated within reactor build for whatever reason.
3) If the problem is indeed property propagation and antrun plugin is at fault, you can replace your antrun execution with a Maven profile. It should go something like this:
<properties>
<!-- default value goes here: -->
<install.path>C:\MY_SERVER</install.path>
</properties>
<profiles>
<profile>
<id>env</id>
<activation>
<property>
<!-- activate this profile when property is specified: -->
<name>env.SERVER_HOME</name>
</property>
</activation>
<properties>
<!-- override default property value: -->
<install.path>${env.SERVER_HOME}</install.path>
</properties>
</profile>
</profiles>

Maven antrun plugin set property based on OS

I am converting an ant script to Maven and decided to use Maven ant run plugin. I am on the good way, but I hit the following problem. Ant source script uses target definition as follows:
<condition property="isWindows">
<os family="windows"/>
</condition>
<condition property="isUnix">
<os family="unix"/>
</condition>
<target name="init-windows" depends="" if="isWindows">
<property file="${user.home}/abc.properties"/>
</target>
<target name="init-unix" depends="" if="isUnix">
<property name="abc.home" value="${env.ABC_HOME}"/>
</target>
The point is to use property value
abc.home
later in the build cycle which is dependent on OS (Win,Linux).
In the ant script it is ok,but maven ant run plugin does not enable using the multiple targets. I do not want to use Maven profile tags. I would like to use ant tag for this if there is any? Does anybody have a hint?
I think an easier solution would be not to use the maven-antrun-plugin and use profiles instead.
Profiles are a good way to have a different of properties depending of some activation property. One of those activation property can be the OS which is running the build.
Consider the following POM:
<profiles>
<profile>
<id>windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<!-- Associate the read-project-properties goal with the initialize phase, to read the properties file. -->
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>${user.home}/abc.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</profile>
<profile>
<id>unix</id>
<activation>
<os>
<family>unix</family>
</os>
</activation>
<properties>
<abc.home>${env.ABC_HOME}</abc.home>
<properties>
</profile>
</profiles>
When run on a Windows machine, the windows profile will be activated. Reading a property file is done with the properties-maven-plugin and its content will be placed in properties, just like the Ant <property> task.
When run on an Unix machine, the unix profile will be activated and the abc.home property will be set to ${env.ABC_HOME}.
Then, in your Maven build, you can use ${abc.home} without having to worry in which profile you are in.
Having said that, another solution would be to run multiple executions of the maven-antrun-plugin. In the first execution, you decide whether the build in running in a Windows or Unix machine and then skip the following executions accordingly. This would be a sample configuration, where myPhase would be the phase you want this to run.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>myphase</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<condition property="isWindows">
<os family="windows" />
</condition>
<condition property="isUnix">
<os family="unix" />
</condition>
</target>
<exportAntProperties>true</exportAntProperties>
</configuration>
</execution>
<execution>
<phase>myphase</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target name="init-windows" depends="">
<property file="${user.home}/abc.properties" />
</target>
<exportAntProperties>true</exportAntProperties>
<skip>${isUnix}</skip>
</configuration>
</execution>
<execution>
<phase>myphase</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target name="init-unix" depends="">
<property name="abc.home" value="${env.ABC_HOME}" />
</target>
<exportAntProperties>true</exportAntProperties>
<skip>${isWindows}</skip>
</configuration>
</execution>
</executions>
</plugin>

Execute script as part of mvn package

My pom.xml contains
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<warName>${project.artifactId}</warName>
<outputDirectory>${wlp.install.dir}/usr/servers/liberty/apps</outputDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
When I run mvn package I can see this step running:
[INFO] --- maven-war-plugin:2.3:war (default-war) # frontEnd ---
That's great. However, I also want to run a shell script before the war file is created. I tried adding
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<configuration>
<tasks>
<exec dir="${basedir}"
executable="${basedir}/src/main/webapp/concat"/>
</tasks>
</configuration>
</plugin>
before the maven-war plugin, but it does not run. I don't even see antrun in the output of mvn. Adding the <tasks> element to the <configuration> for maven-war-plugin does nothing either.
What can I do to have maven simply run a script as part of mvn package?
The position in the pom.xml is irrelevant, you have to bind the maven-antrun-plugin execution to the correct lifecycle phase (e.g. compile) as shown below:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase> <!-- a lifecycle phase --> </phase>
<configuration>
<target>
<!--
Place any Ant task here. You can add anything
you can add between <target> and </target> in a
build.xml.
-->
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
See The maven-antrun-plugin Usage Page for more details and The Maven Introduction to the Build Lifecycle for further reference.

How to call maven-antrun-plugin target without attach execution to a maven phase ?

I use maven-antrun-plugin for init config files for my project. But i need to init config files just once, when i first start to init my dev environment, not each time i launch jetty:run.
If I attach phase to process-resouces for example, each time I launch jetty, my config files are reseted.
So i configured antrun like this :
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target name="init_config_files">
<!-- init files -->
</target>
</configuration>
</execution>
</executions>
</plugin>
If I launch mvn antrun:run, it just return me this error : "[INFO] No ant target defined - SKIPPED". And it is the same thing, if I specify target : "mvn antrun:run -Dtarget=init_config_files".
Try this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>default-cli</id>
<configuration>
<target>
<property name="compile_classpath" refid="maven.compile.classpath" />
<echo message="compile classpath: ${compile_classpath}" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
and run this:
mvn antrun:run
Best solution I have found so far:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>go-live</id>
<configuration>
<target>
<!-- go live! -->
<exec executable="${basedir}/deploy2server.sh" failonerror="true" dir="${basedir}">
<arg value="deploy" />
<arg value="${deploy.to.server}" />
<arg value="${jetty.port.live}" />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
and run this:
mvn antrun:run#go-live
This solution avoids the target being run by accident, ie. it does not run just by typing "mvn antrun:run" and it also does not run during regular maven runs. I'm using this for qa auto-deployment in my jenkins instance after all modules incl integration done against the final distribution package have been successfully executed.
I just ran into the same problem and finally figured it out: If you want to run the ant tasks only once, you can set the plugin up like this:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<configuration>
<target name="init_config_files">
<!-- init files -->
</target>
</configuration>
</plugin>
and use mvn antrun:run to execute it. That way, the ant stuff is not bound to any phase.
If you need to run some part of build on special conditions (e.g. once), you can put those parts into a Maven profile and then invoke Maven specifying profile name, e.g. mvn -p init_config_files package

How can I set a environment variables in Maven per run?

In my project, we've created a Maven module to get the specific JBoss AS and unpacked.
Then all the test cases can be run under this Jboss AS as embedded container.
We're using jboss-ejb3-embedded-standalone to call the embedded container, however, it just find the JBOSS_HOME from environment variables and use that one to run.
Thus we have to update the JBOSS_HOME per mvn install.
I tried to do this in maven by introduce exec-maven-plugin as below:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<executable>env</executable>
<environmentVariables>
<JBOSS_HOME>
C:/Sample/embedded-container/jboss-${version.org.jboss.jbossas}
</JBOSS_HOME>
</environmentVariables>
</configuration>
<executions>
<execution>
<id>resetJbossHome</id>
<phase>integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
In the output of console, I can see
[INFO] --- exec-maven-plugin:1.2.1:exec (resetJbossHome) # test-embedded ---
....
JBOSS_HOME=C:/Sample/embedded-container/jboss-6.1.0.Final
....
But when launching JBOSS, it's still running the one with origin JBOSS_HOME set.
Besides, I've tried using maven-antrun-plugin too.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>copyRelease</id>
<phase>pre-integration-test</phase>
<configuration>
<tasks>
<exec executable="env">
<env key="JBOSS_HOME" value="C:/Sample/embedded-container/jboss-${version.org.jboss.jbossas}"/>
</exec>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
It turns out the same.
Am I wrong on the configuration or there're some better way?
Take a look at the Maven profiles.
You can define one profile for testing, one for production, with different properties, such as
<profiles>
<profile>
<id>test</id>
<jboss.home>PATH TO JBOSS TEST INSTANCE</jboss.home>
</profile>
<profile>
<id>prod</id>
<jboss.home>PATH TO JBOSS PROD INSTANCE</jboss.home>
</profile>
</profiles>
And in your exec plugin :
<environmentVariables>
<JBOSS_HOME>
${jboss.home}
</JBOSS_HOME>
</environmentVariables>

Resources