P. 1
Better Builds With Maven

Better Builds With Maven


|Views: 9,548|Likes:
Published by anon-313500

More info:

Published by: anon-313500 on Aug 10, 2007
Copyright:Attribution Non-commercial


Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less





Releasing a project is one of the most important procedures you will perform, but it is often tedious
and error prone. While the next chapter will go into more detail about how Maven can help automate
that task and make it more reliable, this section will focus on improving the quality of the code
released, and the information released with it.

An important tool in determining whether a project is ready to be released is Clirr (http://clirr.sf.net/).
Clirr detects whether the current version of a library has introduced any binary incompatibilities with
the previous release. Catching these before a release can eliminate problems that are quite difficult to
resolve once the code is “in the wild”. An example Clirr report is shown in figure 6-13.

Figure 6-13: An example Clirr report

This is particularly important if you are building a library or framework that will be consumed by
developers outside of your own project.

Libraries will often be substituted by newer versions to obtain new features or bug fixes, but then
expected to continue working as they always have.

Because existing libraries are not recompiled every time a version is changed, there is no verification
that a library is binary-compatible – incompatibility will be discovered only when there's a failure.


Assessing Project Health with Maven

But does binary compatibility apply if you are not developing a library for external consumption? While
it may be of less importance, the answer here is clearly – yes. As a project grows, the interactions
between the project's own components will start behaving as if they were externally-linked. Different
modules may use different versions, or a quick patch may need to be made and a new version
deployed into an existing application.

This is particularly true in a Maven-based environment, where the dependency mechanism is based
on the assumption of binary compatibility between versions. While methods of marking incompatibility
are planned for future versions, Maven currently works best if any version of an artifact is backwards
compatible, back to the first release.

By default, the Clirr report shows only errors and warnings. However, you can configure the plugin to
show all informational messages, by setting the minSeverity parameter. This gives you an
overview of all the changes since the last release, even if they are binary compatible. To see this in
action, add the following to the reporting section of proficio-api/pom.xml:





If you run mvn site in proficio-api, the report will be generated in target/site/clirr-
report.html. You can obtain the same result by running the report on its own using mvn

If you run either of these commands, you'll notice that Maven reports that it is using version 0.9 of
proficio-api against which to compare (and that it is downloaded if you don't have it already):

[INFO] [clirr:clirr]
[INFO] Comparing to version: 0.9
[INFO] -------------------------------------------------------------
[INFO] -------------------------------------------------------------

This version is determined by looking for the newest release in repository, that is before the current
development version.

You can change the version used with the comparisonVersion parameter. For example, to
compare the current code to the 0.8 release, run the following command:

mvn clirr:clirr -DcomparisonVersion=0.8


Better Builds with Maven

These versions of proficio-api are retrieved from the repository, however you can see the original
sources by extracting the Code_Ch06-2.zip file.

You'll notice there are a more errors in the report, since this early development version had a different
API, and later was redesigned to make sure that version 1.0 would be more stable in the long run.

It is best to make changes earlier in the development cycle, so that fewer people are affected. The
longer poor choices remain, the harder they are to change as adoption increases. Once a version has
been released that is intended to remain binary-compatible going forward, it is almost always
preferable to deprecate an old API and add a new one, delegating the code, rather than removing or
changing the original API and breaking binary compatibility.

In this instance, you are monitoring the proficio-api component for binary compatibility changes
only. This is the most important one to check, as it will be used as the interface into the
implementation by other applications. If it is the only one that the development team will worry about
breaking, then there is no point in checking the others – it will create noise that devalues the report's
content in relation to the important components.

However, if the team is prepared to do so, it is a good idea to monitor as many components as
possible. Even if they are designed only for use inside the project, there is nothing in Java preventing
them from being used elsewhere, and it can assist in making your own project more stable.

Like all of the quality metrics, it is important to agree up front, on the acceptable incompatibilities, to
discuss and document the practices that will be used, and to check them automatically. The Clirr
plugin is also capable of automatically checking for introduced incompatibilities through the
clirr:check goal.

To add the check to the proficio-api/pom.xml file, add the following to the build section:







Assessing Project Health with Maven

If you now run mvn verify, you will see that the build fails due to the binary incompatibility
introduced between the 0.9 preview release and the final 1.0 version. Since this was an acceptable
incompatibility due to the preview nature of the 0.9 release, you can choose to exclude that from the
report by adding the following configuration to the plugin:





This will prevent failures in the Proficio class from breaking the build in the future. Note that in this
instance, it is listed only in the build configuration, so the report still lists the incompatibility. This allows
the results to be collected over time to form documentation about known incompatibilities for
applications using the library.

A limitation of this feature is that it will eliminate a class entirely, not just the one acceptable failure.
Hopefully a future version of Clirr will allow acceptable incompatibilities to be documented in the
source code, and ignored in the same way that PMD does.

With this simple setup, you can create a very useful mechanism for identifying potential release
disasters much earlier in the development process, and then act accordingly. While the topic of
designing a strong public API and maintaining binary compatibility is beyond the scope of this book,
the following articles and books can be recommended:

Evolving Java-based APIs contains a description of the problem of maintaining binary
compatibility, as well as strategies for evolving an API without breaking it.

Effective Java describes a number of practical rules that are generally helpful to writing
code in Java, and particularly so if you are designing a public API.

A similar tool to Clirr that can be used for analyzing changes between releases is JDiff. Built as a
Javadoc doclet, it takes a very different approach, taking two source trees and comparing the
differences in method signatures and Javadoc annotations. This can be useful in getting a greater
level of detail than Clirr on specific class changes. However, it will not pinpoint potential problems for
you, and so is most useful for browsing. It has a functional Maven 2 plugin, which is available at


Better Builds with Maven

You're Reading a Free Preview

/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->