Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

EJB 3.1 + Hessian = (Almost) Perfect Binary Remoting

DZone's Guide to

EJB 3.1 + Hessian = (Almost) Perfect Binary Remoting

· Java Zone ·
Free Resource

How do you break a Monolith into Microservices at Scale? This ebook shows strategies and techniques for building scalable and resilient microservices.

EJB 3.1 + REST are the perfect combo for HTTP and resource style programming. REST is not very well suited for the exposure of already existing interfaces. The RPC-misuse of REST will result in hard to understand and so to maintain code. With Hessian it is very easy to expose existing Java-interfaces with almost no overhead. Hessian is also extremely (better than IIOP and far better than SOAP) fast and scalable. The size of the whole hessian library (hessian-4.0.7.jar) is smaller than 400 kB and so compatible with the "Kilobyte Deployment" style of Java EE 6 programming and deployment.

To expose an existing EJB 3.1 with hessian:

@Stateless
public class CurrentTime {
public long nanos(){
return System.nanoTime();
}
}

You will need an interface:

public interface TimeService {
public long nanos();
}

...and Hessian-specific implementation of the endpoint:
public class HessianTimeEndpoint extends HessianServlet implements TimeService{

@EJB
CurrentTime currentTime;

@Override
public long nanos() {
return currentTime.nanos();
}
}

The Hessian enpoint is an servlet - so the dependency injection works here without any XML configuration. You can just inject your no-interface EJB 3.1 view bean into the servlet.  The client side is also very lean. You only need a two lines of code to get a reference tot he proxy:

public class HessianTimeEndpointTest {
private TimeService timeService;
@Before
public void initProxy() throws MalformedURLException {
String url = "http://localhost:8080/EJB31AndHessian/TimeService";
HessianProxyFactory factory = new HessianProxyFactory();
this.timeService = (TimeService) factory.create(TimeService.class,url);
assertNotNull(timeService);
}
@Test
public void nanos() {
long nanos = this.timeService.nanos();
assertTrue(nanos>0);
System.out.println("Nanos: " + nanos);
}
}

HessianServlet inherits from GenericServlet and not from HttpServlet. This is a shame, because you will have to use a web.xml deployment descriptor, instead of a single annotation @WebServlet:

<web-app >
<servlet>
<servlet-name>TimeService</servlet-name>
<servlet-class>com.abien.patterns.business.sf.hessian.HessianTimeEndpoint</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TimeService</servlet-name>
<url-pattern>/TimeService</url-pattern>
</servlet-mapping>
</web-app>

You will find the executable project (tested with Netbeans 6.9 and Glassfish v3.0.1) in: http://kenai.com/projects/javaee-patterns/ [project name: EJB3AndHessian]. The whole WAR (EJB 3, Servlet, web.xml and the hessian "framework") is 393 kB. 385 kB hessian, and 7 kB EJB + Servlet :-)

The initial deployment of the WAR with EJBs took:
INFO: Portable JNDI names for EJB CurrentTime : [java:global/EJB31AndHessian/CurrentTime!com.abien.patterns.business.sf.CurrentTime, 
java:global/EJB31AndHessian/CurrentTime]
INFO: Loading application EJB31AndHessian at /EJB31AndHessian
INFO: EJB31AndHessian was successfully deployed in 807 milliseconds.

Don't worry: the subsequent deployments are substantially faster :-):

INFO: Portable JNDI names for EJB CurrentTime : [java:global/EJB31AndHessian/CurrentTime!com.abien.patterns.business.sf.CurrentTime, 
java:global/EJB31AndHessian/CurrentTime]
INFO: Loading application EJB31AndHessian at /EJB31AndHessian
INFO: EJB31AndHessian was successfully deployed in 568 milliseconds.

From http://www.adam-bien.com/roller/abien/entry/ejb_3_1_hessian_almost

How do you break a Monolith into Microservices at Scale? This ebook shows strategies and techniques for building scalable and resilient microservices.

Topics:

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}