Fail Maven build if Maven property is not aligned to convention - java

Maven properties in pom.xml of Java repos have to be aligned to some convention for CI processes to work correctly.
For example:
<app-name.prop-name-version>X.X.X.X</app-name-version.prop-name-version>
Is there a way to fail maven builds if maven property is not aligned to convention?
I thought about developing maven plugin from scratch, but is there another way?

Maven Enforcer Plugin exactly does what you need. That has a lot of built-in rules like Require Property
According the documentation this rule can enforce the declared property is set and optionally fits for a regex rule.
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<executions>
<execution>
<id>enforce-property</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireProperty>
<property>app-name.prop-name-version</property>
<message>"Project version must be specified."</message>
<regex>.*[...]$</regex>
<regexMessage>"Invalid format."</regexMessage>
</requireProperty>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>

Related

Configuring the maven java-docs plugin for multi module projects(Aggregate)

I would like to set up the maven java-docs plugin in my project to create an aggregated report that includes only some classes from some of the modules and output the report to a folder of choice.
I have already tried to work with the Maven documentation here however whats indicated there does not seem to work for me.
I have tried the following configuration in the past and ran it as:
mvn javadoc:javadoc, or even javadoc:aggregate with the following parent/child pom configurations:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.0</version>
<inherited>false</inherited>
<configuration>
<!-- Default configuration for all reports -->
</configuration>
<executions>
<execution>
<id>aggregate</id>
<goals>
<goal>aggregate</goal>
</goals>
<phase>package</phase>
<configuration>
</configuration>
</execution>
</executions>
</plugin>
I have used something like this in the past:
parent pom.xml
<pluginManagement>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</pluginManagement>
...
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<!-- Default configuration for all reports -->
</configuration>
<executions>
<execution>
<id>aggregate</id>
<goals>
<goal>aggregate</goal>
</goals>
<phase>site</phase>
<configuration>
<skip>false</skip>
</configuration>
</execution>
</executions>
</plugin>
</build>
Desired child module pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<skip>false</skip>
<noqualifier>all</noqualifier>
<sourceFileIncludes>
<include>**\/\Class1.java</include>
<include>**\/\Class2.java</include>
<include>**\/\Interface3.java</include>
<include>**\/\Class4.java</include>
</sourceFileIncludes>
<reportOutputDirectory>${project.parent.basedir}/..</reportOutputDirectory>
<destDir>java-docs</destDir>
</configuration>
</plugin>
</plugins>
</build>
This configuration works fine if I am only generating from one single module, however once another child module is picked and configured as the one shown before, running mvn javadoc:aggregate continues to generate the docs for module 1 only, and module 2 gets ignored(or maybe even overriden)
Has anyone worked with a similar scenario, a multi module project structured like so:
ParentFolder
. . . module1
pom.xml
. . . module3
pom.xml
. . . module4
pom.xml
pom.xml
and have succeeded generating an aggregated java docs report using the maven java docs plugin, while excluding some classes and outputting the results to a folder of their choice?
Any help with this would be greatly appreciated!
Do you have one parent POM that contains both plugin config for the child POMs, and module definitions? If so, you may want to consider separating this POM into a separate aggregator (module definitions) and parent (anything else in the current POM that should be shared with children).
This answer goes into a lot more detail about Maven build order and why the behavior occurs.
The aggregator POM will also hold the configuration for child module data that should be aggregated, such as Javadoc.

Prevent maven module from being built with no activated profile

I have a multi-module maven project with parent POM. One child of project is customized for different environments by profiles and parent pom also build needed modules depending on selected environment (profile).
I want to prevent building (read as "to run mvn package" in child module) customized child project without profile activated, because there is no "generic" or "default" version for environment. Another words, I want to force developer to use environment-dependent profile.
Is it possible to do so?
Maven Enforcer is made just for this requirement. Simply add the required profiles.
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>enforce-all-profiles-are-activated</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireActiveProfile>
<profiles>first,second</profiles>
</requireActiveProfile>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>

JavaDoc will not publish on jenkins

I have an aggregator project built in jenkins and I want to publish javadocs. So I installed javadoc plugin and changed my parent pom as follows:
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<aggregate>true</aggregate>
<outputDirectory>${project.build.directory}/apidocs</outputDirectory>
</configuration>
I tried different configurations but this is the only one that won't fail the build. With this configuration the build doesn't fail but no javadocs are to be found. Am I missing something here? Does anyone has the same problem?
First you should use the aggregate goal instead of the parameter cause it's marked deprecated.
Furthermore you should configure javadoc plugin like the following in your root pom like this:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<!-- Default configuration for all reports -->
...
</configuration>
<executions>
<execution>
<id>aggregate</id>
<goals>
<goal>aggregate</goal>
</goals>
<phase>package</phase>
<configuration>
<!-- Specific configuration for the aggregate report -->
...
</configuration>
</execution>
...
</executions>
</plugin>
...
</plugins>
</build>
...
</project>
Afterwards you should be able just by:
mvn clean package
This will result in a folder in the root target/apidoc which contains the created aggregated javadocs.
I found a way to publish the javadocs as .jar. I used the above pom configuration with the small change:
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
It publishes javadocs as .jars for every sub-module. The javadocs are to be found in the sub-module directory not in the parent directory.

maven checkstyle unable to find where to insert the includes configuration

We have a maven project where I use a checkstyle plugin in the build process and we are very fond of checkstyle. Anyway recently we need to insert web services to our project. The web services classes are not compatible with checkstyle so we want to exclude them when building. So as a way of exclude we want to specify the folders to be included.
I have come across maven.checkstyle.includes and sourceDirectory of checkstyle plugin. But I could not be able to figure out how to use them in pom.xml.
Anyone have an idea?
Here is my checkstyle section of pom.xml
<build>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<failsOnError>true</failsOnError>
<consoleOutput>true</consoleOutput>
<configLocation>sample_config.xml</configLocation>
<sourceDirectory>${maven.checkstyle.includes}</sourceDirectory>
</configuration>
</plugin>
...
</build>
<excludes>my/package/**/*</excludes>
Add this to your configuration section. These are ant style patterns and you can give the plugin multiple patterns by separating them with a comma.

Setup Java 6 annotation processing configuration for eclipse compiler with maven

What's the best way to setup the eclipse project compiler configuration for Java 6 annotation processors?
My solution is to setup the org.eclipse.jdt.apt.core.prefs and factorypath files manually. This is a bit cumbersome:
Reference the processor jar in the factorypath file
Configure the eclipse annotation processor output directory (org.eclipse.jdt.apt.genSrcDir property in org.eclipse.jdt.apt.core.prefs)
Add the eclipse annotation processor output directory as source folder
One problem is that eclipse generated sources will be compiled with maven. Only maven clean compile is reliable as it removes the eclipse generated source files. (Eclipse and javac generated source files could be out of sync.)
Is there are better solution to configure maven without eclipse generated source files at the maven source path?
<project>
<properties>
<eclipse.generated.src>${project.build.directory}/eclipse</eclipse.generated.src>
</properties>
<build>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals> <goal>add-source</goal> </goals>
<configuration>
<sources>
<source>${eclipse.generated.src}</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<additionalConfig>
<file> <name>.factorypath</name>
<content><![CDATA[<factorypath>
<factorypathentry kind="VARJAR" id="M2_REPO/processor/processor.jar" enabled="true" runInBatchMode="false"/>
</factorypath>
]]> </content>
</file>
<file>
<name>.settings/org.eclipse.jdt.apt.core.prefs</name>
<content><![CDATA[
eclipse.preferences.version=1
org.eclipse.jdt.apt.aptEnabled=true
org.eclipse.jdt.apt.genSrcDir=${eclipse.generated.src}
org.eclipse.jdt.apt.reconcileEnabled=true
]]> </content>
</file>
</additionalConfig>
</configuration>
</plugin>
</plugins>
</build>
</project>
Update: You could try using the apt-maven-plugin. It currently provides three goals:
apt-process Executes apt on project sources.
apt:test-process Executes apt on project test sources.
apt:eclipse Generates Eclipse files for apt integration.
You can configure the goals to run as part of your build as follows:
<build>
...
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<goals>
<goal>process</goal>
<goal>test-process</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build>
By default the output directory is set to ${project.build.directory}/generated-sources/apt,
There is an open Jira against the compiler plugin to add APT support for Java 6, you can go and vote for it if this is something you want to to see in future versions.
I am using http://code.google.com/p/maven-annotation-plugin/ wich is simpler to configure. You can use it in two ways:
generate sources during compilation (configuration below)
generate sources "by hand" to src/main/generated and keep them on SCM
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<compilerArguments>-encoding ${project.build.sourceEncoding}</compilerArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<executions>
<execution>
<id>process-test</id>
<goals>
<goal>process-test</goal>
</goals>
<phase>generate-test-sources</phase>
<configuration>
<compilerArguments>-encoding ${project.build.sourceEncoding}</compilerArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>${project.build.sourceEncoding}</encoding>
<!-- Disable annotation processors during normal compilation -->
<compilerArgument>-proc:none</compilerArgument>
</configuration>
</plugin>
There is a simpler solution in Eclipse Juno (I'm not sure about previous versions). In Preferences / Maven / Annotation Processing there are three modes for annotation processing. It is disabled by default, but I've tested both other options and worked like a charm for me. This way, you don't need to configure APT processing for every project or modify its pom.xml.

Categories