random technical thoughts from the Nominet technical team

Using hessiancpp to call Java servlets from C++

1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5 out of 5)
Loading ... Loading ...
Posted by Anthony on Oct 3rd, 2008

Background

Hessian is a binary web service protocol. It’s quite efficient (see Daniel Gredler’s and Miquel’s benchmarks) and it’s dynamically typed.

[proto-footnote] Dynamic typing is of course very convenient for Java-Java communication building from a single source tree. I expect it’ll be much less of a good thing if we make a habit of calling from C++ to Java via Hessian, at which point the overhead of using a different remoting mechanism which uses an IDL might be worth it, to enforce a contract between the two languages.

Hessian is written by a company called Caucho, who also make Resin, a webserver / servlet container.

Grammar

Caucho provide what they call a “Formal Definition” of the Hessian protocol; it would be more helpful if it didn’t omit several carriage returns - there’s an older version of the document which is better formatted. To be honest, I found Caucho’s documentation to be a bit of a maze of twistly little packages, all alike.

Bindings for C++

One of the reasons Nominet originally chose to use Hessian was that client bindings are available for many languages, including C++. The (only) C++ binding is hessiancpp [sourceforge]. It is released under LGPL, but isn’t being actively maintained.

Building hessiancpp

hessiancpp depends on a library called “sslpp”. A bit of searching brings up a package called SSL++; this looks promising but it’s a red herring; hessiancpp is written to use a modified version of it.
The modified version is hidden in the CVS repository for hessiancpp. It’s had a few minor changes and a GPL licence added to the original author’s copyright statement.

With a bit of fiddling to Boost include paths etc., sslpp builds fine & so does hessiancpp.

Running a basic/demo program

There are some tutorials on Caucho’s site. They use Resin, which is simple to set up. Of course if you’re already using another server (e.g. TomCat) then you can’t run both simultaneously on the same port!

  • install Resin
  • set Resin’s user/password by getting server to create a digest & pasting that into [RESIN_INSTALL_DIR]/conf/resin.conf
  • download hessian_3.1.6.jar (or whatever’s the current version)

Make a Java package (which for example I’ll call pkg_foo) with demo servlet class interface (e.g. IFoo). Write a concrete class (e.g. CFoo) which

  • imports com.caucho.hessian.server.HessianServlet;
  • extends HessianServlet
  • implements IFoo

and compile with the hessian_xxx.jar and [RESIN_INSTALL_DIR]/lib/jsdk-15.jar in the classpath.

Copy or make a link in [RESIN_INSTALL_DIR]/webapps/ROOT/WEB-INF/classes to your demo servlet package directory.

Add a file web.xml in [RESIN_INSTALL_DIR]/webapps/ROOT/WEB-INF/ containing something like:


<web-app xmlns=“http://caucho.com/ns/resin”>
  <servlet
    servlet-name=“foo”

    servlet-class
=“pkg_foo.CFoo”/>
  <servlet-mapping
    url-pattern=“/hessian/foo”
    servlet-name=“foo”/>
</web>

Make a demo client:

  • import com.caucho.hessian.client.HessianProxyFactory;
  • import your servlet interface
  • making a Hessian call like:

    HessianProxyFactory factory = HessianProxyFactory();
    String url = (“http://” + “localhost” + “:” + “8080″ + “/hessian/foo”);
    try {
        IFoo f = (IFoo) factory.create(IFoo.class, url);
        int i = f.fmethod(42);
        }
        catch (etc. …)
    {}
  • compile with hessian_xxx.jar in the classpath
  • run with hessian_xxx.jar in the classpath

Calling from C++

So far we’ve just demonstrated that you can call from Java->Java. It’s easier because both client & server can share the Java interface. Calling from C++ using hessiancpp will be more laborious, so it was worth the overhead of having made it work from Java first. We’ve verified the server set-up, and also now have a framework for prototyping the methods & their parameters, and a fallback.

There’s an example “main” in the hessiancpp distribution;

  • create a hessian_proxy instance, noting that:
    - hostspec is “host:port” (i.e. no “http://”)
    - leading slash is expected on url (e.g. “/hessian/pkg_foo”)
  • call method “call”, passing in the method name, the parameter count & the parameters

This is where you meet a hurdle: hessiancpp doesn’t include much in the way of error-handling/checking, for example

  • parameter count isn’t checked against number of parameters
  • result for the HTTP call doesn’t check the HTTP status code (e.g. 200=success, 404=page not found etc)
  • the decoding of hessian datatype “fault” makes assumptions about which fields will be populated (and their ordering) in the response, so crashes decoding some basic exceptions e.g. “wrong method name”
  • doesn’t cope with exceptions thrown in Java-land

It’s often not obvious how to construct more complicated types; what/whether to put in the “type” fields of a Hessian map representing an object, for example. However if you add code to dump the Hessian datastream input & outputs it’s straightforward to refer to the Hessian grammar & make sense of the datastream. It’s a small matter of programming to modify hessian_wrappers & hessian_input to make hessiancpp decode it correctly, and hessian_output to serialise correctly.

Download

Files as discussed above

Improvements

I’ve made some changes to hessiancpp, which I’ll document and post on this blog.

One Response

  1. Matthias Gehring Says:

    Hei,
    i need the Hessian Protocol for my Thesis. I have a of lot problems to great a .net project which runs correctly. May you have the .net project of your Hessian implementation with all project dependencies and additional libs?

    greeting Matthias Gehring

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.

Recent Posts

Highest Rated

Categories

Archives

Meta: