Category Archives: Build Processes

Is findbugs-maven-plugin onlyAnalyze broken?

I cannot seem to get onlyAnalyze working for my multi-module project: regardless of what package (or pattern) I set, maven-findbugs-plugin either parses everything or nothing and it doesn’t evaluate sub-packages as I’d expect from passing it packagename.*.

To prove either myself or the plugin at fault (though I always assume it’s the former!), I setup a small Maven project with the following structure:


pom.xml
src/
main/java/acme/App.java
main/java/acme/moo/App.java
main/java/no_detect/App.java

which is very simple!

The POM has the following findbugs configuration:

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>findbugs-maven-plugin</artifactId>
                <version>2.4.0</version>
                <executions>
                    <execution>
                        <phase>verify</phase>
                        <goals><goal>findbugs</goal><goal>check</goal></goals>
                    </execution>
                </executions>
                <configuration>
                    <debug>true</debug>
                    <effort>Max</effort>
                    <threshold>Low</threshold>
                    <onlyAnalyze>acme.*</onlyAnalyze>
                </configuration>
            </plugin>
        </plugins>
    </build>

and every App.java has the following code with two obvious violations:


package acme;
import java.io.Serializable;

public class App implements Serializable
{
private static final class NotSer {
private String meh = "meh";
}

private static final NotSer ns = new NotSer();// Violation: not serializable field

public static void main( String[] args )
{
ns.meh = "hehehe";// Vilation: unused
System.out.println( "Hello World!" );
}
}

Note that no_detect.App has the same content as above, but my expectation is that it wouldn’t be
evaluated by findbugs because I have the “onlyAnalyze” option set to acme.* which I assume would
evaluate acme.App and acme.moo.App and nothing else.

I now execute a mvn clean install to clean, build, test, run findbugs, package, install, which
produces the following findbugs report (snipped for brevity) and results in a build failure which is expected
because acme.App and acme.moo.App:


<BugInstance category='BAD_PRACTICE' type='SE_NO_SERIALVERSIONID' instanceOccurrenceMax='0'>
<ShortMessage>Class is Serializable, but doesn't define serialVersionUID</ShortMessage>
<LongMessage>acme.App is Serializable; consider declaring a serialVersionUID</LongMessage>
<Details>
<p> This field is never read.&nbsp; Consider removing it from the class.</p>
</Details>
<BugPattern category='BAD_PRACTICE' abbrev='SnVI' type='SE_NO_SERIALVERSIONID'><ShortDescription>Class is Serializable, but doesn't define serialVersionUID</ShortDescription><Details>
<BugCode abbrev='UrF'><Description>Unread field</Description></BugCode><BugCode abbrev='SnVI'><Description>Serializable class with no Version ID</Description></BugCode>

To summarise: only acme.App is analysed, acme.moo.App (bad) isn’t and neither is
no_detect.App (good).

I tried with two wildcards in the onlyAnalyze option but that produces a **successful build** but
with a findbugs error (Dangling meta character '*' etc).

I tried with onlyAnalyze set to acme.*,acme.moo.* which analyzes all the expected
classes (acme.App and acme.moo.App) which means it “works” but not as I expect; i.e. I have to explicitly declare all parent-packages for the classes I want to analyze: that could get large and difficult to maintain on a multi-module project!

Must. Keep. Trying.

Notes on Maven vs Ant

The Problem

Do you have lack of consistency and understanding how your software is built? Does this equal varying degrees of success – both in each build and in changing or adding new features to it – and lack of confidence from your developers?

Did you roll your own build process that’s "the best thing since sliced bread" but only a select few developers really know how to use it? Do you dedicate resource to tweaking or fixing your build scripts?

To put it another way: are all your developers building the software using the same scripts your continuous integration environment is using?

What’s Wrong with the Above?

I believe building software should not be a complex process. It should be rare for a developer to delve into the build system to tweak it.

I also believe that because there are common parts to building – source code, tests, packaging – that there is little need for a "shop" to be going it alone and building something vanilla just because they can.

Essentially, building software comes down to performing a few tasks regularly and consistently; a developer will need to build, test and package regularly. Rarely do they need to work on the build system (unless something’s broken…).

With this in mind, should developers therefore not be able to perform these tasks without thinking about it? Wouldn’t it be beneficial to us all – as an industry even – to be able to go anywhere and build most software the same way because the requirements for building doesn’t differ?

I’m not making a case for never "rolling your own", I’m merely trying to clarify that those who do may not need to do so. Granted, some scenarios warrant custom build scripts and the like.

The Ant Perspective

With Ant, building means code. It means logic and that invariably doesn’t get the same strictness and quality applied to it like your everday Java and its counterparts. This means the build scripts quickly become convoluted, poorly maintained due to a "get it working" attitude. Unless a good/strong developer is dedicated to maintaining and scaling the build scripts, the job gets shared around and each unique developer’s perspective warps the overall goal.

Most software building is just a set of tasks that are repeated for each build. Compile this. Package this. Distribute that. It doesn’t make sense to have a human do that: computers are here to do the mundane stuff.

The Maven Perspective

With Maven, you just provide metadata. The framework provides the logic in a consistent and predictable manner.Don’t you want developers to be concentrating on writing code: fixing bugs, implementing new functionality and improving the quality of the product.

Maven allows one to have artefacts produced properly, with correct structure, metadata and naming conventions, that mean a developer – or person – doesn’t have to think to do it. These artefacts are of production quality, always.

Consistency

Consistency means one does not have to think about how or what they’re going to do when it comes to the build process.

If you’re a foreman building me a house and I say "build it this way please" and hand you a 3000 page instruction manual on how the Tudors and Stuarts built their houses prior to the great fire of London, you don’t say "Yeah sure!" you recoil because years of history and experience has taught you otherwise.

Is it fair to say that developers need to spend time fixing bugs and implementing new features and not spending time tweaking the bugs in the build system? Would you be happy to pay for a plumber to spend time fixing his toolbox instead of correcting that leak? If this isn’t acceptable, then you can understand why businesses might not want to spend the time (money) correcting your poor house keeping.

Quality Across the Board

Consistency breeds quality. A scenario where best practice is common, reliable and well-established norms are instinct encourages going the extra mile to write better software. In contrast, an unreliable, poorly designed and maintained mode of practice breeds contempt. Building your software is part of all of this and is a contributor to success or failure.

I’m by no means saying "blame your tools", just that better-quality tools can contribute to improved output.

Environments are a Different Beast

Environments have numerous issues whereas development seems fine; "Works for me" is far too common a response for when someone has to investigate a problem in a given deployment target.

The big wins with Maven

  • Consistency across the board. It shouldn’t matter where you go or what customer project you’re on, you build, deploy, package and distribute artefacts the same way. Imagine a situation where developers can go anywhere and "pick up where they left off": start developing within minutes.

  • Junit testing – maven bakes testing from the beginning, which brings it to the developer’s mindset at the right points (i.e. always)

  • Greatly simplifies build processes: it doesn’t become a matter of how, but when. Developers learn a simple set of commands that never changes

  • Dependency management is excellent: simplifies set up of projects, developers can get up-and-running within minutes

  • Packaging is excellent. Multiple formats supported, from JARs, EARs to Zip, TAR etc and it is not left to the understanding and implementation of the developer implementing the build script

  • Industry recognised: we don’t have to have developers "get up to speed" because maven works the same everywhere, developers just remember a few goals to tell maven what to do: compile, clean, test, package and they’re ready to start coding

  • Have your developers building code and understanding how it’s built, not programming by coincidence. Don’t be in a position where your developers are relying on their IDE to build and having a separate process entirely for your CI!

You wouldn’t build a palace with breeze blocks

I strongly believe that if you want to build awesome software, then every aspect of it needs to be as good as you want the final product to be.

It is often the case that aged software shops will have put in place aspects of their software that they’ll “revisit later on”, which then doesn’t happen.

It gets lost to the crowd of “more important things to do”.

One of the most common neglects I see is how a shop will build, deploy and distribute its software. At best their solution is amateur. It’s usually home-baked and rigged with esoteric and often superfluous tasks and features that are “necessary” due to some poor design decision made previously. The build system — be it continuous integration or some poor sod in the corner — has to do 30 different things, copy 11 thousand files, just to compile the few.

And so the problem persists; the rot festers; the software continues to be sub-par and so do the profit margins.

I feel that if you start from the ground-up, that you build consistently and efficiently then your software becomes such. If it is easy for a developer to build and deploy or distribute your software, it’s then easy for them to do their job. Any developer knows the pains they’ll go through day-to-day when making a change that requires a 15-minute rebuild and 5 minute deployment wait just to check the first name field doesn’t fall over on a null pointer.

With poor practice comes poor software comes poor profit.

So if you’re heading up a development shop and your developers are crying for a more efficient, simpler, consistent build process, then heed their recommendations and concerns. Let them spend the time and money streamlining how they work, because you’ll get reliability, efficiency and less coffee breaks if you do.

Would you pay for that shiny new tablet PC if it came packaged in A4 paper?

How disappointed do you feel with a product when you hold it and you “know” its build quality is poor.

Why is software any different?

You wouldn’t build a palace with breeze blocks.

Ant TODO gets some love

Updated: I’ve added another item to the implemented features below…

Yonks ago I spent an afternoon hacking together a TODO task for Apache Ant; the result of which was Ant TODO.

Now, I hadn’t touched it in a while until a user emailed me asking for some help and some nifty new features. Having returned home from a weekend away with a few hours spare I decided to implement the following:

  1. allow for setting of results to an Ant property, instead of to a file or so-on
  2. support a custom delimiter string for each item
  3. call Ant TODO after JAR’ing Ant TODO (chicken, meet egg)
  4. numerous housekeeping tasks, such as a little refactoring and better test data

You can download the latest version if you like. Feel free to contribute too.

Apache Ant & FTP timeout

Having spent a considerable amount of time hacking a new temporary build system together at my new workplace, we were nearing the end of our initial aim. One feature of the development processes they run here is the continuous deployment to the test servers, which is a very good place to be. Our overall goal was to decouple ourselves from the wider development team to allow for more control and flexibility over our build tools and processes.

We’re moving from Visual Build Professional to a more industry-recognisable stack: Apache Ant, Jenkins/Hudson and deployment included within the Ant build scripts via separated targets. This latter requirement was a little cumbersome using the built-in FTP task of Ant.

After writing the FTP task calls in our target, we noticed that when testing on the target build server that the FTP was timing out. To rub salt in the wound, it transpired that the Apache Ant FTP tasks do not allow for setting the timeout. If you want such functionality, you’ll need to duplicate the FTP task itself and add a simple setDataTimeout call, or use an alternative client (or fix the bug!). Whilst brainstorming ideas, a colleague and I discovered that using timeout for Ant FTP connections might not even be necessary if you use the passive=”yes” attribute; as the task’s documentation says:

selects passive-mode (“yes”) transfers, for better through-firewall connectivity, at the price of performance. Defaults to “no”

Doing so on our build made it lightening fast and we no longer suffered from timeout issues.