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

griffon.plugins.hessian.HessianHandler.java
@Nullable
<R> R withHessian(@Nonnull Map<String, Object> params, @Nonnull HessianClientCallback<R> callback)
    throws HessianException;

void destroyHessianClient(@Nonnull String clientId);
griffon.plugins.hessian.BurlapHandler.java
@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.

griffon.plugins.hessian.HessianCallback.java
public interface HessianClientCallback<R> {
    @Nullable
    R handle(@Nonnull Map<String, Object> params, @Nonnull HessianClient client)
        throws HessianException;
}
griffon.plugins.hessian.BurlapClientCallback.java
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

HessianCalculatorService.java
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

GroovyHessianCalculatorService.groovy
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

BurlapCalculatorService.java
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

GroovyBurlapCalculatorService.groovy
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.

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-hessian-groovy-compile-2.1.0.jar, with locations

  • dsdl/griffon_hessian.dsld

  • gdsl/griffon_hessian.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-hessian-plugin:2.1.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-hessian-core:2.1.0'
}
Compile Only
dependencies {
    compileOnly 'org.codehaus.griffon.plugins:griffon-hessian-groovy-compile:2.1.0'
}

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>
Provided scope
<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();