Robert Matthews Richard Pawson Stef Cascarini

Permission is granted to make and distribute verbatim copies of this manual provided that the copyright notice and this permission notice are preserved on all copies.

Preface

This manual documents the development of the Naked Objects Framework, its associated components and tools.

This manual has not yet been updated for Naked Objects 4.0.

You can download Naked Objects via www.nakedobjects.org, or direct from SourceForge, under an open source licence.

This edition of the manual is intended for use with version 3.0 of the Naked Objects framework, which works with Java version 1.5 or higher.

How to build Naked Objects from source

If you are thinking about modifying or contribute to Naked Objects, then you’ll want to be able to build Naked Objects from source.

Naked Objects is built using Maven 2. So it pretty much builds itself, provided you are on the Internet to download any dependencies. However:

  • Naked Objects also uses a couple of its own Maven plugins. Although the plan is for these to be made available in public repositories, that hasn’t happened at the time of writing. Therefore you may need to build these first.
  • There is one further dependency that is unavailable (due to licensing restrictions) from repositories, so that must be installed manually. This doc also describes how to install that dependency manually.

Although you can just use Maven from the command line, you’ll almost certainly want to use an IDE for proper development. We use Eclipse IDE with the M2Eclipse plugin. The maven-eclipse-plugin can be used to generate the Eclipse .project and related files; that’s why they aren’t checked into source code. If you use another IDE, then you may well find a similar Maven plugin.

Maven Modules

Full details of Maven modules are at http://nakedobjects.org/wiki/Maven_Modules.

Source Code Repository

The source code can be downloaded as a zip file, but we suggest accessing the repository directly so you can keep up to date with the latest ongoing developments.

The development version of the Naked Objects framework can be downloaded from the Subversion repository on SourceForge using the URL https://nakedobjects.svn.sourceforge.net/svnroot/nakedobjects. The following command gets hold of the trunk (main line of ongoing development) and creates a working directory called nakedobjects:

svn checkout https://nakedobjects.svn.sourceforge.net/svnroot/nakedobjects/framework/trunk nakedobjects

If you are a registered developer then also specify your SourceForge user name:

svn checkout https://username@nakedobjects.svn.sourceforge.net/svnroot/nakedobjects/framework/trunk nakedobjects

Prerequisites

  • Install a Subversion client, for example TortoiseSVN.
  • Install Java 5 or 6 and setup the JAVA_HOME environment variable.
  • Install Maven 2.0.9 or later, setup the MAVEN_HOME environment variable and add the path the mvn executable to PATH environment variable.
  • Install Eclipse 3.4 (JEE edition).

We also recommend that you install the following plugins for Eclipse:

Building Naked Objects

Building Naked Object’s own Maven plugins

The plugins are available from the URL https://nakedobjects.svn.sourceforge.net/svnroot/nakedobjects/maven-plugins/trunk. Check out that directory as for the framework itself. Then build from within the new direcotry using

$ mvn clean install

All being well, the plugins should build okay:

Running org.nakedobjects.doclet.xml.FileTest
Loading source files for package org.nakedobjects.doclet.tests...
Constructing Javadoc information...
/home/rcm/tmp/plugins/xmldoclet/target/api.xml
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.258 sec

Results :

Tests run: 22, Failures: 0, Errors: 0, Skipped: 0

[INFO] [jar:jar]
[INFO] Building jar: /home/rcm/tmp/plugins/xmldoclet/target/xmldoclet-1.0-SNAPSHOT.jar
[INFO] [install:install]
[INFO] Installing /home/rcm/tmp/plugins/xmldoclet/target/xmldoclet-1.0-SNAPSHOT.jar to /home/rcm/.m2/repository/org/nakedobjects/xmldoclet/1.0-SNAPSHOT/xmldoclet-1.0-SNAPSHOT.jar
[INFO] 
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] Naked Objects ......................................... SUCCESS [7.796s]
[INFO] code-example-plugin Maven Mojo ........................ SUCCESS [5.159s]
[INFO] xmldoclet ............................................. SUCCESS [15.622s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 29 seconds
[INFO] Finished at: Tue Sep 16 21:02:15 BST 2008
[INFO] Final Memory: 28M/247M
[INFO] ------------------------------------------------------------------------
[rcm@localhost plugins]$ 

Building from the Command Line

Building using Maven is a two step process. This allows the core framework and the distribution to be run separately so that work on the code can be quickly built and tested, while producing a distribution will take more time, but only when it is needed.

After checking out the source as descibed in an earlier section, build the core using:

$ mvn clean install

This will build to completion and all the generated jars will be added to the Maven repository [NB: the modules may have changed from the following list]:

[INFO] Authentication Implementations ........................ SUCCESS [0.059s]
[INFO] LDAP Authorization .................................... SUCCESS [1.209s]
[INFO] File-based Authorization .............................. SUCCESS [1.216s]
[INFO] Hibernate Authorization ............................... SUCCESS [1.703s]
[INFO] Authorization Proxy ................................... SUCCESS [0.745s]
[INFO] Authorization Implementations ......................... SUCCESS [0.065s]
[INFO] Viewer Drag and Drop Implementation ................... SUCCESS [28.322s]
[INFO] Viewer HTML Implementation ............................ SUCCESS [11.655s]
[INFO] Viewer Implementations ................................ SUCCESS [0.050s]
[INFO] Remoting Command Transport Encoding ................... SUCCESS [2.205s]
[INFO] Remoting Command Transport Serialize .................. SUCCESS [0.984s]
[INFO] Remoting Command Transport XStream .................... SUCCESS [1.103s]
[INFO] Remoting Command Transport Pipe ....................... SUCCESS [1.744s]
[INFO] Remoting Command Client Installer ..................... SUCCESS [1.174s]
[INFO] Remoting Command Server Installer ..................... SUCCESS [1.040s]
[INFO] Remoting Command Implementation ....................... SUCCESS [0.068s]
[INFO] XAT Documentor ........................................ SUCCESS [5.561s]
[INFO] XAT Framework ......................................... SUCCESS [2.529s]
[INFO] XAT (Executable Application Testing) .................. SUCCESS [0.113s]
[INFO] Bootstrap System ...................................... SUCCESS [0.677s]
[INFO] Bootstrapper Command Line Implementation .............. SUCCESS [2.970s]
[INFO] Bootstrapper Command Line DnD Client .................. SUCCESS [1.342s]
[INFO] Bootstrapper Command Line Jetty Client ................ SUCCESS [1.650s]
[INFO] Bootstrapper Web App Implementation ................... SUCCESS [6.644s]
[INFO] Bootstrap XAT JUnit4 Integration ...................... SUCCESS [1:11.722s]
[INFO] Bootstrapper Implementations .......................... SUCCESS [0.077s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7 minutes 7 seconds
[INFO] Finished at: Tue Sep 16 21:19:07 BST 2008
[INFO] Final Memory: 58M/247M
[INFO] ------------------------------------------------------------------------
[rcm@localhost nakedobjects_DEV_4.0]$

To create the documentation and the the distribution files use the dist profile

$ mvn clean install -P dist

The very first time you run the build, it’ll get most of the way until it hits the missing dependency while building the documentation:

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.

Missing:
----------
1) com.java:jimi:jar:1.0

  Try downloading the file manually from the project website.

  Then, install it using the command: 
      mvn install:install-file -DgroupId=com.java -DartifactId=jimi -Dversion=1.0 -Dpackaging=jar -Dfile=/path/to/file

  Alternatively, if you host your own repository you can deploy the file there: 
      mvn deploy:deploy-file -DgroupId=com.java -DartifactId=jimi -Dversion=1.0 -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]

  Path to dependency: 
      1) com.agilejava.docbkx:docbkx-maven-plugin:maven-plugin:2.0.8
      2) com.java:jimi:jar:1.0

----------
1 required artifact is missing.

for artifact: 
  com.agilejava.docbkx:docbkx-maven-plugin:maven-plugin:2.0.8

from the specified remote repositories:
  central (http://repo1.maven.org/maven2),
  jboss.org (http://repository.jboss.org/maven2),
  java.net (https://maven-repository.dev.java.net/repository)


[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 32 seconds
[INFO] Finished at: Tue Sep 16 21:21:58 BST 2008
[INFO] Final Memory: 48M/247M
[INFO] ------------------------------------------------------------------------
[rcm@localhost nakedobjects_DEV_4.0]$

The fix is as suggested by Maven itself:

  • Download the jimi jar file. You’ll find it within the JimiProClasses.zip downloadable from the Jimi page.
  • Install into your local Maven repository using:
    mvn install:install-file –D groupId=com.java –D artifactId=jimi –D version=1.0 –D packaging=jar \ –D file=/path/to/jimi.jar

You can then restart the build.

mvn clean install

This time it should complete to the end:

[INFO] Setting property: resource.manager.logwhenfound => 'false'.
[INFO] [archetype:jar]
[INFO] [archetype:add-archetype-metadata]
[INFO] [archetype:integration-test]
[INFO] [install:install]
[INFO] Installing /home/rcm/no-development/nakedobjects_DEV_4.0/archetype/target/nakedobjects-archetype-1.0-SNAPSHOT.jar to /home/rcm/.m2/repository/org/nakedobjects/nakedobjects-archetype/1.0-SNAPSHOT/nakedobjects-archetype-1.0-SNAPSHOT.jar
[INFO] [archetype:update-local-catalog]
[INFO] 
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] Naked Objects ......................................... SUCCESS [6.775s]
[INFO] Distribution Documentation Examples ................... SUCCESS [6.412s]
[INFO] Distribution Documentation ............................ SUCCESS [3:12.485s]
[INFO] Example Expenses DOM .................................. SUCCESS [4.136s]
[INFO] Example Expenses Email Service ........................ SUCCESS [2.525s]
[INFO] Example Expenses Fixtures ............................. SUCCESS [4.082s]
[INFO] Example Expenses Hibernate ............................ SUCCESS [3.362s]
[INFO] Example Expenses Client ............................... SUCCESS [15.070s]
[INFO] Distribution Tarball .................................. SUCCESS [1:40.606s]
[INFO] Distribution Eclipse Framework ........................ SUCCESS [21.527s]
[INFO] Distribution Eclipse Viewer DnD ....................... SUCCESS [7.374s]
[INFO] Distribution Eclipse Remoting Command XStream ......... SUCCESS [10.428s]
[INFO] Distribution Eclipse Hibernate ........................ SUCCESS [16.988s]
[INFO] Distribution Eclipse XAT .............................. SUCCESS [9.526s]
[INFO] Distribution Eclipse Example Expenses ................. SUCCESS [10.379s]
[INFO] Distribution Eclipse Example Expenses ................. SUCCESS [21.736s]
[INFO] Example Facet JSR303 Validation ....................... SUCCESS [7.168s]
[INFO] Distribution Eclipse Example Facet JSR303 ............. SUCCESS [8.454s]
[INFO] Distribution Eclipse .................................. SUCCESS [0.097s]
[INFO] Distribution .......................................... SUCCESS [0.055s]
[INFO] Examples Expenses Client Distribution ................. SUCCESS [7.160s]
[INFO] Example Expenses Server Distribution .................. SUCCESS [9.371s]
[INFO] Example Expenses ...................................... SUCCESS [0.059s]
[INFO] Example Facet Namefile ................................ SUCCESS [4.011s]
[INFO] Example Facets ........................................ SUCCESS [0.098s]
[INFO] Examples .............................................. SUCCESS [0.050s]
[INFO] Naked Objects Archetype ............................... SUCCESS [2.336s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7 minutes 59 seconds
[INFO] Finished at: Tue Sep 16 21:35:52 BST 2008
[INFO] Final Memory: 107M/267M
[INFO] ------------------------------------------------------------------------
[rcm@localhost nakedobjects_DEV_4.0]$ 

If you go to the ...... directory - documentation; zip files

Building in Eclipse

You can directly import all the projects into Eclipse. (Note: there no need to run mvn eclipse:m2eclipse).

[NB: the following screenshots are a little out-of-date, but you get the idea...]

File > Import

Specify the framework/trunk as root directory. The M2Eclipse plugin will locate all the Maven projects referenced:

Hit finish. You’ll end up with a bunch of projects:

You might then want to organize into working sets. We tend to organize by the top-level modules.

You can now set to develop using either Maven or Eclipse. One suggestion (pretty obvious really): if doing a command line build, then do a full refresh in Eclipse afterwards.

Code style

The style of framework code has developed over the lifetime of the project. This style should be adhere to in every class to provide consistency across the code base.

Code formatting

A code formatter specification is available for use within Eclipse. Every class should be formatted using this formatter before the code is checked back into the repository. The specification can be found in the root of source tree in the file java-format.xml. This can be summarised as follows:

File footer. Each code file should end with a copyright statement exactly as follows, starting in the first column

// Copyright (c) Naked Objects Group Ltd.

  • Indentation is achieved using spaces, not tabs; there should be no tabs, except where needed in quoted strings
  • Each level of indentation is 4 characters
  • Code lines are wrapped at 130 characters, with a two space indentation for wrapped lines
  • Comment lines are wrapped at 110 characters, with a two space indentation for wrapped lines
  • Statements should only be wrapped when too long for the line
  • Block braces ({}) start on the same line as their controlling statement and end, indented to the same level as the starting line, on a new line
  • No comments or blank lines should be placed before the package statement
  • One blank line between package statement and imports
  • Imports should be grouped by major type (java, com, org etc), with a blank line
  • Two blank lines between imports and class/interface declaration
  • A single blank line between each method declaration, and blocks of field etc

To set up code formatting use the Java/Code Style/Formatter section in the preferences to load in the format file, using the Import button, from the checked out source.

To set up the correct import order use the Java/Code Style/Organize Imports section in the preferences to load in the order file, nof.importorder, from the checked out source.

Naming

All names should be written in English and be full words.

Abbreviation should be avoided unless they are very well known and unambiguous. For example use international not i18n, and position not pos.

Abbreviations and acronyms should not be uppercase when used as name, and should only be used when it is common, such as XML, SQL, POP etc. Using all uppercase for the base name conflicts with the naming conventions below and reduces readability.

XmlObjectStore(); // NOT: XMLObjectstore

Where there are complementary concepts, then complementary names should be used, such as: start/stop; next/previous; begin/end, open/close, show/hide. This helps to indicate that things are related.

Package naming. All package names should be in lower case.

org.nakedobject.application

Class naming. All class names should be nouns and written in camel case. Interfaces should not have an 'I' placed in front of it.

NakedObject, Configuration

Method naming. Method names should be verbs and written in mixed case starting with lower case.

isActionStatic(), prepare()

Variable naming. Variable names must be in mixed case starting with lower case (never an underscore). Variables should have full sensible name, reflecting their purpose.

count, target, previousOid

Short variable names should only be used within small blocks of codes or short method, but never for parameter names.

Constant naming. Constants' names should be all uppercase with an underscore between words.

isActionStatic(), prepare()

Property naming. Accessor and mutator method names should be prefixed with get and set.

getActionName(), setDelay(int time)

Boolean methods and variables. Boolean variable and accessor method names should be prefixed with is, can, has or should.

isDirty(), canSave(NakedObject object)

Mutator methods for boolean variables should use a set prefix.

setDirty(), setInitialised(boolean initialised)

Constants

Use constants instead of fixed phrases, except for messages, debug information and the like. For example:

if (name.equals(OPENING_TAG)) // Not if (name.equals("<"))

Also use constants instead of magic numbers. For example:

if (line > MAXIMUM_LINES) // Not if (line > 5)

Code conventions

  • Classes, not packages, should be imported - no * - use the organise imports option to set up imports
  • Unless there is a clash of class names, fully qualified names should not be used in the code
  • No uneeded imports should be left in the code - this can be ensured via the organise imports option
  • Comments should not contain any JavaDoc tags that are not complete, including @param markers that simply echo the name of the parameter - these are often left in by the code templates
  • The end of each file should end with // Copyright (c) Naked Objects Group Ltd.\n on a line by itself
  • Where possible use final variables
  • All parameters should be marked as final
  • Do not check in commented-out code, use the repository to revert to previous versions
  • Add TODO, REVIEW, FIXME tasks to code wherever work is to be done on the code that you are not going to do now

A code template is also provided with the NOF code to provide consistent formatting and the exclusion of unwanted comments that are normally added by the IDE. This is set up in the Java/Code Style/Code Templates section of the preferences by loading in the file codetemplates.xml file from the root of the source tree.

Code order

Declarations within each class should follow the standard order, with each set ordered alphabetically. To avoid problems with static initialization set up dependent static variables within a static block. This order can be specified in the preferences under Java/Appearance/Members Sort Order, and the code can be ordered using the Source/Sort Members options.

  • Typed (inner classes etc)
  • Static field
  • Static initializers
  • Static methods
  • Initializers
  • Fields
  • Constructors
  • Methods

This order can be set up in the Java/Appearance/Member Sort Order section of the preferences. There is no import facility so it needs to be set up by hand as shown below.

Package naming

The NOF is released under the domain nakedobjects.org, so all packages start with org.nakedobjects. The main groupings are then:

  • noa - the NO architecture
  • applib - the application library for building independent domain models
  • nof - the core framework
  • nos - the components for building NO systems
  • example - example DOMs

Within the components (nos) there are currently the following subgoupings:

  • client - users of the framework, such as viewers and the testing framework
  • store - object store implementations
  • remote - remoting code for distributed processing