1. Introduction

This plugin enables the usage of the Java RMI protocol on a Griffon application.

Griffon version: 2.11.0

2. Usage

The following sections describe how you may use this plugin in an project.

2.1. Configuration

The plugin’s module registers a RmiHandler helper class that defines the base contract for issuing RMI calls using an appropriate client class. This helper class has the following methods

griffon.plugins.rmi.RmiHandler.java
@Nullable
<R> R withRmi(@Nonnull Map<String, Object> params, @Nonnull RmiClientCallback<R> callback) throws RmiException;

void destroyRmiClient(@Nonnull String clientId);

The following properties must be defined:

host

The host on which remote objects haven been registered. String. Default localhost.

port

The port on which objects were exported. Integer. Default 1099.

lazy

Attempt a connection to the RMI registry as late as possible. Boolean. Default true.

These methods will create a new client when invoked unless you define an id: attribute. When this attribute is supplied the client will be stored in a cache managed by their respective storage classes (RmiClientStorage).

You can inject an instance of RmiHandler anywhere it’s needed using @Inject.

The RmiClientCallback callback is defined using a functional interface approach, which means you can apply lambda expressions if running with JDK8+ or closures if running Groovy.

griffon.plugins.rmi.RmiCallback.java
    @Nullable
    R handle(@Nonnull Map<String, Object> params, @Nonnull RmiClient client) throws RmiException;
}

2.2. Example

The following is a trivial usage of the RmiHandler inside a service

CalculatorService.java
import griffon.core.GriffonApplication;
import griffon.core.artifact.GriffonService;
import griffon.exceptions.GriffonException;
import griffon.metadata.ArtifactProviderFor;
import griffon.plugins.rmi.exceptions.RmiException;
import griffon.util.CollectionUtils;
import org.codehaus.griffon.runtime.core.artifact.AbstractGriffonService;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import java.rmi.RemoteException;
import java.util.Map;

@ArtifactProviderFor(GriffonService.class)
public class CalculatorService extends AbstractGriffonService {
    @Inject
    private RmiHandler rmiHandler;

    @Inject
    public CalculatorService(@Nonnull GriffonApplication application) {
        super(application);
    }

    public Double calculate(final double num1, final double num2) {
        Map<String, Object> params = CollectionUtils.<String, Object>map()
            .e("id", "client");
        return rmiHandler.withRmi(params,
            new RmiClientCallback<Double>() {
                @Nullable
                public Double handle(@Nonnull Map<String, Object> params, @Nonnull RmiClient client) throws RmiException {
                    return client.service(Calculator.NAME, new UnaryConsumer<Calculator, Double>() {
                        @Override
                        public Double consume(Calculator calculator) {
                            try {
                                return calculator.add(num1, num2);
                            } catch (RemoteException e) {
                                throw new GriffonException(e);
                            }
                        }
                    });
                }
            });
    }
}

Here’s the Groovy version of the same service

GroovyCalculatorService.groovy
import griffon.core.artifact.GriffonService
import griffon.metadata.ArtifactProviderFor

import javax.inject.Inject

@ArtifactProviderFor(GriffonService)
class GroovyCalculatorService {
    @Inject
    private RmiHandler rmiHandler

    Double calculate(double num1, double num2) {
        Map params = [id: 'client', port: 1199]
        rmiHandler.withRmi(params, { Map<String, Object> ps, RmiClient client ->
            client.service(Calculator.NAME) { Calculator calculator ->
                calculator.add(num1, num2)
            }
        })
    }
}

2.3. AST Transformation

You can apply the @RmiAware AST transformation on any class. This injects the behavior of RmiHandler into said class.

2.4. DSL Descriptors

This plugin provides DSL descriptors for Intellij IDEA and Eclipse (provided you have the Groovy Eclipse plugin installed). These descriptors are found inside the griffon-rmi-groovy-compile-2.0.0.jar, with locations

  • dsdl/griffon_rmi.dsld

  • gdsl/griffon_rmi.gdsl

3. Build Configuration

3.1. Gradle

You have two options for configuring this plugin: automatic and manual.

3.1.1. Automatic

As long as the project has the org.codehaus.griffon.griffon plugin applied to it you may include the following snippet in build.gradle

dependencies {
    griffon 'org.codehaus.griffon.plugins:griffon-rmi-plugin:2.0.0'
}

The griffon plugin will take care of the rest given its configuration.

3.1.2. Manual

You will need to configure any of the following blocks depending on your setup

dependencies {
    compile 'org.codehaus.griffon.plugins:griffon-rmi-core:2.0.0'
}
Compile Only
dependencies {
    compileOnly 'org.codehaus.griffon.plugins:griffon-rmi-groovy-compile:2.0.0'
}

3.2. Maven

First configure the griffon-rmi-plugin BOM in your POM file, by placing the following snippet before the <build> element

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.codehaus.griffon.plugins</groupId>
            <artifactId>griffon-rmi-plugin</artifactId>
            <version>2.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Next configure dependencies as required by your particular setup

<dependency>
    <groupId>org.codehaus.griffon.plugins</groupId>
    <artifactId>griffon-rmi-core</artifactId>
</dependency>
Provided scope
<dependency>
    <groupId>org.codehaus.griffon.plugins</groupId>
    <artifactId>griffon-rmi-groovy-compile</artifactId>
</dependency>

Don’t forget to configure all -compile dependencies with the maven-surefire-plugin, like so

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <classpathDependencyExcludes>
            <classpathDependencyExclude>
                org.codehaus.griffon:griffon-rmi-groovy-compile
            </classpathDependencyExclude>
        </classpathDependencyExcludes>
    </configuration>
</plugin>

4. Modules

The following sections display all bindings per module. Use this information to successfully override a binding on your own modules or to troubleshoot a module binding if the wrong type has been applied by the Griffon runtime.

4.1. Rmi

Module name: rmi

bind(RmiClientStorage.class)
    .to(DefaultRmiClientStorage.class)
    .asSingleton();

bind(RmiClientFactory.class)
    .to(DefaultRmiClientFactory.class)
    .asSingleton();

bind(RmiHandler.class)
    .to(DefaultRmiHandler.class)
    .asSingleton();

bind(GriffonAddon.class)
    .to(RmiAddon.class)
    .asSingleton();