1. Introduction
This plugin enables the usage of the Java RMI protocol on a Griffon application.
Griffon version: 2.12.0
2. Usage
The following sections describe how you may use this plugin in a 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
@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 |
port |
The port on which objects were exported. Integer. Default |
lazy |
Attempt a connection to the RMI registry as late as possible. Boolean. Default |
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.
@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
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
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.
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.1.0'
}
The griffon
plugin will take care of the rest given its configuration.
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.1.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>
<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();