![]() |
Sponsored Link •
|
ServiceItem
"East Conference Room"
group: services offered by
all devices in the East Conference Room
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
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
ServiceItem
ServiceRegistrar.register(ServiceItem item, long leaseDuration);
ServiceItem
has 3 parts:
ServiceID
object, or null
if registering
for the first time
Entry[]
Entry
interface
and contains public fields of reference (object) types
UIDescriptor
:
1 public class UIDescriptor extends AbstractEntry { 2 3 public String role; 4 public String toolkit; 5 public Set attributes; 6 public MarshalledObject factory; 7 8 public UIDescriptor() { 9 } 10 11 public UIDescriptor(String role, String toolkit, Set attributes, 12 MarshalledObject factory) { 13 14 this.role = role; 15 this.toolkit = toolkit; 16 this.attributes = attributes; 17 this.factory = factory; 18 } 19 20 public final Object getUIFactory(final ClassLoader parentLoader) 21 throws IOException, ClassNotFoundException { 22 23 //... 24 } 25 }
ServiceItem
DiagramSummerService
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 }
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
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
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
In the RuntimeInfa/ex2
directory, write a Jini chat client. The chat client will participate
with other chat clients by reading and writing entries to a JavaSpace. While you are developing your
chat client, you should make certain that you are actually using your own JavaSpace for testing, the one that
is registered with "YOUR_NAME_HERE"
. (In the rest of the exercises, I'll call your
"YOUR_NAME_HERE"
space your "test space."
If you end up messing inadvertently with someone else's JavaSpace,
you will likely interfere with their work in ways that won't leave them very happy with you. Ultimately, once
you get your program debugged, you can switch to using a shared JavaSpace and actually chat with others
in the class through the shared space.
Write a Java application named ChatWriter
, whose main()
method merely creates
an ChatWriter
instance and invokes its run()
method. The run()
method should be an instance method that takes no parameters and returns void
.
run()
will take strings
from the standard input and post them as messages to a chat room in the JavaSpace. As a first step, just
make ChatWriter
's run()
method read lines from the standard input and
echo each line back to the
standard output. If the user types in a blank line (just hits return), ChatWriter
should
exit. (Feel free to borrow code from previous SummerClient
programs, which also read
lines from the standard input.)
Modify ChatWriter
so that it gets a JavaSpace proxy for your test space from a Jini lookup
service. Use multicast discovery to find lookup services. Each time you find a lookup service, query it
for your test space. Right at the beginning of your main()
method, before you start
looking for the JavaSpace, print out a message to the standard output that says:
Looking for the space.Once you find the appropriate space, print a message to the standard output that says:
Found the space!
To do multicast discovery, you can use a LookupDiscovery
object:
String[] groups = new String[] {""}; LookupDiscovery lookupDisc = new LookupDiscovery(groups); lookupDisc.addDiscoveryListener(new SpaceFinder());You'll need to define a
DiscoveryListener
whose discovered()
method will
look for the test JavaSpace
in any discovered lookup services. To query the lookup
service for the test space, you'll need to use both the JavaSpace
class and a
Name
entry with the value "YOUR_NAME_HERE"
, as in:
// Look up the JavaSpace by type and name // Matching service object must be an instance of JavaSpace Class[] types = new Class[1]; types[0] = JavaSpace.class; // Matching service must contain a name entry with the value spaceName Entry[] entries = new Entry[1]; entries[0] = new Name(spaceName); // Perform the lookup ServiceTemplate tmpl = new ServiceTemplate(null, types, entries); JavaSpace someSpace = null; try { someSpace = (JavaSpace) registrar.lookup(tmpl); } catch (RemoteException e) { e.printStackTrace(System.out); return false; }
Once your test space has been located in a lookup service, the discovery listener should stop caring about newly discovered lookup services.
Modify ChatWriter
so that posts each message read from the standard input to the
JavaSpace. For the time being, place filler values in the author
,
position
, and chatRoom
fields, as in:
// Create a new ChatMessage and post it to the space ChatMessage msgEntry = new ChatMessage("DefaultRoom", "GenericUser", new Long(0), userLine); try { space.write(msgEntry, null, MESSAGE_LEASE_LENGTH); } catch (TransactionException e) { e.printStackTrace(System.out); }Write the entry into the space with a lease of about 5 minutes, so that after 5 minutes, the message will be automatically purged from the space:
// Determines length of the lease that is requested for all messages // posted to chat rooms. This lease is never renewed, so after this // amount of time, the chat message is kicked out of the room. private static final int MESSAGE_LEASE_LENGTH = 5000 * 60;
Save ChatWriter.java
as ChatReader.java
, and change all ChatWriter
s
to ChatReader
s. Leave in everything but the forever loop in which lines are read from
the standard input. ChatReader
should do discovery and look for the appropriate test
JavaSpace. However, when the JavaSpace is discovered, ChatReader
will loop forever taking
ChatMessage
entries from the space. Print out the author, a colon, a space, and the
the content of every ChatMessage
taken from the space. Something like:
for (;;) { // Create a new ChatMessage template ChatMessage msgTemplate = new ChatMessage("DefaultRoom", "GenericUser", new Long(0), null); try { ChatMessage msg = (ChatMessage) space.take(msgTemplate, null, Long.MAX_VALUE); System.out.println(msg.author + ": " + msg.content); } catch (UnusableEntryException e) { e.printStackTrace(System.out); } catch (TransactionException e) { e.printStackTrace(System.out); } catch (InterruptedException e) { e.printStackTrace(System.out); } }
Test your program by posting messages to the space with one or more ChatWriter
s, and reading
those messages via the ChatReader
.
Sponsored Links
|