Run static analysis tools in compile or package step in Maven2? - maven-2

I'm researching using Maven for my team, and one of my goals for the build is to have static analysis tools run for every build, and perhaps fail the build for certain severe errors. However, in maven it seems that these are treated as reports and run on the site lifecycle. This presents a couple of problems as we don't intend to use the site for most projects, and it requires an extra step (or at least additional phase) to get the static analysis.
Is there a way to run static analysis tools in maven-2 in the compile or package phase (or equivalent)?

This can be done by configuring the plugin (findbugs for example) in the <build> section and configuring the <phase> in the <executions>:
<executions>
<execution>
<id>findbugs-run</id>
<phase>process-classes</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>

Related

Which is correct combination of versions of cucumber-jvm parallel, maven surefire and compiler to be configured for running test cases in parallel

I am new to cucumber-jvm parallel plugin and want to understand 2 things basically -
First - Which is correct combination of version i shall choose of cucumber-jvm parallel plugin, maven surefire and compiler plugin
Second - what is difference between cucumber-jvm implementation supporting parallel execution from V 4.0 and cucumber-jvm-parallel plugin
There are 2 phases people configure in cucumber-jvm-parallel plugin. Goal as validate or generateRunners. Can someone guide me whts the difference between these 2.
<id>generateRunners</id>
<phase>generate-test-sources</phase>
<goals>
<goal>generateRunners</goal>
</goals>
Is there any mandatory configuring missing in below jvm implementation
<plugin>
<groupId>com.github.temyers</groupId>
<artifactId>cucumber-jvm-parallel-plugin</artifactId>
<version>2.2.0</version>
<executions>
<execution>
<id>generateRunners</id>
<phase>generate-test-sources</phase>
<goals>
<goal>generateRunners</goal>
</goals>
<configuration>
<glue>com.jacksparrow.automation.steps_definitions.functional</glue>
<outputDirectory>${project.build.directory}/generated-test-sources</outputDirectory>
<featuresDirectory>src/test/resources/features/functional/</featuresDirectory>
<cucumberOutputDir>target/cucumber-parallel</cucumberOutputDir>
<format>json,html</format>
<tags>"~#ignored"</tags>
</configuration>
</execution>
</executions>
</plugin>
Please guide me as this is making me confused.
Maven Surefire has two levels of parallel execution for JUnit tests. It can run individual classes in parallel and it can provide a scheduler to test runners that correctly implement the ParentRunner. Normally this is used to run methods in parallel by the BlockJUnit4ClassRunner.
Until version v4 Cucumber did not correctly implement ParentRunner so feature files could not be executed in parallel using the scheduler.
As explained in the cucumber-jvm-parallel-plugin/README the plugin will create an individual runner class for each feature. This means that parallel execution depends on Surefires ability to run classes in parallel rather then its ability to provide a scheduler.
If you are using Cucumber v4 you should not use the parallel plugin. For all but a few limited use cases there are no benefits to doing so and a whole slew of downsides.
The cucumber-jvm/junit/README.md describes how to configure surefire parallel execution (the latest stable version is surefire:2.22.1 and should work).
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<parallel>both</parallel>
<threadCount>4</threadCount>
</configuration>
</plugin>
</plugins>
</build>
So overall picture is, if we are using cucumber v 4.0.0 or above then we shall not use cucumber-jvm parallel plugin. Because one of the main principle of Cucumber 4.0.0 implementation is to provide support to parallel execution and coming to Maven Surefire version, we can use latest one as well i.e. 3.0.0-M3.

Execution point between prepare-package and package in Maven build-process

The package phase of a project with packaging war, prepares an exploded-war in the target folder and packages this into the final war-file.
Is it possible to make some changes, editing files, removing files and so on, between prepare-package and package phases? I'm searching for an extension point (Maven execution-phase) where the resources are already copied and in the exploded-war structure.
[maven phase] Copy resources and explode to target/{finalName}.
[custom] Do some complex custom changes (e.g. implemented with maven-antrun).
[maven phase] Package the changed stuff into the final war.
I thought this could be possible between the phases prepare-package and package. Unfortunately after the prepare-package no exploded war is available to be changed and packaged later.
Can you give me a hint how to achieve this? Thank you very much.
This configuration calls the exploded goal in the prepare-package phase. This gives you the chance to work on the exploded war directory in subsequent plugin definitions e.g. maven-antrun.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<id>prepare-war</id>
<phase>prepare-package</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
It sound to me like you should bind the antrun task to the prepare package phase, because at this point the resources have already been processed see Lifecycle Reference.

maven-assembly-plugin causing tests to run twice

I have a maven project where I am using the assembly plugin.
I typically create my artifacts by running:
mvn clean verify assembly:assembly
(I have integration tests which I want run separately to unit tests).
When this runs, the assembly plugin is running the unit tests itself.
This causes them to be run twice.
Is there a way I can tell the assembly plugin not to run the tests?
I am tempted to run this in two steps:
1. mvn clean verify
2. if previous command successful, run mvn assembly:assembly -DskipTests=true
However, this is a little clumsy and would rather the single command.
Thanks,
Steven
When this runs, the assembly plugin is running the unit tests itself. This causes them to be run twice.
The assembly:assembly goal Invokes the execution of the lifecycle phase package prior to executing itself and running it on the command line will thus invoke any phase prior to package. And this includes the test phase.
Is there a way I can tell the assembly plugin not to run the tests?
No. My suggestion would be to create the assembly as part of the build lifecycle instead of invoking the plugin on the command line i.e. to bind it on a particular phase. For example:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<executions>
<execution>
<id>create-my-assembly</id>
<phase>package</phase><!-- change this if not appropriate -->
<goals>
<goal>single</goal>
</goals>
<configuration>
...
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
And if you don't want the assembly to be created if your integration tests fail, then bind it on a later phase (e.g. post-integration-test or verify).
And if you don't want the assembly to be systematically created, put the above configuration in a profile.

How to display dependency conflicts in 'mvn site'

I can easily see if there are conflicts between (transitive) dependency versions using:
mvn dependency:tree -Dverbose=true
... this will show the full resolution tree, including which elements were omitted (for duplicate or conflict or whatever). What I would like to do is to add the full tree to the 'mvn site' report.
Currently, the site report includes the dependency tree but only as resolved, i.e., without any conflicts. I see in the project-info-reports plugin that there is not currently any way to do what I want using the standard report.
I tried adding a section to the pom to include the maven-dependency-plugin 'tree' goal with the outputFile specified, but it wasn't included when I ran 'mvn site'. It was something like this:
<reporting>
....
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<reportSets>
<reportSet>
<id>deptree</id>
<reports>
<report>tree</report>
</reports>
<configuration>
<verbose>true</verbose>
<outputFile>${project.reporting.outputDirectory}/deptree.txt</outputFile>
</configuration>
Of course, the 'tree' goal is explicitly identified as not a report, but I was hoping to at least be able to produce a file that I could link to from the generated site. No dice.
Is there any way to force an arbitrary plugin's goal to execute during site generation? Am I totally out of luck here? Obviously I could write my own reporting plugin to do this, and/or submit a patch for the project-info-reports plugin, but I want to make sure I've exhausted all the built-in maven options.
(I'm using maven 2.1.0, but I didn't see anything about a change to this functionality in the release notes for later versions.)
Is there any way to force an arbitrary plugin's goal to execute during site generation? Am I totally out of luck here?
Just to answer your question, you can bind a mojo to the pre-site phase of the Site Lifecycle:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>tree</id>
<phase>pre-site</phase>
<goals>
<goal>tree</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
...
</reporting>
If you then run mvn site, dependency:tree will run.

Combined site/deploy goal for Maven

When running a Maven build on the CI server, I generate the site to publish the documentation and reports, and also deploy the artifact to the snapshot repository for use by other projects. To do this I run the following goals:
mvn clean site deploy
This means the unit tests are run twice, once for the site lifecycle and once for the deploy lifecycle. If I configure the site goal to be bound to the standard lifecycle the tests are still run twice, running the site goal always causes the tests to be run because of the #requiresDependencyResolution test annotation. This is fine if you're only creating the site, but in the context of a deploy it greatly increases the build time for no benefit.
I have a workaround that involves copying the SiteMojo (and the required parents) to a new plugin and removing the #requiresDependencyResolution test annotation from the copy.
This modified mojo will generate the reports without forcing the tests to be run again but I'd prefer a solution that doesn't involve any hacking of the site plugin. Is there a way to suppress the requiresDependencyResolution annotation?
I'm surprised this works - the #requiresDependencyResolution test tag doesn't actually trigger the tests being built - that should be one of the reports that you've included. Normally, I recommend running the site and the build in separate Maven executions in CI so you can get fast feedback on your build and publish the latest site only when that succeeds.
Another alternative is to run it as mvn clean deploy site, and choose the report-only mojo for surefire-report-maven-plugin (this is usually the report that is running the tests again). This will use the previous test results. Of course, another alternative is disabling that report altogether, since you likely get those results from another source such as your CI server anyway.
My current approach is to create a new plugin with copies of the relevant types from the maven-site-plugin. These types are identical to the standard versions except for changing the type name, the goal name and the removal of the #requiresDependencyResolution test annotation.
The copied types are:
org.apache.maven.plugins.site.AbstractSiteMojo
org.apache.maven.plugins.site.AbstractSiteRenderingMojo
The parent mojos are required so Maven can process the javadoc-based annotations (this shouldn't be required for Maven 2.2.0+).
org.apache.maven.plugins.site.SiteMojo
org.apache.maven.plugins.site.SiteJarMojo
These two are copied as SiteOnlyMojo and SiteJarOnlyMojo respectively, SiteJarOnlyMojo is changed to inherit from SiteOnlyMojo . Otherwise the only changes are to change the goal namess and remove the annotation.
So SiteOnlyMojo has:
* #goal site
* #requiresDependencyResolution test
changed to:
* #goal site-only
and SiteJarOnlyMojo has:
* #goal jar
* #phase package
changed to:
* #goal jar-only
* #phase package
These types are declared in a maven-plugin project with artifactId maven-site-only-plugin with a dependency declared on the proper site plugin.
To use this I define a profile (I don't want the reports running on every execution, only when -Psite is declared on the command line) and bind it to the prepare-package phase (prior to 2.1.0, you'd have to bind it to the package phase instead).
<profile>
<id>site</id>
<build>
<plugins>
<plugin>
<artifactId>maven-site-only-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>jar-only</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<build>
<pluginManagement>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.2</version>
<executions>
<execution>
<goals>
<goal>site</goal>
<goal>deploy</goal>
</goals>
<phase>deploy</phase>
</execution>
</executions>
</plugin>
...
</plugins>
</pluginManagement>
</build>
This will automatically execute the site action when issuing a 'mvn deploy' command, as well as ensuring the testing suite is only executed once.