Java Champion / JavaOne Rockstar Adam Bien (adam-bien.com) is a self-employed consultant, lecturer, software architect, developer, and author in the enterprise Java sector. He is also the author of several books and articles on Java and Java EE technology, as well as distributed Java programming. adam has posted 59 posts at DZone. View Full User Profile

EJB 3.1 + Hessian = (Almost) Perfect Binary Remoting

06.22.2010
| 7652 views |
  • submit to reddit

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

Published at DZone with permission of its author, adam bien.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Michael Eric replied on Wed, 2012/09/26 - 3:35pm

made an example project located on gihub which combines Maven, JEE 6, NetBeans RCP, Flex and Hessian. To avoid writing an extra wrapper servlet for every session bean I wrote a servlet that dynamically invokes the required bean/method.

linux archive 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.