Hessian and Burlap


Caucho Technology, the makers of the Resin application server, have released two lightweight remoting protocols, which are available as standalone distributions under the Apache license: Hessian, a slim binary protocol, and Burlap, a slim XML-based protocol. Both use HTTP as their transport mechanism. The protocols are defined in concise specifications. While Java-oriented, they allow for implementations in other languages.

Hessian and Burlap use their own serialization algorithms for primitive types, collections, and so on. This avoids the hassle of Java serialization, which requires strictly compatible classes on both sides, while still working efficiently for Java objects. However, it does incur side effects. For example, Hessian and Burlap are not able to deserialize a state that is held in final instance variables, as they need to be able to rebuild an object's fields through reflection. Furthermore, they are not able to detect objects with customized serialization, for example Hibernate collections: Such objects often cause deserialization failures.

Important 

Hessian's and Burlap's own serialization mechanisms allow for loose coupling (between loosely related Java processes or even different languages) but can incur side effects. If encountering deserialization failures, we recommend switching to the tighter coupling of Spring's HTTP invoker (discussed later in this chapter), which uses standard Java serialization over HTTP.

Both Hessian and Burlap services are traditionally defined as servlets in web.xml, using Caucho's prebuilt HessianServlet or BurlapServlet class, respectively. The application service to be exported is either implemented as a subclass of such a servlet (being tied to a protocol) or as a plain Java class implementing the service interface. In the latter case, the implementation will simply get instantiated and used; there is no way to wire it with middle tier services other than via JNDI lookups.

On the client side, standard Hessian and Burlap provide proxy factory classes, which can generate a proxy for a specific service interface and target URL. Remote invocation failure will lead to special HessianRuntimeExceptions or BurlapRuntimeExceptions being thrown.

To allow seamless integration of Hessian and Burlap into a Spring-based architecture, Spring provides the following prebuilt support classes:

  • org.springframework.remoting.caucho.HessianProxyFactoryBean and org.springframework.remoting.caucho.BurlapProxyFactoryBean: Proxy factories for Spring-compliant proxies that communicate with backend Hessian or Burlap services, respectively. To be defined in a Spring bean factory or application context, exposing the proxy object for references (through the FactoryBean mechanism). Proxies will throw Spring's generic RemoteAccessException in case of remote invocation failure.

  • org.springframework.remoting.caucho.HessianServiceExporter and org.springframework.remoting.caucho.BurlapServiceExporter: Exporters implemented as Controllers for Spring's web MVC framework. Can take any existing Spring-managed bean and export it at a given HTTP URL, allowing the target bean to be fully configured and wired via Spring. The same target bean can easily be exported through both Hessian and Burlap at the same time, at different URLs.

Note that Spring's Hessian and Burlap support works with standard Hessian and Burlap means underneath; that is, it does not use a special invoker mechanism. Any existing Hessian or Burlap service can be accessed via Spring's accessor classes, even if the target service is not exported via Spring; and any Hessian or Burlap client can access a Spring-managed bean that has been exported via Spring's exporter classes.

Important 

Hessian and Burlap are compelling choices for HTTP-based remoting — in particular, for Java-to-Java remoting. Spring allows for convenient definition of proxies on the client side and service exporters on the server side, without tying client objects or service implementations to a specific protocol.

Setup and maintenance efforts for Hessian and Burlap services are close to negligible. Because of their HTTP-based nature, there are no issues with stale proxies on server restart or the like (that is, none of the traditional headaches of RMI). The simplicity of configuration is matched only by Spring's own HTTP invoker, discussed later in this chapter.

Accessing a Service

On the client side, a proxy for a target service can easily be created via a Spring bean definition. The configuration needed is the proxy factory class name, the HTTP URL of the target service, and the service interface to expose. For example, for Hessian:

<bean      >   <property name="serviceUrl">     <value>http://localhost:8080/remoting/OrderService-hessian</value>   </property>   <property name="serviceInterface">     <value>org.springframework.samples.jpetstore.domain.logic.OrderService</value>   </property> </bean>

The service interface can be a plain Java business interface that doesn't have to derive from specific base interfaces or throw special remoting exceptions:

public interface OrderService {       Order getOrder(int orderId); } 

For Burlap, only the class name of the proxy factory would have to change. Spring uses consistent property naming across its remote service accessors, as much as possible.

<bean      >   <property name="serviceUrl">     <value>http://localhost:8080/remoting/OrderService-burlap</value>   </property>   <property name="serviceInterface">     <value>org.springframework.samples.jpetstore.domain.logic.OrderService</value>   </property> </bean>

Such a proxy is then available for bean references; for example:

<bean  >   <property name="orderService">     <ref bean="hessianProxy"/>   </property> </bean>

The MyOrderServiceClient class would simply expose a bean property of type org.springframework.samples.jpetstore.domain.logic.OrderService here, thus the client is not tied to a remote service but rather to a plain Java business interface, which could have a local implementation too.

public class MyOrderServiceClient {       private OrderService orderService;       public void setOrderService(OrderService orderService) {     this.orderService = orderService;   }       public void doSomething() {     Order order = this.orderService.getOrder(...);     ...   } }

Note that switching between a Hessian and a Burlap proxy for our OrderService would just involve redefining the proxy from HessianProxyFactoryBean to BurlapProxyFactoryBean. Through using a placeholder, this can even be driven from outside an XML bean definition file:

<bean  >   <property name="orderService">     <ref bean="${proxyBeanName}"/>   </property> </bean>

The actual bean name to be wired to would typically be defined in a Properties file, for example an admin.properties file residing in the WEB-INF directory of a web application. (See Chapter 2 for details on Spring's placeholder mechanism for bean definitions.)

proxyBeanName=hessianProxy   #proxyBeanName=burlapProxy 
Important 

Switching between a Hessian proxy and a Burlap proxy is a configuration matter; the actual protocol used can be considered a deployment choice. This basically applies to all of Spring's supported remoting strategies: A client object can seamlessly receive a different proxy for the service interface that it expects, as it is not tied to a particular proxy factory.

Both HessianProxyFactoryBean and BurlapProxyFactoryBean support some customization options, for example specifying username and password properties for HTTP-based authentication. Such settings apply to the entire service instance; they cannot be customized at a per-invocation level. Furthermore, secure communication via SSL is straightforward: Simply specify an HTTPS URL as service URL.

Exporting a Service

On the server side, exporting an existing Spring-managed bean as Hessian and/or Burlap service is straightforward. Corresponding service exporters need to be defined as Spring Controllers in a Spring web MVC context. It is usually advisable to define such exporters in a separate DispatcherServlet with its own context. However, defining them in an existing DispatcherServlet context will also work.

For example, such Controller definitions in a DispatcherServlet context could look as follows, relying on the default BeanNameUrlHandlerMapping strategy. (See Chapter 12 for details on Spring's DispatcherServlet and its strategies.)

<bean name="/OrderService-hessian"      >   <property name="service">     <ref bean="petStore"/>   </property>   <property name="serviceInterface">     <value>org.springframework.samples.jpetstore.domain.logic.OrderService</value>   </property> </bean>     <bean name="/OrderService-burlap"      >   <property name="service">     <ref bean="petStore"/>   </property>   <property name="serviceInterface">     <value>org.springframework.samples.jpetstore.domain.logic.OrderService</value>   </property> </bean>

The actual OrderService implementation in JPetStore's middle tier is the PetStoreImpl object, which also implements the PetStoreFacade interface. Therefore, the exporter refers to the petStore bean from the root application context.

Those exporters could be defined in the context of a DispatcherServlet called remoting: that is, in a file remoting-servlet.xml in the WEB-INF directory of a web application. The correspondingweb.xml entries would look like this:

<servlet>   <servlet-name>remoting</servlet-name>   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>   <load-on-startup/> </servlet>     <servlet-mapping>   <servlet-name>remoting</servlet-name>   <url-pattern>/remoting/*</url-pattern> </servlet-mapping>

Assuming that the server is available at http://localhost:8080, the remote OrderService would then be available as Hessian service at http://localhost:8080/remoting/OrderService-hessian and as Burlap service at http://localhost:8080/remoting/OrderService-burlap.

Of course, defining only one exporter — that is, for either Hessian or Burlap — will work too. However, as you can see in the previous example, it is straightforward to define multiple exporters, binding them to different URLs but wiring them with the same target service instance.

Important 

In contrast to classic remoting frameworks, a service instance for use with Hessian or Burlap (or effectively any other remoting strategy supported by Spring) is not tied to a particular endpoint. It can seamlessly be exported through multiple endpoints at the same time. A client can then choose which protocol to use for communication with that service, through talking to the endpoint at a specific URL.



Professional Java Development with the Spring Framework
Professional Java Development with the Spring Framework
ISBN: 0764574833
EAN: 2147483647
Year: 2003
Pages: 188

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net