1. Introduction
This plugin enables the usage of the Hessian and Burlap transfer protocols by Caucho Technology 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 pair of helper classes (HessianHandler
and BurlapHandler
)
that define the base contract for issuing Hessian or Burlap calls using an appropriate client class. These helper classes
have the following methods
@Nullable
<R> R withHessian(@Nonnull Map<String, Object> params, @Nonnull HessianClientCallback<R> callback)
throws HessianException;
void destroyHessianClient(@Nonnull String clientId);
@Nullable
<R> R withBurlap(@Nonnull Map<String, Object> params, @Nonnull BurlapClientCallback<R> callback)
throws BurlapException;
void destroyBurlapClient(@Nonnull String clientId);
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 (HessianClientStorage
,
BurlapClientStorage
).
You can inject an instance of HessianHandler
and/or BurlapHandler
anywhere they’re needed using
@Inject
. There are two callbacks you may use with these handlers: either you work with a HessianClient
instance using HessianClientCallback
or with a BurlapClient
instance using BurlapClientCallback
.
Both options will come in handy with other plugins or APIs that require one instance or the other.
Both callbacks are defined using a functional interface approach, which means you can apply lambda expressions if running with JDK8+ or closures if running Groovy.
public interface HessianClientCallback<R> {
@Nullable
R handle(@Nonnull Map<String, Object> params, @Nonnull HessianClient client)
throws HessianException;
}
public interface BurlapClientCallback<R> {
@Nullable
R handle(@Nonnull Map<String, Object> params, @Nonnull BurlapClient client)
throws BurlapException;
}
2.2. Example
The following is a trivial usage of the HessianHandler
inside a service
import griffon.core.GriffonApplication;
import griffon.core.artifact.GriffonService;
import griffon.metadata.ArtifactProviderFor;
import griffon.plugins.hessian.exceptions.HessianException;
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.util.Map;
@ArtifactProviderFor(GriffonService.class)
public class HessianCalculatorService extends AbstractGriffonService {
@Inject
private HessianHandler hessianHandler;
@Inject
public HessianCalculatorService(@Nonnull GriffonApplication application) {
super(application);
}
public Double calculate(final double num1, final double num2) {
Map<String, Object> params = CollectionUtils.<String, Object>map()
.e("url", "http://localhost:8080/hessian/calculator")
.e("id", "client");
return hessianHandler.withHessian(params,
new HessianClientCallback<Double>() {
@Nullable
public Double handle(@Nonnull Map<String, Object> params, @Nonnull HessianClient client)
throws HessianException {
return client.proxy(Calculator.class, new UnaryConsumer<Calculator, Double>() {
@Override
public Double consume(Calculator calculator) {
return calculator.add(num1, num2);
}
});
}
});
}
}
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)
class GroovyHessianCalculatorService {
@Inject
private HessianHandler hessianHandler
double calculate(double num1, double num2) {
Map args = [id: 'client', url: 'http://localhost:8080/hessian/calculator']
hessianHandler.withHessian(args) { Map params, HessianClient client ->
client.proxy(Calculator) { Calculator calculator ->
calculator.add(num1, num2)
}
}
}
}
The Java based, Burlap version of the same service looks like
import griffon.core.GriffonApplication;
import griffon.core.artifact.GriffonService;
import griffon.metadata.ArtifactProviderFor;
import griffon.plugins.hessian.exceptions.BurlapException;
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.util.Map;
@ArtifactProviderFor(GriffonService.class)
public class BurlapCalculatorService extends AbstractGriffonService {
@Inject
private BurlapHandler hessianHandler;
@Inject
public BurlapCalculatorService(@Nonnull GriffonApplication application) {
super(application);
}
public Double calculate(final double num1, final double num2) {
Map<String, Object> params = CollectionUtils.<String, Object>map()
.e("url", "http://localhost:8080/burlap/calculator")
.e("id", "client");
return hessianHandler.withBurlap(params,
new BurlapClientCallback<Double>() {
@Nullable
public Double handle(@Nonnull Map<String, Object> params, @Nonnull BurlapClient client)
throws BurlapException {
return client.proxy(Calculator.class, new UnaryConsumer<Calculator, Double>() {
@Override
public Double consume(Calculator calculator) {
return calculator.add(num1, num2);
}
});
}
});
}
}
and the Groovy version of the same service
import griffon.core.artifact.GriffonService
import griffon.metadata.ArtifactProviderFor
import javax.inject.Inject
@ArtifactProviderFor(GriffonService.class)
class GroovyBurlapCalculatorService {
@Inject
private BurlapHandler hessianHandler
double calculate(double num1, double num2) {
Map args = [id: 'client', url: 'http://localhost:8080/burlap/calculator']
hessianHandler.withBurlap(args) { Map params, BurlapClient client ->
client.proxy(Calculator) { Calculator calculator ->
calculator.add(num1, num2)
}
}
}
}
2.3. AST Transformation
You can apply the @HessianAware
and/or @BurlapAware
AST transformations on any class. They inject the
behavior of HessianHandler
and BurlapHandler
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-hessian-plugin:2.1.0'
}
The griffon
plugin will take care of the rest given its configuration.
3.2. Maven
First configure the griffon-hessian-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-hessian-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-hessian-core</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.griffon.plugins</groupId>
<artifactId>griffon-hessian-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-hessian-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. Hessian
Module name: hessian
bind(HessianClientStorage.class)
.to(DefaultHessianClientStorage.class)
.asSingleton();
bind(HessianClientFactory.class)
.to(DefaultHessianClientFactory.class)
.asSingleton();
bind(BurlapClientStorage.class)
.to(DefaultBurlapClientStorage.class)
.asSingleton();
bind(BurlapClientFactory.class)
.to(DefaultBurlapClientFactory.class)
.asSingleton();
bind(HessianHandler.class)
.to(DefaultHessianHandler.class)
.asSingleton();
bind(BurlapHandler.class)
.to(DefaultBurlapHandler.class)
.asSingleton();
bind(GriffonAddon.class)
.to(HessianAddon.class)
.asSingleton();