Accessing and Modifying the Source Code

Now that your development system is ready, you can get to work! These instructions will demonstrate some of the typical tasks you'll want to accomplish in browsing, building, and modifying the DrJava sources.

Downloading the Sources

You can use Subversion to get a copy of the DrJava source code. In Subversion terminology, downloading a fresh copy is (usually) synonymous with "checking out" the code. You can download the sources with the following command:

svn co https://drjava.svn.sourceforge.net/svnroot/drjava/trunk/drjava

A drjava directory will be created in your working directory, and Subversion will output the name of each file it downloads.

Note that the above command only checks out part of the DrJava sources. The sources are divided into independent modules, each a subdirectory of trunk. Each module can be built, tested, and modified without the others. You can check out a different directory by simply modifying the URL given to Subversion.

Warning

While it is possible to check out the entire https://drjava.svn.sourceforge.net/svnroot/drjava directory, you should not do so! This top-level directory contains dozens of copies of the sources, including snapshots at various stages of development. If you download this directory, it will take a lot of time and disk space.

The full list of trunk's subdirectories includes:

drjava

The main application, containing the bulk of the code. Building this module will create the DrJava application.

dynamicjava

The DynamicJava interpreter, which implements the functionality behind the Interactions Pane.

javalanglevels

A Java preprocessor used to provide the Language Levels facility.

plt

General-purpose utility classes, including things that are "missing" from the Java API like predicates and tuples.

platform

A collection of platform-dependent code, such as the concrete compiler interfaces and special OS-specific GUI setup instructions.

docs

The project documentation, including this document and end-user help files.

eclipse

A wrapper for the interactions pane that allows it to be run as a plug-in to the Eclipse IDE.

jedit

A similar wrapper for the interactions pane in the JEdit IDE.

misc

Files that don't belong in a specific module.

You may find it helpful to streamline the check-out process by creating an alias or a script file for the check-out command.

Building the Sources

In the drjava directory, you will find the file build.xml. This is the module's Ant script, containing instructions that automate a variety of development tasks. While in the drjava directory, enter:

ant help

or just

ant

The name help refers to an Ant target. Different targets can be used to accomplish different tasks, and they are often set up to recognize dependencies. For example, the test target recognizes its dependency on the compile target; when you ask Ant to run the tests, it will automatically compile them first. In this particular example, the help target (which is set up as the default when none is specified) simply prints a message about the script and the environment settings it expects. If an error occurs here, Ant may not be properly set up.

Second, enter the following command:

ant -p

You will see a list of all the documented targets in the project. Note that, due to the dependencies between targets, the build target will run generate-source, compile, test, and jar. That is, it will do everything required to build and test a new application. Try it out:

ant build

The process will take awhile. Ant will generally log each action it takes to the console; you should make sure you can follow what's going on. Here's a summary of the major steps:

  • generate-sourcePerforms any necessary preprocessing before the Java compiler is invoked. For example, a Version.java file is created so that a unique version number for this build will be accessible to the code (in particular, the DrJava application's About dialog box).

  • do-compileInvokes the javac compiler (the specific version used depends on your command path). Generated class files will be placed in a new classes directory, with the subdirectories base and test for standard and test classes, respectively. Any compiler errors or warnings will be printed to the console. Where warnings are expected, they will be tagged in the code with a @SuppressWarnings annotation. Thus, any warnings you see during compilation highlight a problem that should be addressed.

  • unjar-libsExpands the *.jar files in the lib directory into classes/lib. These library classes will be bundled with the finished product.

  • testRuns the JUnit tests in classes/test (the specific version of java used depends on your command path). This will constitute the bulk of the build time. A summary of the running time for each test will be logged, and if a failure occurs, testing will halt immediately.

  • jarCreates the drjava.jar file. This is the executable application. It will contain a MANIFEST.MF file listing the build's unique version number and your user name.

Now that you've built the application, you can run it with the following command:

java -jar drjava.jar

You can also run the application in some systems by double-clicking on the drjava.jar file. And the Ant script includes a variety of run commands that act as shortcuts: ant run-jar, for example, will compile, build a jar file, and run the application with assertions and error logging turned on.

Mac OS X

When you run the drjava.jar file, the DrJava GUI may not look quite right. This is because the official OS X application release wraps the jar file in some additional packaging and settings. However, all the essential functionality should still be there in your unofficial version.

Modifying the Sources

Once you've got a fresh copy of the sources and verified that they will build correctly, you're ready to start making modifications. The source files are stored in the src directory; you should be able to explore and edit them in any IDE or text editor. IDEs will be able to interface with the build script with various degrees of sophistication. If the IDE you use does not support Ant scripts (or you'd rather not bother with making it work properly), you can either do most of your building and testing from the command line, or do your "casual" development in the IDE, and just run the scripts when you are ready to commit a change. In the latter case, you'll want to keep a few things in mind:

  • It's best to consider the contents of the drjava directory transient — you will want to occasionally delete the directory completely and start from a fresh checkout. Thus, IDE-specific files like project descriptions are better stored somewhere else (unless you don't mind recreating them).

  • By default, the javac compiler places the *.class files it generates in the same location as their sources. That approach clutters up the src directory significantly, and should be avoided. You should also avoid putting the compiled classes in one of the Ant script's target locations (such as classes/base), as that might lead to confusing behavior when you invoke the script later. The best option is to either create a classes/ide-name directory in which to place your classes, or just store the IDE-compiled classes somewhere else entirely.

  • Your IDE's classpath should contain all the jar files in the lib directory (but not the lib/buildlib directory, with the exception of lib/buildlib/junit.jar).

  • You'll need to invoke the generate-source Ant target before you attempt to compile in the IDE (that is, unless the files have already been generated). Otherwise, some sources will be missing and the compilation will fail. Some IDEs may also have trouble with these files occasionally disappearing and reappearing, so you might want to ensure that the sources are in a consistent state before opening or closing the IDE application.

If you're using Eclipse, see the Eclipse section for instructions on setting up a project.

To get oriented and understand the program design, you may want to browse the System Architecture notes, along with the javadocs from the latest release (available at drjava.org). You can also generate your own up-to-date copy of the javadocs by invoking the Ant javadoc target. Before you make significant changes to the code, you should familiarize yourself with the Development Best Practices section of this document.

Once you've made some modifications, you'll probably want to try them out. The Ant script offers a couple of ways to do this. First, you can enter

ant run

This will run the DrJava application located in the classes/base directory. You can also run the JUnit tests. You can run a specific test (rather than waiting for all of them to run) by typing

ant -Dtest-spec=filterString test

All test classes in classes/test with paths matching filterString will be run by JUnit.

Submitting Your Changes

When you're ready to submit the changes you've made to the Subversion archive (in Subversion terminology, commit the changes), and assuming you're a member of the DrJava SourceForge project, you can do so with the Ant script. While the svn command could be invoked directly from the command line (or some IDEs), using Ant is the preferred approach because it allows you to ensure that your changes do not break any functionality or conflict with other changes that have been made by other developers concurrently. The Ant script will run a fresh compile and all tests before committing your changes.

If this is the first time you've committed a change on your current system, you will need to perform a manual commit in order to check your authentication. You can do this by checking out the https://drjava.svn.sourceforge.net/svnroot/drjava/trunk/misc/authenticate directory and following the instructions in authenticate/authenticate.txt. When you commit, you will be prompted for a password (if the username is incorrect, just hit Enter and you will be prompted for a username as well). [TODO: Improve this process, if possible. It would be nice if there were just an "svn authenticate" command.] That authentication information will be stored on your system, and future commits will not require you to reenter your password.

After your system is set up for automatic authentication, you can perform a commit with the following:

ant commit

The major steps in this process are enumerated below:

  • clean-intermediateRemoves all intermediate build products — that is, files that didn't come from the Subversion repository and that aren't finished products. This will include generated sources and the classes directory. Note that, typically, this target (or just clean) is also invoked directly as the need arises.

  • clean-productsRemoves all final build products. This will include DrJava jar files and generated javadocs.

  • updateDownloads all new changes that have been made in the Subversion repository since you last checked out (or updated) your sources. The command will list all filenames that are being changed locally; after the update, the status Subversion command will display any discrepancies between the repository and your working copy. If there is a conflict in the update (you and someone else have both changed the same file, or perhaps specifically an overlapping part of the same file), Subversion will let you know and give you a chance to manually merge the changes. This target is also typically invoked directly as the need arises (and you should use it often to catch conflicts while they are still small).

  • buildThe project is built from scratch, as described previously. This ensures that your submission is a valid, tested copy of the program.

  • clean-intermediateTo prevent extraneous messages when the commit takes place, the project is cleaned up once again.

  • commitYou are first prompted to enter a log message describing the changes you've made. These are generally just one-line summaries. Keep in mind that your message will be read in the context of the entire project when, for example, someone wants to know what changes have been made to the application recently. If you need help in remembering what files you've touched, look at the output of update, which ran just before the project was rebuilt. Next, each file you've modified will be uploaded and the changes will be assigned a fresh revision number.