Code documentation

Development tools

Code Structure

Techniques and Standards

How To

Functional Info

Background Info

JMRI Code: Recommended Practices

This page contains miscellaneous info and pointers for JMRI developers.

Class Library Preferences

Collections

Take a few moments to learn about the different types of Java collections that are available ( List, Deque, HashMap, etc) in the java.util package.

Code Format

The Java Code Conventions (if that link is broken, try this one from the Internet Archive) for names, formatting, etc are really useful. If you find that you can't read a piece of code, these will help make it better.

Note that we have a few local conventions beyond those in the Java recommendations. You'll find them on other pages in this section, but for example, we recommend that you define the logger reference at the bottom of each file.

Deprecating Code

As development proceeds, sometimes old ways of doing things have to be replaced by new ways. In many cases, you can just change all the using code in our repository, and move forward. For general interfaces that might be used externally to JMRI, such as in scripts and CATS, we prefer to leave the old interface in place for a while, marking it as "deprecated" so that people can discover that it will eventually go away. (The current list of those is available as part of the Javadocs) The sequence is then:

Note that a deprecated interface is meant to still work. Deprecated should only mean that you can't count on the deprecated interface working in the future, so that it would be good to code away from it while it's still working.

There are two forms of marking something as deprecated (Javadoc tag and Annotation), and both allow you to add additional information. A nice discussion of the technicalities is here. We strongly recommend using both of them like this:

/**
 * (Other Javadoc comments)
 * @deprecated As of 2.7.8, use {@ link #foo()} instead
 */
@Deprecated // 2.7.8
where the line contains the version in which the deprecation is applied. That lets you easily know how long ago it was deprecated. (There's a better way to do this in Java 9, but JMRI still has to compile under Java 8 so please don't use that; see the release roadmap for background)

You may want to work with the deprecation checks "on" during compilation. To do that, change this line of build.xml:

<property name="deprecation" value="on" />

This lets you pay attention to new deprecation warnings as you code.

Exceptions

Throwing Exceptions

When checking inputs (i.e. for valid parameter values) and you find a problem, what should you do? Generally, JMRI developers tend to throw an unchecked exception, i.e. IllegalArgumentException or similar.

Catching Exceptions

SpotBugs will object to code like this:
  try {
     // do something here
  } catch (Exception e) {
  }
with a REC_CATCH_EXCEPTION and/or a DE_MIGHT_IGNORE (less often DE_MIGHT_DROP). This is an example of two problems: Let's discuss those separately:

Catching the Exception class

There are two subcases here:

Empty catch block

What's an empty catch block trying to say?