Getting Under The Hood
When faced with a maven "that's not supposed to happen" problem, the spartan nature of maven's project object module (pom) files doesn't show why maven configured a classpath without an essential library or created an empty distribution zip file. Perhaps, if we knew the convention really well, it would be obvious. However, making me feel stupid probably isn't maven's design goal so we've got tools to shed light our problem:
- Effective Pom
- Debug output "-X"
- Source code for the plugin
Effective Pom - Discovering Maven's Intent
Prior to building, maven combines your project's pom with its ancestor poms and the default super pom. We can generate this effective pom and use it to see all the properties and set configuration options.mvn help:effective-pom > epom.txt
Maven supports grouping configuration settings into build profiles. You can activate profiles for any maven command by adding "-P profileId" to the command. For example, you may have a distribution profile which copies additional content to create an installer. We'd generate the effective pom thus to capture all of that distribution goodness:
mvn -P distribution help:effective-pom > epom.txt
The command activates "distribution" profile and runs the "effective-pom" goal for "help" plugin. Plugins provide goals which maven executes at build time. You can execute goals for plugins manually by adding <plugin>:<goal> to the command line.
The effective-pom resolves all properties and shows executions of plugin goals. This information can point to why maven didn't behave as expected and enable you to review pom ancestry to see where a value was set or what properties you need to enable to change build execution.
The effective-pom resolves all properties and shows executions of plugin goals. This information can point to why maven didn't behave as expected and enable you to review pom ancestry to see where a value was set or what properties you need to enable to change build execution.
Debug - Discovering What Maven's Up To
Adding "-X" to a maven command switches on a torrent of debug messages. Maven produces way too much information but we can tame the flood thus:
- Run maven command using standard debugging a direct output to a file:
mvn install > mvn.log
- Run command with debug and direct output to a file:
mvn -X install > debug.log
- Find the area of interest in mvn.log and locate a nice unique looking string
- Search for that string in the debug.log. Scan back and forward to tease out:
- Additional properties which control behavior
- Full text of the command line invocation (e.g., javac tool compiles java source into byte code and debug output shows all options, environment variables and classpath settings - except when it doesn't)
Review source code for the plugin
Stop:
If you've got this far you either face a massive challenge or should reconsider your approach. Extreme difficulty can indicate time for me to rethink my strategy. Great challenges and/or wrong headed attempts are best done after a short walk, cup of coffee or some other way to disengage mentally. The re-coupling of my mind to the problem may result in an insight that allows me to side step the intractable problem.
The majority of maven plugins generate a maven web site with documentation and source downloads. You can download the source, import it into eclipse via m2e and take a walk through it looking for some of those keyword or properties found in the debug log. I found this necessary to understand the maven-native-plugin's use of environment and registry settings for windows compilers. I didn't discover a bug, but I did learn how the plugin interacted with Microsoft tools and eventually found the proper environment variables to set
Afterthoughts
Maven does a good job of providing standard ways to handle build and release complexity. In the simple case, maven reduces duplication and needless wheel reinvention. Debug and effective pom help us to crack open maven's encapsulation and deepen our understanding of the problem. Reading up on maven helped me to better understand the nuances of the convention.Finally, I create tiny maven projects via maven quickstart archetype so I can test theories. I work on 100+ project multi-module builds with many plugins and much custom build logic. If I need to explore how a plugin functions, I want the simplest and quickest environment in which to test. I can either select a simple project within main build or create a tiny quickstart build. I want the time from idea to result as short as possible. A 5 minute loop per idea provides less chances to tinker than a 20 second loop. I try to choose the path that seems the simplest to create and then iterate through the problem.
I hope this was of use to you.