Using Enterprise Java Beans from .NET


When you are faced with the problem of calling EJBs from another language, you —like most people— will probably think web services. That's particularly true if the other language is a .NET language like C#, or VB.NET, which comes with a nice web services stack. Your application server comes with a built-in web services stack that's just waiting to be used anyway.

If you're using JBoss, you might also be considering the JBoss.NET webservice bindings, which we will use as an example of a vendor-specific integration extension.

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

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


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 .NET client use case from the server's perspective.

On the client side, you obviously have the .NET 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 .NET developer wrote code directly against these generated bindings, almost as if the J2EE server were really publishing a .NET based infrastructure rather than a Java infrastructure.

Under the hood, completely hidden from the .NET developer, the proxy types and the Codemesh runtime load a JVM into the CLR 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# or VB.NET or some other .NET language 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 .NET client. As far as it is concerned, it is communicating with a Java client, which happens to be "hosted" by a CLR 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.

JuggerNET 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 .NET application. In the above picture, the developer decided not to generate proxies for EJB1, presumably because the .NET application does not need to use that particular EJB.

Once the .NET 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 .NET project, it's totally up to you. Regardless, you can now write .NET code such as the snippets below (it might look slightly different for your app server because some app servers don't require the PortableRemoteObject operation). First, a C# example:

    InitialContext   ictx = new InitialContext( );
    Context          myEnv = (Context)ictx.Lookup( "java:comp/env" );
    Java.Lang.Object objref = myEnv.Lookup( "ejb/SimpleConverter" );
    ConverterHome    home = (ConverterHome) 
                                   Class.ForName( "com.myapi.ConverterHome" ) );
    Converter        currencyConverter = home.Create();
    BigDecimal       param = new BigDecimal( "100.00" );
    BigDecimal       amount = currencyConverter.DollarToYen( param );
    System.Out.Println( amount );
    amount = currencyConverter.YenToEuro( param );
    System.Out.Println( amount );  
catch( Exception e )
    System.Err.Println( "Caught an unexpected exception!" );

In VB.NET, the same sample might look like this:


    Dim ictx As InitialContext = new InitialContext()
    Dim myEnv As Context = ictx.Lookup( "java:comp/env" )
    Dim home As ConverterHome = PortableRemoteObject.Narrow( 
                                   myEnv.Lookup( "ejb/SimpleConverter" ),
                                   Class.ForName( "com.myapi.ConverterHome" ) )
    Dim currencyConverter As Converter = home.Create()
    Dim param As BigDecimal = new BigDecimal( "100.00" )
    Dim amount As BigDecimal = currencyConverter.DollarToYen( param )
    System.Out.Println( amount )
    amount = currencyConverter.YenToEuro( param )
    System.Out.Println( amount )
Catch e As Exception

    System.Err.Println( "Caught an unexpected exception!" )

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


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

Your .NET 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).

Your client application will have to configure the proper Java Runtime Environment so the connection to the server can be made. For a JBoss 3.2 client for example, you might have a configuration such as:

loader.ClassPath = @"..\lib\jbossall-client.jar;..\lib\myEjbClient.jar";
loader.DashDOption[ "java.naming.factory.url.pkgs" ] = "org.jboss.naming:org.jnp.interfaces";
loader.DashDOption[ "java.naming.factory.initial" ] = "org.jnp.interfaces.NamingContextFactory";
loader.DashDOption[ "java.naming.provider.url" ] = "localhost";

Summary & Comparison

When you contrast Codemesh's approach with pure web services or proprietary vendor extensions like JBoss.NET, you will find some distinguishing factors:

  • Codemesh's solution requires a JRE on the client, web services based solutions do not.
  • All web services based solutions incur significant overhead on client and server when compared to a JuggerNET-based solution.
  • Proprietary extensions like JBoss.NET tie you to a particular server vendor, JuggerNET-based integration does not.

It sounds strange to use in-process integration for such an explicit 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. EJBs and other J2EE APIs work very well with .NET if you allow JuggerNET to do the heavy integration work.

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

ejb .net
home products support customers partners newsroom about us contact us