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-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use