Developing Spring Roo Addons

5 minute read Published:

As of Roo 1.1.0, addons are created with the addon command. This is slightly different than previous versions, where addons were created with a template argument to the project command. If you find documentation referencing this old style, it’s probably out of date.

The first thing you need to do, is checkout the Roo source code. The Git repository is located at git://git.springsource.org/roo/roo.git. There are very good instructions explaining how to build Roo in the readme.txt file at the root of the source tree. Once Roo is built, you’ll need to create a new directory and fire up the Roo shell.

mkdir roo-addon-example
cd roo-addon-example
roo-dev
    ____  ____  ____  
   / __ \/ __ \/ __ \ 
  / /_/ / / / / / / / 
 / _, _/ /_/ / /_/ /  
/_/ |_|\____/\____/    1.1.1.RELEASE [rev 3057660]

roo>

With the shell running, you can create either a simple, advanced or i18n addon.

roo> addon create 

addon create advanced    addon create i18n        addon create simple
addon create simple --topLevelPackage com.example.roo.addon.example
Created /Users/marc/src/roo-addon-example/pom.xml
Created /Users/marc/src/roo-addon-example/readme.txt
Created /Users/marc/src/roo-addon-example/legal
Created /Users/marc/src/roo-addon-example/legal/LICENSE.TXT
Created SRC_MAIN_JAVA
Created SRC_MAIN_RESOURCES
Created SRC_TEST_JAVA
Created SRC_TEST_RESOURCES
Created SRC_MAIN_WEBAPP
Created SRC_MAIN_RESOURCES/META-INF/spring
Created SRC_MAIN_JAVA/com/example/roo/addon/example
Created SRC_MAIN_JAVA/com/example/roo/addon/example/ExampleCommands.java
Created SRC_MAIN_JAVA/com/example/roo/addon/example/ExampleOperations.java
Created SRC_MAIN_JAVA/com/example/roo/addon/example/ExampleOperationsImpl.java
Created SRC_MAIN_JAVA/com/example/roo/addon/example/ExamplePropertyName.java
Created ROOT/src/main/assembly
Created ROOT/src/main/assembly/assembly.xml
Created SRC_MAIN_RESOURCES/com/example/roo/addon/example
Created SRC_MAIN_RESOURCES/com/example/roo/addon/example/info.tagx
Created SRC_MAIN_RESOURCES/com/example/roo/addon/example/show.tagx

After the addon is created, exit the roo shell, then build and install the addon. You can package the addon from within Roo with perform package, but you’ll see why we installed it shortly.

quit
mvn clean install

Having installed the addon, you’re almost ready to use it. There are a few ways to load your addon into the Roo runtime. The one I like the best is to set up your local maven repository as an OSGI Bundle Repository (OBR). The project created with the addon create command is configured to use the Maven Bundle Plugin, which will create a repository.xml file in your local Maven repository. To tell Roo to use your local Maven repository as an OBR, simply add a line to the config.properties file as shown below, where ROO_HOME is the Roo source directory.

// $ROO_HOME/bootstrap/src/main/conf/config.properties
obr.repository.url=file:/home/whoever/.m2/repository/repository.xml

If you’ve recently built Roo from source, you may want to null out the repository.xml file before building your addon, as it will be full of the core Roo addons. Keep in mind that you can use git stash to clean your working directory if you want to pull down the latest development changes later on. Now that Roo knows where to look for your addon, you can start the shell back up.

roo-dev

If you set everything up right, your local Maven repository should now show up as an OBR, and the addon you just installed should be available within it.

roo> osgi obr url list
file:/home/whoever/.m2/repository/repository.xml

roo> osgi obr list
com-example-roo-addon-example [com.example.roo.addon.example] (0.1.0.BUILD-SNAPSHOT)

The main advantage of this approach is that you don’t have to type the path to addons when starting them. Roo will tab-complete the addon bundle name, so you should only have to type enough to make it unique.

roo> osgi obr start --bundleSymbolicName com.example.roo.addon.example
[Thread-2] [com.example.roo.addon.example [73]] BundleEvent INSTALLED
[Thread-2] [com.example.roo.addon.example [73]] BundleEvent RESOLVED
[Thread-2] [com.example.roo.addon.example [73]] BundleEvent STARTED
roo> Target resource(s):
-------------------
   com-example-roo-addon-example (0.1.0.BUILD-SNAPSHOT)

Deploying...done.

[Thread-2] [com.example.roo.addon.example [73]] ServiceEvent REGISTERED

Your addon should now show up in the output of osgi ps.

roo> osgi ps
...
[  75] [Active     ] [    1] com-example-roo-addon-example (0.1.0.BUILD-SNAPSHOT)

roo> say hello --name marc
Welcome marc!
Country of origin: None of your business!
It seems you are a running JDK 1.6.0_22
You can use the default JDK logger anywhere in your add-on to send messages to the Roo shell

You can make changes to your addon and reload it without restarting the Roo shell. To change the command output for the example addon, you can modify the ExampleCommands.java file, change the sayHello method, then reinstall the addon.

mvn clean install
roo> osgi uninstall --bundleSymbolicName com.example.roo.addon.example
[Thread-2] [com.example.roo.addon.example [73]] ServiceEvent UNREGISTERING
[Thread-2] [com.example.roo.addon.example [73]] BundleEvent STOPPED
[Thread-2] [com.example.roo.addon.example [73]] BundleEvent UNRESOLVED
[Thread-2] [com.example.roo.addon.example [73]] BundleEvent UNINSTALLED
[Thread-2] [org.apache.felix.framework [0]] FrameworkEvent PACKAGES REFRESHED

roo> osgi obr start --bundleSymbolicName com.example.roo.addon.example
[Thread-2] [com.example.roo.addon.example [74]] BundleEvent INSTALLED
[Thread-2] [com.example.roo.addon.example [74]] BundleEvent RESOLVED
Target resource(s):
-------------------
   com-example-roo-addon-example (0.1.0.BUILD-SNAPSHOT)

Deploying...done.

[Thread-2] [com.example.roo.addon.example [74]] ServiceEvent REGISTERED
[Thread-2] [com.example.roo.addon.example [74]] BundleEvent STARTED
[Thread-2] [com.example.roo.addon.example [74]] ServiceEvent REGISTERED

roo> say hello --name marc                                            
This is my new message

One downside to the OBR approach, is that you can’t just use the osgi update command to reload your addon. I think this is a bug, as it works fine if you load the addon from an explicit file system path via osgi start --url. Until that gets fixed, you need to uninstall and start the addon to reload it as was shown above.

If you need to debug Roo or your own addon, you can uncomment the DEBUG line towards the end of the roo-dev script. Roo will suspend on startup until you connect to it as a remote application with your IDE of choice.

DEBUG="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y"

That’s all you need to know to get started. The Spring Roo Forum is a good place to go if you need additional information. This post in particular has some useful direction. You can also build the project documentation locally with mvn site, but be prepared to wait a while. The documentation will be at $ROO_HOME/target/site/reference/html/index.html. It’s still in progress, but the content that’s there is good.