Checking architecture conformance or complexity thresholds at build time is easy to set up with the Structure101 Maven Plugin – this is a step-by-step guide, discussing some options along the way.
Firstly, in determining where to integrate the plugin, I first need to answer two questions:
1. At what phase do I want Structure101 architectural violations to break my Maven build?
2. What type of Structure101 project have I configured, or should I configure?
In some ways, these questions are interconnected, as the phase you want to break to build can affect what project type you use, and vice-versa.
Recently, the Maven project type was added to the Structure101 for Java client. This simply requires the user to point at a root pom file and all JARS generated by the Maven build are discovered automatically, irrespective of build number or filename, and as a result there is no manual searching for JAR files by the user required. Very handy. To use this project type in the Structure101 Maven Plugin, it is recommended you use the integration-test phase, as this is called after the package phase, which is required to build the JARS, and the Maven project type by definition will search for generated JARS.
So, to answer the two questions above, 1) integration-test, and 2) Structure101 for Java Maven project.
Traditionally, the Structure101 for Java client asked users to enter a static classpath manually, and this is still supported. In this case the project file contains a list of classpaths (class folders and/or JARs) that are static, in the sense they are not discovered later in the process like in a Maven project, but they CAN be overridden by the Maven plugin. Recently, a customer chose this mechanism to break their Maven build by using a static classpath project, overriding the classpaths in the Maven plugin pom section, and they used the process-classes phase to perform violation checking. The main reason they did this was because they did not want to create the JARS, and didn’t want to proceed beyond the process-classes phase.
So, to answer the two questions above in this case, 1) process-classes, and 2) Structure101 for Java Static classpath project (with the option of overriding classpaths in the pom file).
So, I now have two recommended, tried and tested, configurations:
1. When using integration-test phase, use a Structure101 for Java Maven project (if a POM is available, else configure a Static Classpath project in the Structure101 for Java client when setting up a project)
Figure 1: Select Maven for project type in Structure101 for Java
Figure 2: Select the root pom for the Maven project
2. When using process-classes phase, use a Structure101 for Java Static Classpath project (as JARS not available to use a Maven project in the Structure101 for Java client )
Figure 3: Select Static classpath in Structure101 for Java
Figure 4: Select class folders and archives for the Static classpath project
I will talk about integrating into these phases soon, but let us first decide on which level I wish to integrate.
Configuring Structure101-Maven-Plugin in the root POM
If the plugin is integrated in the root POM, the plugin will be invoked for every sub-module. This may be fine, but if it is a large scale codebase invoking this plugin for each sub-module may be time consuming and it is worth considering a delay in checking, and using a dedicated Structure101 module (discussed in next section), if you feel there may be a build performance hit.
The slight advantage of configuring the plugin in the root pom is: when a violation is discovered in a sub-module, the build fails immediately. Whereas, delaying the checking until a Structure101 module means that the build effectively completes for each sub-module (with or without violations) until the Structure101 module is invoked.
One thing to be aware of when configuring the plugin in the root pom is, to catch violations between this module and another module, hide-externals in the project file (defined by a local-project property) must be false. If it is enabled (true), only internal violations within each module will be detected.
To configure the plugin in your root pom, refer to online help.
Configuring Structure101-Maven-Plugin in a Structure101 module
Where I decide I want to delay violation checking until compilation has completed, I can use a dedicated Structure101 module. This is a child module of the root pom, contains only the Strucure101 Maven Plugin configuration, and has dependencies on its sibling modules. For example, level1 and level2 are siblings:
<dependencies>
<dependency>
<groupId>com.headway</groupId>
<artifactId>level1</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.headway</groupId>
<artifactId>level2</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
As previously mentioned, and with this Structure101 module having dependencies on its sibling modules, this module will be invoked last by the root pom, and once invoked it can do a once-off violation check across all modules, detecting inter-module violations without the requirement for setting hide-externals to false.
To configure the plugin in your Structure101 module’s pom, refer to online help.
Integrating at the integration-test phase
At the integration-test phase, JARS have been generated. In this case it is possible to use the Maven or Static Classpath project type for your local-project.
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>check-architecture</goal>
</goals>
</execution>
</executions>
The local-project parameter refers to a path to a Structure101 for Java project file, which can be a Maven or Static Classpath project type. In here you can define properties like externals, detail mode, and default classpath/project settings.
<localProject>C:/Documents and Settings/user/mavenEclipseTest.java.hsp</localProject>
See online help for more detail on plugin parameters and available goals.
Figure 5: Maven build failing when Structure101 Maven Plugin detects a violation (using mvn integration-test)
Integrating at the process-classes phase
At the process-classes phase, JARS have NOT been generated. In this case it is only possible to use the Static Classpath project type for your local-project.
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>check-architecture</goal>
</goals>
</execution>
</executions>
The local-project parameter is a Structure101 for Java project file. In here you can define properties like externals, detail mode, and default classpath settings.
<localProject>C:/Documents and Settings/user/mavenEclipseTest.java.hsp</localProject>
Since this local-project can just provide defaults, it is possible to override the classpath to your build machine’s configuration by adding a classpath parameter to point to your module output directories (separated by the OS’s path separator). For example:
<classpath>${basedir}/../level1/target/classes;${basedir}/../level2/target/classes</classpath>
Trying to override the classpath for a Maven project type has no effect, as the Structure101 for Java Maven project type searches for JARS each time.
See online help for more detail on plugin parameters and available goals.
Figure 6: Maven build failed when Structure101 Maven Plugin detects a violation (using mvn process-classes)
Summary
This was just a brief summary on integrating Structure101-Maven-Plugin into your build environment, and it complements the online help already available here.
For more information please contact us, and we will be more than happy to help you to catch those architectural violations at build time.
Leave a Reply