Over a million developers have joined DZone.
Platinum Partner

EJB 3.1 + Hessian = (Almost) Perfect Binary Remoting

· Java Zone

Discover how AppDynamics steps in to upgrade your performance game and prevent your enterprise from these top 10 Java performance problems, brought to you in partnership with AppDynamics.

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

The Java Zone is brought to you in partnership with AppDynamics. AppDynamics helps you gain the fundamentals behind application performance, and implement best practices so you can proactively analyze and act on performance problems as they arise, and more specifically with your Java applications. Start a Free Trial.

Topics:

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

{{ parent.tldr }}

{{ parent.urlSource.name }}