The Artima Developer Community
Sponsored Link

Objects and Java Seminar
Jini and JavaSpaces
Lecture Handout

Agenda


Why Jini?


What is Jini?


Jini Example


Jini is the Glue


The Runtime Infrastructure


Groups


Discovery, Join, Lookup


Discovery - Multicast Request Protocol


Discovery - Multicast Request Protocol


Discovery - Unicast Discovery Protocol


Discovery - The Unicast Discovery Protocol


Discovery - The Multicast Announcement Protocol


Discovery - The Multicast Announcement Protocol


A Discovery Example


Lookup Service Ping

 1 import net.jini.core.discovery.LookupLocator;
 2 import net.jini.core.lookup.ServiceRegistrar;
 3 import net.jini.core.lookup.ServiceID;
 4
 5 import java.io.*;
 6 import java.rmi.*;
 7 import java.rmi.server.*;
 8 import java.util.StringTokenizer;
 9
10 public class LSP
11 {
12     public static void main (String[] args) {
13
14         if (args.length == 0) {
15             System.out.println("LSP requires a lookup service URL as first arg.");
16             System.out.println("Example: \"LSP jini://localhost:2000\"");
17             System.exit(0);
18         }
19
20         String urlString = args[0];
21
22         try {
23             System.setSecurityManager (new RMISecurityManager());
24
25             // Instantiate a LookupLocator object set to perform
26             // unicast discovery on the lookup service indicated
27             // by the passed in host and port number. (If no port number
28             // is specified, the default port of 4160 will be used.)
29             LookupLocator lookupLocator = new LookupLocator(urlString);
30             String host = lookupLocator.getHost();
31             int port = lookupLocator.getPort();
32
33             System.out.println("Lookup Service: jini://" + host + ":" + port);
34
35             // Invoke getRegistrar() on the LookupLocator to cause it to
36             // perform unicast discovery on the lookup service indicated
37             // by the host and port number passed to the constructor.
38             // The result is a reference to the registar object sent from
39             // the lookup service.
40             ServiceRegistrar registrar = lookupLocator.getRegistrar();
41
42             // A lookup service is, after all, a service -- a service
43             // so proud of itself that it registers itself with itself. To
44             // get the ID it assigns to itself, call getServicerID() on
45             // the registrar object.
46             ServiceID id = registrar.getServiceID();
47
48             System.out.println ("Lookup Service ID: " + id.toString());
49         }
50         catch (Exception e) {
51               System.out.println("LSP Exception:" + e);
52         }
53     }
54 }

$ java -Djava.security.policy="policy.all" LSP jini://localhost

Lookup Service: jini://localhost:4160
Lookup Service ID: a1366531-5805-4f2e-8b40-e6b9b36f78fb

Lookup Service Find

 1 import net.jini.discovery.LookupDiscovery;
 2 import net.jini.core.discovery.LookupLocator;
 3 import net.jini.discovery.DiscoveryListener;
 4 import net.jini.discovery.DiscoveryEvent;
 5 import net.jini.core.lookup.ServiceRegistrar;
 6 import net.jini.core.lookup.ServiceID;
 7
 8 import java.io.*;
 9 import java.rmi.*;
10 import java.rmi.server.*;
11 import java.util.StringTokenizer;
12
13 // Lookup Service Find - Does discovery to find the nearby lookup
14 // services and prints out a list
15 public class LSF implements DiscoveryListener
16 {
17     public static void main (String[] args) {
18
19         try {
20             System.setSecurityManager (new RMISecurityManager());
21
22             LookupDiscovery ld = new LookupDiscovery(LookupDiscovery.NO_GROUPS);
23             ld.addDiscoveryListener(new LSF());
24             ld.setGroups(LookupDiscovery.ALL_GROUPS);
25
26             Thread.currentThread().sleep(1000000000L);
27         }
28         catch (Exception e) {
29               System.out.println("LSF Exception:" + e);
30         }
31     }
32
33     public void discovered(DiscoveryEvent de) {
34
35         try {
36             // Invoke getRegistrar() on the LookupLocator to cause it to
37             // perform unicast discovery on the lookup service indicated
38             // by the host and port number passed to the constructor.
39             // The result is a reference to the registar object sent from
40             // the lookup service.
41             ServiceRegistrar[] registrars = de.getRegistrars();
42
43             for (int i = 0; i < registrars.length; ++i) {
44                 // A lookup service is, after all, a service -- a service
45                 // so proud of itself that it registers itself with itself. To
46                 // get the ID it assigns to itself, call getServicerID() on
47                 // the registrar object.
48                 ServiceID id = registrars[i].getServiceID();
49
50                 LookupLocator lookupLocator = registrars[i].getLocator();
51                 String host = lookupLocator.getHost();
52                 int port = lookupLocator.getPort();
53
54                 System.out.println("Lookup Service: jini://" + host + ":"
55                     + port + ", " + id.toString());
56             }
57         }
58         catch (Exception e) {
59               System.out.println("LSF Exception:" + e);
60         }
61     }
62
63     public void discarded(DiscoveryEvent de) {
64     }
65 }


$ java -Djava.security.policy="policy.all" LSF

Lookup Service: jini://bvenners:4160, a1366531-5805-4f2e-8b40-e6b9b36f78fb


Join


The ServiceItem


A ServiceItem Diagram


The Join Process


The SummerService

 1 import net.jini.core.discovery.LookupLocator;
 2 import net.jini.core.lookup.ServiceRegistrar;
 3 import net.jini.core.lookup.ServiceID;
 4 import net.jini.core.lookup.ServiceTemplate;
 5 import net.jini.core.lookup.ServiceMatches;
 6 import net.jini.core.lookup.ServiceItem;
 7 import com.sun.jini.lookup.JoinManager;
 8 import com.sun.jini.lookup.ServiceIDListener;
 9 import net.jini.core.entry.Entry;
10 import net.jini.lookup.entry.Name;
11 import com.sun.jini.lease.LeaseRenewalManager;
12
13 import java.io.*;
14 import java.rmi.*;
15 import java.rmi.server.*;
16 import java.util.StringTokenizer;
17
18 public class SummerService extends UnicastRemoteObject
19     implements Summer, ServiceIDListener, Serializable
20 {
21     public SummerService() throws RemoteException {
22         super ();
23     }
24
25     public long sumString(String s) throws InvalidLongException,
26         RemoteException {
27
28         System.out.println("sumString(\"" + s + "\")");
29         long sum = 0;
30         StringTokenizer st = new StringTokenizer(s);
31         String token;
32         while (st.hasMoreTokens()) {
33             token = st.nextToken();
34             try {
35                 sum += Long.parseLong(token);
36             }
37             catch (NumberFormatException e) {
38                 throw new InvalidLongException(
39                     "Invalid number: " + token);
40             }
41         }
42
43         return sum;
44     }
45
46     public void serviceIDNotify (ServiceID idIn) {
47     }
48
49     public static void main (String[] args) {
50
51         try {
52             System.setSecurityManager(new RMISecurityManager());
53
54             Entry[] attributes = new Entry[1];
55             attributes[0] = new Name("SummerService");
56
57             SummerService summerService = new SummerService();
58
59             JoinManager joinManager = new JoinManager(summerService,
60                 attributes, summerService, new LeaseRenewalManager());
61         }
62         catch (Exception e) {
63             System.out.println("SummerService Exception:" + e);
64         }
65     }
66 }


$ java -Djava.security.policy=/sun/jini/bv/policy.all
    -Djava.rmi.server.codebase=http://localhost:8080/ SummerService




1 import java.rmi.*;
2
3 public interface Summer extends Remote {
4
5     long sumString(String s)
6         throws InvalidLongException,
7         RemoteException;
8 }


 1 public class InvalidLongException
 2     extends Exception {
 3
 4     private String message;
 5     InvalidLongException(String s) {
 6         message = s;
 7     }
 8     public String getMessage() {
 9         return message;
10     }
11 }

The Lookup Process


Lookup Service Directory

 1 import net.jini.core.discovery.LookupLocator;
 2 import net.jini.core.lookup.ServiceRegistrar;
 3 import net.jini.core.lookup.ServiceID;
 4 import net.jini.core.lookup.ServiceTemplate;
 5 import net.jini.core.lookup.ServiceMatches;
 6 import net.jini.core.lookup.ServiceItem;
 7
 8 import java.io.*;
 9 import java.rmi.*;
10 import java.rmi.server.*;
11 import java.util.StringTokenizer;
12
13 public class LSD
14 {
15     public static void main (String[] args) {
16
17         if (args.length == 0) {
18             System.out.println("LSP requires a lookup service URL as first arg.");
19             System.out.println("Example: \"LSP jini://localhost:2000\"");
20             System.exit(0);
21         }
22
23         String urlString = args[0];
24
25         try {
26             System.setSecurityManager (new RMISecurityManager());
27
28             // Instantiate a LookupLocator object set to perform
29             // unicast discovery on the lookup service indicated
30             // by the passed in host and port number. (If no port number
31             // is specified, the default port of 4160 will be used.)
32             LookupLocator lookupLocator = new LookupLocator(urlString);
33             String host = lookupLocator.getHost();
34             int port = lookupLocator.getPort();
35
36             System.out.println();
37             System.out.println("Lookup Service: jini://" + host + ":" + port);
38
39             // Invoke getRegistrar() on the LookupLocator to cause it to
40             // perform unicast discovery on the lookup service indicated
41             // by the host and port number passed to the constructor.
42             // The result is a reference to the registar object sent from
43             // the lookup service.
44             ServiceRegistrar registrar = lookupLocator.getRegistrar();
45
46             // Create a ServiceTemplate object that will match all the
47             // services in the lookup service.
48             ServiceTemplate serviceTemplate = new ServiceTemplate(null, null,
49                 null);
50
51             // Do the lookup. This is bad LSD in a way, because it will
52             // only report at most 1000 services in the lookup service.
53             ServiceMatches matches = registrar.lookup(serviceTemplate, 1000);
54
55             System.out.println("Total Services: " + matches.totalMatches);
56             System.out.println();
57             for (int i = 0; i < matches.totalMatches; ++i) {
58
59                 ServiceItem item = matches.items[i];
60                 String typeName = item.service.getClass().getName();
61                 String idString = item.serviceID.toString();
62
63                 System.out.println(typeName + ": " + idString);
64             }
65             System.out.println();
66         }
67         catch (Exception e) {
68               System.out.println("LSD Exception: " + e);
69         }
70     }
71 }


$ java -Djava.security.policy="policy.all" LSD jini://localhost

Lookup Service: jini://localhost:4160
Total Services: 2

SummerService_Stub: f6731f98-9bf2-4434-814f-fee57deadaf4
com.sun.jini.reggie.RegistrarProxy: a1366531-5805-4f2e-8b40-e6b9b36f78fb


Using a Service


The SummerClient

 1 import net.jini.entry.*;
 2 import net.jini.core.lookup.*;
 3 import net.jini.core.entry.*;
 4 import net.jini.lookup.entry.*;
 5 import net.jini.core.discovery.*;
 6 import java.rmi.*;
 7 import java.io.*;
 8
 9 class SummerClient
10 {
11     public static void main (String[] args) {
12
13
14         try {
15             System.setSecurityManager (new RMISecurityManager ());
16
17             // Perform unicast lookup on localhost
18             LookupLocator lookup = new LookupLocator("jini://localhost");
19
20             // Get the service registrar object for the lookup service
21             ServiceRegistrar registrar = lookup.getRegistrar();
22
23             // Search the lookup server to find the service that has the
24             // name attribute of "SummerService".
25             Entry[] attributes = new Entry[1];
26             attributes[0] = new Name("SummerService");
27             ServiceTemplate template = new ServiceTemplate(null, null,
28                 attributes);
29
30             // lookup() returns the service object for a service that matches
31             // the search criteria passed in as template
32             // Here, although I searched by Name attribute, I'm assuming that
33             // the object that comes back implements the Summer interface
34             Summer summer = (Summer) registrar.lookup(template);
35
36             LineNumberReader stdinReader = new LineNumberReader(
37                 new BufferedReader(new InputStreamReader(System.in)));
38
39             for (;;) {
40
41                 String userLine = stdinReader.readLine();
42
43                 if (userLine == null || userLine.length() == 0) {
44                     break;
45                 }
46
47                 String outString;
48                 try {
49                     long sum = summer.sumString(userLine);
50                     outString = Long.toString(sum);
51                 }
52                 catch(InvalidLongException e) {
53                     outString = e.getMessage();
54                 }
55                 System.out.println(outString);
56             }
57         }
58         catch (Exception e)
59         {
60           System.out.println("client: MyClient.main() exception: " + e);
61           e.printStackTrace();
62         }
63     }
64 }


$ java -Djava.security.policy=/sun/jini/bv/policy.all
    -Djava.rmi.server.codebase=http://localhost:8080/ SummerClient
1 1
2
2 2
4
3 3 3
9


The SummerClient2

import net.jini.entry.*;
import net.jini.lookup.*;
import net.jini.lookup.entry.*;
import net.jini.discovery.*;
import java.rmi.*;
import java.io.*;

class SummerClient2
{
    public static void main (String[] args) {

        try {
            System.setSecurityManager(new RMISecurityManager ());

            // Perform unicast lookup on localhost
            LookupLocator lookup = new LookupLocator("jini://localhost");

            // Get the service registrar object for the lookup service
            ServiceRegistrar registrar = lookup.getRegistrar();

            // Search the lookup server to find a service that implements
            // the Summer interface.
            Class[] types = new Class[1];
            types[0] = Summer.class;
            ServiceTemplate template = new ServiceTemplate(null, types, null);

            // lookup() returns the service object for a service that matches
            // the search criteria passed in as template
            // Here, because I searched by type, I'm certain that
            // the object that comes back implements the Summer interface.
            Summer summer = (Summer) registrar.lookup(template);

            LineNumberReader stdinReader = new LineNumberReader(
                new BufferedReader(new InputStreamReader(System.in)));

            for (;;) {

                String userLine = stdinReader.readLine();

                if (userLine == null || userLine.length() == 0) {
                    break;
                }

                String outString;
                try {
                    long sum = summer.sumString(userLine);
                    outString = Long.toString(sum);
                }
                catch(InvalidLongException e) {
                    outString = e.getMessage();
                }
                System.out.println(outString);
            }
        }
        catch (Exception e)
        {
          System.out.println("client: MyClient.main() exception: " + e);
          e.printStackTrace();
        }
    }
}


$ java -Djava.security.policy=/sun/jini/bv/policy.all
    -Djava.rmi.server.codebase=http://localhost:8080/ SummerClient2
1 1
2
3 -1
2
9999999 1
10000000

The Protocol is Private

Service object can:

Jini Programming Model


JavaSpaces


The JavaSpace Interface



write()
    public Lease write(Entry e, Transaction txn, long lease)
        throws TransactionException, SecurityException,
        java.rmi.RemoteException;
read()
    public Entry read(Entry tmpl, Transaction txn, long timeout)
        throws UnusableEntryException, TransactionException,
        SecurityException, InterruptedException, java.rmi.RemoteException;
readIfExists()
    public Entry readIfExists(Entry tmpl, Transaction txn, long timeout)
        throws UnusableEntryException, TransactionException,
        SecurityException, InterruptedException, java.rmi.RemoteException;
take() and takeIfExists()
    public Entry take(Entry tmpl, Transaction txn, long timeout)
        throws UnusableEntryException, TransactionException,
        SecurityException, InterruptedException, java.rmi.RemoteException;

    public Entry takeIfExists(Entry tmpl, Transaction txn, long timeout)
        throws UnusableEntryException, TransactionException,
        SecurityException, InterruptedException, java.rmi.RemoteException;
notify()
    public EventRegistration notify(Entry tmpl, Transaction txn,
        RemoteEventListener listener, long lease,
        java.rmi.MarshalledObject handback)
        throws TransactionException, SecurityException,
        java.rmi.RemoteException;

Entries and Matching


JavaSpaces Uses


Sponsored Links

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us