ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button
Head First EJB

How to Talk About Jini, J2EE, and Web Services at a Cocktail Party

by Kathy Sierra and Bert Bates, authors of Head First Java, 2nd Edition
06/15/2005

Editor's note: Kathy Sierra and Bert Bates, the brains behind O'Reilly's Head First series, first wrote this article in 2003 at the time of the release of Head First Java. It was hugely popular and we are still receiving requests for more like it, so much so that we decided to bring it back again now that Head First Java, 2nd Edition has released. So, if you didn't catch this piece the first time around, let Kathy and Bert show you how to hold your own in conversation with Java geeks.

It's all so predictable. There you are at a dinner party, sipping a second martini, when the conversation turns, inevitably, to distributed programming. What to do? Relax, because here we'll tackle three of the most interesting distributed technologies, complete with all the napkin-ready drawings you can use to up your whuffie. (Don't know about whuffie either? Read Richard Koman's interview with Cory Doctorow.)

But first, in case you're actually at a party right now, we'll start with a few quick phrases that you can use even if you don't know Java. After that, for those who do know some Java, we'll dig a little deeper.

"What's dynamic discovery? It just means that clients and services find each other, you know, dynamically, over the network, without any prior knowledge of one another. It's all based on IP multicast."

"What's an automatic self-healing network? It means the Jini network is always reflecting the current status of all the available services -- like, 'OK, this one's up and this one's not ...' without any human administration!"

Related Reading

Head First Java
By Kathy Sierra, Bert Bates

"Of course, most routers have IP multicast disabled, so you aren't going to use Jini on the web. But Jini was designed to work for local networks, or collections of local networks, so that's not so much of a problem."

"The cool things about J2EE are vendor-independence and that you get to focus on your business logic and leave all the big plumbing/heavy lifting to the server vendor. You work on the rules for your particular business, and leave the security, transactions, concurrency, persistence, and even the networking code implementations up to the server. And you have to learn only one API, and you can redeploy your J2EE apps to any vendor's J2EE-compliant server, so now the vendors have to kiss up to you instead of the way it used to be, where you were locked in and had to beg the vendor to add some new capability or fix bugs ..."

"The cool thing about Web services is ... well, OK, so maybe in its current state there isn't anything really cool about Web services. But that could change. Sometime in the future. When all the standards are worked out, and the tools mature, and ..."

"But if Web services were cool, it would be because you can take the business apps you already have, even legacy apps, and expose them on the Web using XML as the interface. A client sends an XML message (in a format called, cutely, SOAP) to a service in an interoperable way."

"Security and transactions are the two glaring holes in Web services right now, which means everybody has to roll their own solutions. There's no big ol' transaction manager sitting out there on the Web, and the only security you've got is HTTPS for mutual authentication.

"Jini and J2EE are both Java technologies. With J2EE, it's like the spec is saying, 'Oh, don't you worry your little developer head about all these big, hard, things. The vendor will take care of all those messy things so you can pay attention to your own domain-specific needs (like, how to sell more lingerie).' But with Jini, it's like the spec is saying, 'You are so out there on your own with this. Don't expect anybody to come to your rescue with a bunch of big infrastructure. This is lean and mean, baby, but you can do the most amazing and elegant things. And check out JavaSpaces while you're here.'"

"Web services is not a Java-specific technology, but Java can sure make it a gazillion times easier to do, especially if you switch to J2EE 1.4. No, you're right, J2EE 1.4 isn't out yet, but it will be before the end of the year. You'll probably see some solid vendor support in early 2004."

(Before we go further, some disclaimers: First, if you have any problem with the high-level nature of this article, re-read the title. We're taking huge bartender license with the content. We won't tell you anything that's not true, but you aren't getting the whole story, either. Each of these topics requires a book of its own. (And darned if we're not just about to come out with one, Head First EJB. What are the odds?) Let's just say the cocktail view of a topic probably isn't what you want driving your next architecture. (We know you know this, but for that one disturbed person who will somehow mistake this for a Serious Technical White Paper, we felt compelled to cover our a**es).)

So now it's time to dive down a level. We'll start with a look at what it means to have a service, and, most importantly, how you expose yourself to others. In other words, how you tell potential clients about your service.

With Jini, J2EE, and Web services, the goal is for a client to access a service. What's a service? Pretty much anything you can do as the result of a message sent from one piece of software to another (which may or may not involve human direction). You might have a service that does huge calculations for genetic matching. Or a service that plays a mean game of Go. Or a service that lets you buy concert tickets. Or books an exotic tropical cruise. Or even sends your text to a high-volume printer. In other words, a service is anything that starts as software, but the result doesn't necessarily stay in software.

You might have a service that moves a video camera, prints to a printer, dials a phone. Doesn't matter. Or at least it shouldn't matter. One of the main goals, as it always with OO, is have the least amount of coupling — in this case, between the client and server. In other words, we want the players (the clients and services) to know as little about one another as possible.

But let's say you've got a service ... now what? How do clients find you? And if they find you, how do they know what your service can do? In other words, how do they know the methods they can call on your service? Somehow, you have to expose yourself to clients, and it's a little different for each of the three technologies we're looking at. Regardless of whether you've talking Jini, J2EE, or Web services, though, there's always an interface in there somewhere. That interface declares what you can do.

Service Interfaces

As a service developer, you have to tell folks what your service can do. In other words, you have to declare your service's methods. That includes declaring what the client can pass to your methods (the arguments) and what the service will return to the client (the return types).

The interface above is for a service called Advice. It has one method, getAdvice(). You call the method and you get back a String of stunningly useful, randomly chosen advice. (We've chosen to not show the return types in our little fake UML-ish things. It was a really small napkin.)

For Jini and EJB (Enterprise JavaBeans — the heart and soul of J2EE), that interface is usually Remote. A Remote interface means the service developer writes a Java interface that extends java.rmi.Remote. Oh yeah, the Remote methods (meaning all of the methods in the Remote interface) have to declare a java.rmi.RemoteException — a checked exception that says to the client, "Things can go horribly wrong, so be prepared."

For Web services, the interface is defined in a WSDL (pronounced "wizdle," rhymes with "fizdle") — a special type of XML document. So, to summarize, here's another little phrase you can drop in casual conversation:

"In other words, with Jini and EJB you expose yourself with a Java interface, but with Web services, you expose yourself with an XML interface."

(Actually, if you're a Java developer, you create the WSDL by first writing a Java interface, and then pushing a magic red button on your development tool that turns your Java interface into an XML WSDL, but that is, as they say, beyond the scope of cocktail party conversation.)

OK, so now we've got a service, and we have an interface that exposes our service. Now what? How do clients know about the interface? How do they actually get the interface and whatever else they need to talk to your service? That depends on the type of service. And it's different for each of the three types. You'll access Jini, J2EE, and Web services each a little differently, and the rest of this article looks at some of the details and key differences.

First, we'll start with a little background with Java's Remote Method Invocation (RMI). It's the backbone of most of Java's distributed technologies, and Jini and EJB depend on it. In fact, since virtually all distributed technologies work on something that is conceptually like RMI, anything you get here will help make sense of the whole distributed world, Java or non-Java.

With RMI, you write your service and you make it a Remote object. It's a piece of cake to make it Remote — write a Remote interface, then create a Remote class that implements it.

To Make a Remote Interface:

  1. Extend java.rmi.Remote

  2. Declare a java.rmi.RemoteException for each method:

    public interface Advice 
    extends java.rmi.Remote {
    
       String getAdvice() throws 
       java.rmi.RemoteException;
    
    }

To Make a Remote Class:

  1. Implement your Remote interface

  2. Write the actual business logic for the interface methods:

    public class AdviceImplementation implements Advice {
    
       public String getAdvice() {
    
       // monumentally important 
        business logic here
    
      }
    
    }

(OK, so code is maybe a bit much for a cocktail party, but we're all geeks here ...)

The Key to Everything: The Stub

Once you're got your interface and your class, you run your class through the RMI Compiler (rmic) that ships with J2SE. (If you've got javac, you've got rmic.) That process creates what you'll find in nearly all modern distributed programming models — the stub. The stub is just a helper on the client, which acts like the Remote object (the service) by implementing the Remote interface just as the service does. But really, the stub is just a little object that takes the method call, packages it up, and sends it over the wire to the real one true Remote Object. In other words, the stub knows how to phone home and ask the real service to do the real work.

The stub's methods are fake. Well, they are methods and they do have a lot of code, including all the networking and I/O stuff needed to contact the service. But they aren't the actual business methods. So for the Advice service, the stub has a getAdvice() method, but that method simply passes the client's request to the real AdviceImplementation on the server.

That way, the client gets to pretend that he's making calls on the Remote object, but of course we know that can't really happen, since the Remote object (i.e., the service) is in a different JVM heap.

(Yes, there is also something on the server side that accepts the Socket connection from the client and unpacks the method call, packages and ships the return values, etc., but we're not talking about that in this article. It's a more trivial process, because you don't have to worry about delivering that functionality to the client. So yes, there's a companion to the stub's functionality on the server, but no, you probably won't have to worry about it.)

RMI Basic Architecture

With RMI, the Remote Object Is the Service


RMI Exposure

If you're a client and you want something from a Remote service (in other words, a Remote object), you have to have the Remote service interface (at both compile time and runtime), and you have to get the stub object (runtime). It's the stub, remember, that actually knows how to send your method call to the Remote object (and give you back the return value), so you're dead without it. Chances are, you'll get both the interface and the stub .class file from the service developer.

(There is, however, a much cooler way to get the stub class just in time, without having it prior to runtime, through a process called dynamic code downloading. It's one of the most powerful things you can do in Java, and not very hard, either. But, you can of course always do it the wimpy way and just have the developer email you the stub class file, or carry it down the hall to your cube.)

Finding the Service (i.e., Getting Hold of the Stub So That You Can Call Business Methods on the Service)

In RMI, you look up the stub using the RMI Registry (which ships with J2SE). The RMI Registry is like a little white pages phone book; you look up the name and you get back the stub. Remember, when the stub object comes over, it's serialized. That means it has to be deserialized when it gets to the client, and for that to work, the stub class has to either be on the current classpath, or be findable using dynamic code downloading. That's just basic Java -- an instance can't be deserialized without its class!

Finding the Lookup Service (RMI Registry)

With RMI, you must know where the stub is located. That means you have to know the IP address and TCP port number for the RMI Registry. (Which also happens to be the server where the Remote object/service itself lives.) Actually you probably don't have to know the port number, since there's a default, but if the service deployer changes it, you'll need to know. The client does a simple one-line lookup, using a static method (java.rmi.Naming.lookup()), and then a miracle occurs and it has a freshly deserialized, live, stub. An object that knows how to phone home.

Now that we've looked at RMI, this part'll make more sense. Jini is like extreme RMI. And we use the word extreme here in the sporting sense, not the XP way.

Dynamic Discovery: How Services and Lookup Services Find One Another

This is where plain RMI and Jini differ most. In RMI, the client has to know a lot, and the service has to be explicitly registered (under a logical name) with the RMI Registry, and the registry must be on the same machine with the service!

But with Jini, everything is just... out there. Somewhere. And nobody knows much of anything except interfaces. Here's a quote about it, which we've found especially helpful to drop at strategic moments in a conversation:

"With Jini, services are always trying to discover lookup services, clients are always trying to discover lookup services, and lookup services are always trying to let services and clients know that they (the lookup services) are out there. And it's all automatic!"

The basic Jini architecture uses RMI, although in Jini you can also send the client the whole service itself, rather than having the service be a 100 percent Remote object on the server. When the client asks for a reference to a service, it might get a stub to a Remote object (if the service is implemented as a Remote object), or it might get the whole darn service shipped over, on which it can make plain old local calls. In fact, with Jini, the client might even get a hybrid or "smart-proxy" (drop that phrase at the bar for extra credit) -- that is, a non-Remote Java object that contains a stub to a Remote object (like, in an instance variable). That way, the client makes local calls directly to the service, but the service itself might turn around and make Remote calls to something else. A smart-proxy can help performance on both the client and service by having some of the work done on the client.

Pages: 1, 2

Next Pagearrow