This chapter aims to give some suggestion to developers of OpenJMX, in order to have some common base to start from. Furthermore it gives also some indication on how to create and distribute a new OpenJMX release.
The base to start from are the coding conventions for Java,
see here.
We require as additional convention the one-line one-brace style:
Example 7.1. One-line one-brace style
public class Main { // bad private String name; public Main(String n) { // bad if (n != null) { // bad name = n; } } } public class Main { // good private String name; public Main(String n) { // good if (n != null) { // good name = n; } } }
It is good practice to insert logging statements in the code, to help debugging and to record information about what the program is doing.
OpenJMX has a built-in logging system based on the openjmx.log.Logger class, whose usage is very similar to the Category class of the Log4J project.
Class Logger has six methods that logs at a different priority; from the lowest priority to the highest they are:
public void trace
(...);
public void debug
(...);
public void info
(...);
public void warn
(...);
public void error
(...);
public void fatal
(...);
Class Logger has another useful method that returns the priority enabled for that instance of Logger:
public boolean isEnabledFor
(...);
Example 7.2. Saving run-time cost of String concatenation
Logger logger = ...; if (logger.isEnabledFor(Logger.TRACE)) { logger.trace("Result is: " + result + " on item: " + item + " for process: " + process); }
Another useful way to avoid creation of temporary String objects is to use the StringBuffer class, following this example:
Example 7.3. Saving run-time cost of String concatenation with StringBuffer
Logger logger = ...; if (logger.isEnabledFor(Logger.TRACE)) { StringBuffer message = new StringBuffer("Result is: ").append(result).append(" on item: ").append(" for process: ").append(process); logger.trace(message); }
How do you obtain an instance of the Logger class ? You must use the openjmx.log.Log class, this way:
Example 7.4. Retrieving a Logger instance
Logger logger = Log.getLogger("MyCategory");
Choosing the right priority is important, and here there are few guidelines:
Use Logger.trace
to log execution flow.
Always surround a log with trace priority with a call
to Logger.isEnabledFor
.
Use Logger.debug
to log variables values.
Always surround a log with debug priority with a call
to Logger.isEnabledFor
.
Use Logger.info
to log information that
can be of interest for the user. For every public method there should
be at least one log with info priority.
Always surround a log with info priority with a call
to Logger.isEnabledFor
.
Use Logger.warn
to log recoverable errors that
in normal situations should not happen. The warn priority is the default priority
for OpenJMX.
Use Logger.error
to log exceptions.
Typically, log with error priority are inside catch blocks, just before rethrowing:
Example 7.5. Logs with error priority
Logger logger = ...; try { thisMethodThrows(); } catch (Exception x) { logger.error("Exception happened: ", x); throw x; }
Use Logger.fatal
(...); to log fatal errors that
will force the JVM to terminate.
Typically log with fatal priority are inside catch blocks, just before
calling System.exit
:
Example 7.6. Logs with fatal priority
Logger logger = ...; try { Class.forName("java.lang.Object"); } catch (ClassNotFoundException x) { logger.fatal("Can't find core classes", x); System.exit(1); }
System.exit
is never called.
The documentation that comes with OpenJMX is written using DocBook. It is very easy to use DocBook, and an on-line manual is available here.
Generally, the layout is defined in the file index.xml. All other files are DocBook sections belonging to a chapter, also defined in index.xml.
Every section must contain a sectioninfo with the information about the authors and revision history. It is mandatory that every author that adds a paragraph to the section adds him/herself to the list of authors, and it is mandatory that the tags revnumber and date contains the CVS keywords $Revision$ and $Date$ respectively. This ensures that every section will be automatically updated by CVS on every commit, thus allowing the reader to immediately know how old is the document.
The following steps are required for a new release of OpenJMX: