Using JavaSpaces from .NET

Introduction

JavaSpaces and Jini are wonderfully dynamic technologies that combine simplicity with power. Before SOA (service-oriented architecture) became a buzzword, Jini and JavaSpaces already had a beautiful framework for architecting dynamic, scalable, distributed systems. They allow developers to design and implement highly reliable distributed systems that leverage Java's strengths to the utmost.

Leveraging Java's bytecode portability and remoting framework, code does not need to be deployed on clients, it can migrate automatically from the server to the client or even from the client to the server.

Unfortunately, its strengths have also turned into a weakness by causing the perception that both of them can only be used by Java applications. How can you leverage Jini and JavaSpaces from a .NET client?

Solution

This code example shows a real-life JavaSpaces client that is completely implemented in terms of generated proxy classes. This example happens to use APIs from a GigaSpaces SDK, but you could replace the GigaSpaces-specific parts with vendor-neutral Jini/JavaSpaces APIs and it would work just as well.

using System;
using System.Configuration;
using System.Collections;
using System.ComponentModel;
using System.Data;

// always include the JuggerNET namespace for framework classes

using Codemesh.JuggerNET;

// namespaces that were generated; notice that we used the 
// Java naming policy, yielding .NET names that look pretty 
// much identical to the names in Java

using java.lang;
using net.jini.core.entry;
using net.jini.core.lease;
using net.jini.core.transaction;
using net.jini.space;
using com.j_spaces.core.admin;
using com.j_spaces.core.client;
using com.j_spaces.core;

//
// A little test class that performs some JavaSpaces operations
// from a .NET C# application.
//
// This example demonstrates how the code mobility and flexibility
// of a Jini/JavaSpaces architecture can be leveraged by a native
// .NET application.  The application code is virtually identical
// to what you would write in Java (with the exception of the use 
// of .NET specific APIs).
//
class MainClass
{
  [STAThread]
  public static void Main(string[] args)
  {
    // our JavaSpace reference
    IJSpace                 space = null;

    //
    // First we try to read a URL from the application's configuration file.
    // If that does not yield a valid value, we default to a "match all" URL
    // on the local host.
    //

    try
    {
      AppSettingsReader   config = new AppSettingsReader();
      String              space_url = (string)config.GetValue( "JavaSpace", typeof(String) );

      if( space_url == null )
        space_url = "jini://localhost/*/JavaSpaces";

      space = (IJSpace)SpaceFinder.find(space_url);

      Console.WriteLine("Connected successfully to space {0}", space.getName() );
    }
    catch( FinderException fe )
    {
      // this exception is thrown if we cannot connect to the JavaSpace in question

      Console.WriteLine( "A FinderException occurred: {0}", fe.Message );
      return;
    }
    catch( JuggerNETException je )
    {
      // this framework exception is thrown if we could not initialize the Java
      // runtime environment for any reasons;  it is also a baseclass for all
      // proxy exception classes, so it will catch all Throwables

      Console.WriteLine( "A JuggerNETException occurred: {0}", je.Message );
      return;
    }

    try
    {
      // we create an instance of a Request object;
      // this is an application-specific type for which we generated a proxy class
      model.Request         myObj = new model.Request();

      myObj.RequestString = "A";

      // we write the object into the JavaSpace and request a 
      // non-expiring lease for it
      Lease                 lease = space.write( myObj, null, LeaseImpl.FOREVER );
      LeaseProxy            leaseproxy =(LeaseProxy)lease ;

      // output some progress reports and let us know what kind of
      // lease we were granted
      Console.WriteLine( "Write succeeded! Expiration time: {0}", lease.getExpiration() );
      Console.WriteLine( "UID: {0}", leaseproxy.getUID() );

      // create a template for a lookup operation;
      // we assume that there are some Result objects in the JavaSpace already;
      model.Result          template = new model.Result();

      template.RequestObjectID = leaseproxy.getUID();

      // we read an object based on the template we created
      Entry                 e = space.read( template, null, 60000 );

      // if we found anything, we output the results
      if( e != null )
      {
        // notice how we can simply cast the Entry to the proper type;
        // JuggerNET is very smart about proxy types and will enable 
        // you to cast to any concrete proxy type
        model.Result      result = (model.Result)e;

        Console.WriteLine("replyString: {0}", result.replyString  );
        Console.WriteLine("Read object: {0}", result.U__getEntryUID() );
      }
    }
    catch( java.lang.Exception je )
    {
      // the call to getMessage() is synonymous to je.Message
      Console.WriteLine( "A Exception occurred: {0}", je.getMessage() );
    }
    catch( JuggerNETException jne )
    {
      Console.WriteLine( "An Exception occurred: {0}", jne.Message );
      Console.WriteLine( jne.StackTrace );
    }
  }
}

Deployment

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 application, 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.

Summary

A JuggerNET-based JavaSpaces solution combines the strengths of JavaSpaces and Codemesh's in-process technology. It leverages JuggerNET in in-process mode to call from .NET into Java and it uses the JavaSpaces abstraction around distributed storage, code mobility, security, etc. for everything else.


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

:
javaspaces.net
home products support customers partners newsroom about us contact us