DEV Community

Nils
Nils

Posted on

A custom Maven Mojo to show the effective project properties

A custom Maven Mojo?!

Recently I came across the requirement to print all effective project properties during a Maven build. So, why not write a custom Mojo to do that?

I try to get more into writing custom Maven Mojos, so I created a new project and put together a simple class that accesses the current project and prints all project properties to the Maven build log in info level.

If you are interested in the code, you can head over to my GitHub and check it out: https://github.com/NilsCoding/mvn-show-settings

What I've learned in this project

Injecting the Maven project

You can annotate a field of type org.apache.maven.project.MavenProject with the @Parameter annotation and specify defaultValue = "${project}" as an annotation attribute to inject the current project as an object into the Mojo.

Dependency for MavenProject inject

Also, you need to add org.apache.maven:maven-core as a dependency to have access to MavenProject.

I've included more Maven dependencies in my mvn-show-settings project (and commented out some injects in the Mojo code) to have a starting point for extending the Mojo by using more information at build time.

Custom configuration for helper class generation

A custom Maven Mojo project needs some configuration files and a helper class, so it is highly recommeded to include org.apache.maven.plugins:maven-plugin-plugin in the build process to auto-generate those files. As a side-note, you might want to configure helpPackageName for that plugin to specify the package of the generated helper class. Otherwise, a package name will be generated from the artifact name and will result in a (maybe) unwanted package name.

Excluding generated code from Checkstyle

I've also added a custom Checkstyle configuration to my project to enforce some coding "standards". By default, all sources will be checked, which also includes the gerenated sources for the helper classes. To prevent those helper classes from being checked, you can specify which directories should be included by the Checkstyle plugin:

<sourceDirectories>
    <sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
</sourceDirectories>
Enter fullscreen mode Exit fullscreen mode

If you configure Checkstyle to be used in the reporting, then you might want to add this configuration there, too.

What's next?

I'm currently working on some other custom Maven Mojos which I will definitely publish on GitHub, too, and there will also be some interesting details on what you can actually do in custom Maven Mojos.

So, stay tuned. πŸ˜‰

Top comments (8)

Collapse
 
khmarbaise profile image
Karl Heinz Marbaise

The example project uses the maven-project in version 2.2.1 which is of 2009. That should be removed, because you are already using the maven-core (which is the right way to go). You have correctly defined them with scope provided. The maven-plugin-annotations version should be in synch with the maven-plugin-plugin version..The checkstyle part can simply solved by using excludeGeneratedSources in your plugin setup which is documented here:
maven.apache.org/plugins/maven-che...

Collapse
 
nilscoding profile image
Nils

Thank you for your detailed feedback.

I must admit that I played around with some other code before settling to the version that I've put on Github. That's also the reason why there are so many parts in the Mojo that got commented out and why I did not pay any additional attention to the dependencies.

The detail with matching the maven-plugin-annotations and maven-plugin-plugin is something that I did not know about yet, guess I found that implicitly now in the annotations documentation (and there in the code example). What I couldn't find there was how this version is related to the targeted Maven version.

And maybe I'm doing something wrong but excludeGeneratedSources for the Checkstyle plugin does not seem to work for me here. As far as I can see, the Checkstyle plugin mainly uses project.getCompileSourceRoots() which in the early invocation only points to the main source path. But in a later step during Maven execution it also contains the generated annotations and plugin folders and therefore the generated sources are included and result in Checkstyle errors.
Interestingly, this only happens with mvn install but neither with mvn package nor mvn checkstyle:check.

I just took your hints and pushed an updated version to Github to polish my example code.

Collapse
 
khmarbaise profile image
Karl Heinz Marbaise

Your welcome.

The version of maven-plugin-annotations is not related to the targeted maven version. This is more related to the used maven-core versions (or other maven-X parts).. I recommend to use at least Maven 3.6.3 as base...
If there is a problem with the mentioned excludeGeneratedSources for the checkstyle maven plugin it would be great if you could file in a jira issue.. and describe the problem and best would be a reproducer (as your own project)...

Thank for your detailed answer.

Thread Thread
 
nilscoding profile image
Nils

I tried to dig a little bit deeper into the sources of the Checkstyle plugin and even though I am not familiar with the internals of Maven Mojos (still learning about that) I might have tracked down the problem:

While AbstractCheckstyleReport.filterBuildTarget(...) honors the excludeGeneratedSources flag building the site report and CheckstyleViolationCheckMojo.filterBuildTarget(...) seems to do so, too, I took a look at the -X debug output of the Checkstyle plugin during a build and noticed lines of Added [number] source files found in [target directory], tracking this down to DefaultCheckstyleExecutor which in its getFilesToProcess(...) method does not honor the excludeGeneratedSources flag, which does not seem to be accessible to that class.

That said, it's just an educated guess on what is going wrong here, and I am neither an expert in analyzing existing Maven plugins nor in filing bugs against them, so for now I would leave that to somebody more experienced and stick with my workaround by explicitly defining the source root for Checkstyle processing.

Thread Thread
 
khmarbaise profile image
Karl Heinz Marbaise

maven.apache.org/plugins/index.html find in the list Checkstyle plugin and on the right side you will find the link to the JIRA..(registration process needed yes. because of spam).
File in the description and tests you have made (plus example project)... You are more than experienced enough, because you have found something which looks like a bug... also put in the analysis you already made into the JIRA issue...

Thread Thread
 
nilscoding profile image
Nils

While looking for similar tickets in JIRA bug tracking, I found a hint why the error was - of course - on my side: excludeGeneratedSources not only needs to be present in the configuration section, but it needs to be set to the value true (just having the tag in the pom file is not enough). I don't know why that results in the correct filtering of the source directories, because the code DefaultCheckstyleExecutor.getFilesToProcess(...) still seems to be executed, but it works as expected. Thankfully, I did not open a ticket and made a fool of myself for such a silly configuration mistake.

Collapse
 
grisha9 profile image
Grigoriy Myasoedov • Edited

This can also be done using the task: help:effective-pom
example for one build file
mvn -f build_file_path help:efficient-pom - N

Collapse
 
nilscoding profile image
Nils

Yes, displaying the effective POM can be very helpful.
Actually, my custom Maven plugin had two other use cases in mind. First, I wanted a simple example project for a custom Maven project. Second, I'm working on another plugin to modify the properties during the build, so I need a way to show the properties while Maven is running a build. But thanks for pointing out the option for displaying the effective POM.