Abstract
A generic software developers' guide which draws upon the best open source convensions, processes and tools.
Note, this guide is still in alpha state.
This guide was built with generguide version $Name: $.
Table of Contents
This document provides comprehensive software development processes tailored for open source projects. It covers processes, conventions, and recommended tools. The guide aims to help developers quickly get up to speed with best practises.
You are not expected to read this guide cover-to-cover. You probably should be familiar with the contents and reference the appropriate section when you need it. Documentation aims to be concise with references elsewhere on the web for details like installation instructions.
This guide is written in a modular fashion so that different projects can easily add, delete, or modify sections. It is hoped that this guide will become the de-facto standard software developers guide for java based open source projects.
For this guide to be useful it needs to be continually added to and improved as tools are developed, processes improved and projects grow. Please consider improving or adding a section if you feel it is required.
Ideally, all recommended tools would be open source, however we have included some no-cost tools where there are gaps in the open source tool set. Where applicable, widely accepted conventions and open standards are used. It has been satisfying to discover the breadth of quality open source tools which support software development. It is hoped that this document will highlight areas where tools can be improved or developed and encourage developers to focus on these areas.
Copyright (c) 2003 Generguide Project Management Committee. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being with no Invariant Sections, with the Front-Cover Texts being no Front-Cover Texts, and with the Back-Cover Texts being no Back-Cover Texts.
Copyright (c) 2003 Generguide Project Management Committee.
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
This section lists applications required to use this tool.
To use Generguide, you should download and install the following:
Requirements Tracing involves mapping high level requirements (usually in a specification or contract) down to lower level requirements (usually in a design document). It is particularly useful in commercial projects to prove completion of a project or compliance to a standard.
This project currently doesn't use Requirements Tracing, and to date I'm yet to see a good open source requirements tracing tool.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
This section describes the language(s) and compilers used by this project.
This project contains Java code which requires java version 1.4 or greater. To ensure the classes compile without errors, you need to specify that you are using 1.4 or greater using the following options:
javac -source 1.4 [other options] [files to compile]
Make sure you update compile options in Netbeans if you use Netbeans.
If you use ant for compiling, or building javadocs or similar, then you will need to include something like:
<javadoc source="1.4">...
Software configuration management involves recording and retreiving all versions of software in a system.
Concurrent Versions System (CVS) is a version control system that allows multiple developers to work on the same files at the same time.
Information on how to download and edit this project's source code are provided at: http://sourceforge.net/cvs/?group_id=83647.
Note, before you can edit files, you will need to be granted write access from the Generguide Project Management Committee.
An excellent CVS manual can be found at http://cvsbook.red-bean.com/.
This section describes the terms used when building a release. This section is explained in more detail at https://sourceforge.net/docman/display_doc.php?docid=6445&group_id=1#componentoverview.
A project represents a web site, and group of people working on the same functionality. For instance, http://generguide.sourceforge.net is the web site for the Generguide project.
A package is a bundle of software being developed within a project. A project may develop multiple packages. For instance, the Generguide project may develop the packages: generguide-lib and developersguide.
A release is a snapshot in the development of a package. It is represented by the package name and release number. For instance, generguide-0.1, or generguide-0.2.
Each release will probably contain multiple files. A file is expected to have multiple versions, however only one version of a file can be in a release.
Release version numbers are based on 3 main digits and an optional release candidate digit : <major>.<minor>.<patch>-rc<release candidate>. It looks like 2.3.4 or 2.3.4-rc5 .
Major version number should be incremented to indicate that project has lost full compatibility with earlier versions. So you can safely upgrade to later versions of a module so long as the major version has not changed.
The second digit (minor) is incremented whenever new features are added. The project is forward compatible across minor versions, but usually not backward compatible.
The third digit is for patches (bug fixes). It is used to indicate fixes in bugs only. No new features were made and full compatibility is preserved.
This digit is optional.
A project may optionally produce release candidate releases for beta testing before the main release.
For projects that use maven, the version number is stored in the <currentVersion> tag in maven's project.xml file.
To do: We need to discuss the meaning of:
alpha
beta
Every time the version number is incremented, you need to tag the relevant files in the repository. This ensures that previous releases can be recreated for future debugging.
Tag names are based on the module version and look like <package_name>-<major>_<minor>_<patch>-rc<release candidate>. Eg: generguide-lib-2_3_4-rc5 .
Note that full stops from the version number are replaced with underscores. This is because CVS doesn't allow full stops in tags.
Typically, you would create a release tag with the following statements in CVS:
cd generguide cvs tag generguide-lib-2_3_4
This section describes the steps to follow when building a release.
At least 24 hours before building a release, email the developers to notify them you are about to build a release. This should allow them to ensure their fixes are in the code base.
If you have not done so already, check all the code you have been editing into CVS.
cvs commit -m"Fixed xxx bugs" <filenames>
Ensure you have the latest files from CVS.
cd generguide/ cvs update -d .
Update and commit CHANGES file with updates between the last release and this one. This file should be in the base directory.
Tag the files that should be in the release. (Usually, not all files in CVS are included in a release).
cd generguide/ cvs tag <tag> dir1 dir2 dir/file1 ...
mkdir ~/tmp
Exporting code from CVS is the same as checking it out, except that the CVS/ directories are not checked out as well.
cd ~/tmp export CVS_RSH=ssh export CVSROOT=:ext:camerons@cvs.sourceforge.net:/cvsroot/generguide cvs export -r <tag> generguide
Many projects will include files in their release which are not contained in CVS. For instance, javadoc documentation, imported libraries etc.
These files need to be built and copied into the release directory.
cd ~/tmp mv generguide/ generguide-0.2
zip -r generguide-0_2.zip generguide-0.2 tar -zcvf generguide-0_2.tar.gz generguide-0.2
Refer to the Sourceforge File Release System for more information.
ftp to upload.sourceforge.net
login as "anonymous"
use email address as password
set ftp client to binary mode
cd /incoming (on the server)
upload release file.
From the http://sourceforge.net/projects/generguide, select Admin, File Releases, Add Release.
Walk through the various forms.
For the release name, use the tag name: eg generguide-0.2
For release notes and change log, extract this information from the comments added to the CHANGES file above.
Download the release from sourceforge, uncompress it, and check it. (This can be covered by the following step).
Send an email notification to the project's announce email list.
The roles and responsibilities that people can assume in this project are based on merit. Everybody can help no matter what their role. Those who have been long term or valuable contributors to the project obtain the right to vote and commit directly to the source repository.
Users are the people who use the products of the Project. People in this role aren't contributing code, but they are using the products, reporting bugs, making feature requests, and such. This is by far the most important category of people as, without users, there is no reason for the Project.
When a user starts to contribute code or documentation patches, they become a Contributor.
Contributors are the people who write code or documentation patches or contribute positively to the project in other ways. A volunteer's contribution is always recognized. In source code, all volunteers who contribute to a source file may add their name to the list of authors for that file.
Contributors who give frequent and valuable contributions to a subproject of the Project can have their status promoted to that of a "Committer" for that subproject. A Committer has write access to the source code repository and gains voting rights allowing them to affect the future of the subproject.
In order for a Contributor to become a Committer, another Committer can nominate that Contributor or the Contributor can ask for it.
Once a Contributor is nominated, all existing committers will vote. If there are at least 3 positive votes and no negative votes, the Contributor is converted into a Committer and given write access to the source code repository. This is an example offer letter that should be sent to the volunteer after 3 positive votes have been received:
Dear Contributor,
Our project would like to offer you commit privileges. We have been impressed with your contributions up till now, and believe that your involvement will improve the quality of the code we produce. If you are interested in having commit privileges, please set up an account with http://sourceforge.net and let us know your account name.
We all hope that you accept this invitation.
The Generguide Project Management Committee.
Committers are asked to coordinate their efforts with the maintainers of the modules they wish to modify/extend.
At times, Committers may go inactive for a variety of reasons. A Committer that has been inactive for 6 months or more may lose their status as a Committer. Getting access back is as simple as re-requesting it on the project's Developer mailing list.
Committers who frequently participate with valuable contributions may have their status promoted to that of a Project Management Committee Member. This committee is the official managing body of the Project and is responsible for setting overall project direction. In order to become a Member, someone on the PMC must nominate the Committer. The individual may then be approved with a 3/4 majority of the PMC.
Internet Chat Relay (IRC) is a protocol which allows a number of users to chat with each other using text messages in real time.
If you are new to IRC, you will need to install one of the many IRC clients. The later versions of Netscape and Mozilla have IRC built in, and you can connect to a IRC meeting with the URL: irc://irc.eu.freenode.net#some_channel.
Developers meet weekly at (time to be specified) UTC.
Check http://www.timeanddate.com/worldclock/ to find what this time translates to in your part of the world.
Members of the Project Management Committee (PMC) who are regular IRC participants should let others know if they are not coming so that the meeting is not delayed on their behalf.
The information you need to configure your IRC client are:
During alpha development, issues are embedded into the code using @task tags which can be read from the maven output files.
Once code has been released, bugs are tracked using this project's bug tracking system: http://sourceforge.net/tracker/?group_id=83647.
You can place @task markers in the javadoc sections of code to track areas for rework. During the maven build process, the tags are extracted to build a report page. Inline Task Tracking is particularly useful during development. After code has been released, bugs should be tracked using the Bug Tracker.
The following tags are available:
TODO:
REVISIT:
HACK:
Building involves processing source files to produce target files. For example, compiling and linking source code, or converting docbook to html documentation.
First off, what is maven? Maven is a Java project management and project comprehension tool, or in other words, yet another build tool.
It is built on top of ant and a number of other open source utilities and brings them together in an easy to use tool.
The key part of maven is the use of project.xml files.
The project.xml file tells you the name of the project, who maintains it, who develops it, what version it has reached and what it depends on. Module project.xml files can extend and inherit from a master project.xml file.
The most important part of the project.xml file is the dependencies section as maven uses this to determine what order to build the modules in and what support jars to download when needed.
You will need Maven 1.0 beta 8 or later which you can download from: http://maven.apache.org/start/download.html
Unpack the archive you downloaded to a convenient location on your machine (c:\program files is good for windoze boxes)
Set an environment variable called MAVEN_HOME to point to this location (e.g. c:\program files\maven-1.0-beta-8)
Add MAVEN_HOME\bin to your systems PATH environment variable.
Maven can require a lot of memory when building. By default it has a limit of 128mb you may need to increase this. Edit the maven.bat (Windows) or maven (*nix) file in the MAVEN_HOME/bin folder.
Look for the : SET MAVEN_OPTS=-Xmx128m
And change it to: SET MAVEN_OPTS=-Xmx256m
Make sure you are connected to the internet, then do the following:
cd ~/generguide maven build
All being well maven should download the required .jar files and build the project. At the end of this process it will display a list of all the modules which were built and installed correctly.
The first build takes a while due to the download time for the .jar files. Future builds check for the most recent .jar files from the internet, however you can bypass the checking and run maven offline using the following:
cd ~/generguide maven build -o
On your machine you will find a directory in $MAVEN_HOME called repository, this is where maven stores all downloaded jars and installed projects.
You should see that any third party jars will have been installed in this repository. You should also see that all successful module builds have had their jars installed in a directory for your project.
If your project contains modules, after doing a complete build you should be able to build just one module.
Change to the modules home directory and type:
maven java:compile
It should do a complete build, note that if you have not done a full build yet then the build may fail because it can't find the jar for a module it depends on. An error caused by not having another module installed can be a little misleading, for example the error may look something like:
Error: unable to download core-0.1.jar
This is because Maven failed to find core-0.1.jar in the local repository (where a full build should have put it) so it tried to download and fails. If you see an error like that either do a full build or change into the module which is missing (core in this case) and type:
maven jar:install
This should build and install that individual module, all being well you should then be able to go back to the module you were trying to build and try again.
In any individual module home you can type maven -g to see a full list of goals that can be run for that module. Handy examples include...
generates a web site in the target/docs folder which provides a LOT of information about the module.
generates the javadoc for the module, (look in target for output).
runs the tests, look in target/test-reports for output
installs the module into the Maven repository for use by other modules
Maven uses a number of files to work out what to do, the most important as mentioned above are the project.xml files, there are however a few others, the layout is as follows:
the parent template project file which the module files extend.
a control file which marshals the building of ALL modules and will soon generate a full web-site.
the specific project file for a given module
some control properties that will eventually be inherited from a parent, but not yet.
folder generated during builds that contains all output (classes, jars and reports)
contains files such as logos or additional web pages that go into the web site
Complete documentation for the project.xml file for maven can be found at the maven site, and in particular in the project descriptor part of the reference section. So, we only show that the things specific to a modular project.xml file here.
The <extend> tag allows one project.xml file to inherit items from another. Modules should extend the main project.xml within the top level directory. Also, the path given to the other project.xml file mush begin with ${basedir} in order for maven to find it. For example: <extend>${basedir}/../../project.xml<extend>
The id should reflect the name of the module. However, because the main project.xml defined groupId to be Generguide, there is no need to prepend a project name prefix.
Dependencies are specified within the project.xml file, but care should be taken. Dependencies uses a groupId to identify the project and an artifactId to identify the jar within that project. ArtifactIds correspond to modules in this project. Also, be aware that dependencies are not transitive. In other words, suppose module B has a dependency on module A. If you are creating module C, and have a dependency on module B, then you do not automatically have a dependency on module A. If C depends on A, then you must add the dependency manually.
Maven complicates things on the logging front, as it does a lot of redirection. By default the logs from testing end up in target/test-reports of each module sub-directory. There should be XML and text files for the results of each test. Be sure to check both, as one of the wrinkles of maven makes it so the output isn't always exactly the same. To have maven display the logging as it tests instead of just writing to files set the maven.junit.usefile property to false. To set a property, you can either pass it in from the command line with the -D flag (maven -D maven.junit.usefile=false) or set it in the build.properties file (just add the line maven.junit.usefile=false).
Another helpful testing hint: in order to run only one test, call maven test:single and set the test case property to the full name of the test to run. If you are having problems with logging output levels be sure to read the logging section.
Javascript files need to be uploaded across potentially slow internet connections. Consequently, it is desirable to keep file sizes to a minimum.
Javascript files can be compressed with The Creativyst CSS and JavaScript Compressor.
To do: Find an open source compression algorithm. The above algorithm removes white spaces and comments, but does not compress file names, which could reduce file size even more.
A design describes how to implement a product. A design is useful during development and maintainance as it provides developers with a quick high level understanding of the product being developed.
A design document should provide a brief overview of the design to help developers gain a quick understanding of the system. The design documentation is enhanced by using more diagrams and less text.
Text in the design document should be written in docbook format. Refer to the documentation section for more details about using docbook.
Documentation about procedures and classes should be embedded in the source code and then extracted into Detailed Design documentation using an external parser.
Javadoc comes as part of the Java Software Development Kit.
To do: Explain how to run javadoc <files>
Jsdoc is a tool that parses inline documentation in JavaScript source files, and produces a HTML summary. Refer to the Code Convensions section to see how comments should be written.
UML is a standard notation used to specify, visualise, construct and document the components of an object-oriented software-intensive system. UML diagrams are used as part of design documentation.
Web applications are modelled in accordance with Modeling Web Application Design with UML, by Jim Conallen. This white paper describes class stereo types to model web components. Class stereotypes provided are:
Server Page
Client Page
Form
Frameset
Target
Scriplet
XML
Poseidon is a UML editor which extends the open source Argo UML. It provides a no-cost version which is more polished than Argo UML.
Note that some of ArgoUML's features are disabled in Poseidon. In particular, Poseidon 2.1 disables reverse engineering of java code.
You can reverse engineer code using Argo UML, then import the project into Poseidon.
Poseidon can be installed into Netbeans as a module. Refer to Poseidon download instructions for more details.
IDEs aim to provide all functionality a developer requires in one tool.
Netbeans is a free java IDE which also provides a framework for adding extra functionality. Sun repackage Netbeans and call it Sun ONE Studio (previously Forte for J).
Before setting up Netbeans for this project's development you need to:
Have ssh installed, and ssh key-value pairs set up so you do not need a password to access sourceforge CVS repository. See Code Versioning for details.
Have CVS installed.
Have checked out this project's CVS repository into a local directory on your computer.
As mentioned, If your project requires Java 1.4 or later, this needs to be specified in netbeans using the following windows:
Tools->Options->Building->Compiler Types->External Compilation
Set Enable JDK 1.4 Source to "True".
A few modules should be added to the standard Netbeans install to help this project's development. For modules installed from the Netbeans Update center use:
Tools->Update Center
For other modules use:
Tools->Options->IDE Configuration->System->Modules
right click on Modules
select add->Module
select the relevant .jar file.
The following modules may be installed:
View over a Filesystem is required by many modular projects where modules are stored in separate directory sturectures to each other.
Jalopy is a Source Code Formatter which should be used to ensure code is written in a consistent style. Download the zipped .nbm file and install from a local directory.
Tools->Update Center->Install Manually Downloaded Modules-><select .nbm file>
After installing, refer to the Jalopy section to configure.
PMD checks code for poor programming patterns. This is optional because output of PMD can be checked from PMD output webpages.
Download the zipped .nbm file and install from a local directory.
Tools->Update Center->Install Manually Downloaded Modules-><select .nbm file>
After installing, refer to the PMD section to configure.
RefactorIT is a useful module for changing many classes at once, and provide a no-cost license for open source projects. See Section 13.1, “Refactor It” for more details. Installation instructions are in the download.
Poseidon is a Unified Modeling Language (UML) editor.
If your netbeans explorer window becomes too crowded, you can create a manageable view of your classes by creating a project.
Right click on your files or modules in the windows explorer, then select Tools->Add to Project.
You can now view your files by selecting the Project tab in the explorer.
Netbeans occasionally gets into a funny state and refuses to debug, or execute, or something. So it is a good idea to backup your netbeans configuration directory. On 'nix systems you do something like:
# change to your home directory cd ~ # copy the netbeans configuration directory cp -pr .netbeans/ .netbeans.bak
Emacs is not a Java IDE, however it can be treated like multi-language IDE without a GUI builder. If you are not a GUI designer or developer emacs is well worth considering for a software development environment.
The most important features for Java developers (most of them provided by JDEE) are:
Efficient and extremely customizable editor which supporting almost all programming and natural languages.
Excellent Java support provided by Java Development Environment for Emacs (JDEE). JDEE provides all standard features provided by dedicated Java IDEs like class browsing, code completion, imports management and so on. In many cases built in wizards and code templates makes emacs better.
Built in Java code formatter and interface to Jalopy. It is worth noting that the "native" JDEE code formatter has capabilities almost equal to Jalopy's and with a little time spent on configuration you can have on-line code formating.
Java-Doc generator and Java-Doc browser.
Java-Debug built-in interface and remote debugging support.
Doc-Book support. You can use emac's default simple support or full SGML and XML support provided by PSGML.
Built in CVS support.
Emacs and JDEE work best on Linux and other Unix like systems. It is possible to use all features of emacs on Windows machine but it requires additional software and effort.
In most cases emacs should be installed with distribution. If not, search package list for your distribution and install emacs separately.
I suggest you download full precompiled binaries “fullbin” from http://ftp.gnu.org/. This directory contains source and full emacs, elisp documentation. The easiest way to make emacs fully functional is to install CygWin. CygWin provides a Unix environment under windows. CygWin contains an emacs package but the native install contains configuration problems relating to ANT and Java so I don't recommend it.
JDEE project main page. The best source for all necessary information about JDEE.
CygWin project main page. It contains link to last available setup.exe CygWin installation program.
JDEE installation script with some additional information about using it in particular cases.
I work on the same Java projects on machines with Linux and Windows+CygWin systems. So I will present configuration options necessary to use it transparently regardless of the environment you use.
Emacs installation is really simple. Put it in any convenient location on HDD and make it available using the system environment variable: "PATH". On Unix like system emacs is Plug and Play software and without any additional effort it can be used immediately after installation. For use of JDEE and Java look in environment variables setting description.
There are some tricks to use it on windows system with CygWin so I will describe it with all details. Below are step by step instructions:
Run setup.exe - CygWin installation program. All default settings should be good for our needs even default packages set is sufficient. I am not sure if libxslt is installed in basic - default set. To ensure go to Text category, expand it and check libxslt package.
Unpack downloaded emacs binaries to CygWin root directory d:/gnu in my case. Because emacs binaries are packed with gzip and gnu tar tools the easiest way to unpack emacs package is to run CygWin console and execute following commands:
Put install-jde.sh script in your CygWin home directory and run it. (If you are an experienced emacs user, look in information at the beginning of the script about how to customize it.) It is necessary to make emacs binaries available in PATH environment variable or set full path name to emacs at the beginning of the script.
All the most necessary components are now installed. To use them effectively some customization should be done.
System, CygWin, emacs and JDEE customization hints.
On Windows systems some variables should be set in system level and others in CygWin level. On Unix systems all variables can be set from user startup - profile files. On Windows they must be separated because CygWin paths are Unix-like and CygWin root directory starts in CygWin installation directory. So some programs will use Windows paths and others will use CygWin paths.
To set environment variable on system level right-click on My-Computer and choose Properties. Go to Advanced tab and click on System environment button.
To set environment variable on CygWin level or on all levels in native Unix system add the following to your .bashrc file:
Example 4. System level variables list with sample values.
JAVA_HOME=d:/jdk1.4.1 ANT_HOME=d:/projects/jakarta-ant-1.5.1 MAVEN_HOME=d:/projects/maven-1.0-beta-8 PROJECTS_HOME=d:/projects
On Unix like system above variables should be set to proper Unix file system locations.
Example 5. CygWin level variables list with sample values.
export PATH="/emacs-21.2/bin:$PATH" export CVS_RSH='ssh' export CVSROOT=":ext:user@cvs.this-project.sourceforge.net:/cvsroot/this-project" # Unix users should uncomment lines below: # export JAVA_HOME=/usr/local/jdk1.4.1 # export ANT_HOME=/usr/local/jakarta-ant-1.5.1 # export MAVEN_HOME=/usr/local/maven-1.0-beta-8 # export PROJECTS_HOME=$HOME/projects
For CVSROOT, replace user with your Source Forge user name.
To start emacs with your home directory set to CygWin home directory and make visible some CygWin variables for emacs, add the following script to your CygWin root directory:
Main emacs configuration file .emacs is located in your home directory. Example below present sample file with necessary settings and some number of not necessary but very useful especially for emacs beginners.
Example 7. Sample .emacs content.
It is rather big sample file, so to prevent scrolling through the number of lines of lisp code I have made my .emacs working file available on web page. I tried to make them readable and well commented. Especially with every external package used I have also added URL to place where the last version is available.
If you work on several projects with different settings (like coding standards), you will appreciate the power of emacs and JDEE. This is one of the biggest advantages emacs has over other IDEs.
JDEE has it's own configuration file where you can set all possible project options. If some of them are common for all projects than they can be moved to .emacs file. If you are working on Java code and you have opened Java file, JDEE looks for project configuration file - prj.el in current directory and all parent directories. Project file located in current directory inherits all parameters from projects files in parent directories and of course from .emacs file. So it is possible to customize each package if necessary. For example you can set a different class as main executable class for each package. Anyway below I present sample JDEE project file with almost all common settings:
Many commands are available through main and context menu. Others are not. I will present below how to effectively use all of them from the keyboard and how quickly find necessary function name.
If you already installed all the software, you should check if it works first. The easiest way to check your JDEE installation is to load any Java file. If you can see new Menu element called JDE it means JDEE mode is selected and activated.
There is one package allowing you to use Jalopy from emacs with JDEE. This is jde-jalopy. It is not part of JDEE yet, so must be downloaded separately from it's home page.
To make it functional in your installation do as follows:
It needs Jalopy console plug-in package available on project download page. So get it and unpack in some convenient for you place. For my case it is $PROJECTS_HOME/jalopy-1.0.2/ directory.
Put jde-jalopy.el file in your custom packages location. Make sure it is in your emacs “load path”. And add to .emacs:
Some jalopy options are global to all your projects and some can vary between projects. Global options should be placed in .emacs and the rest should go to prj.el files.
Example 10. Global Jalopy settings in .emacs.
(custom-set-variables '(jde-jalopy-option-path "$PROJECTS_HOME/jalopy-1.0.2") '(jde-jalopy-option-force t) )
Please note that can be only one expression with custom-set-variables in your .emacs file. If there is already such expression you should only append to it lines with parameters.
Example 11. Project local Jalopy settings in prj.el.
(jde-set-variables '(jde-jalopy-option-preferences-file "$PROJECTS_HOME/project-src/docs/sdocbook/resources/jalopyproject.xml") )
As in above example if there is already jde-set-variables expression in your prj.el file add your settings to existing list instead of creating new one.
Now you can start using it. When you are editing Java file and want to use Jalopy for it run command jde-jalopy-file (M-x jde-jalopy-file). Compilation buffer will open and you can see messages Jalopy generates during formating. Current version does not automatically refreshes changes in emacs buffer so you must “revert buffer” to see changes and work on file when formating is done.
I have put here table with the most important and often used functions of JDEE. Of course you can find all available functions in both off-line and on-line JDEE documentation. But I find it useful to have the most important functions in a table. In most cases descriptions were fully or partially copied from the original JDEE documentation. So for many of them you can find more information in on-line JDEE documentation using: Alt-x describe-function, then ENTER, then write function name.
To see all JDEE key-bindings, call the function jde-keys under emacs. (Alt-x jde-keys)
Table 2. Most often used commands quick reference table.
Function name | Keys binding | Description |
---|---|---|
jde-keys | none | Displays JDEE key bindings. |
jde-bug-keys | none | Displays JDEbug key-bindings. |
describe-bindings | none | Show a list of all emacs defined keys, and their definitions. |
jde-abbrev-mode | none | It is not used indeed. Abbreviations in JDEE are very powerful and you should always have JDEE abbreviations turned ON. To turn them permanently on you don't have to use this function. Set value of jde-enable-abbrev-mode variable to true in your .emacs or prj.el file instead. Look in Section 11.2.6, “Abbreviations available in JDEE” for more details. |
next-error | C-x ` | Visit next compilation error message and corresponding source code. |
jde-find | C-c C-v C-f | Find a regular expression REGEXP in all of the files in the current JDE project. |
jde-open-class-at-point | C-c C-v C-y | Find definition for symbol under cursor. Opens the java-file which defines the class where current point is and jumps to the definition of current thing at point (this can be a variable name, class name, method name, attribute name). |
jde-complete-in-line | C-c C-v . | Completes the method or field name at point. Repeating the command cycles through all potential completions for the name. This function displays the signature of a method completion as specified by `jde-complete-display-current-signature' |
jde-complete | C-c C-v C-. | Displays completions for the Java symbol at point. Depends on user settings possible completions can be displayed as context menu or in minibufer. |
jde-gen-try-catch-wrapper | C-c C-v t | Wrap the region from BEG to END into a try/catch block. BEG and END are modified so the region only contains complete lines. |
jde-gen-try-finally-wrapper | C-c C-v f | Wrap the region from BEG to END into a try/finally block. BEG and END are modified so the region only contains complete lines. |
jde-import-find-and-import | C-c C-v C-z | Insert an import statement for a class in the current buffer. CLASS is an unqualified class name. This function searches the classpath for a class (or classes) that match CLASS. If it finds only one, it inserts an import statements for the class at the head of the current buffer. If it finds more than one class that matches CLASS, it prompts you to select which class to import. |
jde-show-superclass-source | C-c C-v C-x | Show the source for the parent of the class at point. |
jde-wiz-update-class-list | C-c C-v C-q | Update the class list used to resolve class names. The first time you invoke a JDEE wizard, the JDEE builds a list of all classes on the CLASSPATH defined by jde-global-classpath. Wizards use this list to resolve unqualified class names. If you add any classes to the CLASSPATH after invoking a wizard, you should update the class list. |
jde-gen-println | C-c C-v C-l | Insert println statement. |
jde-compile | C-c C-v C-c | Compile the Java program in the current buffer. This command invokes the compiler specified by `jde-compiler' with the options specified by the JDE customization variables that begin with `jde-compile'. |
jde-build | C-c C-v C-b | Rebuild the entire project. This command invokes the function defined by `jde-build-function'. |
This is list of abbreviations taken from version of JDEE - 2.3.2. To see list of abbreviations in your current version execute describe-variable emacs function with parameter jde-mode-abbreviations: Alt-x describe-variable, then ENTER, then jde-mode-abbreviations.
Table 3. JDEE abbreviations table.
Abbreviation | Expansion | Abbreviation | Expansion | Abbreviation | Expansion |
---|---|---|---|---|---|
ab | abstract | bo | boolean | br | break |
by | byte | byv | byvalue | cas | cast |
ca | catch | ch | char | cl | class |
co | const | con | continue | de | default |
dou | double | el | else | ex | extends |
fa | false | fi | final | fin | finally |
fl | float | fo | for | fu | future |
ge | generic | go | goto | impl | implements |
impo | import | ins | instanceof | in | int |
inte | interface | lo | long | na | native |
ne | new | nu | null | pa | package |
pri | private | pro | protected | pu | public |
re | return | sh | short | st | static |
su | super | sw | switch | sy | synchronized |
th | this | thr | throw | throw | throws |
tra | transient | tr | true | vo | void |
vol | volatile | wh | while |
Coding conventions describe the coding styles developers should use when writing code. For example, whether you use 2, 4, or 8 space indents. Standardizing on a coding style across a project improves legibility of the code, and automatic code formatters make conforming to these standards easy.
Jalopy is a source code formatter for Java. It lays out any valid Java source code according to configurable rules to meet a coding style without putting a formatting burden on individual developers.
Jalopy can be integrated into a number of IDEs, and a project's coding convensions can be stored centrally and imported by all developers. Installation is straight forward, refer to the Jalopy documentation for details.
Each developer should setup Jalopy in their prefered IDE and then import this project's coding convensions, jalopyconfig.xml.
Code that you don't want formated by Jalopy can be wrapped by //J- and //J+ comments.
Example 12. Identifying code not to be formatted by Jalopy
//J- private specialFormattedClass(){return True} //J+
This section details the modifications we made to the Jalopy default configuration. The Jalopy default configuration is based on the Sun Java Coding Conventions.
This project uses jalopy's default configuration.
PMD automatically checks code for poor programming patterns.
To do: Reference PMD configuration file. Explain the patterns that are checked.
The logging package (java.util.logging) is bundled into J2SE 1.4 and above. An overview is available on line in the Sun's SDK documentation.
This project uses one logger per class and is named after the class name.
The logger should be declared in the class's static fields.
Example 13. Logger declaration
// J2SE dependencies import java.util.logging.Logger; public class MyClass { /** * The logger for the GML DataSource module. */ private static final Logger LOGGER = Logger.getLogger("net.sourceforge.generguide.mymodule.MyClass"); }
Message can be conveniently logged using one of 7 predefined levels. The levels in descending order are:
severe (highest value)
warning
info
config
fine
finer
finest (lowest value)
By default, level SEVERE, WARNING and INFO are logged to the standard output. Level FINER is commonly used when entering, returning, or throwing an exception. A convenience method exists in Logger for each of those levels.
There is three more convenience methods: entering, exiting and throwing when entering and exiting a method, or when we are about to terminate a method with an exception.
Example 15. Entering/Existing Logger
public Object myMethod(String myArgument) { LOGGER.entering("MyClass", "MyMethod", myArgument); // ... do some process here LOGGER.exiting("MyClass", "MyMethod", myReturnValue); return myReturnValue; }
When logging a message, the logger will include many informations like date and time, source class and method names, current thread, etc. In order to avoid too many informations to be logged, it may be useful to merge consecutive logging into a single log statement.
Example 16. Minimising Logger output
// Wasteful use of logging LOGGER.finer("Value for A is "+A); LOGGER.finer("Value for B is "+B); LOGGER.finer("Value for C is "+C); // Good use of logging LOGGER.finer("Computed values: A="+A+"; B="+B+"; C="+C);
If the log message is expensive to construct, then consider enclosing it in a "if" statement.
Example 17. Selective logging
if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("Current state = "+someVeryExpensiveMethodCall()); }
To change the default logging setting, edit the following file:
$JAVA_HOME/jre/lib/logging.properties
Define the ".level" property to the minimal level of interest for you:
.level= FINER
Define the java.util.logging.ConsoleHandler.level property to the minimal level you want to see on the console. It may be different than the level logged to the XML file.
Example 18. logging.properties configuration file
# Limit the message that are printed on the console to FINE and above. java.util.logging.ConsoleHandler.level = FINE java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter java.util.logging.ConsoleHandler.encoding = Cp850
Note the "encoding" property. For Windows user, it should be set to the value displayed by "chcp" on the command line. Linux and Unix users may ignore this line since Unix systems do a more intelligent work with page codes.
Finally, a different logging level may be specified for each module. For example you may be interested in fairly detailed logging message from module1, but not from module2. Then you could write:
To do: Write this. Ideally some large project will offer their exception handling policy so we don't have to re-invent the wheel.
Directory names shall be all lower case with no spaces. Some versions of windows do not distinguish between upper and lower case, and in unix, writing spaces in filenames is painful.
Refactoring is the process of restructuring/renaming your code to ensure your design remains clean as your requirements and functionality change and grow with time.
To ease refactoring you can use RefactorIt which provides tools to:
research, probe and understand existing source code,
move, organise and transform existing code,
and provide code metrics.
More details can be found from the online help.
RefactorIt is commercial, but provides no-cost licences for Open Source projects. See the RefactorIt web pages for details. It can be plugged into a variety of IDEs, including Netbeans.
Installation into netbeans is fairly strait forward through Tools -> RefactorIt -> Project Options, although setting up soucepath and classpath is a difficult if some of the source files don't compile. You will need to either remove the offending files, get them to compile or remove them from RefactorIt's sourcepath.
Code profilers are tools which analyse performance and memory of applications.
Good free profiling tools that we have used are a combination of hprof (provided with JDK) and HPJMeter (which analyzes profiling data from hprof).
To invoke hprof, run java with the following options: -Xrunhprof:cpu=samples,thread=n,depth=40,cutoff=0,format=a
If you are running from Netbeans, select Toos->Options->Debugging and Executing->Execution Types->(right click)->New->External Executor. Rename the new executor HProf External Executor (or whatever you like). Still in the Options dialog box, open HProf External Executor->Properties->External Process and in arguments add at the beginning: -Xrunhprof:cpu=samples,thread=n,depth=40,cutoff=0,format=a {assertEnabled}
hprof will be launched every time you select this kind of executor. Go to HProf External Executor->Expert->Working Directory. Set a working directory, Eg /home/<username>/tmp/hprof. Hprof dumps the resulting text file in this directory. This setting modifies the working directory of the java JVM. Make sure the working directory exists, otherwise the executor won't work.
Close the options dialog and select the file you want to profile, select (right click on file to profile)->Properties->Execution->Executor. Set to the HProf External Profiler. Run. At the end of the run you'll find a java.hprof.txt file that can be opened with HPJMeter.
As you code, you should write a unit test for each class to test the functionality and robustness of the class.
Junit provides a simple framework to help write repeatable unit tests.
If you are testing net.sourceforge.generguide.module.HelloWorld, you should create a file src/<module>/tests/unit/net/sourceforge/generguide/<module>/HelloWorld.java similar to the following:
Example 20. HelloWorldTest.java
package net.sourceforge.generguide.module; import net.sourceforge.generguide.module.HelloWorld; /** * Unit test for HelloWorld. * * @author Cameron Shorter */ public class HelloWorldTest extends TestCase { /** Test suite for this test case */ private TestSuite suite = null; /** * Constructor with test name. */ public HelloWorldTest(String testName) { super(testName); } /** * Main for test runner. */ public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } /** * Required suite builder. * @return A test suite for this unit test. */ public static Test suite() { TestSuite suite = new TestSuite(HelloWorldTest.class); return suite; } /** * Initialize variables */ protected void setUp() { // initialize variables } /** Test normal constuctors. */ public void testHello(){ assertTrue("HelloWorld should return null is true",HelloWorld.isNull()); } }
Testing with junit is as easy as copying HelloWorldTest.java and adding more tests, and then executing it. More information can be found at the junit site.
Any test data required should be stored in generguide/src/<module>/tests/testdata/.
This section describes how to create modular simple docbook files.
This quick start section will get you editing simple docbook sections quickly and easilly. For more detailed information, refer to the rest of the documentation section.
Simple steps for docbook editing
Download and install a Java Virtual Machine if you have not already done so.
Download and install XXE, a What You See is What You Mean (WYSIWYM) docbook editor.
If you creating a new section, then copy an existing section and modify it. If you are updating an existing section - well, that is even easier.
XXE is similar to any GUI editor. You type in the main panel and most of the list/table/paragraph/section/figure formatting options are selectable from the toolbar. Remember that simple docbook is structured XML. You will often need to select an XML node so you can specify whether the next paragraph should be part of this section or a new section. Select XML nodes with arrow icons:
Commit your changes back into the source repository.
To publish your document after editing, either tell the main document author and get them to do it, or read the rest of the documentation section.
Documentation for this project is written using Simplified Docbook format. Simplified Docbook is a subset of Docbook XML, a versatile format used by the Linux Documentation Project (among others).
Docbook can be easily converted into numerous output formats, like HTML, PDF, etc.
Using Docbook ensures documentation content is kept separate from presentation so content can written once and published in numerous formats and styles.
There are a few GUI editors for docbook now, with more editors promising to support docbook in the future.
According to The Software Release's Howto, docbook is the open source format of the future, and most of the high profile open source projects have moved or are moving to docbook as their coding standards. So we are saving ourselves pain in the future by embracing Docbook now.
Modular DocBook means content is broken up into smaller file modules that are recombined for publication. The advantages of modular documentation include:
Reusable content units.
Smaller file units to load into an editing program.
Distributed authoring.
Finer grain version control.
This project uses modular documents for it's documentation.
Example 22. Including sections into a master document
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE article PUBLIC "-//OASIS//DTD Simplified DocBook XML V1.0//EN" "http://www.oasis-open.org/docbook/xml/simple/1.0/sdocbook.dtd"> <article id="index"> <articleinfo> <title>Software Design Description</title> </articleinfo> <section id="scope"> <title>Scope</title> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="doclicense.xml"/> </section> </article>
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE section PUBLIC "-//OASIS//DTD Simplified DocBook XML V1.0//EN" "http://www.oasis-open.org/docbook/xml/simple/1.0/sdocbook.dtd"> <section id="licence"> <title>License.</title> <para>Copyright (c) 2002 Cameron Shorter. Permission is granted to copy, distribute and/or modify this document under the terms of the <ulink url="http://www.fsf.org/copyleft/fdl.html">GNU Free Documentation License</ulink>, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being with no Invariant Sections, with the Front-Cover Texts being no Front-Cover Texts, and with the Back-Cover Texts being no Back-Cover Texts.</para> </section>
If you want to document a new module, you need to write a new module.xml section file, and then add an <xi:include> tag into design.xml.
Notice in the above example that <section> tags contain an id attribute. This means the URL of published sections will be human readable, something like http://net.sourceforge.generguide/docs/design.html#licence instead of http://net.sourceforge.generguide/docs/design.html#id2754172.
Publishing modular documents is possible with xsltproc. At the time of writing, other XSLT engines don't process modular documents yet because the <xi:include> tags cause the XML to be invalid. (To do, check to see if Saxon and Xalan support <xi:include> yet.)
Instructions on installing and using xsltproc can be found at: http://www.sagehill.net/xml/docbookxsl.
ant can publish standard simple docbook files but cannot publish modular docbook files because they are not valid XML. Hopefully this will change in future.
In version 1.5, ant has a bug which prevents it from publishing more than one docbook document at a time. The workaround is to run ant a number of times. Earlier versions of ant have more bugs and less functionality.
Maven allows uses to process docbook to (arnika/velocity?) and then to html. Since maven is based on ant, it also cannot process modular docbook files yet and at the time of writing, this functionality was still very bug ridden. Hopefully it will improve soon.
To process XML files containing xinclude elements you need only 2 things:
XSL template containing transformation including external documents parts. Good implementation is in selectivexinclude.xsl file available at address on dev.w3.org site.
Any XSL processor. Described above xsltproc available from xmlsoft or saxon available from saxon site or xalan which is one of projects on xml.apache.org. All these tools are good for simple cases. However each of them offers different extensions so you choice depends of your unusual needs. However the use of xsltproc to join parts of modular documentation with selectivexinclude.xsl seems to not make great sense because of built-in support for XInclude into xsltproc.
Java users often ask a question: saxon or xalan? As I said above, if you need only standard XSLT processing they both are the same, they both (current stable versions: xalan-2.5.1, saxon-6.5.3) implement full XSLT 1.0 version and XPath 1.0 version. Current saxon development version: 7.6.5 implements XSLT-2.0 and XPath-2.0 and it is worth to note that the author of saxon library - Michael Kay is editor of the XSLT-2.0 spec. On the other side xalan is accepted library by SUN and is included with their JDK-1.4 and above what, on the third side, causes some problems when you want to use more recent xalan version than the one included in JDK.
Below are presented sample commands for each of 2 java tools for generating target, one XML document from modular documentation. These samples are tested with the most recent versions: saxon-7.6.5 and xalan-2.5.1 and some parameters may not work with earlier versions.
masterxmlfile.xml is source file containing XInclude elements.
targetalldoc.xml is target file containing included content of external files in place of XInclude elements.
selectivexinclude.xsl is XSL template containing transformation definition for including content from external files.
LIB is an environment variable pointing to directory on your disk where you keep JAR files.
Below are 2 kinds of commands. The simpler showing XSL inclusion only and a little bit more complex presenting also how to use CATALOGS with these tools. There are some additional elements in these commands: resolver.jar - library resolving URL to DTDs stored on your local file system and $PROJECTS_HOME/sgml - a directory where is placed CatalogManager.properties - file providing the same function as SGML_CATALOG_FILES environment variable. More information about using CATALOGS you can find in section Tools and methods for XML processing.
Example 24. Sample bash command for saxon.
export SAXON_CLASSPATH=$LIBS/saxon.jar java -cp $SAXON_CLASSPATH net.sf.saxon.Transform \ -w0 -u \ -o targetalldoc.xml \ masterxmlfile.xml selectivexinclude.xsl
Example 25. Sample bash command for saxon using CATALOGS.
export SAXON_CLASSPATH=$SAXON_CLASSPATH:$LIBS/resolver.jar:$PROJECTS_HOME/sgml java -cp $SAXON_CLASSPATH net.sf.saxon.Transform \ -x org.apache.xml.resolver.tools.ResolvingXMLReader \ -y org.apache.xml.resolver.tools.ResolvingXMLReader \ -r org.apache.xml.resolver.tools.CatalogResolver \ -w0 -u \ -o targetalldoc.xml \ masterxmlfile.xml selectivexinclude.xsl
Please remark below examples. If you work with JDK-1.4 or later you can not use CLASSPATH to point to your xalan jar file. There is some xalan version included with JDK-1.4, unfortunately outdated, and it is loaded first before classes given in CLASSPATH. To enforce the use of your classes you must put them in BOOTCLASSPATH as presented below.
Example 26. Sample bash command for xalan.
export XALAN_CLASSPATH=$LIBS/xalan.jar:$LIBS/xercesImpl.jar:$LIBS/xsml-apis.jar java -Xbootclasspath/p:$XALAN_CLASSPATH org.apache.xalan.xslt.Process \ -in masterxmlfile.xml -xsl selectivexinclude.xsl \ -out targetalldoc.xml
Example 27. Sample bash command for xalan using CATALOGS.
export XALAN_CLASSPATH=$XALAN_CLASSPATH:$LIBS/resolver.jar:$PROJECTS_HOME/sgml java -Xbootclasspath/p:$XALAN_CLASSPATH org.apache.xalan.xslt.Process \ -ENTITYRESOLVER org.apache.xml.resolver.tools.CatalogResolver \ -URIRESOLVER org.apache.xml.resolver.tools.CatalogResolver \ -in masterxmlfile.xml -xsl selectivexinclude.xsl \ -out targetalldoc.xml
You can edit docbook with the following free tools:
XXE is a java based, What You See Is What You Mean (WYSIWYM) editor. It provides a slightly clunky but workable GUI interface for editing Docbook documents. It is well worth trying.
Netbeans: Simple Docbook is XML, so XML editors work well. Netbeans has a nice XML plugin which I use.
There are a number of WYSIWYM editors developing Docbook export/import functionality at the time of writing. Of note, Open Office and Lyx look promising.
Viewing Docbook: Tomas has written a useful web page for viewing Docbook pages at http://www.cartesia.org/modules.php?op=modload&name=NS-Docbook&file=index.
There are a few references worth knowing:
The Linux Documentation Project Author Guide provides an introduction to Docbook and some of the key tags. Note that this project uses Simplified Docbook which is XML based. There are numerous versions of Docbook which makes things confusing.
Simplified Docbook, the Definitive Guide provides comprehensive documentation about all the Simplified Docbook tags.
Using the Docbook XSL Stylesheets, in particular, the section on writing modular docbook files.
Xincluder is a java open source project for processing xinlcude tags, which might be able to be used to by maven to publish modular docbook documents.