JMRI: Recommended PracticesThis is page of miscellaneous info and pointers for JMRI developers.
Class Library Preferences
- We use Java Swing for our GUI development. It's a lot more powerful than the original AWT, and the price is right. We have a recommended organization and usage pattern that's documented on another page.
- JMRI uses the RXTX libraries to support serial communications on Macintosh, Linux and Windows. On Windows only, the Serialio package from Serialio.com is also used to be able to use the MS100 baud rate. To do this, the jmri.jmrix.loconet.ms100.MS100Adapter class was converted to use Java reflection to decide which whether the Serialio package is available; on other systems, it uses RXTX. Note that our license for Serialio limits it to this use only; we are not permitted to distribute the libraries for other purposes.
- Take a few moments to learn about the the different types of Java collections that are available (List, HashMap, etc) in the java.util package. Not everything needs to be a Vector or an array!
- JMRI uses Java generics extensively to reduce errors and improve understanding. With lots of people writing and sharing code, using generics instead of casts makes it much easier to understand the code, and allows the compiler to catch many misunderstandings about how things should be used. Most of the important information on them can be found on this page from the Java Tutorial.
- If you need to use comma-separated variable (CSV) files, please use the javacsv API if possible. We are already using that in a number of places, and will probably use it in more. If that doesn't provide enough functionality, we might eventually move to the opencsv API, but since we only want to use one, the conversion will be a lot of work.
Code FormatThe 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 CodeAs 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, it can be good 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. After a suitable number of release cycles, the deprecated interface can then be removed.
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.
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.
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 use them this way:
where the line contains the version in which the deprecation is applied. That lets you easily know how long ago it was deprecated.
* @deprecated 2.7.8 @Deprecated // 2.7.8