Maven PMD plugin reporting not going to correct directory - maven-2

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>

Related

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

Cannot get maven2 profiles to work

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>

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>

How to run individual test in the integration-test target in maven

We have a hundreds of tests defined for our integration-test phase lifecycle in maven, and they take a long time to finish.
What I want to do is run just one test in the integration-test. I tried doing :
mvn -Dtest=<my-test> integration-test
but that does not work. The -Dtest runs only the tests in the unit test goal, not the integration-test phase. I tried the -Dintegration-test=<my-test> instead, and that was ignored.
Is there a way to do that ?
My configuration is:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>surefire-it</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>**/api/**</include>
</includes>
.....
If you're using the Maven failsafe plugin, you can run a single integration test by setting the it.test property to your fully qualified test class name:
mvn -D it.test=your.TestCase verify
See the failsafe plugin docs for more info.
The Failsafe documentation would have you specify the test like so:
mvn -Dit.test=BrokenIT verify
However, -Dit.test does not appear to work any longer. Rather, the same parameter used to specify a Surefire test will apparently work for Failsafe as well. For example:
mvn -Dtest=WorksIT verify
I've filed a bug (EDIT: which was closed as "Cannot Reproduce" in 2.12) to correct the documentation.
just add -DfailIfNoTests=false works for me with testNG. Something like this:
mvn integration-test -Dtest=aITest -DfailIfNoTests=false
I struggled through this, and I created an additional profile to use when I wanted to run just one integration test. I hope that I've successfully extracted just the right part here:
<profile>
<id>integrationTestSingle</id>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>surefire-it</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>
<include>**/integration/**/${test}.java</include>
</includes>
<skipTests>false</skipTests>
</configuration>
</execution>
</executions>
<configuration>
<argLine>-Xms256M -Xmx768M -XX:MaxPermSize=256M</argLine>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>default-test</id>
<configuration>
<skipTests>true</skipTests>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
Now, I call maven with the integrationTestSingle profile and with -DfailIfNoTests=false -Dtest=NameOfTest, and it doesn't run any of the regular tests during the regular "test" phase, and runs just the NameOfTest test during the integration-test phase.
I'm not sure about JUnit, but for TestNG the strategy would be to define a suite XML file with only the one test, and then in your POM configure the surefire plugin to only run that. In your POM, you would have something like this (disclaimer, this is untested):
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<phase>integration-test</phase>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>single-test.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
To configure the suite file, see http://testng.org/doc/documentation-main.html
Just ran into this myself. Something like this worked well for me:
mvn -Pintegration-test -Dtest=<my-test>
The trick was to ensure that the test-group was mentioned before the -Dtest portion.
I am using:
Apache Maven 3.6.3
openjdk version "11.0.2" 2019-01-15
<groupId>org.codehaus.mojo</groupId>
<artifactId>failsafe-maven-plugin</artifactId>
<version>2.4.3-alpha-1</version>
This command worked for me:
mvn failsafe:integration-test -Dsurefire.skip=true -DskipIntegrationTests=false -DskipTests=false -Dtest=com.myxyz.func.ITestGate
Was actually simpler that the answers above by going back to basics with the actual documentation.
Running Junit 5 integration tests:
openjdk version "11.0.11" 2021-04-20
Apache Maven 3.6.3
In the main build just drop in documented failsafe config:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M5</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Then you can run only a specific integration test with:
mvn -Dtest=\*cs1_\* verify
Note that this version will run your tests in the target folder and if you need to load any external files that are something like src\test\resources\x.y then they are copied to target\test-classes\x.y
This works for me, when I gonna run only one test method in integration test
mvn clean -Dit.test=some.package.SomeTestClass#testMethodName integration-test

How to get Maven to run war:exploded but not war:war

I have a Maven pom that uses <packaging>war</packaging>. But actually, I don't want build the war-file, I just want all the dependent jars collected and a full deployment directory created.
So I'm running the war:exploded goal to generate the deploy directory:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<configuration>
<webappDirectory>target/${env}/deploy</webappDirectory>
<archiveClasses>true</archiveClasses>
</configuration>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
The trouble is, the war file still gets built. Is there a simple way of having <packaging>war</packaging> execute the war:exploded goal instead of the war:war goal?
Or is there another simple way to do this?
The solution is quite simple. You need to override the default execution of the war plugin to disable it and add your own execution (for exploded):
<pluginManagement>
<plugins>
<plugin><!-- don't pack the war -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<id>default-war</id>
<phase>none</phase>
</execution>
<execution>
<id>war-exploded</id>
<phase>package</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
According builtin lifecycle bindings for war packaging in package phase war:war mojo is called.
You can call previous 'prepare-package' phase - all actions will be performed and after that call mojo war:exploded
mvn prepare-package war:exploded
The results will be the same as yours but no war created.
I would like to upgrade onto #Michael Wyraz answer and just include install skip settings in case if someone executes mvn clean install build on top level of multimodule project and one of sub-module is web application.
This stands inside war module:
<profiles>
<profile>
<id>war_explode</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>default-war</id>
<phase>none</phase>
</execution>
<execution>
<id>war-exploded</id>
<phase>package</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>default-install</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
Without install skip build fails as it tries to install war into .m2 folder. Error message looks like this:
[INFO] --- maven-install-plugin:2.4:install (default-install) # *** ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-install-plugin:2.4:install (default-install) on project ***: The packaging for this project did not assign a file to the build artifact -> [Help 1]
Executing mvn clean install -P war_explode with this settings (enclosed in maven profile named war_explode) it finishes build without error.
The only way I can think of to do what you want is to set use pom packaging (or create a custom packaging) and bind the required goals from the war packaging to the relevant phases of the lifecycle. If you go for pom packaging you can use define the war:war execution in a profile to allow you to package it, but you'll need to use the build-helper-maven-plugin attach-artifact goal to attach the war to the pom.
Note with this approach if you want to use any other war-specific processing it may cause you problems.
The lifecycle bindings for war packaging are listed in the Introduction to The Build Lifecycle (see the "Default Lifecycle Bindings - Packaging ejb / ejb3 / jar / par / rar / war" section).
To bind the relevant plugin executions to the pom packaging you would do as follows:
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>process-resources</id>
<phase>process-resources</phase>
<goals>
<goal>resources</goal>
</goal>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compile-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goal>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>process-test-resources</id>
<phase>process-test-resources</phase>
<goals>
<goal>testResources</goal>
</goal>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goal>
</execution>
</executions>
</plugin>
<!-- package not wanted, install and deploy already defined for pom packaging-->
<!--define war:war execution in a profile in case it is needed-->
As far as I know (I'm still new to maven) this is not possible. The only default lifecycle you can skip is 'test'. In order to get to the deploy you have to package. You can read all about the default lifecycle order of execution here: http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference