The ModeShape project uses Maven as its primary build tool, Subversion
for its source code repository, JIRA for the issue management and bug tracking system,
and Hudson for the continuous integration system. We do not stipulate a specific integrated
development environment (IDE), although most of us use Eclipse and rely upon the code formatting
and compile preferences to ensure no warnings or errors.

The rest of this chapter talks in more detail about these different tools and how to set them up. But first, we briefly describe
our approach to development.

2.1. Development methodology

Rather than use a single formal development methodology, the ModeShape project incorporates those techniques, activities, and
processes that are practical and work for the project. In fact, the committers are given a lot of freedom for how they develop
the components and features they work on.

Nevertheless, we do encourage familiarity with several major techniques, including:

Agile software development
includes those software methodologies (e.g., Scrum) that promote development iterations and open collaboration. While the
ModeShape project doesn't follow these closely, we do emphasize the importance of always having running software
and using running software as a measure of progress. The ModeShape project also wants to move to more frequent
releases (on the order of 4-6 weeks)

Test-driven development (TDD)
techniques encourage first writing test cases for new features and functionality, then changing the code to add the
new features and functionality, and finally the code is refactored to clean-up and address any duplication or inconsistencies.

Behavior-driven development (BDD)
is an evolution of TDD, where developers specify the desired behaviors first (rather than writing "tests").
In reality, this BDD adopts the language of the user so that tests are written using words that are meaningful
to users. With recent test frameworks (like JUnit 4.4), we're able to write our unit tests to express
the desired behavior. For example, a test class for sequencer implementation might have a test method
shouldNotThrowAnErrorWhenStreamIsNull(), which is very easy to understand the intent.
The result appears to be a larger number of finer-grained test methods, but which are more easily understood
and easier to write. In fact, many advocates of BDD argue that one of the biggest challenges of TDD is knowing what
tests to write in the beginning, whereas with BDD the shift in focus and terminology make it easier for more
developers to enumerate the tests they need.

Lean software development
is an adaptation of lean manufacturing techniques,
where emphasis is placed on eliminating waste (e.g., defects, unnecessary complexity, unnecessary code/functionality/features),
delivering as fast as possible, deferring irrevocable decisions as much as possible,
continuous learning (continuously adapting and improving the process), empowering the team (or community, in our case),
and several other guidelines. Lean software development can be thought of as an evolution of agile techniques
in the same way that behavior-driven development is an evolution of test-driven development. Lean techniques
help the developer to recognize and understand how and why features, bugs, and even their processes impact the development
of software.

2.2. JDK

Currently, ModeShape is developed and built using JDK 5.
So if you're trying to get ModeShape to compile locally, you should make sure you have the JDK 5 installed and are using it.
If you're a contributor, you should make sure that you're using JDK 5 before committing any changes.

Note

You should be able to use the latest JDK,
which is currently JDK 6. It is possible to build ModeShape using JDK 6 without any code changes, but it's
not our official JDK (yet).

Why do we build using JDK 5 and not 6? The main reason is that if we were to use JDK 6, then ModeShape couldn't really be used in any
applications or projects that still used JDK 5. Plus, anybody using JDK 6 can still use ModeShape.
However, considering that the end-of-life for Java 5 is
October 2009, we will likely be switching to
Java 6 sometime in 2010.

When installing a JDK, simply follow the procedure for your particular platform. On most platforms, this should set the
JAVA_HOME environment variable. But if you run into any problems, first check that this environment
variable was set to the correct location, and then check that you're running the version you expect by running
the following command:

$ java -version

If you don't see the correct version, double-check your JDK installation.

2.3. JIRA

ModeShape uses JIRA as its bug tracking, issue tracking, and project management tool.
This is a browser-based tool, with very good functionality for managing the different tasks. It also serves as
the community's roadmap, since we can define new features and manage them along side the bugs and other issues.
Although most of the issues have been created by community members, we encourage any users to suggest new features,
log defects, or identify shortcomings in ModeShape.

The ModeShape community also encourages its members to work only issues that are managed in JIRA, and preferably those
that are targeted to the current release effort. If something isn't in JIRA but needs to get done, then create an
issue before you start working on the code changes. Once you have code changes, you can upload a patch to the JIRA issue
if the change is complex, if you want someone to review it, or if you don't have commit privileges and have fixed
a bug.

2.4. Subversion

ModeShape uses Subversion as its source code management system, and specifically the instance at
JBoss.org. Although you can view the
trunk of the Subversion repository directly
(or using FishEye) through your browser,
in order to get more than just a few files of the latest version of the source code, you probably want
to have an SVN client installed. Several IDE's have SVN support included (or available as plugins),
but having the command-line SVN client is recommended. See
http://subversion.tigris.org/ for downloads and instructions for your
particular platform.

When committing to SVN, be sure to include in a commit comment that includes the JIRA issue that the commit applies to and a very
good and thorough description of what was done. It only takes a minute or two to be very clear about the change. And including
the JIRA issue (e.g., "ModeShape-123") in the comment allows the JIRA system to track the changes that have been made for each issue.

Also, any single SVN commit should apply to one and only one JIRA issue. Doing this helps ensure that each commit is atomic
and focused on a single activity. There are exceptions to this rule, but they are rare.

Sometimes you may have some local changes that you don't want to (or aren't allowed to) commit. You can make a patch file
and upload it to the JIRA issue, allowing other committers to review the patch. However, to ensure that patches are easily
applied, please use SVN to create the patch. To do this, simply do the following in the top of the codebase (e.g., the
trunk directory):

$ svn diff . > ~/ModeShape-000.patch

where ModeShape-000 represents the ModeShape issue number. Note that the above command places the patch file in your home directory,
but you can place the patch file anywhere. Then, simply use JIRA to attach the patch file to the particular issue, also adding
a comment that describes the version number against which the patch was created.

To apply a patch, you usually want to start with a workspace that has no changes. Download the patch file, then issue the
following command (again, from the top-level of the workspace):

$ patch -E -p0 < ~/ModeShape-000.patch

The "-E" option specifies to delete any files that were made empty by the application of the patch, and the "-p0" option instructs
the patch tool to not change any of the paths. After you run this command, your working area should have the changes defined
by the patch.

2.5. Git

Several contributors are using Git on their local development machines. This allows
the developer to use Git branches, commits, merges, and other Git tools, but still using
the ModeShape Subversion repository. For more information, see our
blogposts on the topic.

2.6. Maven

ModeShape uses Maven 2 for its build system, as is this example. Using Maven 2 has several advantages, including
the ability to manage dependencies. If a library is needed, Maven automatically finds and downloads that library, plus
everything that library needs. This means that it's very easy to build the examples - or even create a maven project that
depends on the ModeShape JARs.

To use Maven with ModeShape, you'll need to have JDK 5 or 6 and Maven 2.0.9 (or higher).

Maven can be downloaded from http://maven.apache.org/, and is installed by unzipping the
maven-2.0.9-bin.zip file to a convenient location on your local disk. Simply add $MAVEN_HOME/bin
to your path and add the following profile to your ~/.m2/settings.xml file:

This profile informs Maven of the two JBoss repositories (snapshots
and releases) that contain all of the JARs for ModeShape and all dependent libraries.

While you're adding $MAVEN_HOME/bin to your path, you should also set the $MAVEN_OPTS environment variable
to "-Xmx256m". If you don't do this, you'll likely see an java.lang.OutOfMemoryError sometime during a full
build.

Note

The JBoss Maven repository provides a central location for not only the artifacts produced by the JBoss.org projects (well, at least those
that use Maven), but also is where those projects can place the artifacts that they depend on. ModeShape has a policy that
the source code and JARs for all dependencies must be loaded into the
JBoss Maven repository. It may be a little bit more work for the developers, but it does help ensure that developers have easy
access to the source and that the project (and dependencies) can always be rebuilt when needed.

For more information about the JBoss Maven repository, including instructions for adding source and JAR artifacts,
see the JBoss.org Wiki.

2.6.1. Building

There are just a few commands that are useful for building ModeShape (and it's subprojects).
Usually, these are issued while at the top level of the code (usually just below trunk/), although issuing
them inside a subproject just applies to that subproject.

Table 2.2. Useful Maven commands

Command

Description

mvn clean

Clean up all built artifacts (e.g., the target/ directory in each project)

mvn clean install

Called the "quick build". Clean up all produced artifacts; compile the source code and test cases;
run all of the unit tests; and install the resulting JAR artifact(s)
into your local Maven repository (e.g, usually ~/.m2/repository). This is often what
developers run prior to checking in changes, since it generally runs quickly.
Note that no integration tests are performed, and HSQLDB is used when a database is needed.

mvn clean install -Ddatabase=dbprofile

Same as the "quick build", except that it specifies the database management system
that is to be used by the tests.
Options for "dbprofile" values are:
"hsqldb", "h2",
"postgresql_local", "postgresql8",
"mysql5",
"oracle9i", "oracle10g", "oracle11g",
"db2v8", "db2v9",
"sybase15", and
"mssql2005".
The database connection information for these database profiles are in the parent "pom.xml" file,
and most of these are configured to use database instances within the JBoss Quality Assurance
lab and are accessible only to Red Hat employees. However, feel free to add your own profiles
or even change the settings in the POM file to suit your needs.

mvn -P integration clean install

This "integration build" does everything the "quick" build does plus it compiles and
runs the integration tests, which take several extra minutes to run.
Also, HSQLDB is used when a database is needed.

mvn -P integration clean install -Ddatabase=dbprofile

This does the same as the "integration build", except that it specifies the database management system
that is to be used by the unit and integration tests. Options for the "dbprofile" values are
the same as listed above.

mvn -P assembly clean install

This runs a builds all source code, documentation, JavaDoc, runs all unit and integration tests,
and produces all assemblies (e.g., zip files).
HSQLDB is used when a database is needed.

2.7. Continuous integration with Hudson

ModeShape's continuous integration is done with several Hudson jobs on JBoss.org.
These jobs run periodically and basically run the Maven build process. Any build failures or test failures are reported,
as are basic statistics and history for each job.

Integration build that runs every night (usually around 2 a.m. EDT), regardless of whether changes have been committed to SVN
since the previous night.

2.8. Eclipse IDE

Many of the ModeShape committers use the Eclipse IDE, and all project files required by Eclipse are committed in SVN, making
it pretty easy to get an Eclipse workspace running with all of the ModeShape projects.

We're using the latest released version of Eclipse,
available from Eclipse.org. Simply follow the instructions for your platform.

After Eclipse is installed, create a new workspace. Before importing the ModeShape projects, import (via
File->Import->Preferences) the subset of the Eclipse preferences by importing the
eclipse-preferences.epf file (located under trunk). Then, open the Eclipse preferences and
open the Java->Code Style-> Formatter preference page, and press the "Import" button and
choose the eclipse-code-formatter-profile.xml file (also located under trunk). This will load the code
formatting preferences for the ModeShape project.

Then install Eclipse plugins for SVN and Maven. (Remember, you will have to restart Eclipse after installing them.)
We use the following plugins:

After you check out the ModeShape codebase, you can import the ModeShape Maven projects into Eclipse as Eclipse projects.
To do this, go to "File->Import->Existing Projects", navigate to the trunk/ folder in the import wizard,
and then check each of the subprojects that you want to have in your workspace.
Don't forget about the projects under extensions/ or docs/.

2.9. Releasing

This section outlines the basic process of releasing ModeShape. This must be done
either by the project lead or only after communicating with the project lead.

Before continuing, your local workspace should contain no changes and should be a perfect reflection of Subversion.
You can verify this by getting the latest from Subversion

$ svn update

and ensuring that you have no additional changes with

$ svn status

You may also want to note the revision number for use later on in the process. The release number is returned by
the svn update command, but may also be found using

$ svn info

At this point, you're ready to verify that everything builds normally.

2.9.1. Building all artifacts and assemblies

By default, the project's Maven build process does not build the documentation, JavaDocs, or assemblies.
These take extra time, and most of our builds don't require them. So the first step of releasing ModeShape
is to use Maven to build all of regular artifacts (e.g., JARs) and these extra documents and assemblies.

Note

Before running Maven commands to build the releases, increase the memory available to Maven with this command:
$ export MAVEN_OPTS=-Xmx512m

To perform this complete build, issue the following command while in the trunk/ directory:

$ mvn -P assembly clean install

This command runs the "clean" and "install" goals using the "assembly" profile,
which adds the production of JavaDocs, the Getting Started document, the Reference Guide document,
the Getting Started examples, integration tests, and several ZIP archives. The order of the goals is important.

After this build has completed, verify that the assemblies under target/ have actually been created and that
they contain the correct information.
At this point, we know that the actual Maven build process is building
everything we want and will complete without errors. We can now proceed with preparing for the release.

2.9.2. Determine the version to be released

The version being released should match the JIRA road map. Make sure that all issues related to the release are closed.
The project lead should be notified and approve that the release is taking place.

2.9.3. Release dry run

The next step is to ensure that all information in the POM is correct and contains all the information required for
the release process. This is called a dry run, and is done with the Maven "release" plugin:

$ mvn -P assembly release:prepare -DdryRun=true

This may download a lot of Maven plugins if they already haven't been downloaded, but it will eventually prompt you for
the release version of each of the Maven projects, the tag name for the release, and the next development versions
(again for each of the Maven projects). The default values are probably acceptable; if not, then check that the
"<version>" tags in each of the POM files is correct and end with "-SNAPSHOT".

After the dry run completes you should clean up the files that the release plugin created in the dry run:

$ mvn -P assembly release:clean

2.9.4. Prepare for the release

Run the prepare step (without the dryRun option):

$ mvn -P assembly release:prepare

You will again be prompted for the release versions and tag name. These should be the same as what was used during the dry run.
This will run the same steps as the dry run, with the additional step of tagging the release in SVN.

If there are any problems during this step, you should go back and try the dry run option. But after this runs successfully,
the release will be tagged in SVN, and the pom.xml files in SVN under /trunk will have the
next version in the "<version>" values.
However, the artifacts for the release are not yet published. That's the next step.

2.9.5. Perform the release

At this point, the release's artifacts need to be published to the JBoss Maven repository. This next command check outs the
files from the release tag created earlier (into a trunk/target/checkout directory), runs a build, and then
deploys the generated artifacts. Note that this ensures that the artifacts are built from the tagged code.

$ mvn release:perform -DuseReleaseProfile=false

Note

If during this process you get an error finding the released artifacts in your local Maven repository, you may
need to go into the trunk/target/checkout folder and run $ mvn install. This is a simple
workaround to make the artifacts available locally. Another option to try is adding -Dgoals=install,assembly
to the $ mvn release:perform... command above.

The release has been performed, but we still need to build and deploy the real artifacts
to the JBoss Maven repository. To do
this, go to a working area and check out the recently-produced SVN tag (using the correct {release-number}):

This will rebuild all the artifacts (from your local copy of the tagged source) and deploy them
to the local file system, which is comprised of a local checkout of the JBoss Maven2 repository
in a location specified by a combination of the <distributionManagement> section of several pom.xml
files and your personal settings.xml file. Once this Maven command completes, you will need to
commit the new files after they are deployed. For more information, see the
JBoss wiki.

At this point, the software has been released and tagged, and it's been deployed to a local checked-out copy of the
ModeShape Maven 2 repository (via the "<distribution>" section of the pom.xml files). Those need to be committed
into the Maven 2 repository using SVN. And finally, the last thing is to publish the release onto
the project's downloads and documentation pages.

The assemblies of the source, binaries, etc. also need to be published onto the http://www.jboss.org/modeshape/downloads.html area of the
the project page. This process is expected to change, as JBoss.org
improves its infrastructure.

2.10. Summary

In this chapter, we described the various aspects of developing code for the ModeShape project.
Next, we must discuss the testing practices for ModeShape project.
This is the topic of the next chapter.