How can I set path in this Maven plugin? - maven

I'm new to Maven plugins, and I need to get this plugin working to run the sencha cmd tool to minify our JavaScript app as part of the daily build process.
Currently the executable tag has a hard coded path, but I'm wondering if I can specify the path as an environment variable, and then access that environment variable in the code below so it can be run on any machine?
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>sencha-compile</id>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>C:\Sencha\Sencha\Cmd\4.0.2.67\sencha.exe</executable>
<arguments>
<argument>app</argument>
<argument>build</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>

Check my Sencha ExtJS 5 + Sencha Cmd 5 + Maven integration example at:
https://github.com/dobromyslov/sencha-extjs-maven
You have to set environment variable:
Export it in console via:
$ export SENCHA_CMD="/path/to/your/Sencha/Cmd/5.0.0.116/sencha"
Also you can add this export statement to your ~/.bashrc or /etc/profile file in order to make it permanent.
Or add new environment variable on Windows.
Set Sencha Cmd build environment:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Default build environment -->
<sencha.env>production</sencha.env>
</properties>
<profiles>
<!-- Development profile -->
<profile>
<id>dev</id>
<activation>
<property>
<name>env</name>
<value>development</value>
</property>
</activation>
<properties>
<sencha.env>testing</sencha.env>
</properties>
</profile>
<!-- Production profile -->
<profile>
<id>prod</id>
<activation>
<property>
<name>env</name>
<value>production</value>
</property>
</activation>
<properties>
<sencha.env>production</sencha.env>
</properties>
</profile>
</profiles>
Then use the following Maven plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>sencha-compile</id>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<!-- Set path to your Sencha Cmd executable-->
<executable>${env.SENCHA_CMD}</executable>
<arguments>
<argument>-sdk</argument>
<argument>${basedir}/src/main/webapp</argument>
<argument>app</argument>
<argument>build</argument>
<argument>--clean</argument>
<argument>--environment</argument>
<argument>${sencha.env}</argument>
<argument>--destination</argument>
<argument>${basedir}/src/main/webapp/build</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
And run
$ mvn compile

To answer your question, you can reference system environment variables from within a maven pom file with this syntax:
${env.NAME_OF_VARIABLE}
See this link for more details:
https://maven.apache.org/pom.html#Properties
If you named the environment variable PATH_TO_SENCHA_EXE you could reference it like this:
<executable>${env.PATH_TO_SENCHA_EXE}sencha.exe</executable>
As an alternative to environment variables, you could consider creating a property in your pom to contain this path. Then you could change the value used for different environments by passing a new value for the property on the command line or by loading a properties file in your pom that may contain this property. There are many options here.
Edit:
I found the latter suggestion has been covered on SO at the following link (and likely other places):
Reading properties file from Maven POM file

Related

Maven: How to activate profile based on whether child module contains a file?

I’m using Maven 3.1.1 on Mac 10.9.1. I want to activate a profile based on whether certain child modules contain a file. I have tried the following
<profile>
<id>deploy-war-to-jboss</id>
<activation>
<file>
<exists>${session.executionRootDirectory}/src/main/webapp/WEB-INF/web.xml</exists>
</file>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>${jboss.maven.plugin.version}</version>
<configuration>
<hostname>${jboss.remote.hostname}</hostname>
<port>${jboss.remote.port}</port>
</configuration>
<executions>
<execution>
<id>deploy-to-jboss</id>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
but this profile doesn’t get activated when running “mvm clean install” despite the fact I’ve verified that the child modules in question contain the file. I also tried ${project.basedir} without luck. Any ideas how I make this happen?
Since you define the profile in the parent POM (I guess) you should try this
${basedir}/name-of-your-child-module//src/main/webapp/WEB-INF/web.xml
Furthermore, you should try running Maven in debug mode to get more information at runtime:
mvm -X clean install

How to define conditional properties in maven?

For instance, I would like to have property Configuration set to ${env:AAA} if there is an environment variable AAA and to some other constant value if there is no such environment variable.
How do I do it in maven 2?
It appears as though you activate a profile conditionally...
<profiles>
<profile>
<activation>
<property>
<name>environment</name>
<value>test</value>
</property>
</activation>
...
</profile>
</profiles>
The profile will be activate when the environment variable is defined to the value test as in the following command:
mvn ... -Denvironment=test
On the off-chance that a system property is acceptable, you can simply define the property in your POM file and override when required:
<project>
...
<properties>
<foo.bar>hello</foo.bar>
</properties>
...
</project>
You can reference this property elsewhere in your POM by referring to ${foo.bar}. To override on the command line, just pass a new value:
mvn -Dfoo.bar=goodbye ...
You can set a property conditionally using maven-antrun-plugin. Example setting install.path + echoing the value:
<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.INSTALL_HOME}" else="C:\default-install-home">
<isset property="env.INSTALL_HOME" />
</condition>
<echo message="${install.path}"/>
</target>
</configuration>
</execution>
</executions>
</plugin>

Using DB unit to load DEMO data

I'm using the Maven DBUnit plugin to load test data for unit tests. I'd also like to use it for loading a different set of data to a different db for demo purposes. The dbunit plugin only allows for a single execution. Should I just create a separate pom or is there some trick that I can do to make this happen. (I.e., I'd like to simply do something like mvn load-demo-data).
you can execute a plugin several times if you like it depends just on the configuration you give in the pom:
<plugin>
<artifactId>maven-whatever-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>execution1</id>
<phase>test</phase>
<configuration>
....
</configuration>
<goals>
<goal>WhatEverGoalYouHave</goal>
</goals>
<phase>...</phase>
</execution>
<execution>
<id>execution2</id>
<configuration>
....
</configuration>
<goals>
<goal>WhatEverGoalYouHave</goal>
</goals>
<phase>...</phase>
</execution>
</executions>
</plugin>
You can also define a profile to control the execution which might the right choice for your demo data. The call you described mvn load-demo-data is not possible with maven, cause maven calls only a goal or lifecycle.
Use properties when configuring the database credentials
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>dbunit-maven-plugin</artifactId>
<version>${dbunit.plugin.version}</version>
<configuration>
<url>${db.url}</url>
<driver>${db.driver}</driver>
<username>${db.username}</username>
<password>${db.password}</password>
</configuration>
..
Then add a profiles section to your POM, controling the setting of these properties:
<profiles>
<profile>
<id>db1</id>
<properties>
<db.url>jdbc:h2:target/db1;AUTO_SERVER=TRUE</db.url>
<db.driver>org.h2.Driver</db.driver>
<db.username>user</db.username>
<db.password>pass</db.password>
</properties>
<profile>
<profile>
<id>db2</id>
<properties>
<db.url>jdbc:h2:target/db2;AUTO_SERVER=TRUE</db.url>
<db.driver>org.h2.Driver</db.driver>
<db.username>user</db.username>
<db.password>pass</db.password>
</properties>
<profile>
..
The profile cane be activated as follows to update two different databases
mvn -Pdb1 clean test
mvn -Pdb2 clean test

set java system property during maven 2 compile?

I have a maven profile and want to set a property which is later on available per System.getProperty(..) in java:
<profile>
<id>local-dev</id>
<properties>
<my.comp.my.prop>myValue</my.comp.my.prop>
</properties>
</profile>
I want System.getProperty("my.comp.my.prop") to be "myValue" but it's null..
How do I set it correctly? :)
Thansk!
properties-maven-plugin plugin will help you to do exactly what you're looking for:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<goals>
<goal>set-system-properties</goal>
</goals>
<configuration>
<properties>
<property>
<name>my.property.name</name>
<value>my.property.value</value>
</property>
</properties>
</configuration>
</execution>
</executions>
</plugin>
maven cannot set a property which can be accessed by your application from the environment at runtime.
Instead, you can use maven to update a property file in your codebase during build time, which can then be read by your application at runtime. Different values of the property can be set based on the profile, thereby allowing your application to have different values as desired.
Alternately, you can invoke the application setting the desired property in the environment manually (outside maven).

How to identify and set a missing environment property in Maven?

I have my build set-up so that I pass in my variable via the command line:
mvn clean install -DsomeVariable=data
In my pom I have:
<someTag>${someVariable}</someTag>
This works fine, but I would like to identify if someVariable is not specified on the command line, and then default it so that my script can continue.
Can this be done in Maven?
You can specify default property value in the properties section of your POM file:
<properties>
<someVariable>myVariable</someVariable>
</properties>
If you want to make sure that the property value is ALWAYS supplied on a command line, then you can use maven-enforcer-plugin.
Here is a link that shows how to enforce system property presence -> http://maven.apache.org/enforcer/enforcer-rules/requireProperty.html
I'll just copy the XML verbatim here in case the above link goes bad.
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<id>enforce-property</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireProperty>
<property>basedir</property>
<message>You must have a basedir!</message>
<regex>\d</regex>
<regexMessage>You must have a digit in your baseDir!</regexMessage>
</requireProperty>
<requireProperty>
<property>project.version</property>
<message>"Project version must be specified."</message>
<regex>(\d|-SNAPSHOT)$</regex>
<regexMessage>"Project version must end in a number or -SNAPSHOT."</regexMessage>
</requireProperty>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
You can specify the default value as
<properties>
<someTag>defaultValue</someTag>
</properties>
When you run maven command, you can override that value like this
mvn clean package -DsomeTag=newSpecificValue
You can use profiles instead, but you'll need a profile for each
variable.
<profile>
<id>default-value-1</id>
<activation>
<activeByDefault>false</activeByDefault>
<property>
<name>!someVariable</name>
</property>
</activation>
<properties>
<someVariable>DEFAULT-VALUE</someVariable>
</properties>
</profile>

Resources