Cannot get maven2 profiles to work - maven-2

I have defined the following profile in pom.xml:
<profiles>
<profile>
<id>dev</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>dev</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<delete file="src/main/application/META-INF/data-sources.xml"/>
<copy file="src/main/resources/data-sources-dev.xml" tofile="src/main/application/META-INF/data-sources.xml"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
The issues is that it doesn't seem to work!
mvn help:effective-pom -P dev
Does echo also the profile.
However, if I do
mvn -X -Pdev install
The delete / copy part is not visible in the logs.

There is no phase with the name dev. Please specify a correct phase.

I've just copy-pasted your configuration into a basic pom and it works just fine. Are you sure it doesn't appear in the config as well as the profile? If you redirect the output to a file and search for "antrun" I suspect you'll see that it is declared in the build section of the effective pom.
Your antrun plugin configuration needs to bind to a valid phase for its packaging type before it will be executed. If you want the contents to be available in the jar (assuming jar packaging), this needs to be before the package phase. I would suggest process-resources.
So change:
<phase>dev</phase>
to:
<phase>process-resources</phase>

Related

Maven PMD plugin reporting not going to correct directory

I have the following configuration settings under my pom.xml to generate reports for PMD code analysis:
<pluginManagement>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.4</version>
<executions>
<execution>
<goals>
<goal>pmd</goal>
</goals>
<configuration>
<outputDirectory>code-analysis/reports/html</outputDirectory>
<targetDirectory>code-analysis/reports/</targetDirectory>
<aggregate>true</aggregate>
<rulesets>
<ruleset>code-analysis/rulesets/pmd-custom-rules.xml</ruleset>
</rulesets>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
But after I run mvn pmd:pmd I didn't get the report in the outputDirectory I want. Does setting the aggregate=true only generates 1 report for all the sub-projects under maven? How do I configure it so that it will only generate 1 report to the output directory that I want?
With Maven it is not possible to run a goal by execution(Id), that's only possible by calling it by phase. So if you want to run pmd:pmd from commandline AND have specific configuration, move the configuration outside the executions-block. Now it becomes general configuration. It'll be like:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.4</version>
<configuration>
...
</configuration>
</plugin>

Chaining Maven Flyway commands

How can Flyway commands be chained into a single command using Maven?
For example, I want to run mvn initialize flyway:clean followed by mvn initialize compile flyway:migrate. However, mvn initialize flyway:clean compile flyway:migrate fails.
Thanks!
I just checked
mvn initialize flyway:clean compile flyway:migrate
with both Maven 2.2.1 and Maven 3.0.3 and it works every time.
Could you double check this? In case you think you really found a problem, please file an issue in the Issue Tracker with the necessary steps to reproduce it and I'll do my best to fix it asap.
That will give you the ability to chain maven steps, just add the goals you want in there
<profile>
<id>clean-migrate</id>
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>process-resources1</id>
<goals>
<goal>resources</goal>
</goals>
<!-- Populate the database before querydsl-sql runs -->
<phase>generate-sources</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>com.googlecode.flyway</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<executions>
<execution>
<id>process-resources2</id>
<goals>
<goal>clean</goal>
<goal>migrate</goal>
</goals>
<phase>generate-sources</phase>
</execution>
</executions>
<version>1.4.2</version>
<configuration>
<driver>oracle.jdbc.driver.OracleDriver</driver>
<url>jdbc:oracle:thin:#${database-hostname}:${database-port}:${database-sid}</url>
<user>${database-username}</user>
<password>${database-password}</password>
<schemas>${database-schema}</schemas>
<table>schema_history</table>
<initialVersion>0.1.00</initialVersion>
<initialDescription>Base Migration</initialDescription>
</configuration>
</plugin>
</plugins>
</build>
</profile>
You will also need the following in your settings.xml
<profile>
<id>inject-flyway-properties</id>
<properties>
<database-hostname>${env.DB_HOSTNAME}</database-hostname>
<database-port>${env.DB_PORT}</database-port>
<database-username>${env.DB_USER}</database-username>
<database-password>${env.DB_PASSWORD}</database-password>
<database-sid>${env.DB_DEFAULT_SID}</database-sid>
<database-schema>${env.DB_SCHEMA}</database-schema>
</properties>
</profile>
If i understand the docs correct you have to configure the maven-flyway plugin to do the work and bound it to the correct phases of maven than you can use the default maven calls like mvn clean package or mvn clean verify.
You can use profiles in order to bundle "commands" together. Once it's done you just call:
mvn -Pmy-profile

Is there any maven goal that is similar to 'dist'?

I'm working on a project that used ant. I had a target dist that would basically do jar first, and then install the application into a directory.
This means, it would create directories like bin/, lib/ and config/ in the installation directory, and then copy the relevant files into each of these directories.
My question is two-fold:
Is there any maven goal that does this kind of thing?
If not, I want to do maven dist and make this happen. How would you suggest I accomplish this using Maven?
If I can't have my own "target" (like dist), then what would be the best way?
Bottom line: I want to do all this, but don't want to alter the behavior of the default "targets" like compile and package etc.
Thanks,
jrh
PS: I'm using maven version 2.2.21
I don't know what would go in config, but lib and bin is easy.
To copy all dependencies to a folder just do this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/dist/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
To output your jar to a bin folder do this (reference page):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<finalName>${project.artifactId}</finalName>
<outputDirectory>${project.build.directory}/dist/bin</outputDirectory>
</configuration>
</plugin>
Ah, there are additional requirements:
Bottom line: I want to do all this, but don't want to alter the behavior of the default "targets" like compile and package etc.
In this case I'd use a profile to turn this on:
<profile>
<id>dist</profile>
<build>
<plugins>
<!-- insert stuff from above here -->
</plugins>
</build>
</profile>
Now you would do mvn clean package -Pdist to get your dist directory and if you don't add the profile, you get default behaviour.
Basically, things work differently in maven from the way they do in ant. There are no targets, there are only lifecycle phases and plugin goals.
You can either execute a lifecycle phase, which will call all maven plugin goals that are bound to all phases up to this one (e.g. if you do mvn compile, the following phases will be executed: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile). But there is no (easy) way to define a lifecycle phase named dist.
Or you can execute a specific plugin goal (you can actually execute multiple phases and / or plugin goals). E.g. you could write your own dist plugin and call it using mvn dist:dist, but I wouldn't recommend that because you are using existing functionality and the profile solution should be a pretty good fit.
You could try writing an assembly descriptor for the assembly plugin (or search google for a suitable one).
Something like this
<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>dist</id>
<formats><format>zip</format></formats>
<fileSets>
<fileSet>
<directory>src/main/config</directory>
<outputDirectory>config</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
<files>
<file>
<source>${project.build.directory}/${project.artifactId}.jar</source>
</file>
</files>
<dependencySets>
<dependencySet>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>
will create a ${project.artifactId}-dist.zip inside your target directory. The zip file will be laid out like
yourProjectName/
yourProjectName/config/...
yourProjectName/lib/...
yourProjectName/${project.artifactId}.jar
It looks like the assembly plugin will only create compressed files, it won't just copy them to a dist folder.
Seans answer is good and I almost went for it until I found out about the appassembler plugin http://mojo.codehaus.org/appassembler/appassembler-maven-plugin/.
See here for an example https://github.com/khmarbaise/maven-training/tree/master/502-assembly-plugin
It is called as part of the package lifecycle.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
<configuration>
<binPrefix>utility</binPrefix>
<assembleDirectory>${project.build.directory}/appassembler</assembleDirectory>
<extraJvmArguments>-Xms512m -Xmx1024m</extraJvmArguments>
<generateRepository>false</generateRepository>
<repositoryName>lib</repositoryName>
<repositoryLayout>flat</repositoryLayout>
<includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
<platforms>
<platform>windows</platform>
<platform>unix</platform>
</platforms>
<programs>
<program>
<mainClass>com.soebes.tools.cli.UtilityCLI</mainClass>
<name>utility</name>
</program>
</programs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/bin.xml</descriptor>
<descriptor>src/main/assembly/bin-unix.xml</descriptor>
<descriptor>src/main/assembly/src.xml</descriptor>
</descriptors>
<tarLongFileMode>gnu</tarLongFileMode>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
The descriptors it references are fairly straigtforward and it also creates a batch and shell script for you to run your application!
You cannot have maven dist, with NetBeans (and other IDEs I believe) you can create a custom action dist which executes as mvn install -Pdist (or mvn clean package -Pdist, as suggested by Sean).

Maven - extract /test/resources/my.zip in /target during the Test Phase

I've some test resources (that are specific for a particular task) zipped in /test/resources/my.zip.
I want to extract the zip content to /target during the maven Test Phase.
Do you know what should I specify in the pom.xml to achieve this?
One solution is to use the maven-antrun-plugin to run the unzip Ant task. The following configuration in the build section of your POM should be pretty much what you need (but I haven't tested it):
<build>
<plugins>
<!-- ... -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-test-resources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<unzip src="test/resources/my.zip" dest="target/" overwrite="true"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<!-- ... -->
</plugins>
</build>

Is it possible to override the configuration of a plugin already defined for a profile in a parent POM?

In a POM parent file of my project, I have such a profile defining some configurations useful for this project (so that I can't get rid of this parent POM) :
<profile>
<id>wls7</id>
...
<build>
<plugins>
<!-- use java 1.4 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<fork>true</fork>
<source>1.4</source>
<target>1.4</target>
<meminitial>128m</meminitial>
<maxmem>1024m</maxmem>
<executable>%${jdk14.executable}</executable>
</configuration>
</plugin>
</plugins>
</build>
...
</profile>
But in my project I just would like to override the configuration of the maven-compiler-plugin in order to use jdk5 instead of jdk4 for compiling test-classes.
That's why I did this section in the POM of my project :
<profiles>
<profile>
<id>wls7</id>
<activation>
<property>
<name>jdk</name>
<value>4</value>
</property>
</activation>
<build>
<directory>target-1.4</directory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>my-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<fork>true</fork>
<executable>${jdk15.executable}</executable>
<compilerVersion>1.5</compilerVersion>
<source>1.5</source>
<target>1.5</target>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
...
</profiles>
and it's not working ...
I even tried to override the configuration in regular plugin sections of my POM (I mean, not for a specific profile but for my whole POM).
What could be the problem ?
To clarify some of my requirements :
I don't want to get rid of the parent
POM and the profile (wls7) defined
inside it (since I need many and many
properties, configurations, ...) and
that is not the process in my
company.
A solution based on duplicating
the parent POM and/or the profile
defined inside it is not a good
one. Since if the responsible of
the parent POM change something, I
would have to report it in mine.
It's just an inheritance matter (extend or override a profile, a configuration from an upper-level POM) so I think it should be possible with Maven 2.
Overriding configurations from a parent pom can be done by adding the combine.self="override" attribute to the element in your pom.
Try changing your plugin configuration to:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>my-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration combine.self="override">
<fork>true</fork>
<executable>${jdk15.executable}</executable>
<compilerVersion>1.5</compilerVersion>
<source>1.5</source>
<target>1.5</target>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>
For more information on overriding plugins, see: http://maven.apache.org/pom.html
i had the same issue. By default my maven war plugin excluded a html file. But in my acceptance-tests profile i wanted this file included. So when i added in the maven war plugin again it did not override the default.
To resolve this issue i passed in the combine.self attribute and worked fine.
Default build:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<packagingExcludes>swagger-ui/client.html</packagingExcludes>
</configuration>
</plugin>
Acceptance test profile:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration combine.self="override"/>
</plugin>
Did you try to deactivate the wls7 profile (since maven 2.0.10):
Starting with Maven 2.0.10, one or
more profiles can be deactivated using
the command line by prefixing their
identifier with either the character
'!' or '-' as shown below:
mvn groupId:artifactId:goal -P !profile-1,!profile-2
This can be used to deactivate
profiles marked as activeByDefault or
profiles that would otherwise be
activated through their activation
config.
And then add your configuration in a profile with a different name or directly in your pom.xml.