Clarification on Maven profiles and Phases - maven

In my maven project, I have multiple maven profiles. In each profile, I have docker-maven-plugin and maven-failsafe-plugin. This is how I have bound goals and phases.
docker-maven-plugin
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
<goal>remove</goal>
</goals>
maven-failsafe-plugin
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
</goals>
<phase>verify</phase>
<goals>
<goal>verify</goal>
</goals>
I have profiles for each database type (i.e. MySQL, Postgres etc.). What I'm trying to do is that run my integration tests on docker with each database type.
My question is that, can I run mvn with multiple profiles (i.e. mvn clean install -P local-postgres,local-mysql), so that each profile is executed one after the other? My requirement is not to have 2 docker containers up at once.
What I observed is that pre-integration-test phases of all profiles run first, and fails with The name "/apim-postgres" is already in use by container xxxxx. Is that how maven phases are supposed to work when multiple profiles are given?
Is there a way I can get my requirement fulfilled?

I'm not sure if this will work, but if you define each profile independently it should work. You define each plugin twice, one for each profile. The order of execution depends on various factors. I don't know where you have defined the profiles, but if they are defined in the same pom then the order should be the one defined in that pom. See https://www.waltercedric.com/index.php?option=com_content&view=article&id=1795&catid=129&Itemid=332 for more help.

Related

Use ktlint to format during maven build

I used the following settings for ktlint which allowed auto-formatting for all files during a local maven build but never triggered a pipeline failure if formatting was incorrect:
<plugin>
<groupId>com.github.gantsign.maven</groupId>
<artifactId>ktlint-maven-plugin</artifactId>
<version>1.6.1</version>
<executions>
<execution>
<id>format-and-check</id>
<goals>
<goal>format</goal>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
For ktlint to trigger a pipeline failure if formatting is incorrect I changed the settings to
<execution>
<id>verify-code-style</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
Which does trigger a failure instantly.
But - now I cannot do a local maven build and make use of auto-formatting. Instead it instantly triggers a failure, requiring manual action for example Needless blank line(s) in class X on line Y.
I would like to have the best of both worlds - trigger a failure in the pipeline and make use of auto-formatting locally. Is there any way to achieve this?
Since you want differing behaviour locally compared to your CI, I think the simplest solution would to just run the format goal before the build command that you run locally.
So instead of mvn deploy (or package or whatever you run), just run
mvn ktlint:format deploy

The docker-maven-plugin and jacoco interferes with each other

We have projects where we use jacoco to aggregate code coverage over several modules. We also have some project that use the Fabric8 docker-maven-plugin to run black box test. But for the first time we would now like to run them both i the same project. And it kind of works but not in the same maven command.
We can run mvn test and then jacoco does it job perfecly.
we can run mvn install -Djacoco.skip=true and the black box tests start the necessary docker-containers and run the tests on them.
But running mvn install and thus saying that both blackbox-tests and jacoco codecoverage should run will fail saying that jacoco doesn't find dependencies in a central repository (where they are not supposed to be anyway).
So, my question, what could docker-maven-plugin do to interfere with jacoco? It seems like docker-maven-plugin deletes stuff that jacoco expect to be there.
My configuration for jacoco is using the invoker-plugin (as many of the guides for multi module exampels for jacoco does) with localRepositoryPath, could it be colliding? Or do docker-maven-plugin clean the workspace? Se plugin-definition below.
<plugin>
<!-- To run with different Maven versions use -Dinvoker.mavenHome -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
<version>1.5</version>
<configuration>
<skipInvocation>${skipTests}</skipInvocation>
<projectsDirectory>it</projectsDirectory>
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
<pomIncludes>
<pomInclude>*/pom.xml</pomInclude>
</pomIncludes>
<postBuildHookScript>verify</postBuildHookScript>
<localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
<goals>
<goal>clean</goal>
<goal>install</goal>
</goals>
<settingsFile>it/settings.xml</settingsFile>
<extraArtifacts>
<extraArtifact>org.jacoco:org.jacoco.agent:0.8.3:jar:runtime</extraArtifact>
</extraArtifacts>
</configuration>
<executions>
<execution>
<goals>
<goal>install</goal>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>

Maven 3 goal ordering

There are two goals bound to the test phase of default Maven lifecycle. The first goal (in the order of appearance in the pom.xml) is:
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>update</id>
<phase>test</phase>
<goals>
<goal>update</goal>
</goals>
</execution>
</executions>
and the second is:
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.1</version>
<executions>
<execution>
<id>default-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
During the test phase, the surefire plugin is executed first, which contradicts with the Maven 3 FIFO ordering of goals in the same phase. I verified that the goals have the same order in the effective pom. Is it possible that one of the plugins is overriding the default order? Why is the surefire plugin executed before the liquibase one?
You are right that Maven executes the goals in the order as they are defined in the POM but in this special case, you used the default-test identifier for the second execution, which has a special meaning.
I can't find any reference about this behaviour right now but changing your <id> to something else will restore the behaviour you expect.
However, for this special case again, changing the id will make the maven-surefire-plugin execute twice: it is already executed by default and adding an execution (with an id different than default-test) will add another instead of overriding the default one.

How do I know what are different goals available for plug-in in maven?

I recently started using maven. so this question might sound basic.
This question came up when I was browsing through some code using cargo plug-in.
In the following snippet of maven plugin in pom.xml, that i extracted from here,
my understanding is as follows:
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<executions>
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<configuration>
[Cargo plugin configuration goes in here]
</configuration>
</plugin>
This plug in bound to pre-integration-test and post-integration-test phase of build LifeCycle, which also means when I run mvn install this will be executed.
The goals (start and stop) of this plug-in gets executed during these phases respectively
Q1:: Does the <id>start-container</id> has any relevance? what's its purpose & importance?
Q2:: How do I know what are the different goals available for a plug-in. In this case for cargo plug-in I see in one of the codes in my work, <goal>redeploy</goal> is used. so I am wondering how to find information on these specific goals and other goals available. I did look at online documentation. I did not find any. possible that I did not search in the right place.
A1: the id doesn't change how the execution works, it's just a way of giving it a name.
A2: The best way is to read the documentation. Maven3 is also considerably better than maven2 in this aspect. If you call a plugin with an invalid goal, it will print out all the valid goals, but it won't print what are the different parameters that can be passed to the plugin (and some plugins use different parameter names for command line and pom parameters)
The documentation of cargo is a bit odd, most other plugins have their documentation set up in a different way, which makes it easier to find the goals and the parameters that can be set.
By the way, both your points 1 and 2 are correct.

Customize maven build

Is that possible to customize a maven build lifecycle without writing a plugin? I want to customize my project to package it without running tests, then run the tests. The background is that the tests are running on HTTPUnit and it needs a fully constructed web application directory structure.
As suggested by khmarbaise you can use maven-failsafe-plugin which is an extension of maven-surefire-plugin.
Maven lifecycle has four phases perfect for your intent:
pre-integration-test for setting up the integration test
environment.
integration-test for running the integration tests.
post-integration-test for tearing down the integration test
environment.
verify for checking the results of the integration
tests.
generally speaking during the pre-integration-test we start the server
eg:
<executions>
[...]
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run-exploded</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
I use this plugin with Hudson; in Maven Build Customization - Chapter 5 you can find further details.
It seems that you are writing integration tests.
You could use maven-failsafe-plugin. This plugin is executed by default at the integration-test phase of the maven build lifecycle (which is after the packaging phase)...
For those purposes you need the integration-test phase which exactly is intended for such things. It's after the packaging phase but before install/deploy phase.
This can be achieved by using the maven-failsafe-plugin. You can find a full example here.

Resources