Using Enterprise Java Beans from C++

Introduction

When you are faced with the problem of calling EJBs from another language, you —like most people— will probably think web services. After all, most modern application servers come with a built-in web services stack that's just waiting to be used.

Why do we propose a different solution? Well, for one thing we like to sell our product, but a JunC++ion-based solution truly has many very attractive technical characteristics which we would like to point out to you. EJB and C++ can work very well with each other if you allow JunC++ion to be the middleman.

Please also check out the corresponding .NET example which is based on JunC++ion's .NET sister tool called JuggerNET.

Architecture

EJB C++ architecture

As the image on the right shows, you have your regular J2EE server infrastructure on the server side. You do not need to make any deployment or configuration changes to enable the C++ client use case from the server's perspective.

On the client side, you obviously have the C++ application that wishes to communicate with the J2EE server. Inside the application, you have generated proxy types for the EJB home interfaces and any other Java types that you wish to use. The C++ developer wrote code directly against these generated bindings, almost as if the J2EE server were really publishing a C++ based infrastructure rather than a Java infrastructure.

Under the hood, completely hidden from the C++ developer, the proxy types and the Codemesh runtime load a JVM into the C++ process and delegate (purple connectors) to the underlying Java objects, in this case the Java client-side bindings for the Enterprise Java Beans. These Java objects handle the communication with the server (green connectors). What's so remarkable about this picture?

  1. The developer is writing C++ code that happens to look a lot like Java code, but is otherwise blissfully unaware of the fact that there is any Java involved.
  2. The server is totally unaware that there is a C++ client. As far as it is concerned, it is communicating with a Java client, which happens to be "hosted" by a C++ application.
  3. Assuming you have Java clients for your server, you have to make absolutely no changes to your deployment. There are no security-related changes, no transactionalization-related changes, no firewall-related changes, no deployment-descriptor changes.

This kind of integration is just about as invisible and non-intrusive as possible.

JunC++ion users with this use case have found out through benchmarks on real applications and real application servers that this solution has much better performance than web services-based integration. Not only is there less overhead on the client side, but the server apparently scales better too when tested under load.

Development process

As part of your EJB deployment, your application server's deployment tool will typically offer to create a client deployment jarfile for you. You import this jar file (in a pinch you could also use the server-side jar) into the code generator and generate C++ proxy types for all Java types that you wish to use from within your C++ application. In the above picture, the developer decided not to generate proxies for EJB1, presumably because the C++ application does not need to use that particular EJB.

Once the C++ bindings have been generated (as source files), you can either build them into a library and use that library or you can add them directly to your C++ project, it's totally up to you. Regardless, you can now write C++ code such as this (it might look slightly different for your app server):

try
{
    InitialContext  ictx( _use_java_ctor );
    Context         myEnv = Context::dyna_cast( ictx.lookup( "java:comp/env" ) );
    Object          objref = myEnv.lookup( "ejb/SimpleConverter" );
    ConverterHome   home = ConverterHome::dyna_cast( 
                               PortableRemoteObject::narrow( 
                                   objref,
                                   Class::forName( "com.myapi.ConverterHome" ) ) );
    Converter       currencyConverter = home.create();
 
    BigDecimal      param( "100.00" );
    BigDecimal      amount = currencyConverter.dollarToYen( param );
    
    System::out.println( amount );
 
    amount = currencyConverter.yenToEuro( param );
 
    System::out.println( amount );  
} 
catch( Exception & e )
{
    cerr << "Caught an unexpected exception!" ) << endl;
    e.printStackTrace();
}

If you know the Java original, you will recognize how similar that C++ code is to it. There are just a few C++'isms that you have to get used to, otherwise it looks immediately understandable and it is certainly highly maintainable.

Deployment

As already mentioned, your Java server does not require any changes at all.

Your C++ application will require the Codemesh runtime library to be present and it will require a Java Runtime Environment (JRE). You can bundle a so-called "private" JRE with your a pplication, or you can rely on the presence of a JRE on the client host. The latter alternative might be perfectly acceptable in well-controlled intranet deployment scenarios.

There are no configuration changes required to accommodate the client/server communications (assuming you already have things set up for Java client/Java server communications).

Summary

It sounds strange to use in-process integration for such an explicitly client/server use case, but it has some huge advantages when compared with competing integration approaches. It has better performance, better security, easier deployment, and great maintainability. All of these factors combine for an excellent cost/benefit picture.


Copyright 2006-2011 by Codemesh, Inc., ALL RIGHTS RESERVED

:
ejb c++
home products support customers partners newsroom about us contact us