Java CoG Kit Coding Guide

From Java CoG Kit

Jump to: navigation, search

Gregor von Laszewski and Mike Hategan

Version: 4.1.5 and up

This document includes basic information about coding conventions and how to add new modules to the Java CoG Kit.

Contents

Coding Conventions

In case you like to contribute to the Java CoG Kit we have established these simple coding guidelines.

The Java CoG Kit follows the basic coding conventions given in the "Sun Coding Conventions for the Java Programming Language" HTML. Additionally we have the following rules given in this guide.

Versioning

Java CoG Kit Version Numbers

The version for the CoG Kit can be found in the cog/VERSION file. It follows the same rules as for module versions. Please, note that the Java CoG Kit verison number and the version mumbers for modules differ. Consider the Java CoG Kit as one big module.

[ ] the VERSION file should be renamed to VERSION.txt
[ ] the module versioning is not documented, so no one knows what these rules are.

Module Version Numbers

Java CoG Kit modules must include an acurate versioning. Every time your make a change in a module and commit it to SVN, it needs to be associated with a version that can be figured from just the jar file.

The version of the module is to be integrated in the file

VERSION.txt

[ ] many modules do not have a version number indicating that the documentation is not complete.

This version reflects a per module version number. In addition you must include an entry into into bf two CHANGES.txt file. One, that you maintain as part of your mpodule in which you can include a lot of details about changes, and one in the Chava CoG Kit main directoury in which you write a summary of the cahnges. Many times, you can just write the same changes in both files.

The version numbers you will use between versions are minor versions.

Modules must not have an “_” in their directory name. Instead all modules must use an “-” as this will simplify our process that we use to autogenerate documentation from the modules.

Directory names

Directory names must not have an “_” in their directory name. Instead all modules must use an “-” if realy necessary.

Java Conventions

Imports

All imports must be single class and explicit. That is, import <package>.* is not allowed.

Indentation

All indentation levels should be 2 spaces. No editor tabs are allowed unless they are converted to 4 spaces before saving the file.

Brackets

All brackets must follow the Java Coding guidelines. E.g.

 for (index = 0; index < length; index++) {
     ... code ...
 }

Having the bracket below the “for” should be avoided. The reason for this is that our automatic code checking tools have an easier time to analyze the code.

Variables

No acronyms or abbreviations should be used. For example, a = b + mVarLen should be avoided. Instead, use: totalLength = partLength + newLength.

Instance Variables

Use “this.” prefix when referencing instance variables, for example:

 public MyClass (ServicePropertiesInterface properties) {
     this.properties = properties;
 }
 
 public int foo () {
     int localInt = 3;
     return this.instanceInt + localInt;
 }

One-Liners

Even single line statements should be inside brackets, for example:

 if (isEmpty) {
     return;
 }

Logging

Log4J should be used exclusively. System.out.println and System.err.println is not allowed. Further, exceptions should be logged.

Testing

Each component or class should have a JUnit test The tests should be put in test/ directory under each package directory. A very short introduction is avilable here.

Internationalization

The framework should be internationalized. The samples may be internationalized. The Java I18n/L10n Toolkit may be used to verify whether code is international. However as we do not have funding to support internationalization in our ongoing efforts, we treat it at this time with low priority.

Library Reuse

Treat all code as a library, and as a reusable component. Calls to System.exit() are disallowed (except the main method)

Exceptions

Use chained exceptions. Java CoG Kit provides two simple generic exception classes for chaining multiple exceptions together. Look at ChainedException and ChainedIOException.

System.out

Only commandline tools may call system.out. However it is better to assume that even command line tools should be written first with an exception and another wrapper should call System.out dependent on the exception. This way the command can be reused within other programs without terminating the JVM based on an error (see Logging).

Logging

We use the following conventions for using the log4j calls.

Fatal
Something from which the application cannot recover. Application must be terminated.
Error
An exceptional state was encountered, and the application is very likely to not behave correctly. Continue at your own risk
Warn
An exceptional state was encountered, but the effects will not be on the functional side (say, an icon is missing).
Info
Overall flow
Debug
Detailed flow and data dumps

More information about how to use log4j can be found at

To use log4j you need to include the following import statement

 import org.apache.log4j.Logger;
 

If you use loggers in your code, they must be be private, final, and static.

 private final static Logger logger = Logger.getLogger(HTTPPost.class);
 
 

In the code you can use statements such as

 logger.info("An example for a Information statement: I eneterd this method");
 logger.fatal("An example for a fatal error related to a URL", urlException);
 logger.error("An example for an error", ioException)
 logger.debug("An example for a debug statement");
 logger.wran("An example for a warning statement");  

In case you use a string concatination or other relevant lines to prepare the log message you must use an if statement before printing the log message to increase performance.

 if(logger.isDebugEnabled()) {
   logger.debug("variable="+variable);
 }

The properties of the logging facilities can also be customised during runtime while modifying the log4j.properties file. An example is listed below.

 #############
 #Root category
 #############
 log4j.rootCategory=WARN, STDOUT, ERROR-DIALOG,LOG-FILE
 # uncomment this one to use the ERROR-DIALOG and change root to DEBUG level
 # log4j.rootCategory=DEBUG, STDOUT, ERROR-DIALOG, LOG-FILE
 
 #############
 # ERROR-DIALOG is an error dialog for the desktop that allows errors to be emailed
 #############
 log4j.appender.ERROR-DIALOG=org.globus.cog.gridface.impl.util.ErrorDialogAppender
 # override the value for ERROR-DIALOG to WARN
 log4j.appender.ERROR-DIALOG.level=WARN
 log4j.appender.ERROR-DIALOG.headerPattern=%d %-5p [%t] %C{2} (%F:%L) - %m%n
 log4j.appender.ERROR-DIALOG.layout=org.apache.log4j.HTMLLayout
 
 #############
 # STDOUT is set to be a ConsoleAppender using a PatternLayout
 #############
 log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
 log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
 log4j.appender.STDOUT.layout.ConversionPattern=%-5p [%c] %x - %m%n
 
 #############
 # LOG-FILE appends to a log file and can be read using chainsaw 
 # and the chainsaw-config.xml file
 #############
 log4j.appender.LOG-FILE=org.apache.log4j.RollingFileAppender
 log4j.appender.LOG-FILE.layout=org.apache.log4j.PatternLayout
 log4j.appender.LOG-FILE.layout.ConversionPattern=%d %-5p [%t] %C{2} (%F:%L) - %m%n
 log4j.appender.LOG-FILE.MaxFileSize=20KB
 log4j.appender.LOG-FILE.Append=true
 log4j.appender.LOG-FILE.File=example.log
 
 #############
 # customize classes
 #############
 log4j.logger.org.globus.cog.gridfaces=INFO

The Java CoG Kit Module Concept

It is easy to extend the CoG Kit through contributed modules. A template module that you can copy and modify can be found in modules/template. There are a few requirements that have to be imposed in order to keep consistency which we outline next.

Versioning

TBD.

Module Directory Structure

The basic directory structure that MUST exists for each module is:

etc/MANIFEST.MF.head
etc/MANIFEST.MF.tail
lib/
src/

Build files

There are four files that are required by the build system. An example is given in the modules/template directory.

  1. build.xml - should not be modified unless absolutely necessary. If there is a feature that you would like added to the build system, please tell Mike
  2. dependencies.xml - project dependencies are stored here. Please modify it to suit your needs.
  3. launchers.xml - launchers that you want created in the build process. Use the example in modules/template to see how to use it
  4. project.properties - The module properties. The module name MUST be the same as the directory name of the module. The last line in this file contains the library dependencies for this module. If you don't add the jar files that your project requires there, it will not build. The format is a comma separated list of files. I suggest using <jar-name>.* (so that licenses and other things belonging to a jar will also be copied). Please read below about the libraries.

Build targets

There are a few commonly used build targets:

dist
builds a module, its dependencies and creates a distribution directory that contains everything required to use the module.
dist.joint
does pretty much what dist does, but all compiled classes from all modules are put into one big jar file.
jar
creates a jar file for the current module in the dist/lib directory. It requires the dist/lib directory to be present, all dependencies and libraries to be compiled and the jars copied to the dist/lib directory. You should normally not need to use this target. Use "dist" instead.
clean
removes the compiled classes (the "build" directory)
distclean
removed both the compiled classes and the dist directory. It does recursively clean the dependencies.
deploy.webstart
creates a webstart package for the module. You may need to edit cog/webstart.properties.

Libraries

Libraries can be found in two places:

  1. cog/lib
  2. cog/modules/<yourmodule>/lib

The build system will automatically choose the library from either of the two directories. If a library exists in both directories, priority will be given to the library in the cog/lib directory. This may cause your module not to build. Please talk to Gregor or Mike in this case. Also please note that the libraries in your module may at any time move to the cog/lib directory.

Source

The sources for your module. Not much to say here :)

[ ] This needs more text. the reader will be confused.

Modules and Log4j

Due to potential conflicts with log4j initialization files, if you use log4j in your module please note the following:

  1. There is a global log4j initialization file in cog/etc/log4j.properties.root. It defines the root category and a few appenders. It will be automatically included in builds.
  2. Each module can additionally define specific log4j logging clauses.

This can be done in modules/<module-name>/etc/log4j.properties.module. Please do not re-define the root category there.

Modules and Java Webstart

Creating webstart deployments is easy. You would need to define the webstart launchers in the launchers.xml file of your module. Please take a look at the launchers.xml in the template module.

In order to pass arguments to the application or applet, you can use the "application-params" (for applications) or "applet-params" (for applets) parameters. You would need to literally provide all the arguments as XML tags, while also escaping XML characters.

Examples:

  • You need to pass "one" and "two" as arguments to a webstart application. The correct format is:
<property name="application-params"
   value="&lt;argument&gt;one&lt;/argument&gt; &lt;argument&gt;two&lt;/argument&gt;"/>
  • You need to pass "key1=value1" to an applet:
<property name="applet-params" value="&lt;param name=&quot;key1&quot; value=&quot;value1&quot;/&gt;"/>

In order to deploy the webstart applications, you need to first modify the cog/webstart.properties file to match your particular configuration. After that, you can issue the "ant deploy.webstart" command, either in the main cog directory or inside a module. An HTML index page will be automatically that will point to the generated jnlp files.

You can also put some metadata in your module that can be used to generate nice pages with the webstart applications. The structure is as follows:

<module>/meta/
<module>/meta/description.txt
<module>/meta/icon.png
<module>/meta/screenshot.(png|jpg)
<module>/meta/<launcher-name>/
<module>/meta/<launcher-name>/description.txt
<module>/meta/<launcher-name>/icon.png
<module>/meta/<launcher-name>/screenshot.(png|jpg)

Quality Control Tools

Newlines in files

With some editors you will find ^M characters at the end of the line. You can use in a module the command:

ant fixeol 

which will remove ^M in a given module.

Using PMD

[ ] this section is a replication

We recommend that that developers and contributors use PMD (http://pmd.sourceforge.net) to check their code. Many of the complaints that PMD generates should be taken seriously. Still, there are instances when PMD rules do not apply for a good reason and create false positives.

To use pmd, you need to download it and add all its jar files to the ../tools/pmd-2.3/lib directory. Afterwards, just run 'ant pmd' in the module you want to check. It will generate both an on-screen report and an HTML report (pmd-report.html). For our core developers we have a makefile in the ./cog directory that will install pmd appropriately by calling "make install-qc".

PMD

We are using findbugs and PMD to verify the coding standard.

Tools for to check or manipulate the code quality are currently located in

 /cogkit/src/cog/tools

[ ] These tools may move to cogkit/tools in a seperate CVS that only developers have access to. After the move to SVN this no longer works.
]

There is a special directory called

 ./cogkit/src/cog/qualitycontrol

in that contains various configuration files for findbugs and pmd.

[ ] In future we may include different configuration files for other tools such as deriving UML diagrams.

These files are

 ./cogkit/src/cog/qualitycontrol/pmd.xml
 ./cogkit/src/cog/qualitycontrol/findbugs.fb

The files contain our current defaults. The appropiate quality control programs an be installed as follows.

 cd ./cogkit/src/cog
 make install-qc

[ ] This makefile should at one point become an ant file.

Now you can invoke the quality control programs.

Findbugs

Find bugs can be run by

 cd ./cogkit/src/cog
 make findbugs

Findbugs in Cygwin. Findbugs will not work in Cygwin. In order to invoke it on a Windows machine, you should type in the command findbugs command in a Windows CMD.EXE window.

 cd ./cogkit/src/cog
 cd qualitycontrol; \
 ’../../tools/findbugs-0.8.6/bin/findbugs.bat’ \
      -textui -low -html -project findbugs.fb > findbugs.html

Publishing the Results. On Windows findbugs should be called in the Windows CMD.exe program, it does not work under cygwin.

The results of findbugs may be posted on the release distribution page as an http://www.cogkit.org/release/4_1_3/findbugs.html[HTML] document. This can be done by calling

 make publish

Please note that not all errors are relevant. We will improve the code quality gradually.

We recommend that that developers and contributors use PMD (http://pmd.sourceforge.net) to check their code. Many of the complaints that PMD generates should be taken seriously. Still, there are instances when PMD rules do not apply for a good reason and create false positives.

To use pmd, you need to download it and add all its jar files to the cog/tools/pmd-2.3/lib directory. Afterwards, just run ’ant pmd’ in the module you want to check. It will generate both an on-screen report and an html report (pmd-report.html). For our core developers we have a makefile in the ./cog directory that will install pmd appropiatly by calling “make install-qc”.

Automatic Cron scripts

[ ] write the cron scripts for pmd and findbug and install them on gong or wiggum as a nightly run at around 3:00am
[ ] document them here

Eclipse

[ ] After the move to SVN this section is outdated
[ ] it is possible to import from SVN directly into eclipse whcih should be docmented and is the prefered way.

We do not recommend to use the CVS feature form eclipse at this time. Instead we recommend the following procedure.

1. Create directory “cogkit” under your cygwin home.

> mkdir cogkit
> cd cogkit

2. Checking out from CVS from the pserver:

> cvs -d :pserver:anonymous@cvs.cogkit.org:/cvs/cogkit login
> cvs -d :pserver:anonymous@cvs.cogkit.org:/cvs/cogkit checkout src/cog

with a login acount (We assume you use bash). In your bashrc file set

alias ncvs=’cvs -d <youruserlogin>@cvs.cogkit.org/cvs/cogkit

In a new shell you can no say


ncvs checkout -P src/cog

3. Open Eclipse.

4. Switch workspace if a workspace from a previous project is opened. Create a new Project Workspace directory “CogKit”. It would be better to make the workspace location different from the “cogkit” directory where you checked out the code.

(see Figure 1)

5. Create a new “Java Project”. The screen below is shown when a new project is to be created.

(see Figure 2)

6. Enter a Project Name “Cog” and choose “Create Project at external location”. Browse to find the “cogkit” directory within cygwin where the cogkit was checked out from the cvs.

(see Figure 3)

7. Click on “Configure Defaults” in the above screen and choose Project as the source and output folder.

8. Do not press enter since it will save the project. Click on the “Next” button instead. This will take you to the project Properties screen shown below.

(see Figure 4)

Make sure you don’t have the source folders on your build path since this will lead to a different kind of display of the directories within the eclipse “Package Explorer”. They can be added later on when a build needs to be done.

9. To add modules to the build path: Right click on Project -> Properties -> Java Build Path. Here you could add folders to the build path.

10. Commit to CVS: Log on to cygwin and go to the appropriate directory to do the commits. If adding a new file use cvs add before committing to cvs. Similarly, for to delete files from cvs remove the file from local directory and use cvs remove before committing.

Java Cog Kit Eclipse

Appendix

Refactoring Tip

In case one likes to refactor and query replace a string in a directory, I recommend you use perl. The example

perl -i -pe 's/was/new/g' */*.java

replaces all ocurrences of "was" with "new". Be careful when you do this. This is nice if you like to change package names. However refactoring tools are provided by many Java editors.

Personal tools
Collaboration and Jobs