How to Talk About Jini, J2EE, and Web Services at a Cocktail Party
Pages: 1, 2
Another key difference between Jini and all of the others (plain RMI, EJB, and Web services) is that Jini uses distributed leasing to help create a self-healing network. If a Jini service is Remote, for example, it gives the client a "lease" and says, "Here's your lease. If you don't keep renewing it, I'll assume you've gone away and I'll stop using any resources over here on your behalf." How up to date the network stays depends on the length of those leases. For example, a two-hour lease would mean the client could have been gone nearly two hours and you (the service) wouldn't know. What a waste! On the other hand, a one-second lease means a really up-to-date network ... except everybody's spending all of their cycles and bandwidth renewing leases! So there's a tradeoff, and it really depends on the type of service and other quality-of-service issues.
Another cool thing about the self-healing network is that, since even the Jini lookup service is a Jini service, the lookup service gives the Jini service a lease. So in this case, the Jini service is a client to the Jini lookup service. That way, when a normal client (in other words, a client that isn't itself a Jini service, but rather someone who just wants to use a Jini service) comes to look for a service, like a printer, the client won't see a service as "available" if the service hasn't been renewing its lease with the lookup service. Again, the shorter the lease times, the more current the network snapshot, and the less likely it'll be that a client selects a service that's no longer available.
If you're a client and you want something from a Jini service, you must have the interface for the service. Unlike RMI, Jini's a lot more flexible, because you don't have to know anything else but the interface. You don't have to know the name it's registered under or the location of the service. As long as you know the interface and you're on a network that can discover a lookup service, you're in business.
Today, chances are that a developer gave you this interface. But there are a few interfaces floating around that have become kind of, sort of, standards, including Bill Venners' infamous ServiceUI.
Finding the Service Class
Unlike RMI, with Jini you don't have a choice about dynamic code downloading. You're pretty much forced to use it. (Well, you can get away without it, but it defeats the main purpose of Jini.) With Jini, you aren't required to know where something is on the network, and you aren't necessarily supposed to know who built the service. Remember, all you have is the interface and in many cases, all you care about it that you get something that implements the service interface (could be a stub, could be the real service, or a combination ...).
Remember, with RMI, the class you need on the client is always the
stub class, not the service itself. With Jini, the thing you call
methods on might be a stub, if the service is implemented as a
Remote object, or it might be the real service —
i.e., a class that implements the service interface and actually does the real
work, right there locally on the client.
Looking Up the Service
With Jini, you use a Jini lookup service, rather than RMI Registry. A Jini
lookup service is a lot more flexible and powerful, and it can give you
information as well as service objects, which, again, may or may not be
Remote object stubs, depending on whether the service is a
Remote object that stays on the server or a
Remote service that gets shipped to the client. Best of all,
you don't have to know where the lookup service is! With RMI, you must
know the IP address and port for the
Remote service in order to
find the RMI Registry where the service's stub lives. But with Jini, you know
only that somewhere, there's one or more lookup services sitting out
there on the network, reachable through IP multicast.
So that's Jini. But if Jini is the wild frontier, where nobody knows anything and you're really on your own model, J2EE is pretty much the opposite.
The main idea behind J2EE is that the server (via the containers) gives you a bunch of additional services that you might otherwise have to write yourself, or cobble together from different pieces, or purchase from a proprietary vendor. We're talking Big, Huge, Gravel-Hauling Services, like transaction management, concurrency management, security, resource/lifecycle management, lookup services, persistence, messaging services, and more.
That way, you get to focus on your own business rules instead of reinventing such a big frickin' wheel. (Or, as many have discovered, instead of reinventing a flat tire.) Other app servers have been around for quite a while — things like CICS and TUXEDO are the classic examples. But with those, you had to learn a proprietary API, and you were locked in with the vendor. J2EE is a standard for the enterprise business middle tier, so you learn just a single API, regardless of which server you choose. Best of all, you can deploy your app to any vendor's J2EE-compliant server, so you can kiss vendor lock-in goodbye.
Of course, in reality, it's not that easy to redeploy a J2EE app into a different server, for a variety of reasons. But you can. And if you've got the money to dump your current vendor and switch, isn't it nice to know you can? Better yet, isn't it nice to know that the vendor knows you can?
First, a clarification about the difference between J2EE and EJB: J2EE is a specification for a server that must be able to run Enterprise JavaBeans (EJB). But a J2EE server also has to support servlets and JSPs. You can think of J2EE as almost a meta-server — something that binds together a servlet and JSP-capable web server and an EJB server. In J2EE land, we call those sub-servers containers. So you have a web container and an EJB container living within a J2EE server. We'll focus on the EJB side here, since beans are a little more exotic than servlets and JSPs, and in the EJB world, the service is the bean.
One really cool thing about EJB is that it's a component-based development model. You build reusable components that can even be customized at deploy time without touching the Java code. A component is a little more coarse-grained than just a Java class, so it's the next level of reuse. And since your components (i.e., beans) are deployed using an XML document that describes how the server should handle the bean, you can configure things like security, transactions, resource use, etc. all declaratively, in XML, just by pushing a few buttons in a deployment tool. (You can hack the XML directly, if you really really want to, but these days the tools are good enough that you usually don't have to.)
A key difference between J2EE and plain RMI is that the server has to step
in between the client's call and the service (i.e., the bean) actually
getting the call. If a client makes a remote method call to one of the bean's
exposed methods, the server has to jump in and protect the reclusive, pampered
bean from direct contact with the client. For example, suppose the client
getAddress() on a bean that represents a specific customer.
First, the server has to verify that this client is even authorized to
call this method, but assuming the client makes it past the security
checkpoint, now the server has to do other things to get the bean ready to
handle the call. If the bean returns the customer's address, for example, the
bean might need to be freshly loaded up with the database record for this
customer. And this might need to be part of a transaction. And another client
might already be using this customer. And ... on it goes.
The J2EE solution is to make the bean a non-
object, protected by a
Remote object. So although the
bean really is the service (in other words, it has the business logic
functionality for the service methods the client wants to call), the bean
itself is not
Remote in the RMI way. But the client still
interacts with an RMI stub and Remote object; it's just that with
Remote object is more like the bean's bodyguard.
Remote object (called the
EJBObject in J2EE)
receives the client's
Remote call (i.e., the call the client made
on the stub), and then the server gets involved to decide how, when,
and even if the call should make it to the bean.
With EJB, there's another layer added to the RMI picture (besides the
EJBObject is the
Remote object, but
unlike with RMI, the
EJBObject isn't actually the service. So it's
like there are now two helpers for the service, instead of just the
one (the stub) for plain RMI. Your service interface is still a
Remote interface, but instead of implementing
directly, your service interface implements
EJBObject — an
interface that itself extends
java.rmi.Remote. Notice how the bean
doesn't extend the service interface (
Advice) even though the bean does have
the same methods. (Don't be squeamish; most EJB-aware development tools can
make sure that the bean and the service interface match.)
With J2EE, you're probably working within a single enterprise, so you can just email the client developer the interface, or maybe you even publish it in some sort of internal OO repository. Whatever. The point is that, just as with RMI and Jini, the client must have the interface at the client application's compile time.
And once again, for the stub class, you have a choice of giving it to the client in advance, or using dynamic code downloading. But in this case, dynamic code downloading might not be possible, depending on your particular J2EE server, so you might be stuck with having to personally deliver the stub classes to the client. Most J2EE servers prepare a nice little client JAR for you when you deploy a bean.
Finding the Service
Warning: we're exceeding cocktail party knowledge limits in this section, so this is the part where some people say, "Whoa! I was with you just fine until you got here ..." It's not your fault, it's ours. So it's here if you want it, but you could skip right to Web services now and nobody would really know. Still, if you're single and looking, this might be the very part that gets you that phone number ...
This works a lot like RMI, except the lookup service is now JNDI instead of an RMI Registry or a Jini lookup service. JNDI is an interface that sits in front of a range of Naming and Directory services, and it's a requirement for J2EE. The client does a lookup on the bean's logical name, just like with RMI, and gets back a stub.
There's just one little thing we forgot to mention.
With EJB, the client can't directly ask JNDI for the stub to the
Remote object (the
EJBObject). In other words, the
client can't find the stub with the service methods in JNDI. In JNDI, the
client can get only the bean's Home. The Home is just a factory for
the bean; its main purpose in life is to hand out references to
EJBObjects. In other words, the
Home gives you the
EJBObject stub — the thing you can call service
methods on. But the
Home is itself a
object, so when the client wants to call service methods on a bean, it has to
jump through a couple of extra hoops it didn't have with straight RMI.
Do a JNDI lookup on the bean's logical name (whatever the bean deployer called it).
This gets the client a stub to a
The client calls a
Remotemethod on the
Homestub, to ask for a stub to the service itself. OK, well, it can't have a reference to the real service — the bean — but the client can get the next closest thing: a stub to the bean's bodyguard, the
Remoteobject that implements the bean's service interface.
(A disclaimer on the whole EJB picture — as of EJB 2.0 (which is part
of J2EE 1.3, the current version), not all client interfaces have to be
Remote. In other words, the
EJBObject objects can be local to the client instead of RMI
Remote objects. That means both the client and the bean are
running in the same JVM! Doesn't sound too distributed, does it? No, it's not,
because you lose one of the most valuable benefits — location
independence. If you "co-locate" the client and the bean, you do get some
performance gain, since you're eliminating the whole stub-to-
object process, but you're giving up the chance to move pieces of your
so-called distributed app to other nodes on your network. There is a
compelling, even mandatory, reason to use local
EJBObjects, but it has to do with persistent Entity beans, so you
should consider it only a Very Special Case. For now, anyway. When you're a
J2EE designer, you can worry about the subtleties on your own time.)
Now that you've got RMI, Jini, and J2EE all figured out, let's just say that these are the nice, happy, clean, well-lighted, crisp, technologies when compared to Web services. In fact, we won't say much about Web services, because it's all so wild and wooly out there on the Web services frontier. But we'll say enough to get you through one drink.
Java RMI, Jini, J2EE, and EJB are all Java technologies. Web services is not. Web services is about taking your existing apps (although some folks are creating new apps specifically to deploy as Web services, but this is rare), and exposing them on the Web. Most of the time, that means an intranet. It's pretty unlikely today that you'll find Web services just sitting out there on the Web for all the public to access, although Amazon and Google do offer Web services you can play with to add more Googleability and Amazonity to your own site. We'll put those down as Special Cases.
Today, most folks are using Web services for integration among their own business applications. But the ideal vision is that one day there will be tons of Web services happily playing together in a B2B and C2B way (Business-to-Business and Consumer-to-Business), without anyone having a lot of prior knowledge about the other application other than the business domain.
For example, the classic* example is: you're on a multi-city publicity tour for your latest bestseller, "It's Not About the Kilt. " But there's a massive power outage in what was to have been your next stop, and now your whole schedule is toast. So you make a few clicks in a little app on your laptop and it takes care of everything else. It changes and extends air tickets, hotel reservations, and rental cars. Sure, you could have done it by going to all the various web sites and painstakingly making the changes yourself, to each service in turn, but remember, you're in an Internet cafe with dial-up, and you have better things to do.
(* It's just oxymoronic to call anything about Web Services "classic," but there you go. And we've modified it somewhat. I think it's supposed to be a traveling salesman.)
The big problem with Web services is that it's really hard to approach it the way you would a traditional enterprise app, because transactions and security are basically roll-your-own on the open Web. There's no Transaction Manager out there on the Web, the way there is inside of your J2EE server. There's nobody out there managing all of the security, either. And everything gets tough when the whole idea is that you don't know who — or what — will access your Web service. There is a way to expose Web services in such a way that those services aren't tightly coupled to the client (and/or dependent on both the client and the service using the same programming language, for example).
In some ways, the promise of Web services is that some aspects of it can be like Jini, with a certain level of dynamic discovery. In reality, that's both really hard to work out, and rarely done. But this stuff is changing on a daily basis. Remember, this is Internet time, baby.
Web Services Architecture
This picture is a lot higher-level than the previous ones, so there can be all kinds of other players in here, including stubs of various kinds (Web services can have their own kind of stubs), more interfaces, and many more things doing XML processing.
One key difference between the RMI-driven technologies and Web services is that the others are mostly based on real Java method calls. A call to a stub is still a Java method call. Sure, the stub makes a socket and a stream and uses a particular protocol to transmit the method call (usually RMI-IIOP, another impressive acronym), but once it gets over to the server where the service is running, it turns back into a regular method call, invoked on the Remote service object.
With Web services, the messages are sent using XML, using the SOAP protocol. SOAP is more or less just an envelope for a message, and the message isn't much more than just the actual "method" call the client wants the Web service to perform. (And we use the word "method" loosely here, although when we're talking Web services in Java, it does translate to a actual method call on a real live Java object, complete with arguments and return values.)
Most of the heavy runtime work with Web services is that there're all kinds of XML processing going on all over the place and, well, parsing XML is slooooooooow. Which means performance is an issue (which you can add to the other Web services problems like no transaction support, and very little security.) Then again, the beauty of XML is that it doesn't care about the platform, the programming language, or anything else. It's pretty much just text with tags. So the potential for interoperability and integration of anything and everything is possible with Web services.
You expose RMI, Jini, and EJB services through a regular old Java service interface. You expose Web services through an XML interface known as the WSDL (say it with me again: "wizdle"). The WSDL describes the service, and even tells the client where to find the service. But how the WSDL itself is exposed can really vary.
For example, there is a kind of registry/lookup service for Web services called UDDI, where you can publish, among other things, the WSDL. But since most Web services are being done on internal intranets, there isn't as much use of UDDI, but if (it's more like when) Web services start getting out there, that will probably change.
So a huge difference between Web services and the other Java distributed technologies is that with Web services (if they're to be interoperable, anyway), the client doesn't have to retrieve references to real objects. If you've got the WSDL, you've probably got enough information to make yourself a SOAP message and fire it off to the Web service described in the WSDL.
Remember, with Jini and EJB, it's often only the stub that knows the IP address and TCP port of the Remote service. The Java interface itself is just for declaring the methods, not the location of the service. But with a WSDL, it's different. A WSDL is more like a Java interface on steroids, except without the Java. The WSDL includes not just the method descriptions (name, arguments, return types, etc.) but also the network location of the service.
J2EE 1.4 and Web Services
J2EE 1.4, due out before the end of 2003, adds Web services capabilities, and should make it a lot easier for developers who're already using J2EE to turn a J2EE application into a Web service endpoint (for today, think of the endpoint as the real service). With J2EE 1.4, you shouldn't have to write XML for the WSDL, and best of all, you don't have to translate the incoming XML messages (SOAP) into Java calls, and vice versa. You can do that already, using the JAXP (part of J2EE 1.3) and JAX-RPC (available, but not yet part of J2EE until 1.4 ships) APIs, but with J2EE 1.4, it will all be built into the system, and the deployment tools will make it way more seamless than it is now, trying to cobble together all of the various Web-services-related APIs on your own.
Snapshot for Today
OK, let's face it: Jini is just not the buzzword it once was, with J2EE and Web services all the rage. Except that J2EE really works, with transactions and security, and all the rest, while Web services are still largely an uphill struggle. The word "bleeding" comes to mind. But Jini is out there, used by some of the world's largest banking organizations and even the U.S. military.
Bottom line: for big, serious enterprise-scale apps, J2EE is extremely popular in the marketplace. Web services are painfully immature but potentially very important, and next year we'll see what happens when J2EE embraces and integrates Web services. But Jini is just ... so much cooler. After all, this is about cocktail party conversation, not your next PowerPoint presentation.
Kathy Sierra has been a master Java trainer for Sun Microsystems, teaching Sun's instructors how to teach the latest Java technologies. She is also the founder of one of the largest java community websites in the world, javaranch.com.
Bert Bates is a 20-year software developer, a Java instructor, and a co-developer of Sun's upcoming EJB exam (Sun Certified Business Component Developer).
Return to ONJava.com.