<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta content="Apache Forrest" name="Generator">
<meta name="Forrest-version" content="0.9">
<meta name="Forrest-skin-name" content="pelt">
<title>ZooKeeper Java Example</title>
<link type="text/css" href="skin/basic.css" rel="stylesheet">
<link media="screen" type="text/css" href="skin/screen.css" rel="stylesheet">
<link media="print" type="text/css" href="skin/print.css" rel="stylesheet">
<link type="text/css" href="skin/profile.css" rel="stylesheet">
<script src="skin/getBlank.js" language="javascript" type="text/javascript"></script><script src="skin/getMenu.js" language="javascript" type="text/javascript"></script><script src="skin/fontsize.js" language="javascript" type="text/javascript"></script>
<link rel="shortcut icon" href="images/favicon.ico">
</head>
<body onload="init()">
<script type="text/javascript">ndeSetTextSize();</script>
<div id="top">
<!--+
    |breadtrail
    +-->
<div class="breadtrail">
<a href="http://www.apache.org/">Apache</a> &gt; <a href="http://hadoop.apache.org/">Hadoop</a> &gt; <a href="http://hadoop.apache.org/zookeeper/">ZooKeeper</a><script src="skin/breadcrumbs.js" language="JavaScript" type="text/javascript"></script>
</div>
<!--+
    |header
    +-->
<div class="header">
<!--+
    |start group logo
    +-->
<div class="grouplogo">
<a href="http://hadoop.apache.org/"><img class="logoImage" alt="Hadoop" src="images/hadoop-logo.jpg" title="Apache Hadoop"></a>
</div>
<!--+
    |end group logo
    +-->
<!--+
    |start Project Logo
    +-->
<div class="projectlogo">
<a href="http://hadoop.apache.org/zookeeper/"><img class="logoImage" alt="ZooKeeper" src="images/zookeeper_small.gif" title="ZooKeeper: distributed coordination"></a>
</div>
<!--+
    |end Project Logo
    +-->
<!--+
    |start Search
    +-->
<div class="searchbox">
<form action="http://www.google.com/search" method="get" class="roundtopsmall">
<input value="hadoop.apache.org" name="sitesearch" type="hidden"><input onFocus="getBlank (this, 'Search the site with google');" size="25" name="q" id="query" type="text" value="Search the site with google">&nbsp; 
                    <input name="Search" value="Search" type="submit">
</form>
</div>
<!--+
    |end search
    +-->
<!--+
    |start Tabs
    +-->
<ul id="tabs">
<li>
<a class="unselected" href="http://hadoop.apache.org/zookeeper/">Project</a>
</li>
<li>
<a class="unselected" href="http://wiki.apache.org/hadoop/ZooKeeper">Wiki</a>
</li>
<li class="current">
<a class="selected" href="index.html">ZooKeeper 3.3 Documentation</a>
</li>
</ul>
<!--+
    |end Tabs
    +-->
</div>
</div>
<div id="main">
<div id="publishedStrip">
<!--+
    |start Subtabs
    +-->
<div id="level2tabs"></div>
<!--+
    |end Endtabs
    +-->
<script type="text/javascript"><!--
document.write("Last Published: " + document.lastModified);
//  --></script>
</div>
<!--+
    |breadtrail
    +-->
<div class="breadtrail">

             &nbsp;
           </div>
<!--+
    |start Menu, mainarea
    +-->
<!--+
    |start Menu
    +-->
<div id="menu">
<div onclick="SwitchMenu('menu_1.1', 'skin/')" id="menu_1.1Title" class="menutitle">Overview</div>
<div id="menu_1.1" class="menuitemgroup">
<div class="menuitem">
<a href="index.html">Welcome</a>
</div>
<div class="menuitem">
<a href="zookeeperOver.html">Overview</a>
</div>
<div class="menuitem">
<a href="zookeeperStarted.html">Getting Started</a>
</div>
<div class="menuitem">
<a href="releasenotes.html">Release Notes</a>
</div>
</div>
<div onclick="SwitchMenu('menu_selected_1.2', 'skin/')" id="menu_selected_1.2Title" class="menutitle" style="background-image: url('skin/images/chapter_open.gif');">Developer</div>
<div id="menu_selected_1.2" class="selectedmenuitemgroup" style="display: block;">
<div class="menuitem">
<a href="api/index.html">API Docs</a>
</div>
<div class="menuitem">
<a href="zookeeperProgrammers.html">Programmer's Guide</a>
</div>
<div class="menupage">
<div class="menupagetitle">Java Example</div>
</div>
<div class="menuitem">
<a href="zookeeperTutorial.html">Barrier and Queue Tutorial</a>
</div>
<div class="menuitem">
<a href="recipes.html">Recipes</a>
</div>
</div>
<div onclick="SwitchMenu('menu_1.3', 'skin/')" id="menu_1.3Title" class="menutitle">BookKeeper</div>
<div id="menu_1.3" class="menuitemgroup">
<div class="menuitem">
<a href="bookkeeperStarted.html">Getting started</a>
</div>
<div class="menuitem">
<a href="bookkeeperOverview.html">Overview</a>
</div>
<div class="menuitem">
<a href="bookkeeperConfig.html">Setup guide</a>
</div>
<div class="menuitem">
<a href="bookkeeperProgrammer.html">Programmer's guide</a>
</div>
</div>
<div onclick="SwitchMenu('menu_1.4', 'skin/')" id="menu_1.4Title" class="menutitle">Admin &amp; Ops</div>
<div id="menu_1.4" class="menuitemgroup">
<div class="menuitem">
<a href="zookeeperAdmin.html">Administrator's Guide</a>
</div>
<div class="menuitem">
<a href="zookeeperQuotas.html">Quota Guide</a>
</div>
<div class="menuitem">
<a href="zookeeperJMX.html">JMX</a>
</div>
<div class="menuitem">
<a href="zookeeperObservers.html">Observers Guide</a>
</div>
</div>
<div onclick="SwitchMenu('menu_1.5', 'skin/')" id="menu_1.5Title" class="menutitle">Contributor</div>
<div id="menu_1.5" class="menuitemgroup">
<div class="menuitem">
<a href="zookeeperInternals.html">ZooKeeper Internals</a>
</div>
</div>
<div onclick="SwitchMenu('menu_1.6', 'skin/')" id="menu_1.6Title" class="menutitle">Miscellaneous</div>
<div id="menu_1.6" class="menuitemgroup">
<div class="menuitem">
<a href="http://wiki.apache.org/hadoop/ZooKeeper">Wiki</a>
</div>
<div class="menuitem">
<a href="http://wiki.apache.org/hadoop/ZooKeeper/FAQ">FAQ</a>
</div>
<div class="menuitem">
<a href="http://hadoop.apache.org/zookeeper/mailing_lists.html">Mailing Lists</a>
</div>
</div>
<div id="credit"></div>
<div id="roundbottom">
<img style="display: none" class="corner" height="15" width="15" alt="" src="skin/images/rc-b-l-15-1body-2menu-3menu.png"></div>
<!--+
  |alternative credits
  +-->
<div id="credit2"></div>
</div>
<!--+
    |end Menu
    +-->
<!--+
    |start content
    +-->
<div id="content">
<div title="Portable Document Format" class="pdflink">
<a class="dida" href="javaExample.pdf"><img alt="PDF -icon" src="skin/images/pdfdoc.gif" class="skin"><br>
        PDF</a>
</div>
<h1>ZooKeeper Java Example</h1>
<div id="front-matter">
<div id="minitoc-area">
<ul class="minitoc">
<li>
<a href="#ch_Introduction">A Simple Watch Client</a>
<ul class="minitoc">
<li>
<a href="#sc_requirements">Requirements</a>
</li>
<li>
<a href="#sc_design">Program Design</a>
</li>
</ul>
</li>
<li>
<a href="#sc_executor">The Executor Class</a>
</li>
<li>
<a href="#sc_DataMonitor">The DataMonitor Class</a>
</li>
<li>
<a href="#sc_completeSourceCode">Complete Source Listings</a>
</li>
</ul>
</div>
</div>
  

  

  
<a name="ch_Introduction"></a>
<h2 class="h3">A Simple Watch Client</h2>
<div class="section">
<p>To introduce you to the ZooKeeper Java API, we develop here a very simple 
    watch client. This ZooKeeper client watches a ZooKeeper node for changes 
    and responds to by starting or stopping a program.</p>
<a name="sc_requirements"></a>
<h3 class="h4">Requirements</h3>
<p>The client has four requirements:</p>
<ul>
<li>
<p>It takes as parameters:</p>
    	
<ul>
		
<li>
<p>the address of the ZooKeeper service</p>
</li>
		
<li> 
<p>then name of a znode - the one to be watched</p>
</li>
		
<li>
<p>an executable with arguments.</p>
</li>
</ul>
</li>
	
<li>
<p>It fetches the data associated with the znode and starts the executable.</p>
</li>
	
<li>
<p>If the znode changes, the client refetches the contents and restarts the executable.</p>
</li>
	
<li>
<p>If the znode disappears, the client kills the executable.</p>
</li>
</ul>
<a name="sc_design"></a>
<h3 class="h4">Program Design</h3>
<p>Conventionally, ZooKeeper applications are broken into two units, one which maintains the connection, 
   and the other which monitors data.  In this application, the class called the <strong>Executor</strong> 
   maintains the ZooKeeper connection, and the class called the  <strong>DataMonitor</strong> monitors the data
   in the ZooKeeper tree. Also, Executor contains the main thread and contains the execution logic.
   It is responsible for what little user interaction there is, as well as interaction with the exectuable program you
   pass in as an argument and which the sample (per the requirements) shuts down and restarts, according to the 
   state of the znode.</p>
</div>

   
<a name="sc_executor"></a>
<h2 class="h3">The Executor Class</h2>
<div class="section">
<p>The Executor object is the primary container of the sample application. It contains 
    both the <strong>ZooKeeper</strong> object, <strong>DataMonitor</strong>, as described above in 
    <a href="#sc_design">Program Design</a>.  </p>
<pre class="code">
    // from the Executor class...
    
    public static void main(String[] args) {
        if (args.length &lt; 4) {
            System.err
                    .println("USAGE: Executor hostPort znode filename program [args ...]");
            System.exit(2);
        }
        String hostPort = args[0];
        String znode = args[1];
        String filename = args[2];
        String exec[] = new String[args.length - 3];
        System.arraycopy(args, 3, exec, 0, exec.length);
        try {
            new Executor(hostPort, znode, filename, exec).run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Executor(String hostPort, String znode, String filename,
            String exec[]) throws KeeperException, IOException {
        this.filename = filename;
        this.exec = exec;
        zk = new ZooKeeper(hostPort, 3000, this);
        dm = new DataMonitor(zk, znode, null, this);
    }

    public void run() {
        try {
            synchronized (this) {
                while (!dm.dead) {
                    wait();
                }
            }
        } catch (InterruptedException e) {
        }
    }
</pre>
<p>
    Recall that the Executor's job is to start and stop the executable whose name you pass in on the command line. 
    It does this in response to events fired by the ZooKeeper object. As you can see in the code above, the Executor passes
    a reference to itself as the Watcher argument in the ZooKeeper constructor. It also passes a reference to itself
    as DataMonitorListener argument to the DataMonitor constructor. Per the Executor's definition, it implements both these
    interfaces:
    </p>
<pre class="code">
public class Executor implements Watcher, Runnable, DataMonitor.DataMonitorListener {
...</pre>
<p>The <strong>Watcher</strong> interface is defined by the ZooKeeper Java API.
    ZooKeeper uses it to communicate back to its container. It supports only one method, <span class="codefrag command">process()</span>, and ZooKeeper uses 
    it to communciates generic events that the main thread would be intersted in, such as the state of the ZooKeeper connection or the ZooKeeper session.The Executor 
    in this example simply forwards those events down to the DataMonitor to decide what to do with them. It does this simply to illustrate
    the point that, by convention, the Executor or some Executor-like object "owns" the ZooKeeper connection, but it is free to delegate the events to other
    events to other objects. It also uses this as the default channel on which to fire watch events. (More on this later.)</p>
<pre class="code">
    public void process(WatchedEvent event) {
        dm.process(event);
    }
</pre>
<p>The <strong>DataMonitorListener</strong> 
    interface, on the other hand, is not part of the the ZooKeeper API. It is a completely custom interface, 
    designed for this sample application. The DataMonitor object uses it to communicate back to its container, which
    is also the the Executor object.The DataMonitorListener interface looks like this:</p>
<pre class="code">
public interface DataMonitorListener {
    /**
    * The existence status of the node has changed.
    */
    void exists(byte data[]);

    /**
    * The ZooKeeper session is no longer valid.
    * 
    * @param rc
    * the ZooKeeper reason code
    */
    void closing(int rc);
}
</pre>
<p>This interface is defined in the DataMonitor class and implemented in the Executor class. 
    When <span class="codefrag command">Executor.exists()</span> is invoked,
    the Executor decides whether to start up or shut down per the requirements. Recall that the requires say to kill the executable when the 
    znode ceases to <em>exist</em>. </p>
<p>When <span class="codefrag command">Executor.closing()</span>
    is invoked, the Executor decides whether or not to shut itself down in response to the ZooKeeper connection permanently disappearing.</p>
<p>As you might have guessed, DataMonitor is the object that invokes 
    these methods, in response to changes in ZooKeeper's state.</p>
<p>Here are Executor's implementation of 
    <span class="codefrag command">DataMonitorListener.exists()</span> and <span class="codefrag command">DataMonitorListener.closing</span>:
    </p>
<pre class="code">
public void exists( byte[] data ) {
    if (data == null) {
        if (child != null) {
            System.out.println("Killing process");
            child.destroy();
            try {
                child.waitFor();
            } catch (InterruptedException e) {
            }
        }
        child = null;
    } else {
        if (child != null) {
            System.out.println("Stopping child");
            child.destroy();
            try {
               child.waitFor();
            } catch (InterruptedException e) {
            e.printStackTrace();
            }
        }
        try {
            FileOutputStream fos = new FileOutputStream(filename);
            fos.write(data);
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            System.out.println("Starting child");
            child = Runtime.getRuntime().exec(exec);
            new StreamWriter(child.getInputStream(), System.out);
            new StreamWriter(child.getErrorStream(), System.err);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public void closing(int rc) {
    synchronized (this) {
        notifyAll();
    }
}
</pre>
</div>

<a name="sc_DataMonitor"></a>
<h2 class="h3">The DataMonitor Class</h2>
<div class="section">
<p>
The DataMonitor class has the meat of the ZooKeeper logic. It is mostly 
asynchronous and event driven. DataMonitor kicks things off in the constructor with:</p>
<pre class="code">
public DataMonitor(ZooKeeper zk, String znode, Watcher chainedWatcher,
        DataMonitorListener listener) {
    this.zk = zk;
    this.znode = znode;
    this.chainedWatcher = chainedWatcher;
    this.listener = listener;
    
    // Get things started by checking if the node exists. We are going
    // to be completely event driven
    <strong>zk.exists(znode, true, this, null);</strong>
}
</pre>
<p>The call to <span class="codefrag command">ZooKeeper.exists()</span> checks for the existence of the znode, 
sets a watch, and passes a reference to itself (<span class="codefrag command">this</span>)
as the completion callback object. In this sense, it kicks things off, since the
real processing happens when the watch is triggered.</p>
<div class="note">
<div class="label">Note</div>
<div class="content">

<p>Don't confuse the completion callback with the watch callback. The <span class="codefrag command">ZooKeeper.exists()</span> 
completion callback, which happens to be the method <span class="codefrag command">StatCallback.processResult()</span> implemented 
in the DataMonitor object, is invoked when the asynchronous <em>setting of the watch</em> operation 
(by <span class="codefrag command">ZooKeeper.exists()</span>) completes on the server. </p>

<p>
The triggering of the watch, on the other hand, sends an event to the <em>Executor</em> object, since
the Executor registered as the Watcher of the ZooKeeper object.</p>


<p>As an aside, you might note that the DataMonitor could also register itself as the Watcher
for this particular watch event. This is new to ZooKeeper 3.0.0 (the support of multiple Watchers). In this
example, however, DataMonitor does not register as the Watcher.</p>

</div>
</div>
<p>When the <span class="codefrag command">ZooKeeper.exists()</span> operation completes on the server, the ZooKeeper API invokes this completion callback on 
the client:</p>
<pre class="code">
public void processResult(int rc, String path, Object ctx, Stat stat) {
    boolean exists;
    switch (rc) {
    case Code.Ok:
        exists = true;
        break;
    case Code.NoNode:
        exists = false;
        break;
    case Code.SessionExpired:
    case Code.NoAuth:
        dead = true;
        listener.closing(rc);
        return;
    default:
        // Retry errors
        zk.exists(znode, true, this, null);
        return;
    }
 
    byte b[] = null;
    if (exists) {
        try {
            <strong>b = zk.getData(znode, false, null);</strong>
        } catch (KeeperException e) {
            // We don't need to worry about recovering now. The watch
            // callbacks will kick off any exception handling
            e.printStackTrace();
        } catch (InterruptedException e) {
            return;
        }
    }     
    if ((b == null &amp;&amp; b != prevData)
            || (b != null &amp;&amp; !Arrays.equals(prevData, b))) {
        <strong>listener.exists(b);</strong>
        prevData = b;
    }
}
</pre>
<p>
The code first checks the error codes for znode existence, fatal errors, and 
recoverable errors. If the file (or znode) exists, it gets the data from the znode, and 
then invoke the exists() callback of Executor if the state has changed. Note, 
it doesn't have to do any Exception processing for the getData call because it 
has watches pending for anything that could cause an error: if the node is deleted 
before it calls <span class="codefrag command">ZooKeeper.getData()</span>, the watch event set by 
the <span class="codefrag command">ZooKeeper.exists()</span> triggers a callback; 
if there is a communication error, a connection watch event fires when 
the connection comes back up.
</p>
<p>Finally, notice how DataMonitor processes watch events: </p>
<pre class="code">
    public void process(WatchedEvent event) {
        String path = event.getPath();
        if (event.getType() == Event.EventType.None) {
            // We are are being told that the state of the
            // connection has changed
            switch (event.getState()) {
            case SyncConnected:
                // In this particular example we don't need to do anything
                // here - watches are automatically re-registered with 
                // server and any watches triggered while the client was 
                // disconnected will be delivered (in order of course)
                break;
            case Expired:
                // It's all over
                dead = true;
                listener.closing(KeeperException.Code.SessionExpired);
                break;
            }
        } else {
            if (path != null &amp;&amp; path.equals(znode)) {
                // Something has changed on the node, let's find out
                zk.exists(znode, true, this, null);
            }
        }
        if (chainedWatcher != null) {
            chainedWatcher.process(event);
        }
    }
</pre>
<p>
If the client-side ZooKeeper libraries can re-establish the
communication channel (SyncConnected event) to ZooKeeper before
session expiration (Expired event) all of the session's watches will
automatically be re-established with the server (auto-reset of watches
is new in ZooKeeper 3.0.0). See <a href="zookeeperProgrammers.html#ch_zkWatches">ZooKeeper Watches</a>
in the programmer guide for more on this. A bit lower down in this
function, when DataMonitor gets an event for a znode, it calls
<span class="codefrag command">ZooKeeper.exists()</span> to find out what has changed.
</p>
</div>


<a name="sc_completeSourceCode"></a>
<h2 class="h3">Complete Source Listings</h2>
<div class="section">
<div class="note example">
<div class="label">Executor.java</div>
<div class="content">
<title>Executor.java</title>
<pre class="code">
/**
 * A simple example program to use DataMonitor to start and
 * stop executables based on a znode. The program watches the
 * specified znode and saves the data that corresponds to the
 * znode in the filesystem. It also starts the specified program
 * with the specified arguments when the znode exists and kills
 * the program if the znode goes away.
 */
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

public class Executor
    implements Watcher, Runnable, DataMonitor.DataMonitorListener
{
    String znode;

    DataMonitor dm;

    ZooKeeper zk;

    String filename;

    String exec[];

    Process child;

    public Executor(String hostPort, String znode, String filename,
            String exec[]) throws KeeperException, IOException {
        this.filename = filename;
        this.exec = exec;
        zk = new ZooKeeper(hostPort, 3000, this);
        dm = new DataMonitor(zk, znode, null, this);
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        if (args.length &lt; 4) {
            System.err
                    .println("USAGE: Executor hostPort znode filename program [args ...]");
            System.exit(2);
        }
        String hostPort = args[0];
        String znode = args[1];
        String filename = args[2];
        String exec[] = new String[args.length - 3];
        System.arraycopy(args, 3, exec, 0, exec.length);
        try {
            new Executor(hostPort, znode, filename, exec).run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /***************************************************************************
     * We do process any events ourselves, we just need to forward them on.
     *
     * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.proto.WatcherEvent)
     */
    public void process(WatchedEvent event) {
        dm.process(event);
    }

    public void run() {
        try {
            synchronized (this) {
                while (!dm.dead) {
                    wait();
                }
            }
        } catch (InterruptedException e) {
        }
    }

    public void closing(int rc) {
        synchronized (this) {
            notifyAll();
        }
    }

    static class StreamWriter extends Thread {
        OutputStream os;

        InputStream is;

        StreamWriter(InputStream is, OutputStream os) {
            this.is = is;
            this.os = os;
            start();
        }

        public void run() {
            byte b[] = new byte[80];
            int rc;
            try {
                while ((rc = is.read(b)) &gt; 0) {
                    os.write(b, 0, rc);
                }
            } catch (IOException e) {
            }

        }
    }

    public void exists(byte[] data) {
        if (data == null) {
            if (child != null) {
                System.out.println("Killing process");
                child.destroy();
                try {
                    child.waitFor();
                } catch (InterruptedException e) {
                }
            }
            child = null;
        } else {
            if (child != null) {
                System.out.println("Stopping child");
                child.destroy();
                try {
                    child.waitFor();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            try {
                FileOutputStream fos = new FileOutputStream(filename);
                fos.write(data);
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                System.out.println("Starting child");
                child = Runtime.getRuntime().exec(exec);
                new StreamWriter(child.getInputStream(), System.out);
                new StreamWriter(child.getErrorStream(), System.err);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
</pre>
	

</div>
</div>
<div class="note example">
<div class="label">DataMonitor.java</div>
<div class="content">
	
<title>DataMonitor.java</title>
	
<pre class="code">
/**
 * A simple class that monitors the data and existence of a ZooKeeper
 * node. It uses asynchronous ZooKeeper APIs.
 */
import java.util.Arrays;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.AsyncCallback.StatCallback;
import org.apache.zookeeper.KeeperException.Code;
import org.apache.zookeeper.data.Stat;

public class DataMonitor implements Watcher, StatCallback {

    ZooKeeper zk;

    String znode;

    Watcher chainedWatcher;

    boolean dead;

    DataMonitorListener listener;

    byte prevData[];

    public DataMonitor(ZooKeeper zk, String znode, Watcher chainedWatcher,
            DataMonitorListener listener) {
        this.zk = zk;
        this.znode = znode;
        this.chainedWatcher = chainedWatcher;
        this.listener = listener;
        // Get things started by checking if the node exists. We are going
        // to be completely event driven
        zk.exists(znode, true, this, null);
    }

    /**
     * Other classes use the DataMonitor by implementing this method
     */
    public interface DataMonitorListener {
        /**
         * The existence status of the node has changed.
         */
        void exists(byte data[]);

        /**
         * The ZooKeeper session is no longer valid.
         *
         * @param rc
         *                the ZooKeeper reason code
         */
        void closing(int rc);
    }

    public void process(WatchedEvent event) {
        String path = event.getPath();
        if (event.getType() == Event.EventType.None) {
            // We are are being told that the state of the
            // connection has changed
            switch (event.getState()) {
            case SyncConnected:
                // In this particular example we don't need to do anything
                // here - watches are automatically re-registered with 
                // server and any watches triggered while the client was 
                // disconnected will be delivered (in order of course)
                break;
            case Expired:
                // It's all over
                dead = true;
                listener.closing(KeeperException.Code.SessionExpired);
                break;
            }
        } else {
            if (path != null &amp;&amp; path.equals(znode)) {
                // Something has changed on the node, let's find out
                zk.exists(znode, true, this, null);
            }
        }
        if (chainedWatcher != null) {
            chainedWatcher.process(event);
        }
    }

    public void processResult(int rc, String path, Object ctx, Stat stat) {
        boolean exists;
        switch (rc) {
        case Code.Ok:
            exists = true;
            break;
        case Code.NoNode:
            exists = false;
            break;
        case Code.SessionExpired:
        case Code.NoAuth:
            dead = true;
            listener.closing(rc);
            return;
        default:
            // Retry errors
            zk.exists(znode, true, this, null);
            return;
        }

        byte b[] = null;
        if (exists) {
            try {
                b = zk.getData(znode, false, null);
            } catch (KeeperException e) {
                // We don't need to worry about recovering now. The watch
                // callbacks will kick off any exception handling
                e.printStackTrace();
            } catch (InterruptedException e) {
                return;
            }
        }
        if ((b == null &amp;&amp; b != prevData)
                || (b != null &amp;&amp; !Arrays.equals(prevData, b))) {
            listener.exists(b);
            prevData = b;
        }
    }
}
</pre>

</div>
</div>
</div>




<p align="right">
<font size="-2"></font>
</p>
</div>
<!--+
    |end content
    +-->
<div class="clearboth">&nbsp;</div>
</div>
<div id="footer">
<!--+
    |start bottomstrip
    +-->
<div class="lastmodified">
<script type="text/javascript"><!--
document.write("Last Published: " + document.lastModified);
//  --></script>
</div>
<div class="copyright">
        Copyright &copy;
         2008-2013 <a href="http://www.apache.org/licenses/">The Apache Software Foundation.</a>
</div>
<!--+
    |end bottomstrip
    +-->
</div>
</body>
</html>
