Although Macromedia architect Sean Neville currently works on Flash-related rich application products for both .NET and J2EE platforms, he originally joined Macromedia to work on the JRun application server. As enterprise architect of JRun 4, Neville was involved with implementing many aspects of the J2EE (Java 2 Platform, Enterprise Edition) specifications, including EJB (Enterprise JavaBeans) containers, JNDI (Java Naming and Directory Interface) providers, JDBC (Java Database Connectivity) managers, and JTA (Java Transaction API) monitors. Neville also represents Macromedia on the JCP (Java Community Process) Executive Committee. In this two-part interview, Neville describes how he used Jini to enable clustering in the JRun 4 application server. In Part I, Neville describes the object clustering architecture he wanted for the app server, and how Jini facilitated it. In this second and final installment, Neville describes a messaging approach underlying method invocations on remote objects in JRun, and suggests situations in which enterprise developers may find Jini useful.
Bill Venners: In the clustering architecture you created for the JRun J2EE application server, you used the Jini lookup service to enable remote objects in a cluster to discover each other and exchange stubs. When a client receives a remote reference, that reference actually contains all the stubs in the cluster of equivalent remote objects, which enables a pluggable algorithm to perform load balancing and failover.
The remote objects also register for and receive events from the lookup service, indicating new peers have arrived or existing peers have departed from the lookup service. Is there a way to notify a client of changes in the peer list?
Sean Neville: There is a callback mechanism. If a client makes a call -- during which the server discovers, via a Jini event, that the stub list has changed (either someone has dropped out or joined) -- then the server gives the client the updated stub list, in addition to actually performing the invocation. The server tacks the stubs onto the invocation.
Sean Neville: Underneath the covers, JRun's RPC method invocations are fundamentally a messaging subsystem. When you perform an invocation, in JRun we actually wrap the invocation in a message object. Onto that message, we can tack transaction IDs, security IDs, thread local info, and more. We can also tack a peer list onto it, so that we can update the client's peer list under the covers.
Bill Venners: What do you mean you wrap the invocation in a message object?
Sean Neville: When you perform an invocation on what appears to be a remote object, no matter what method you invoke, in our invocation subsystem it's routed to a single method that internally generates a message to describe the invocation.
Bill Venners: Like the invoke method of an invocation handler on a dynamic proxy.
Sean Neville: Yes, similar to an invocation handler. We first figure out if we can just invoke the method locally. If we need to make a remote call, we actually wrap the method invocation in something called an invocation context. That name comes from the CORBA intercepting filter pattern, but in our case it's really a message; it is a specific message format that is class-based, not XML-based.
Bill Venners: The invocation context is an object that you're serializing?
Sean Neville: Yes.
Bill Venners: And on the other side, you deserialize it. Now you've got this message object, from which you can retrieve the invocation's parameters and the method that needs to be invoked, plus anything else that has been tacked on.
Sean Neville: That's right. The pattern has been implemented in many ORBs and servers, and in DCOM, and now .NET Remoting. It's probably best described in Pattern-Oriented Software Architecture, Volume 2. When the EJB container gets the invocation message, it passes it through all the filters, before it gets to the instance. So if you have a transaction interceptor, it gets the invocation first. It pulls off the transaction ID, and discovers the transaction attributes of this particular instance. It does whatever it needs to do for the transaction. It then passes it onto the next interceptor, which may put something on or take something off the invocation message. Some folks consider this a Pipes-and-Filters pattern, and in the default cases where the interceptors are hardwired that's a good match. The concept isn't too different from designs that application developers create with servlet filters or message sinks, though in this implementation the container filters are a bit more dynamic and can account for more dependencies than a servlet filter could.
Eventually, the result of the invocation comes back through the intercepting filters and the invocation context message returns to the client subsystem, which will detach the right result or exception. It will also detach the peer list if it needs to update it. So on that message, we can add peer updates to notify clients that objects have joined or dropped out of the cluster.
So as you can tell from all this, Jini is not really in the RPC invocation path. Jini is built into the server, because it is the way we implemented cluster lookup, discovery and events. Using Jini was a great convenience to us because it excels at making those things work in a light and simple way. We used Reggie, Sun's implementation of the Jini lookup service, rather than create our own lookup service.
The fact that we used Jini in JRun has two benefits. First, Jini helped us implement this functionality as quickly and safely as possible. Second, since we now ship a Jini lookup service in a J2EE server, users have a mechanism for doing Jini work without having to start up and configure Reggie, and can now deploy Jini services in the same process as J2EE resources.
Bill Venners: Jini is a useful tool in certain situations. Can you shed any light on when developers should consider pulling that tool out of the toolbox?
Sean Neville: Certain situations do come to mind. Jini may make sense when you start doing wild things with JNDI. Jini may make sense if you find yourself doing a lot of static lookups, then storing the names that you looked up. The Jini lookup service is an option if you want to do something more dynamic in terms of JNDI lookup, which is fundamentally a static mechanism.
Bill Venners: What do you mean by static in this sense?
Sean Neville: In JNDI, you just look up by name.
Bill Venners: So I have to know a logical name for everything.
Sean Neville: Right.
Bill Venners: And what kind of object do I get back?
Sean Neville: It could be a remote object or something that was passed by value.
Bill Venners: And I have to know what type the logical name corresponds to.
Sean Neville: You have to know a least a supertype of what you are looking up.
Bill Venners: Does JNDI have an automatic expiration mechanism like the Jini lookup service does? Or does each binding have to actually be removed?
Sean Neville: Each binding has to be explicitly unbound.
Bill Venners: So that's another difference. Things in JNDI can become stale; whereas in the Jini lookup service, registrations are automatically kicked out of the lookup service if their lease expires. So once again it sounds like Jini makes sense in more dynamic situations, in which services are expected to come and go regularly.
Sean Neville: We implement JNDI remoting through this whole Jini mechanism. If you are performing a lookup and this JNDI naming server dies, you can failover to another naming server. Because when you deploy a clustered EJB, its reference is bound to all JNDI trees across the cluster.
Another situation has to do with network failure: EJBs have system exceptions and application exceptions. A system exception causes a roll back and an instance loss. That indicates that something really messed up on the network, like the process died. But beyond that, EJBs assume that you're running on an enterprise system that, because of clustering or administration or whatever, the remote object will be there. If you work in an environment that lacks that sort of assurance, and you need to be more cognizant that things could disappear, then the Jini leasing mechanism could help make things more robust.
Bill Venners: The network is always unreliable to some extent, but it has a spectrum of unreliability. At some point, the network is reliable enough to ignore the fact that it might be unreliable. So you're saying that if you get far enough down that spectrum, you need to deal with the chance for failure, and that's where leasing may make sense.
Sean Neville: Yes.
Sean Neville: One thing I think has hurt Jini a bit in the Java community is that it doesn't offer a high-level programming model per se. Jini is more a set of principles accompanied by several specific technologies, each with their own API's. You use certain utilities to handle discovery and lookup, or specific methods to use Jini transactions or events. But it has nothing quite the same as a J2EE API. It offers terrific mechanisms, but doesn't impose a specific over-arching development policy. Developers can't immediately read a book or a spec, see a specific enterprise or corporate IT ROI problem, and learn at an API level where Jini fits within their applications and architectures. In speaking with folks on the Jini team about this, I learned that the decision not to have an over-arching public API can be viewed as a strength. In focusing on a few high-level principles and building technologies that address them, Jini casts a very wide net.
Bill Venners: What do you mean by public API? Jini has one set of discovery protocols, and everything else is defined in terms of interfaces, which are APIs.
Sean Neville: Those APIs are tied to specific mechanisms rather than a programming model, whereas most J2EE APIs at least suggest a programming model. The programming model offers specific patterns for how you might arrange an application and APIs that directly support these types of patterns. By contrast, Jini APIs give you methods to perform particular types of functions.
Bill Venners: The distinction you are drawing is that Jini doesn't provide APIs that tell you how to build a Jini service. Basically, it is just up to you to build and deploy it yourself.
Sean Neville: Right. In the best-case scenario, somebody outside the Jini team would come up with those higher-level service APIs, but that hasn't happened yet, at least not in a big way, and with the possible exception of printing it also hasn't happened in a domain-specific way. However, that doesn't say anything about the technology's value. Policy is needed, but it has its negative consequences in addition to its positives. J2EE's policy is heavily oriented toward how to pump data into and out of relational databases in the most secure, scalable, managable way, without becoming domain-specific, which has a clear ROI story but also leads to debates about EJB CMP, Data Access Objects, JDO, when and where to use JDBC, and more complexities that do cost money as those debates affect specific projects over time. The absence of such a strict policy, with no over-arching architectural patterns implied by the specifications, could be a good thing for Jini. It keeps Jini open to more domain-specific work, and to new types of development beyond the database-dominated web or enterprise application. Service-oriented applications, including conversations among multiple web service peers and their rich user interfaces, might forge some policy around Jini's dynamic discovery and event mechanisms. There are also great possibilities in systems management software. As aspects of features and use cases, Jini mechanisms might be great artifacts for generative programming strategies. And of course, it can be used as an implementation mechanism for J2EE policy, which is what we did.
Bill Venners: Any complaints about your experience with Jini?
Sean Neville: My only real complaint about Jini is that it worked immediately. It was amazing how quickly we were up and running. Since it worked so quickly, I couldn't justify spending more time on it.
Bill Venners: You mean playing with it?
Sean Neville: Yes, exactly. We were spending lots of time basically reinventing Jini, and it was amazing how quickly we got the product running with Jini. It was astounding, really.
The Jini Community, the central site for signers of the Jini Sun Community Source License to interact:
http://www.jini.org
Information on Macromedia JRun is at:
http://www.macromedia.com/software/jrun/
Have an opinion? Readers have already posted 1 comment about this article. Why not add yours?
Bill Venners is president of Artima Software, Inc. and editor-in-chief of Artima.com. He is author of the book, Inside the Java Virtual Machine, a programmer-oriented survey of the Java platform's architecture and internals. His popular columns in JavaWorld magazine covered Java internals, object-oriented design, and Jini. Bill has been active in the Jini Community since its inception. He led the Jini Community's ServiceUI project that produced the ServiceUI API. The ServiceUI became the de facto standard way to associate user interfaces to Jini services, and was the first Jini community standard approved via the Jini Decision Process. Bill also serves as an elected member of the Jini Community's initial Technical Oversight Committee (TOC), and in this role helped to define the governance process for the community. He currently devotes most of his energy to building Artima.com into an ever more useful resource for developers.
Artima provides consulting and training services to help you make the most of Scala, reactive
and functional programming, enterprise systems, big data, and testing.