CASE tools

Here we give high-level overviews of and references to the tools we will be using: Eclipse, JavaDoc, Ant, Subversion, and JUnit.

Eclipse IDE

An Integrated Development Environment (IDE) is a tool that supports code edit-compile-debug in a unified environment.

Eclipse has become the standard open sourceJava IDE. It has several advantages for us, primarily its integrated suport for JUnit and SVN, so those tools can be smoothly incorporated into your projects. Additionally there are many plug-ins available for it, including ones that allow WYSIWYG GUI building, UML diagram editing, XML, web, J2EE, Database, etc integration. In short, its the singular programming tool of the future and you need to know it! Eclipse is installed on the CS Undergraduate Lab PC's, and you can download your own free copy for Win32/Mac/Linux. Note the program is a memory and CPU hog so it may not work satisfactorily on an old PC.

Eclipse plugins

We recommend using the following plugins. Click on the links below to download; all are free in some edition.
For UML: Omondo EclipseUML Free
With this plugin you can draw UML diagrams within Eclipse. Some tutorials on Omondo are found here. The PC's in the undergrad lab have Omondo installed on them. Another UML plugin is UMLet.
For WYSIWYG GUI building, the Visual Editor Project is the main plug-in for this purpose.
A tutorial article on VEP is here. The VEP doesn't seem to work on Macintosh at this point, but it does work on Win32/Linux. Jigloo and SWT Designer are other good Eclipse GUI builder plugins to try.
Subclipse
Ecplise has built-in support for CVS; this plugin adds subversion support. More below on it.
eclipse-plugins.info
This website indexes all the Eclipse plugins out there.

JavaDoc

JavaDoc is a Sun tool which allows html documentation to be generated from Java comments. It comes with the Sun JDK so you shouldn't need to install it.
How to Write Doc Comments for Javadoc
The all-important tutorial introduction to JavaDoc.
JavaDoc Reference (Linux/Solaris) (Windows)
Reference manual for the details and how to invoke the javadoc command, which produces .html files from your .java files.

JavaDoc Super Brief Overview

JavaDoc is so simple that one example can give you most of the idea.

Here is an example commented class. The key thing is to exactly follow the comment formatting below in terms of the initial /** and *'s starting each subsequent line, and note various special "@" commands may be used to good purpose:


       /**
        * Graphics is the abstract base class for all graphics contexts
        * which allow an application to draw onto components realized on
        * various devices or onto off-screen images.
        * A Graphics object encapsulates the state information needed
        * for the various rendering operations that Java supports.  This
        * state information includes:
        * <ul>
        * <li>The Component to draw on
        * <li>A translation origin for rendering and clipping coordinates
        * <li>The current clip
        * <li>The current color
        * <li>The current font
        * <li>The current logical pixel operation function (XOR or Paint)
        * <li>The current XOR alternation color
        *     (see <a href="#setXORMode">setXORMode</a>)
        * </ul>
        * <p>
        * Coordinates are infinitely thin and lie between the pixels of the
        * output device.
        * Operations which draw the outline of a figure operate by traversing
        * along the infinitely thin path with a pixel-sized pen that hangs
        * down and to the right of the anchor point on the path.
        * Operations which fill a figure operate by filling the interior
        * of the infinitely thin path.
        * Operations which render horizontal text render the ascending
        * portion of the characters entirely above the baseline coordinate.
        * <p>
        * Some important points to consider are that drawing a figure that
        * covers a given rectangle will occupy one extra row of pixels on
        * the right and bottom edges compared to filling a figure that is
        * bounded by that same rectangle.
        * Also, drawing a horizontal line along the same y coordinate as
        * the baseline of a line of text will draw the line entirely below
        * the text except for any descenders.
        * Both of these properties are due to the pen hanging down and to
        * the right from the path that it traverses.
        * <p>
        * All coordinates which appear as arguments to the methods of this
        * Graphics object are considered relative to the translation origin
        * of this Graphics object prior to the invocation of the method.
        * All rendering operations modify only pixels which lie within the
        * area bounded by both the current clip of the graphics context
        * and the extents of the Component used to create the Graphics object.
        * 
        * @author      Sami Shaio
        * @author      Arthur van Hoff
        * @version     %I%, %G%
        * @since       JDK1.0
        */
       public abstract class Graphics {

           /** 
            * Draws as much of the specified image as is currently available
            * with its northwest corner at the specified coordinate (x, y).
            * This method will return immediately in all cases, even if the
            * entire image has not yet been scaled, dithered and converted
            * for the current output device.
            * <p>
            * If the current output representation is not yet complete then
            * the method will return false and the indicated {@link ImageObserver}
            * object will be notified as the conversion process progresses.
            *
            * @param img       the image to be drawn
            * @param x         the x-coordinate of the northwest corner of the 
            *                  destination rectangle in pixels
            * @param y         the y-coordinate of the northwest corner of the 
            *                  destination rectangle in pixels
            * @param observer  the image observer to be notified as more of the 
            *                  image is converted.  May be <code>null</code>
            * @return          <code>true</code> if the image is completely 
            *                  loaded and was painted successfully; 
            *                  <code>false</code> otherwise.
            * @see             Image
            * @see             ImageObserver
            * @since           JDK1.0
            */
           public abstract boolean drawImage(Image img, int x, int y, 
                                             ImageObserver observer);


           /**
            * Dispose of the system resources used by this graphics context.
            * The Graphics context cannot be used after being disposed of.
            * While the finalization process of the garbage collector will
            * also dispose of the same system resources, due to the number
            * of Graphics objects that can be created in short time frames
            * it is preferable to manually free the associated resources
            * using this method rather than to rely on a finalization
            * process which may not happen for a long period of time.
            * <p>
            * Graphics objects which are provided as arguments to the paint
            * and update methods of Components are automatically disposed
            * by the system when those methods return.  Programmers should,
            * for efficiency, call the dispose method when finished using
            * a Graphics object only if it was created directly from a
            * Component or another Graphics object.
            *
            * @see       #create
            * @see       #finalize
            * @see       Component#getGraphics
            * @see       Component#paint
            * @see       Component#update
            * @since     JDK1.0
            */
           public abstract void dispose();

           /**
            * Disposes of this graphics context once it is no longer referenced.
            * @see       #dispose
            * @since     JDK1.0
            */
           public void finalize() {
               dispose();
           }
       }
The command javadoc Graphics.java produces This html output.

Wasn't that easy?

Ant

Ant is a simple make-like build tool for Java. You can easily install it on your own machine. It is also bundled with Eclipse so you probably won't need to install it. Eclipse has its own build tool which generally works well for most projects; only projects requiring special operations in the build will need to use Ant.
Manual
The above contains everything you need to learn how to use Ant.
Here is a very quick review of Ant.

What Buildfiles do

A Buildfile has several main elements Ant syntax is in XML notation. Here is an example build.xml file.
<project name="MyProject" default="dist" basedir=".">

  <!-- set global properties for this build -->
  <property name="src" value="."/>
  <property name="build" value="build"/>
  <property name="dist"  value="dist"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init">
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}"/>
  </target>

  <target name="dist" depends="compile">
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}/lib"/>

    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
  </target>

  <target name="clean">
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>
Once you have a file just type command "ant" to invoke the buildfile build.xml in the current directory with the default target, or name a target.

There are a lot more features of Ant which you can read the manual to find out:

Subversion

It is recommended that you use Subversion version control software for your projects. Subversion is newer and better version of the classic CVS version control system, but it is still a bit "bleeding edge" and is a bit harder to get running if you are a Windows PC user.

To use Subversion, you need a Subversion program both on the repository machine which is a machine that stores the master copies of the files and should be on the internet all the time (ugradx.cs.jhu.edu is recommended for team projects), and you need a copy on the local computer you are editing on, e.g. your own PC. Subversion is also available inside Eclipse via the subclipse plug-in described below, so by using Eclipse on your PC you get the client-side functionality for free. Download the binaries for your own computer from the Subversion homepage.

Help and Docs on Subversion

The Subversion book, at http://svnbook.red-bean.com/ is the standard reference.

Subversion Very Quick Overview

Subversion terminology:

An incredibly brief guide to using Subversion

Setting up the Subversion repository on e.g. ugradx is generally via the following sequence of UNIX/DOS command-line operations (we focus on the UNIX version here). In the below assume your home directory has path /home/group22.
  1. Initialize the new repository:
    $ svnadmin create /home/group22/repos --fs-type fsfs
    This creates a new directory repos/ in which all the files will go. RULE: Never cd into this directory -- think of it as a raw database you never directly look at.
    The option '--fs-type fsfs' is essential if you are creating the repository on an NFS mounted volume under UNIX. The locking semantics of NFS are not strong enough to use BerkeleyDB without risking corruption.
  2. Create the standard SVN directory structure in your repository.
      $ svn mkdir file:///home/group22/repos/trunk
      $ svn mkdir file:///home/group22/repos/tags
      $ svn mkdir file:///home/group22/repos/branches
      
    These directories have special purposes in SVN. The main copy of all files is in the 'trunk' directory. Working branches are made to the 'branches' directory and tagging is performed in the 'tags' directory. (See more on Branching and Tagging below)
  3. Copy the current source tree myproject/ into the repository trunk (assumes you already had some code)
    $ svn import myproject/ file:///home/group22/repos/trunk
    --this will create a new project named myproject in the repository.
Then the process to check files out to edit on a UNIX computer is
  1. svn checkout file:///home/group22/repos/trunk myproject - checks out a copy of all the files and puts them in a new directory myproject/.
  2. cd myproject/
  3. ... edit ...
  4. svn commit to save changes to the repository
  5. ... go away for the weekend ...
  6. cd myproject; svn update to update your copy to pick up any changes in or additions to the repository.
  7. To create a new file Snork.java under myproject/, do
    svn add Snork.java; svn commit Snork.java to get it in the repository.
  8. See the docs for how to move, delete, recover old versions, etc etc.
  9. Thats it!
If multiple people changed a file it attempts to merge changes in a smart manner. Usually it succeeeds, but if not you will need to go in by hand and patch the two versions.

Branching and Tagging

Branching is a concept common to most version control systems. Is allows you to maintain a number of parallel versions of your repository. A process called merging is used to apply the chnages made to one branch to another. Branches are usually created by making a copy of the 'trunk' of your repository.
Creating a branch
>From within your working copy you can create a branch named 'mybranch' by executing the following commands.
$ svn copy trunk branches/mybranch
$ svn commit -m "Creating mybranch"
Now you can commit changes to the working copy in branches/mybranch independently of trunk.
Merging
To apply changes made to one branch to another, you are said to be merging. In SVN merging works by choosing a range of revisions numbers, generating a diff for those versions (so all edits in the revision range are included) and then applying that diff to a working copy. For example, if you had been working on the branch made previously, and want to merge back into trunk, you would do the following (from the trunk directory of your working copy):
$ svn merge -r begin:end file:///home/group22/repos/branches/mybranch
Where begin and end are the revision numbers corresponding to the earliest and latest changes you wish to merge. At this point, it is as if you had performed an svn update -- your working copy may be in a conflicted state. You must manually edit any conflicts.
Then you need to commit to actually save the merge into trunk.
Tagging
Tagging simply allows you to mark a specific revision of you repository with some name, and easily view that version later. You should never make changes to a tag. A common tagging scenario might be when your project reaches a milestone. To make a tag, you just make a copy, just like branching:
$ svn copy trunk tags/milestone1
$ svn commit -m "Creating mybranch"

Accessing a remote repository via svn+ssh://

You can access a repository residing on a remote machine hooked to the Internet by repository URLs such as
svn+ssh://group22@ugradx.cs.jhu.edu/home/group22/repos/trunk
instead of the file:////home/group22/repos/trunk above -- this will use ssh to communicate with the remote machine, logging into your group22 account there. This is likely the way you will want to use it: keep your repository on ugradx and check out code remotely via the above, from your home or dorm or office PC or Linux or Mac box.

If you have a Windows PC you need to tell subversion where your ssh program is for svn+ssh to work -- see this message for how you can do this. If your PC doesn't have ssh on it, one good program is PuTTY.

Setting up a remote repository accessed via svn://

You can even run your own svn server -- see the documentation for how to do this. You need a computer to run an Internet service on which is always up and accessible, so this approach is only for the more ambitious (and well-connected).

Subversion in Eclipse: subclipse

Subversion is not built into Eclipse but can be added via the plugin subclipse. It is recommended that you use subclipse; you will not need to use the above command-line options directly because subclipse will invoke them for you. Installation instructions are here and the documentation is here. Windows users connecting via svn+ssh will still need to configure that, see above.

TortoiseSVN

Windows users may also find the TortoiseSVN Windows Explorer plugin useful. It can be used instead of the command line program, or a plugin for your development environment. Access the SVN commands from the right click context menu in Explorer.

CVS

Subversion is preferred, but support is still not uniform and you can use CVS instead if you are having problems getting subversion to work.

To use CVS, you need a CVS program both on the repository machine which is a machine that stores the master copies of the files and should be on the internet all the time (barley.cs.jhu.edu is recommended), and you need a copy on the local computer you are editing on, e.g. your own PC. CVS is also built into Eclipse, so by using Eclipse on your PC you get the client-side functionality for free.

Help and Docs on CVS

CVS Very Quick Tutorial

CVS terminology:

A brief guide to using CVS

Setting up the CVS repository on e.g. barley is generally via the following sequence of operations:
  1. Set the CVSROOT to point to a new directory which will be the repository
    mkdir ~group22/cvsroot
    setenv CVSROOT ~group22/cvsroot
  2. Initialize the new repository:
    cvs  init
  3. Copy the current source tree if any into the CVSROOT
    $ cd ~group22/ouroldprojecthome/
          $ cvs import -m "Imported sources" project junkfield start
    --they will be under the "project" directory in the repository.
Then the process to check files out to edit on barley or another CS Linux computer is
  1. cd myprojectcopy
  2. cvs checkout project
  3. ... edit ...
  4. cvs commit to save changes
  5. ... go away for the weekend ...
  6. cd myprojectcopy; cvs update to update your copy to pick up any changes in or additions to the repository.
  7. Create a new file Snork.java under myprojectcopy/, do cvs add Snork.java; cvs commit Snork.java to get it in the repository.
If multiple people changed a file it attempts to merge changes in a smart manner. Usually it succeeeds, but if not you will need to go in by hand and patch the two versions.

CVS on your Windows PC and via Eclipse

If you are using a Windows PC at home, Eclipse has CVS functionality built into it -- all you need is an SSH client on your PC (Eclipse's CVS can also be used instead of the command line CVS on your Linux or Mac box). Here is some helpful information.
  1. If your PC doesn't have ssh on it, one program is PuTTY.
  2. Alternatively, Cygwin includes command-line SSH.
  3. When checking out a new CVS project, choose the extssh connection type.
  4. If you want to run CVS outside of Eclipse, you can either use Cygwin above which has CVS built in, or use WinCVS. Read this guide on configuring WinCVS to work with SSH.

Running a CVS client directly on your Linux box

If your machine has cvs and ssh installed (it does if its Linux), here is how you can set it up to use a CS Linux machine repository for your files:

setenv CVS_RSH ssh
setenv CVSROOT :ext:group17@ugradx.cs.jhu.edu:/home/2/group17/cvsroot
Then, regular cvs commands above work across the network (you will need to enter your password each time).

JUnit

JUnit is the simple unit testing framework developed for Java. It is itself written in Java. It is also free and easy to download and install.
junit.org
One-stop shopping for JUnit downloads, getting started info, and documentation. Below are some good links from this site.
JUnit information
The above page contains all you need to know to get going with JUnit, in particular the Cookbook which is a good simple tutorial.
JUnit API docs
via Javadoc
For testing GUI's automatically, use Abbot. For automated testing of distributed applications, use Cactus.
Look here for a huge list of open sourse JUnit-inspired testing tools.

Brief JUnit tutorial

Here is a brief tutorial.

Class Testing Example: Say you have a class FileReader. Make a class FileReaderTester extends TestCase that has methods:
  setUp() // for all tests of this class, this creates object and sets it up
          // for test
  tearDown() // clean up after test
  static suite() // tests we're going to run
   { 
      suite = new TestSuite();
      suite.addTest (new FileReaderTest("testRead"));
             // reflection above: testRead is a method name in FileReaderTest
      // add rest of tests..
      return (suite);
   }

  // file reader test suite
  testRead() // our methods to do the testing ...
       ... assert(character == '2') ... // condition that must hold
       ... assertEquals(character,'2') ... // better way to do above.
  testWrite()
  testEmpty()
Now to run tests, use the JUnit TestRunner class:
junit.textui.TestRunner.run(aTestSuite);
Note that for each test, setUp() and tearDown() are run before and after. This means each test should be independent.

All the tests

In general you want to make a master test suite containing all the individual class test suites
      class MasterTester extends TestCase {
        public static void main (String [] args) {
          junit.textui.TestRunner.run(suite());
      }
      public static Test suite() {
        testSuite result = new TestSuite();
        result.addTest(new TestSuite(FileReaderTester.class));
           // -- adds a suite of tests when a testCase class is passed
        result.addTest(new TestSuite(FileWriterTester.class));
        // .. etc
        return result;
      
Then java MasterTester will run all the tests for all the classes.

JUnit Test Infected -- an example of JUnit in action »

Eclipse and JUnit

Another tutorial on using JUnit in Eclipse »