300 likes | 314 Views
Learn how to create an enterprise knowledge base system using Jini and JavaSpaces. Discover the benefits, review the technologies involved, and get insights into application architecture and implementation. Explore the experimental approach and understand the significance of community-friendly knowledge bases.
E N D
Jini and JavaSpaces as an Enterprise Knowledge Base System O’Reilly Conference on Java Jason Monberg President Carbon Five Jason@carbonfive.com
Introduction Jason Monberg Carbon Five
Project Background • Experiment with Jini and JavaSpaces • Widely applicable problem • Work in progress • What we have experienced and learned
Presentation Structure • 25% Review: Jini, JavaSpaces, Knowledge Base • 70% Application Implementation • 5% Resources, Questions
Jini Review • Lookup Service • Services register • Clients discover and lookup and lookup services • Events and Transactions • Services (Includes Lookup Service) • Lease Jini resources • Register by supplying info and code • Client • Discovery - Bootstrap • Lookup Service using templates • Access Service through downloaded java code • Interact directly with the service
response (unicast) announce (multicast) response (unicast) service ID 01010 01010 request (multicast) register request (unicast) Jini Enabled Service Lookup Service 01010 01010 Jini Interaction Diagram Jini Core 01010 Client 01010
Jini Benefits • Spontaneous and Self recovering • Services come and go • No Jini administration required • ‘Plug and Play’ • Redundant • Scalable • Instances • Performance • Java as proxy for *
JavaSpaces Review • A Jini Service • Distributed Shared Memory • Replication • Persistent Storage • Object Based • Search • Entry: values, class, superclass, interface… • Entry Interface • Tagging Interface, no methods • Public Objects, no primitives • Write, Read, Take - IfExists
Lookup Service 01010 JavaSpaces Diagram Jini Core 01010 JavaSpace Service Client 01010 01010
Knowledge Base Review • Data Store • Data Management • Data Analysis Knowledge • Implemented Store and Management • Plans for Analysis
Summary and Motive • Jini • Lookup Services, Additional Knowledge Base Services • JavaSpaces • Object Storage • Knowledge Base • Application • Motive • Needed tool to store, share, and manage information • Community friendly knowledge base • Emerging technology • Learn best by doing, experiments!
Application Architecture • Security • HTTP – Resin • RMID • Jini Services: Lookup, Transaction (not used directly), JavaSpaces • Custom Services • Custom Client
Architecture Diagram Jini Server HTTP – Caucho’s Resin RMI Activation Daemon Client Jini Services Jini Specific Lookup: Reggie Transaction Manager: Mahalo JavaSpaces – Front-end: Outrigger Custom Services…
Discovering Services • Jini Service Discovery and Lookup • LookupDiscoveryManager • New in Jini 1.1 • Manages Discovery • multicast request … groups • unicast request. … names • Manages ServiceRegistrars
public class JavaSpaceManager { // initialization of groups, locator and DiscoveryListener // and then start discovering! . . . // Kickoff the discovery process public void startDiscovery() { // Create the LookupDiscoveryManager try { // groups=LDM.ALL_GROUPS, locators = null lstnr = JavaSpacesListener discoveryManager = new LookupDiscoveryManager(groups, locators, discoveryListener); } catch (IOException e) { System.out.println("Creating Lookup DiscoveryListener " + e); } } public JavaSpace getJavaSpace() { . . . } public void setJavaSpaceDiscoveryListener(OxJavaSpaceDiscoveryListener discoveryListener) { . . . } CODE SAMPLE: Discovery and Lookup I – Wrap LDM public class JavaSpaceManager { // initialization of groups, locator and DiscoveryListener // and then start discovering! . . . // Kickoff the discovery process public void startDiscovery() { // Create the LookupDiscoveryManager try { // groups=LDM.ALL_GROUPS, locators = null lstnr = JavaSpacesListener discoveryManager = new LookupDiscoveryManager(groups, locators, discoveryListener); } catch (IOException e) { System.out.println("Creating Lookup DiscoveryListener " + e); } } public JavaSpace getJavaSpace() { . . . } public void setJavaSpaceDiscoveryListener(OxJavaSpaceDiscoveryListener discoveryListener) { . . . }
public class JavaSpaceDiscoveryListener implements DiscoveryListener { public Class [] types = new Class[] { JavaSpace.class }; public ServiceTemplate tmpl = new ServiceTemplate(null, types, null); . . . public void discovered(DiscoveryEvent e) { //When we find a ServiceRegistrar, try to find a JavaSpace regs = e.getRegistrars(); javaSpace = getJavaSpace(); } public JavaSpace getJavaSpace() { if (javaSpace == null) { javaSpace = (JavaSpace)lookForService(regs, tmpl); } return javaSpace; } public Object lookForService(ServiceRegistrar lusvc[], ServiceTemplate tmpl) { //uses ServiceRegistrar.lookup(ServiceTemplate to find services . . . o = lusvc[0].lookup(tmpl); return o; } public class JavaSpaceDiscoveryListener implements DiscoveryListener { . . . public void discovered(DiscoveryEvent e) { //When we find a ServiceRegistrar, try to find a JavaSpace regs = e.getRegistrars(); javaSpace = getJavaSpace(); } public JavaSpace getJavaSpace() { if (javaSpace == null) { javaSpace = (JavaSpace)lookForService(regs, tmpl); } return javaSpace; } public Object lookForService(ServiceRegistrar lusvc[], ServiceTemplate tmpl) { //uses ServiceRegistrar.lookup(ServiceTemplate to find services . . . o = lusvc[0].lookup(tmpl); return o; } CODE SAMPLE: Discovery and Lookup II – JSDL public class JavaSpaceDiscoveryListener implements DiscoveryListener { public Class [] types = new Class[] { JavaSpace.class }; public ServiceTemplate tmpl = new ServiceTemplate(null, types, null); . . . public void discovered(DiscoveryEvent e) { //When we find a ServiceRegistrar, try to find a JavaSpace regs = e.getRegistrars(); javaSpace = getJavaSpace(); } public JavaSpace getJavaSpace() { if (javaSpace == null) { javaSpace = (JavaSpace)lookForService(regs, tmpl); } return javaSpace; } public Object lookForService(ServiceRegistrar lusvc[], ServiceTemplate tmpl) { //uses ServiceRegistrar.lookup(ServiceTemplate to find services . . . o = lusvc[0].lookup(tmpl); return o; }
Storing Data • Long term storage • Front-end space • Non-transactional • Available but not used • Entry Implementation • JavaSpaces write • Entry, transaction, lease
CODE SAMPLE: Entry Implementation public class OxEntry implements Entry { //data fields public Long timestamp = null; public String group = null; public String name = null; public String body = null; public StringBuffer notes = null; public ArrayList links = null; public ArrayList files = null //includes display fields //includes xml container . . . //takes the current data in the object and establishes the xml representation public void syncOxml() { . . . } public String getOxml() { . . .} public void addLink(String link) { . . . } public String getLinks() { . . . } public void setName(String name) { . . . } public String getName() { . . .} public void appendNote(String note) { . . .} public String getNotes() { . . . } } public class OxEntry implements Entry { //data fields public Long timestamp = null; public String group = null; public String name = null; public String body = null; public StringBuffer notes = null; public ArrayList links = null; public ArrayList files = null //includes display fields //includes xml container . . . //takes the current data in the object and establishes the xml representation public void syncOxml() { . . . } public String getOxml() { . . .} public void addLink(String link) { . . . } public String getLinks() { . . . } public void setName(String name) { . . . } public String getName() { . . .} public void appendNote(String note) { . . .} public String getNotes() { . . . } }
Reading and Searching • JavaSpaces object retrieval model • Templates • Entry • Exact matching vs. Pattern Matching • Take vs. Read • First object found • The Great Work Around: • Retrieving groups of entry objects
CODE SAMPLE: Retrieving Result-set Groups public Vector readAllSpace(Entry tmpl) { //verify space is available Vector vec = new Vector(); try { // tmpl – Entry template for matching, null – txn, 1000 – timeout OxEntry token = (OxEntry)space.takeIfExists(tmpl, null, 1000); while (token != null) { vec.add(token); token = (OxEntry)space.takeIfExists(tmpl, null, 1000); } OxEntry[] tmp = new OxEntry[vec.size()]; tmp = (OxEntry[])vec.toArray(tmp); for (int i = 0; i < tmp.length; i++ ) { writeSpace( space, tmp[i] ); } return vec; } catch (IOException e) {} catch (UnusableEntryException e) {} catch (TransactionException e) {} catch (InterruptedException e) {} return null; } public Vector readAllSpace(Entry tmpl) { //verify space is available Vector vec = new Vector(); try { // tmpl – Entry template for matching, null – txn, 1000 – timeout OxEntry[] tmp = new OxEntry[vec.size()]; tmp = (OxEntry[])vec.toArray(tmp); for (int i = 0; i < tmp.length; i++ ) { writeSpace( space, tmp[i] ); } return vec; } catch (IOException e) {} catch (UnusableEntryException e) {} catch (TransactionException e) {} catch (InterruptedException e) {} return null; } public Vector readAllSpace(Entry tmpl) { //verify space is available Vector vec = new Vector(); try { // tmpl – Entry template for matching, null – txn, 1000 – timeout OxEntry token = (OxEntry)space.takeIfExists(tmpl, null, 1000); while (token != null) { vec.add(token); token = (OxEntry)space.takeIfExists(tmpl, null, 1000); } OxEntry[] tmp = new OxEntry[vec.size()]; tmp = (OxEntry[])vec.toArray(tmp); for (int i = 0; i < tmp.length; i++ ) { writeSpace( space, tmp[i] ); } return vec; } catch (IOException e) {} catch (UnusableEntryException e) {} catch (TransactionException e) {} catch (InterruptedException e) {} return null; }
Alt Result Set Retrieval • Entry Tagging • Simultaneous searches? • Transaction Wrapping • Data locking • Take if exists • Client data loss risk • Service oriented searches • Optimize with snapshot() • Other Ideas?
Displaying Data • XML/XSLT • HTML • Swing • Self Aware vs. Interpreters
Updates and Notes • Simple management of data updates within workgroup • Adding Notes to Entries • Embedded Text vs. Appending Objects • Time based • Updating Entries • Update contention • get time (read) > last pub time (current) • Rely on Take – could lose data • Event Based Client Synchronization
Connecting Data • Object Relationships • Easier than RDBM • Automatic Relationship • Implicit search relationships • Explicit automatic relationships • Through a service • Arbitrary Relationships • User imposed relationships
Data Integration Services • File Structure Information Stores • Service to integrate data from existing file store • Heterogeneous Data Stores • File Based • RDBMS • Object DB • Peer to Peer
Lookup Service 01010 Data IntegrationService Diagram RDBMS File Store Jini Lookup Service 01010 01010 Data Integration Service events 01010 events JavaSpace Service Client 01010 01010 01010
Jini in Practice • Administration of the Carbon Five Knowledge Base system • Set-up vs. Using • The ‘kill’ script • Distributed Environments • Most coding is on client side • Quiet Period
Conclusions • Pros • Abstract access to data • Object based • Simple and powerful service and leasing mechanism • JavaSpaces similar to object data base or xml server • Cons • Poor searching support • Performance • Production use growing slowly • Gotchas • Understand set-up • Code Defensively – network resources come and go
Additional Resources • Online • www.jini.org/ • www.litefaden.com/sv/jd/ • www.javacoffeebreak.com/books/extracts/jini/jini.html • www.artima.com/jini/ - Bill Venners • www.carbonfive.com/oreilly - This Presentation • Books • Core Jini, 2nd Edition • W. Keith Edwards • A Programmers Guide to Jini Technology • Jan Newmarch • The Jini Specifications, 2nd Edition • Jim Waldo • JavaSpaces Principles, Patterns, and Practice • Freeman, Hupfer, Arnold