Java Development Tools

This article covers the tools I use during java development. The first section covers the tool types and the choices available, with subsequent sections focusing on some of my tools of choice and the extensions that I find useful with them.

Tool Types

Shell

Bash is the most common shell, although Zsh is becoming a very popular alternative. If you are on a windows platform then Cygwin can be configured to run either shell.

Version Control System (VCS)

Subversion is the defacto standard free, open source, centralised version control system. More recently there has been an increase in distributed version control systems, such as my preferred choice of Git. DVCS has more standing in open source circles and will undoubtedly find its way into the corporate environment over time.

Other VCSs of note are the venerable CVS, which is now largely succeeded by Subversion, and other DVCSs such as Mercurial and Bazaar.

Visualisation of the repositories is also important and can often be overlooked. Most VCSs have a number of web enablement tools that give minimal visualisation of the repository in the browser. Fisheye is a good choice if you need something a little more advanced and most of the Project Management tools have some form of repository viewer also.

Integrated Development Environment (IDE)

Eclipse is (arguably) the best free, open source, cross platform IDE for Java. Another popular free IDE is Netbeans and there is a fantastic commercial IDE called IntelliJ Idea which I would use if I worked somewhere that would buy it.

Build

Maven is a software project management tool that is capable of building applications from project descriptors. It has an extensible plugin architecture and favours convention over configuration with a good solid project structure that most projects should be able to easily adopt. Maven introduced library dependency resolution and was a great force in pushing forward standardised repositories of java libraries, and since then many other tools have taken advantage of this work.

As with any such tool, it comes with its advantages and disadvantages. Having maintained a number of large projects, maven can simplify the maintenance considerably when compared to some of the monolithic ant scripts that predated it. That said, some prefer the absolute control over every aspect of the build that ant gives, and there are newer tools in the area such as gradle or buildr that are worth exploring.

To make full use of maven, a corporate repository server should be considered to both act as a proxy for external artifacts and house any internally published artifacts. Artifactory and Archiva are the predominate tools for this.

Automated Testing

Most projects advocate a test driven development (TDD) approach although this is starting to be superseded by behaviour driven development (BDD). BDD is a refinement of TDD (some would say its ‘TDD done the right way’) where the focus is on expected behaviour and more suitable use of vocabulary that stakeholders can relate to. Regardless of the approach, testing automation is critical to ensure that the testing occurs frequently and consistently.

Although the following tools have their sweet spots, most can be used with different methodologies and at different levels of testing as deemed most appropriate by the project and the resources available.

JUnit is the defacto standard for unit testing and the corner stone of test driven development. Other frameworks have come and gone, with their stronger points being assimilated into JUnit over time. TestNG is a good direct replacement should you want one.

Cucumber via Cuke4Duke is a ruby based BDD tool that allows behaviour to be defined in plain text. Another is JBehave which is a pure java BDD tool that gave inspiration to the BDD movement.

To unit test effectively, you often need to inject dependencies and observe how the object under scrutiny interacts with it. Test Doubles are designed for this purpose, the most popular being stubs, spies and mocks. Unfortunately, in java circles it is common for the term mock to represent any of the different types of test doubles. My favourite library is Mockito, but there are others such as EasyMock and JMock.

Another important aspect of testing is knowing how complete your testing is. Whilst 100% test coverage is somewhat utopian, test coverage tools can certainly help ensure you are aware of the limitations of your testing and that due attention is given to the more critical areas. Tools in this area are Cobertura, EMMA and Clover.

Some areas require more specialised frameworks. DBUnit is great for database integration testing, Selenium for web application functional testing, JMeter for load testing.

Continual Integration

Hudson is a great continual integration server that is simple and extensible through various plugins. Other notable alternatives are CruiseControl, Continuum, and Bamboo

Project Management (Issue Tracking and Documentation)

Project Management (also known as Application Lifecycle Management) tools typically provide issue tracking and documentation repositories. They allow knowledge to be authored, collaborated on, shared and tracked throughout the lifecycle of a project.

Atlassian has a suite of tools that can be “pick and mixed” to suit needs. Jira provides issue tracking, Greenhopper extends Jira to provide agile features, Confluence for wiki and collaboration, and Fisheye for source repository visualisation. With the Get started for $10 initiative, you can get all these for $40 for up to 10 people.

Some good all round free, open source choice are Trac and Redmine.

Quality Standard Tools

There are a number of tools that can help ensure a particular quality standard is met and maintained. I use the following:

All of the above tools have maven and eclipse plugins available so they can be used at coding time.

Sonar is quality standards web app that will use many of the above tools and more to build a comprehensive report that can be drilled into. This is very useful when integrated into the continual integration process and refreshed on a regular basis.

Eclipse

I use the JEE distribution of Eclipse, although I tend to spend most of my time in the standard Java perspective or Debug perspective. Like most IDEs, Eclipse has an extensive range of plugins to customise it as required.

Plugins

The following sub-sections cover the plugins I use on most projects. They are available in the eclipse marketplace unless otherwise stated.

Mylyn

Mylyn is a framework for integrating to ALMs (Application Lifecycle Management). There are connectors available for bugzilla and trac in the standard install and jira in a plugin maintained by atlassian.

AnyEdit

AnyEdit contains improvements over the standard editor preferences.

Subversive

Subversive provides subversion integration. I recommend the SVNKit connector when prompted as part of the installation process.

Additionally, add *.svn to the filtered resources in the preferences under Java -> Compiler -> Building -> Output folder to ensure that you don’t get subversion working files in your output folders.

Task Tag Decorator

Task Tag Decorator finds keywords (e.g. “TODO”, “FIXME”) in your source code and highlights them on the package explorer view. It can be downloaded from the update site at http://www.krupets.com/ttd/update/.

m2eclipse

m2eclipse provides maven integration.

Jadclipse

Jadclipse provides integration of Jad, a java decompiler. It can be downloaded from the update site at http://jadclipse.sourceforge.net/update/.

EclipseCS

EclipseCS provides integration with checkstyle, showing violations in the editor view as they occur.

FindBugs

Findbugs project provides their own eclipse plugin.

PMD

PMD project also provides their own eclipse plugin.

eCobertura

eCobertura provides integration with cobertura, showing coverage reports within the IDE.

SpringSource Tool Suite

SpringSource Tool Suite provides a number of extensions that make working with spring easier.

Aptana Studio

Aptana Studio 3 provides a number of extensions that make working with web technologies easier (e.g. javascript, ruby, git). It can be downloaded from the update site at http://download.aptana.com/studio3/plugin/install.

Preferences

First, ensure that you have the the latest updates and install any of the plugins you want to use.

I have the following preferences that are not the defaults:

  • General
    • Select Show heap status
  • General -> Editors -> AnyEdit Tools
    • Select Create new line at the end of the file
    • Select Convert tabs <-> spaces
  • General -> Editors -> Text Editors
    • Select Insert spaces for tabs
    • Select Show print margin with your preferred setting
    • Select Show line numbers
  • General -> Editors -> Text Editors -> Spelling
    • Platform dictionary: English (United Kingdom)
    • User defined dictionary: dictionary.txt
    • Encoding: UTF-8
  • General -> Startup and Shutdown
    • Deselect Confirm exit when closing last window
  • General -> Startup and Shutdown -> Workspaces
    • Deselect Prompt for workspace on startup
  • General -> Workspace
    • Text file encoding: UTF-8
    • New text file line delimiter: Unix
  • Java -> Code Style -> Clean Up
  • Java -> Code Style -> Code Templates
  • Java -> Code Style -> Formatter
  • Java -> Code Style -> Organize Imports
  • Java -> Compiler -> Building
    • Append , *.svn to Output folder -> Filtered resources
  • Java -> Compiler -> Errors/Warnings
    • Potential Programming Problems
      • warn: possible accidental boolean assignment
      • warn: potential null pointer access
      • warn: class overrides equals but not hashcode
    • Unnecessary code
      • warn: redundant null check
      • warn: unnecessary else statement
      • warn: unnecessary cast or instanceof operation
      • warn: unnecessary declaration of thrown checked ex
  • Java -> Compiler -> Task Tags
    • Enter IDEA, NOTE as low priority, TODO as normal priority, BUG, FIXME as high priority
  • Java -> Editor -> Mark Occurrences
    • Deselect Keep marks when the selection changes
  • Run/Debug -> Launching
    • Select Always launch the previously launched application
  • XML -> XML Files -> Editor
    • Select Indent using spaces
    • Set Indentation size to 2
  • General -> Appearance -> Label Decorations
    • Select Task Tag Decorator
  • General -> Appearance -> Label Decorations -> Task Tag Decorator
    • IDEA, NOTE -> Green, TODO -> Blue, BUG, FIXME -> Red

Additional Settings

  • Package Explorer
    • Top Level Elements: Working Sets
    • Filters
      • Select Empty packages
      • Select Libraries from external
      • Select Libraries in project

Maven

There are a number of good presentations on the web from Brett Porter advising on Maven best practices that should be read and applied.

Developers should always thoughtfully consider at which point in the project hierarchy they add dependencies and consider their scope. Its far too easy for inexperienced developers to bloat the library lists and this can really slow down the deployment cycle with overly large distibutions.

Configuration on a per user basis is achieved through a settings xml file which is searched for at ~/.m2/settings.xml. Proxies, mirrors and many other user / environment specific values can be customised keeping the project descriptors free from such conditional logic. In particular I recommend changing the local repository setting to somewhere friendly. I have the following settings:

<settings>
  <localRepository>~/tools/maven/m2-local</localRepository>
</settings>

I use the following maven project structure:

.
├── pom.xml
├── business-impl
│   └── pom.xml
├── business-interface
│   └── pom.xml
├── model
│   └── pom.xml
├── package
│   └── pom.xml
└── parent
    └── pom.xml

There are 3 project roles in this structure:

  • module projects - contains modules for multi builds
  • parent projects - contains shared configuration
  • artifact projects - produces artifacts such as jars and packages

The following points explain the usage of the poms:

  • Module projects poms contain a module entry for each immediate child directory that is a maven project
  • Top level pom is a module project containing just modules, version and scm details
  • All projects use the same versioning number defined in the top level pom
  • Release plugin operates on the top level project
  • Parent projects poms contain all the plugin and dependency mangement sections and any additional shared configuration
  • Artifact projects are responsible for producing suitable artifacts e.g. jars, wars, zips etc.

For larger projects, typically I end up with multiple module sets. The versioning scheme in place affects how these are partitioned and built. If each set of projects has independent versioning then the above file structure is just repeated for each set. Where there is a single version, simply use sub directories and each pom only references its sub directories in the list of modules.

.
├── pom.xml
├── business
│   ├── pom.xml
│   ├── business-impl
│   │   └── pom.xml
│   └── business-interface
│       └── pom.xml
├── model
│   └── pom.xml
└── parent
    └── pom.xml

Checkstyle

There are many available rules in checkstyle that can be configured as required. Some of the rules are obviously best practice, some of them are overly opionated. People often start with one of the predefined configs such as the sun checks one. Having customised a few of these, I have created my own starting point which includes all the rules with those that I consider over the top commented out. See checkstyle.xml.

Comments

blog comments powered by Disqus
Fork me on GitHub