Вы находитесь на странице: 1из 6

Jini Example

This example comes from chapter 5 of


Core Jini
W. Keith Edwards
Prentice Hall
(This is an excellent book on Jini. Buy It!)

Service Interface
// This is the interface that the service's proxy
// implements

package corejini.chapter5;

public interface HelloWorldServiceInterface {


public String getMessage();
}

Service
// This is a Hello, World
// service--it publishes a proxy that returns
// a string when asked by clients.

package corejini.chapter5;

import net.jini.discovery.DiscoveryListener;
import net.jini.discovery.DiscoveryEvent;
import net.jini.discovery.LookupDiscovery;
import net.jini.core.lookup.ServiceItem;
import net.jini.core.lookup.ServiceRegistrar;
import net.jini.core.lookup.ServiceRegistration;
import java.util.Hashtable;
import java.io.IOException;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;

// This is the proxy object that will be downloaded


// by clients. It's serializable and implements
// our well-known HelloWorldServiceInterface.
public class HelloWorldServiceProxy implements Serializable,
HelloWorldServiceInterface {
public HelloWorldServiceProxy() {
}
public String getMessage() {

1
return "Hello, world!";
}
}

// HelloWorldService is the "wrapper" class that


// handles publishing the service item.
public class HelloWorldService implements Runnable {
// 10 minute leases
protected final int LEASE_TIME = 10 * 60 * 1000;
protected Hashtable registrations = new Hashtable();
protected ServiceItem item;
protected LookupDiscovery disco;

// Inner class to listen for discovery events


class Listener implements DiscoveryListener {
// Called when we find a new lookup service.
public void discovered(DiscoveryEvent ev) {
System.out.println("discovered a lookup service!");
ServiceRegistrar[] newregs = ev.getRegistrars();
for (int i=0 ; i<newregs.length ; i++) {
if (!registrations.containsKey(newregs[i])) {
registerWithLookup(newregs[i]);
}
}
}

// Called ONLY when we explicitly discard a


// lookup service, not "automatically" when a
// lookup service goes down. Once discovered,
// there is NO ongoing communication with a
// lookup service.
public void discarded(DiscoveryEvent ev) {
ServiceRegistrar[] deadregs = ev.getRegistrars();
for (int i=0 ; i<deadregs.length ; i++) {
registrations.remove(deadregs[i]);
}
}
}

public HelloWorldService() throws IOException {


item = new ServiceItem(null, createProxy(), null);

// Set a security manager


if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}

// Search for the "public" group, which by


// convention is named by the empty string
disco = new LookupDiscovery(new String[] { "" });

// Install a listener.
disco.addDiscoveryListener(new Listener());
}

protected HelloWorldServiceInterface createProxy() {


return new HelloWorldServiceProxy();

2
}

// This work involves remote calls, and may take a


// while to complete. Thus, since it's called from
// discovered(), it will prevent us from responding
// in a timely fashion to new discovery events. An
// improvement would be to spin off a separate short-
// lived thread to do the work.
protected synchronized void registerWithLookup(ServiceRegistrar
registrar) {
ServiceRegistration registration = null;

try {
registration = registrar.register(item, LEASE_TIME);
} catch (RemoteException ex) {
System.out.println("Couldn't register: " +
ex.getMessage());
return;
}

// If this is our first registration, use the


// service ID returned to us. Ideally, we should
// save this ID so that it can be used after
// restarts of the service
if (item.serviceID == null) {
item.serviceID = registration.getServiceID();
System.out.println("Set serviceID to " + item.serviceID);
}

registrations.put(registrar, registration);
}

// This thread does nothing but sleep, but it


// makes sure the VM doesn't exit.
public void run() {
while (true) {
try {
Thread.sleep(1000000);
} catch (InterruptedException ex) {
}
}
}

// Create a new HelloWorldService and start


// its thread.
public static void main(String args[]) {
try {
HelloWorldService hws = new HelloWorldService();
new Thread(hws).start();
} catch (IOException ex) {
System.out.println("Couldn't create service: " +
ex.getMessage());
}
}
}

3
Client

// A simple Client to exercise the HelloWorldService

package corejini.chapter5;

import net.jini.discovery.DiscoveryListener;
import net.jini.discovery.DiscoveryEvent;
import net.jini.discovery.LookupDiscovery;
import net.jini.core.lookup.ServiceRegistrar;
import net.jini.core.lookup.ServiceTemplate;
import java.util.Vector;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;

public class HelloWorldClient implements Runnable {


protected ServiceTemplate template;
protected LookupDiscovery disco;

// An inner class to implement DiscoveryListener


class Listener implements DiscoveryListener {
public void discovered(DiscoveryEvent ev) {
ServiceRegistrar[] newregs = ev.getRegistrars();
for (int i=0 ; i<newregs.length ; i++) {
lookForService(newregs[i]);
}
}
public void discarded(DiscoveryEvent ev) {
}
}

public HelloWorldClient() throws IOException {


Class[] types = { HelloWorldServiceInterface.class };

template = new ServiceTemplate(null, types, null);

// Set a security manager


if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}

// Only search the public group


disco = new LookupDiscovery(new String[] { "" });

// Install a listener
disco.addDiscoveryListener(new Listener());
}

// Once we've found a new lookup service, search


// for proxies that implement
// HelloWorldServiceInterface
protected Object lookForService(ServiceRegistrar lusvc) {
Object o = null;

4
try {
o = lusvc.lookup(template);
} catch (RemoteException ex) {
System.err.println("Error doing lookup: " +
ex.getMessage());
return null;
}

if (o == null) {
System.err.println("No matching service.");
return null;
}

System.out.println("Got a matching service.");


System.out.println("It's message is: " +
((HelloWorldServiceInterface)o).getMessage());

return o;
}

// This thread does nothing--it simply keeps the


// VM from exiting while we do discovery.
public void run() {
while (true) {
try {
Thread.sleep(1000000);
} catch (InterruptedException ex) {
}
}
}

// Create a HelloWorldClient and start its thread


public static void main(String args[]) {
try {
HelloWorldClient hwc = new HelloWorldClient();
new Thread(hwc).start();
} catch (IOException ex) {
System.out.println("Couldn't create client: " +
ex.getMessage());
}
}
}

5
Compile and Deploy

You need to download Jini from Sunsoft for this example to work. While compiling the
code for the Service and Client, include the appropriate Jini JAR files in the
CLASSPATH.

When deploying the service and client on different machines, keep in mind that for the
service the following classes need to be compiled:

HelloWorldServiceInterface.java
HelloWorldServiceProxy.java
HelloWorldService.java

For the client, compile the following classes:

HelloWorldServiceInterface.java
HelloWorldClient.java

Note that the client does not need HelloWorldServiceProxy.java at compile time,
since the byte code HelloWorldServiceProxy.class is not needed on the
client’s machine, when the client is started. The code,
HelloWorldServiceProxy.class, will automatically be downloaded, along with
the proxy object, when the client requests the service from a lookup service.

Make sure to place the compiled code HelloWorldServiceProxy.class in a


network accessible directory on the machine in which the service is running. And
start a HTTP server on that machine, so that this code can be downloaded by the
client. Also don’t forget to start a lookup service.

To keep this example simple, the service needs to be started before the client. Notice
however, that the service has been implemented in such a way that it can be started
before or after a lookup servide. If the service can not find a lookup, then it simply waits
until a lookup service joins the community, at which time the service registers itself with
the lookup, and sends it its proxy object.