Description
The RMI plugin adds a remoting client that uses the Java RMI protocol. It is compatible with Grails' Remoting plugin 1.0.
Installation
The current version of griffon-rmi-plugin is 0.1
To install just issue the following command
griffon install-plugin rmi
Usage
The plugin will inject the following dynamic methods:
- withRmi(Map params, Closure stmts) - executes stmts using the Java RMI protocol. You must use a nested service() call in order to access a remote service.
Where params may contain
| Property | Type | Required | Notes |
|---|---|---|---|
| host | String | |
|
| port | int | |
|
| id | String | |
|
| lazy | boolean | |
if true will locate the java.rmi.Registry when the first service call is made. Defaults to true |
Examples
This example relies on Grails as the service provider. Follow these steps to configure the service on the Grails side:
- Download a copy of Grails and install it.
- Create a new Grails application. We'll pick 'exporter' as the application name.
grails create-app exporter
- Change into the application's directory. Install the remoting plugin.
grails install-plugin remoting
- Create a service interface. This interface will be used on the Griffon side too.
src/main/groovy/exporter/MathService.groovy
package exporter import java.rmi.Remote import java.rmi.RemoteException interface MathService extends Remote { double add(double arg0, double arg1) throws RemoteException }

The service interface must be placed in a package other than the default one.
- Create an implementation for exporter.MathService
grails create-service MathService
grails-app/services/MathService.groovyclass MathService implements exporter.MathService { boolean transactional = false static expose = ["rmi"] double add(double arg0, double arg1){ println "add($arg0, $arg1)" // good old println() for quick debugging return arg0 + arg1 } }
- Start the application
grails run-app
Keep an eye on http://jira.codehaus.org/browse/GRAILSPLUGINS-865 as the remoting plugin has problems with Grails +1.1 |
Now we're ready to build the Griffon application
- Create a new Griffon application. We'll pick MathClient as the name
griffon create-app mathClient
- Install the rmi plugin
griffon install-plugin rmi
- Fix the view script to look like this
griffon-app/views/MathClientView.groovy
application(title: 'RMI Plugin Example', pack: true, locationByPlatform: true, iconImage: imageIcon('/griffon-icon-48x48.png').image, iconImages: [imageIcon('/griffon-icon-48x48.png').image, imageIcon('/griffon-icon-32x32.png').image, imageIcon('/griffon-icon-16x16.png').image]) { gridLayout(cols: 2, rows: 4) label("Num1:") textField(columns: 20, text: bind(target: model, targetProperty: "num1")) label("Num2:") textField(columns: 20, text: bind(target: model, targetProperty: "num2")) label("Result:") label(text: bind{model.result}) button("Calculate", enabled: bind{model.enabled}, actionPerformed: controller.calculate) }
- Let's add required properties to the model
griffon-app/models/MathClientModel.groovy
import groovy.beans.Bindable class MathClientModel { @Bindable String num1 @Bindable String num2 @Bindable String result @Bindable boolean enabled = true }
- Now for the controller code. Notice that there is minimal error handling in place. If the user types something that is not a number the client will surely break, but the code is sufficient for now.
griffon-app/controllers/MathClientController.groovy
class MathClientController { def model def calculate = { evt = null -> double a = model.num1.toDouble() double b = model.num2.toDouble() model.enabled = false doOutside { try { def result = withRmi(host: "localhost", port: 1199) { service("MathService") { add(a, b) } } doLater { model.result = result.toString() } } finally { model.enabled = true } } } }
- The final step will be to locate and jar up the exposed service interfaces and place them in your [Griffon] application's lib directory. They will be located at ~/.grails/<version>/projects/exporter/classes
- Start the application
griffon run-app
All dynamic methods will create a new client when invoked unless you define an id: attribute. When this attribute is supplied the client will be stored as a property on the instance's metaClass. You will be able to access it via regular property access or using the id: again.
The first argument to service() may be a String with the full qualified classname or a Class.


