<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title>Making Software Work</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/felcey/" />
   <link rel="self" type="application/atom+xml" href="http://blogs.oracle.com/felcey/xml/rss.xml" />
   <id>tag:blogs.oracle.com,2009:/felcey//1017</id>
   <updated>2009-11-23T11:47:27Z</updated>
   
   <generator uri="http://www.sixapart.com/movabletype/">Movable Type Enterprise 4.23-en</generator>


<entry>
   <title>Caching PHP HTTP Sessions in Coherence</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/felcey/2009/11/caching_php_http_sessions_in_c.html" />
   <id>tag:blogs.oracle.com,2009:/felcey//1017.15681</id>
   
   <published>2009-11-23T11:09:16Z</published>
   <updated>2009-11-23T11:47:27Z</updated>
   
   <summary>Coherence already provides HTTP Session caching support for ASP.NET and J2EE applications without any application changes. Coherence for .NET includes a custom SessionStateStoreProvider implementation that uses a Coherence cache to store session state. This makes Coherence for .NET the best...</summary>
   <author>
      <name>david.felcey</name>
      
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/felcey/">
      <![CDATA[<p>Coherence already provides HTTP Session caching support for ASP.NET and J2EE applications without any application changes. Coherence for .NET includes a <a href="http://wiki.tangosol.com/display/COH34UG/Special+Considerations+Regarding+Web+Applications+for+.NET+Clients">custom SessionStateStoreProvider implementation</a> that uses a Coherence cache to store session state. This makes Coherence for .NET the best solution for any large ASP.NET application running within a web farm. The HTTP session state of J2EE Web Applications is managed using Coherence*Web. Coherence*Web is an <a href="http://coherence.oracle.com/display/COH35UG/Coherence*Web+Session+Management+Module">HTTP session management module</a> dedicated to managing session state in clustered environments. Built on top of Oracle Coherence, it has a wide range of features and supports a wide range of J2EE containers. With WebLogic Suite Coherence*Web is built in, but for other containers a Coherence utility modifies the necessary settings in the Web Applications <font face="Courier New">web.xml</font> file to transfer management of the HTTP Session state from the container to Coherence. With PHP there is no “out-of-the-box” Coherence support for HTTP Session state management, until now. The rest of this article outlines how using a standard PHP extension Coherence can be used as a clustered, reliable HTTP session handler for PHP.</p>  <p>Like ASP.NET and J2EE application containers, PHP makes it quite easy to <a href="http://php.net/manual/en/function.session-set-save-handler.php">plug-in your own HTTP session handler</a> and lots of different flavours exist already, from in-memory stores using tools like memcached to file and database persistent session mechanisms using products like MySQL.&#160; Coherence is an ideal persistence store for HTTP sessions because it is:</p>  <ul>   <li>Very fast, enabling dynamic web pages to be quickly displayed </li>    <li>Resilient and fault-tolerant, ensuring that process or server failures do not impact users – logging them off etc. </li>    <li>Scalable, to support and ever increasing number of online users/customers </li>    <li>Simple to integrate and manage, so the overhead of introducing Coherence does not burden either web development of operational staff </li> </ul>  <p>So can Coherence be used with PHP?. Well using the native <a href="http://coherence.oracle.com/pages/viewpage.action?pageId=4228630">Coherence C++ client</a> to create a PHP extension that can then be wrapped using a PHP session_set_save_handler to setup some user defined session storage functions. A diagram to illustrate the relationship between the PHP runtime, Coherence C++ extension and the Coherence cache is shown below:</p>  <p>&#160;</p>  <p><a href="http://blogs.oracle.com/felcey/WindowsLiveWriter/CachingPHPHTTPSessionsinCoherence_9D63/image3.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="436" alt="image" src="http://blogs.oracle.com/felcey/WindowsLiveWriter/CachingPHPHTTPSessionsinCoherence_9D63/image3_thumb.png" width="614" border="0" /></a> </p>  <p>To include the PHP custom session handlers in your PHP page add the following to the top of your PHP page:</p>  <blockquote>   <p><font face="Courier New" color="#000080" size="2">&lt;?php        <br />require 'coherence_session.php';         <br />$s = new CoherencePHPSessionHandler();         <br />.         <br />.         <br />?&gt;</font></p> </blockquote>  <p>This basically enables a new session to be started using the custom session save handler. The custom session save handler looks like this:</p>  <blockquote>   <p><font face="Courier New" color="#000080" size="2">&lt;?php       <br />class CoherencePHPSessionHandler        <br />{        <br />&#160;&#160;&#160; private static $debug = False; </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; /**       <br />&#160;&#160;&#160;&#160; * A reference to a Coherence named cache        <br />&#160;&#160;&#160;&#160; * @var resource        <br />&#160;&#160;&#160;&#160; */        <br />&#160;&#160;&#160; private $cache; </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; /**       <br />&#160;&#160;&#160;&#160; * Session lifetime        <br />&#160;&#160;&#160;&#160; * @var resource        <br />&#160;&#160;&#160;&#160; */        <br />&#160;&#160;&#160; private $lifeTime; </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; private static function Log($msg)       <br />&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160; if(CoherencePHPSessionHandler::$debug)        <br />&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; echo &quot;&lt;br&gt;DEBUG PHP: &quot; . $msg . &quot;\n&quot;;        <br />&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160; } </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; function __construct()       <br />&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; // get session-lifetime        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; $this-&gt;lifeTime = get_cfg_var(&quot;session.gc_maxlifetime&quot;); </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160; CoherencePHPSessionHandler::Log(&quot;Lifetime: &quot; . $this-&gt;lifeTime);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; $this-&gt;cache = new Cache(&quot;dist-php-sessions&quot;); </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160; if ($this-&gt;cache == null)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return false;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160; CoherencePHPSessionHandler::Log(&quot;Got cache handle&quot;); </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160; session_set_save_handler(array(&amp;$this, 'open'),       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; array(&amp;$this, 'close'),        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; array(&amp;$this, 'read'),        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; array(&amp;$this, 'write'),        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; array(&amp;$this, 'destroy'),        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; array(&amp;$this, 'gc'));        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; register_shutdown_function('session_write_close');        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; session_start(); </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160; CoherencePHPSessionHandler::Log(&quot;Started session&quot;);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return true;        <br />&#160;&#160;&#160; } </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; /**       <br />&#160;&#160;&#160;&#160; * Open the session        <br />&#160;&#160;&#160;&#160; * @return bool        <br />&#160;&#160;&#160;&#160; */        <br />&#160;&#160;&#160; function open($savePath, $sessName)        <br />&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; // get session-lifetime        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; $this-&gt;lifeTime = get_cfg_var(&quot;session.gc_maxlifetime&quot;);        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; CoherencePHPSessionHandler::Log(&quot;Opening session&quot;);        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return true;        <br />&#160;&#160;&#160; } </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; /**       <br />&#160;&#160;&#160;&#160; * Close the session        <br />&#160;&#160;&#160;&#160; * @return bool        <br />&#160;&#160;&#160;&#160; */        <br />&#160;&#160;&#160; public function close()        <br />&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; // ToDo: need to release Coherence resources        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return true;        <br />&#160;&#160;&#160; } </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; /**       <br />&#160;&#160;&#160;&#160; * Read the session        <br />&#160;&#160;&#160;&#160; * @param int session id        <br />&#160;&#160;&#160;&#160; * @return string string of the session        <br />&#160;&#160;&#160;&#160; */        <br />&#160;&#160;&#160; public function read($id)        <br />&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; $result = $this-&gt;cache-&gt;get($id); </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160; if($result != null)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CoherencePHPSessionHandler::Log(&quot;Read session, id: &quot; . $id . &quot;, value: &quot; . $result);        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return $result;        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return '';        <br />&#160;&#160;&#160; } </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; /**       <br />&#160;&#160;&#160;&#160; * Write the session        <br />&#160;&#160;&#160;&#160; * @param int session id        <br />&#160;&#160;&#160;&#160; * @param string data of the session        <br />&#160;&#160;&#160;&#160; */        <br />&#160;&#160;&#160; public function write($id, $data)        <br />&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; CoherencePHPSessionHandler::Log(&quot;Session value: &quot; . serialize($data)); </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160; $this-&gt;cache-&gt;put($id, $data, $this-&gt;lifeTime);       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; CoherencePHPSessionHandler::Log(&quot;Written session, id: &quot; . $id . &quot;, value: &quot; . $data);        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return true;        <br />&#160;&#160;&#160; } </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; /**       <br />&#160;&#160;&#160;&#160; * Destoroy the session        <br />&#160;&#160;&#160;&#160; * @param int session id        <br />&#160;&#160;&#160;&#160; * @return bool        <br />&#160;&#160;&#160;&#160; */        <br />&#160;&#160;&#160; public function destroy($id)        <br />&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; $this-&gt;cache-&gt;remove($id);        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return true;        <br />&#160;&#160;&#160; } </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; /**       <br />&#160;&#160;&#160;&#160; * Garbage Collector        <br />&#160;&#160;&#160;&#160; * @param int life time (sec.)        <br />&#160;&#160;&#160;&#160; * @return bool        <br />&#160;&#160;&#160;&#160; * @see session.gc_divisor&#160;&#160;&#160;&#160;&#160; 100        <br />&#160;&#160;&#160;&#160; * @see session.gc_maxlifetime 1440        <br />&#160;&#160;&#160;&#160; * @see session.gc_probability&#160;&#160;&#160; 1        <br />&#160;&#160;&#160;&#160; * @usage execution rate 1/100        <br />&#160;&#160;&#160;&#160; *&#160;&#160;&#160;&#160;&#160;&#160;&#160; (session.gc_probability/session.gc_divisor)        <br />&#160;&#160;&#160;&#160; */        <br />&#160;&#160;&#160; public function gc($max)        <br />&#160;&#160;&#160; {        <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return true;        <br />&#160;&#160;&#160; }        <br />}        <br />?&gt;</font></p> </blockquote>  <p>As for the Coherence PHP extension there is too much to show here, though in total it does not amount to a lot of code. The C++ client class that wraps the Coherence client API is also very simple and the class functions are shown below:</p>  <blockquote>   <p><font face="Courier New" color="#000080" size="2">#include &quot;cache.h&quot; </font></p>    <p><font face="Courier New" color="#000080" size="2">extern &quot;C&quot; {        <br />#include &lt;stdio.h&gt;         <br />#include &lt;stdlib.h&gt;         <br />#include &quot;php.h&quot;         <br />} </font></p>    <p><font face="Courier New" color="#000080" size="2">static char * copyString(const char *str)        <br />{         <br />&#160;&#160;&#160; char *s; </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; if(str != NULL &amp;&amp; (s = (char *)emalloc(sizeof(char) * (strlen(str)&#160; + 1))) == NULL)        <br />&#160;&#160;&#160; {         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return NULL;         <br />&#160;&#160;&#160; }         <br />&#160;&#160;&#160; else         <br />&#160;&#160;&#160; {         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(strncpy(s, str, strlen(str) + 1) == NULL)         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; efree(s);         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return NULL;         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return s;         <br />&#160;&#160;&#160; }         <br />} </font></p>    <p><font face="Courier New" color="#000080" size="2">Cache::Cache(const char *name)        <br />{         <br />&#160;&#160;&#160; // Get handle to a Named Cache         <br />&#160;&#160;&#160; String::View vsCacheName = String::create(name);         <br />&#160;&#160;&#160; hCache = CacheFactory::getCache(vsCacheName);         <br />} </font></p>    <p><font face="Courier New" color="#000080" size="2">const char *Cache::getCacheName()        <br />{         <br />&#160;&#160;&#160; String::View name = cast&lt;String::View&gt;(hCache-&gt;getCacheName()); </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; return copyString(name-&gt;getCString());        <br />} </font></p>    <p><font face="Courier New" color="#000080" size="2">char* Cache::put(const char *key, const char *value, long ttl)        <br />{         <br />&#160;&#160;&#160; if(key == NULL || value == NULL)         <br />&#160;&#160;&#160; {         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; throw std::invalid_argument(&quot;Key or value for put() NULL&quot;);         <br />&#160;&#160;&#160; }         <br />&#160;&#160;&#160; String::View vKey = String::create(key);         <br />&#160;&#160;&#160; String::View vValue = String::create(value);         <br />&#160;&#160;&#160; String::View vOldValue = cast&lt;String::View&gt;(hCache-&gt;put(vKey, vValue, ttl)); </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; return (vOldValue == NULL ? NULL : copyString(vOldValue-&gt;getCString()));        <br />} </font></p>    <p><font face="Courier New" color="#000080" size="2">char* Cache::remove(const char *key)        <br />{         <br />&#160;&#160;&#160; String::View vKey = String::create(key);         <br />&#160;&#160;&#160; String::View vOldValue = cast&lt;String::View&gt;(hCache-&gt;remove(vKey)); </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; return (vOldValue == NULL ? NULL : copyString(vOldValue-&gt;getCString()));        <br />} </font></p>    <p><font face="Courier New" color="#000080" size="2">char* Cache::get(const char *key)        <br />{         <br />&#160;&#160;&#160; String::View vKey = String::create(key);         <br />&#160;&#160;&#160; String::View vOldValue = cast&lt;String::View&gt;(hCache-&gt;get(vKey)); </font></p>    <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; return (vOldValue == NULL ? NULL : copyString(vOldValue-&gt;getCString()));        <br />} </font></p>    <p><font face="Courier New" color="#000080" size="2">int Cache::size()        <br />{         <br />&#160;&#160;&#160; return (int)hCache-&gt;size();         <br />}</font></p> </blockquote>  <p>The Coherence PHP extension can also be used for simply caching PHP values, as well as PHP session information. The above example was tested on Oracle Enterprise Linux 4, but can easily be compiled on Windows. You can download the whole example from <a href="http://blogs.oracle.com/felcey/2009/11/23/code/coherence_php_extension.zip">here</a> to try it out for yourself. Instructions are included which should hopefully be easy to follow. A couple of outstanding issues still remain with the Coherence PHP extension which I have not been able to resolve. Although simple PHP types as well as objects and arrays can be cached – both as keys and values – I could not get objects with private or protected variables to serialize. If anyone more experienced in the internals of PHP can help here it would be much appreciated, as I drew a blank. </p>]]>
      
   </content>
</entry>

<entry>
   <title>Look, no Java!</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/felcey/2009/10/look_no_java.html" />
   <id>tag:blogs.oracle.com,2009:/felcey//1017.15046</id>
   
   <published>2009-10-15T09:54:25Z</published>
   <updated>2009-10-15T10:03:57Z</updated>
   
   <summary>With release 3.5 of Oracle Coherence it is now possible to query, aggregate and modify serialized POF (Portable Object Format) values stored in a cache natively, that is without writing a Java representation of the object. So&#160; .NET and C++...</summary>
   <author>
      <name>david.felcey</name>
      
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/felcey/">
      <![CDATA[<p>With release 3.5 of Oracle Coherence it is now possible to query, aggregate and modify serialized POF (Portable Object Format) values stored in a cache natively, that is without writing a Java representation of the object. So&#160; .NET and C++ developers can just write C# etc. and C++. </p>  <p>This is achieved with the introduction of <a href="http://coherence.oracle.com/display/COH35UG/PofExtractors+and+PofUpdaters">POF extractors and POF updaters</a>, that fetch and update native POF objects without de-serializing the value to Java. As well as allowing .NET and C++ developers to just work in the language they are most comfortable and productive in, this new feature also has a number of other benefits:</p>  <ul>   <li>It dramatically improves performance, as no de-serialization needs to take place, so no new objects need to be created – or garbage collected. </li>    <li>Less memory is required as a result. </li>    <li>The development and deployment process is simpler, as no corresponding Java classes need to be created, managed and deployed. </li> </ul>  <p>However, there are some occasions where you do still need to create complementary Java objects to match your .NET or C++ objects. These are:</p>  <ul>   <li>When you want to use <a href="http://coherence.oracle.com/display/COH35UG/Data+Affinity#DataAffinity-SpecifyingDataAffinitywithaKeyAssociation">Key Association</a>, as Coherence will always de-serializes keys to determine whether they implement <font face="Courier New">KeyAssociation</font>. </li>    <li>If you use a <a href="http://coherence.oracle.com/display/COH31UG/cachestore-scheme">Cache Stores</a> - Coherence passes the de-serialized version of the key and value to the cache store to write to the back end so that ORM (Object Relational Mapping) tools, like Hibernate and EclipseLink (JPA) have access to the Java objects. </li> </ul>  <p>To update a value in a cache from C# you would use code similar to that shown below:</p>  <pre><font color="#0000ff">    // Parameters: key, (extractor, new value)
    cache.Invoke(0, new UpdaterProcessor(new PofUpdater(BetSerializer.ODDS), 1)); 
</font></pre>

<p>Here a cache value identified by the key ‘0’ is being updated using an <font face="Courier New">UpdateProcessor</font>. The <font face="Courier New">ValueUpdator</font> being used is a C# <font face="Courier New"><a href="http://download.oracle.com/otn_hosted_doc/coherence/350NET/index.html">PofUpdater</a></font> which will access the attribute at offset <font face="Courier New">BetSerializer.ODD</font> in the serialized POF value. Values held in a cache are held in a serialized format. When the POF serialization mechanism is used the values of an object are written and read from the POF stream in the same order. So here a constant&#160; (<font face="Courier New">BetSerializer.ODDS</font>) is being used to provide a more readable representation for an offset like 3, i.e. the 3rd object value to be written and read from the POF stream.</p>

<p>For reading values from a cache in C# a similar approach is used, as shown below: </p>

<pre><font color="#0000ff">    // Query cache for all entries whose event name is 'FA Cup'
    EqualsFilter equalsFilter =
        new EqualsFilter(new PofExtractor(BetSerializer.EVENT_NAME), &quot;FA Cup&quot;);
</font></pre>

<pre><font color="#0000ff">    Object[] results = cache.GetValues(equalsFilter);
    Console.WriteLine(&quot;Filter results:&quot;);
</font></pre>

<pre><font color="#0000ff">
    for (int i = 0; i &lt; results.Length; i++)
    {
        Console.WriteLine(&quot;Value = &quot; + results[i]);
    }
</font></pre>

<p>Here all cache values that have an event name or “FA Cup” will be returned by the <font face="Courier New">EqualsFilter</font>. The C# <font face="Courier New"><a href="http://download.oracle.com/otn_hosted_doc/coherence/350NET/index.html">PofExtractor</a></font> is being used to extract the attribute at the offset <font face="Courier New">BetSerializer.EVENT_NAME</font>, which will be a number , like 4 indicating it was the 4th value to be written and read from the POF stream when the object it was part of was serialized.</p>

<p>This is a great new feature of Coherence and very easy to use. If you would like to see the full example the above extracts were taken from the you can download it from <a href="http://blogs.oracle.com/felcey/2009/10/15/code/POFExtractorExample.zip">here</a>. Happy coding - in C# and C++ ;). </p>]]>
      
   </content>
</entry>

<entry>
   <title>Pushing real-time data changes from an Oracle database into Coherence</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/felcey/2009/06/pushing_realtime_data_changes.html" />
   <id>tag:blogs.oracle.com,2009:/felcey//1017.12911</id>
   
   <published>2009-06-17T14:00:32Z</published>
   <updated>2009-10-15T08:50:50Z</updated>
   
   <summary>A common requirement when using Coherence is for the data in it to remain synchronised with database. If all changes to the database flow through Coherence or the cached data can be periodically refreshed (using the refresh-ahead mechanism) then Coherence...</summary>
   <author>
      <name>david.felcey</name>
      
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/felcey/">
      <![CDATA[<p>A common requirement when using Coherence is for the data in it to remain synchronised with database. If all changes to the database flow through Coherence or the cached data can be periodically refreshed (using the <a href="http://coherence.oracle.com/display/COH34UG/Read-Through,+Write-Through,+Write-Behind+and+Refresh-Ahead+Caching#Read-Through%2CWrite-Through%2CWrite-BehindandRefresh-AheadCaching-RefreshAheadCache">refresh-ahead</a> mechanism) then Coherence will be aware of of any database changes. However, if another application changes the database outside of Coherence or the database changes need to be relayed to Coherence in real-time then an alternative approach is required.</p>  <p>To push database changes to Coherence in real-time when they are being made outside of Coherence, a queue needs to be used. Fortunately most databases support the queuing of transactional change information, either implicitly or explicitly. In this example architecture the explicit queuing of changes to an Oracle database, using Triggers and Oracle’s Advanced Queuing (AQ) technology, will be used to propagate them to a Coherence cache holding objects representing the same information.</p>  <h3>Overview</h3>  <p>Below is a diagram showing how the changes flow from the Oracle database to the Coherence cache.</p>  <p><a href="http://blogs.oracle.com/felcey/WindowsLiveWriter/PushingrealtimedatachangesfromanOracleda_ABF9/AQ%202008_4.jpg"><img title="AQ 2008" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="493" alt="AQ 2008" src="http://blogs.oracle.com/felcey/WindowsLiveWriter/PushingrealtimedatachangesfromanOracleda_ABF9/AQ%202008_thumb_1.jpg" width="623" border="0" /></a> </p>  <p>In the example the read/receive operation from the queue is performed as a transaction, so the message is only removed from the queue once the corresponding cache object has been updated. This ensures that if the Coherence JVM/node that the client runs on fails the update message will not be lost. Although the example code focuses on cache updates it could easily be modified to accommodate inserts and deletes as well.</p>  <p>To enable Advanced Queuing (AQ) to be used for propagating table changes a number of database permissions first need to be granted. The PL/SQL to do this is shown below:</p>  <p><font face="Courier New" color="#000080" size="2">-- Execute as sys/welcome1 </font></p>  <p><font face="Courier New" color="#000080" size="2">GRANT SELECT_CATALOG_ROLE TO scott;      <br />GRANT EXECUTE ON DBMS_APPLY_ADM TO scott;       <br />GRANT EXECUTE ON DBMS_AQ TO scott;       <br />GRANT EXECUTE ON DBMS_AQADM TO scott;       <br />GRANT EXECUTE ON DBMS_CAPTURE_ADM TO scott;       <br />GRANT EXECUTE ON DBMS_FLASHBACK TO scott;       <br />GRANT EXECUTE ON DBMS_STREAMS_ADM TO scott;       <br />EXECUTE dbms_aqadm.grant_system_privilege('ENQUEUE_ANY', 'scott', TRUE);       <br />EXECUTE dbms_aqadm.grant_system_privilege('DEQUEUE_ANY', 'scott', TRUE);       <br />GRANT aq_administrator_role TO scott;       <br />GRANT EXECUTE ON dbms_lock TO scott;       <br />GRANT EXECUTE ON sys.dbms_aqin TO scott;       <br />GRANT EXECUTE ON sys.dbms_aqjms TO scott;       <br />EXIT;</font></p>  <p><em>Note: These GRANT statements need to be executed as the database administrator (sys) or another database user who has privileges to grant them.</em></p>  <p>Then the AQ queue need to be setup and the PL/SQL procedure and trigger created to put the database table changes in the appropriate queue. Below is the PL/SQL used to do this:</p>  <p><font face="Courier New" color="#000080" size="2">-- Execute as scott/tiger </font></p>  <p><font face="Courier New" color="#000080" size="2">-- Create queue      <br />EXECUTE dbms_aqadm.stop_queue(queue_name =&gt; 'trade_queue');       <br />EXECUTE dbms_aqadm.drop_queue(queue_name =&gt; 'trade_queue');       <br />EXECUTE DBMS_AQADM.DROP_QUEUE_TABLE(queue_table =&gt; 'trade_queue_table');       <br />EXECUTE dbms_aqadm.create_queue_table(queue_table =&gt; 'trade_queue_table',queue_payload_type =&gt; 'sys.aq$_jms_text_message', multiple_consumers =&gt; false);       <br />EXECUTE dbms_aqadm.create_queue(queue_name =&gt; 'trade_queue', queue_table =&gt;'trade_queue_table', queue_type =&gt; DBMS_AQADM.NORMAL_QUEUE, retention_time =&gt; 0, max_retries =&gt; 5, retry_delay =&gt; 60);       <br />EXECUTE dbms_aqadm.start_queue(queue_name =&gt; 'trade_queue'); </font></p>  <p><font face="Courier New" color="#000080" size="2">-- Create table</font></p>  <p><font face="Courier New" color="#000080" size="2">DROP TABLE Trade CASCADE CONSTRAINTS;      <br />CREATE TABLE Trade       <br />(       <br />&#160;&#160;&#160; Id&#160;&#160;&#160;&#160; NUMBER PRIMARY KEY,       <br />&#160;&#160;&#160; Symbol VARCHAR2(5)&#160;&#160;&#160;&#160;&#160;&#160; ,       <br />&#160;&#160;&#160; Created DATE&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,       <br />&#160;&#160;&#160; Quantity NUMBER&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,       <br />&#160;&#160;&#160; Amount&#160;&#160; NUMBER(8,2)       <br />); </font></p>  <p><font face="Courier New" color="#000080" size="2">-- Enable SERVEROUTPUT in SQL Command Line (SQL*Plus) to display output with      <br />-- DBMS_OUTPUT.PUT_LINE, this enables SERVEROUTPUT for this SQL*Plus session only       <br />SET SERVEROUTPUT ON       <br />CREATE OR REPLACE       <br />PROCEDURE testmessage(text_message VARCHAR2)       <br />AS       <br />&#160; msg SYS.AQ$_JMS_TEXT_MESSAGE;       <br />&#160; msg_hdr SYS.AQ$_JMS_HEADER;       <br />&#160; msg_agent SYS.AQ$_AGENT;       <br />&#160; msg_proparray SYS.AQ$_JMS_USERPROPARRAY;       <br />&#160; msg_property SYS.AQ$_JMS_USERPROPERTY;       <br />&#160; queue_options DBMS_AQ.ENQUEUE_OPTIONS_T;       <br />&#160; msg_props DBMS_AQ.MESSAGE_PROPERTIES_T;       <br />&#160; msg_id RAW(16);       <br />&#160; dummy VARCHAR2(4000);       <br />BEGIN       <br />&#160; msg_agent := SYS.AQ$_AGENT(' ', NULL, 0);       <br />&#160; msg_proparray := SYS.AQ$_JMS_USERPROPARRAY()&#160; ;       <br />&#160; msg_proparray.EXTEND(1);       <br />&#160; msg_property := SYS.AQ$_JMS_USERPROPERTY('JMS_OracleDeliveryMode', 100, '2', NULL, 27);       <br />&#160; msg_proparray(1) := msg_property;       <br />&#160; msg_hdr := SYS.AQ$_JMS_HEADER(msg_agent,NULL,'&lt;USERNAME&gt;',NULL,NULL,NULL,msg_proparray);       <br />&#160; msg := SYS.AQ$_JMS_TEXT_MESSAGE(msg_hdr,NULL,NULL,NULL);       <br />&#160; msg.text_vc&#160; := text_message;       <br />&#160; msg.text_len := LENGTH(msg.text_vc);       <br />&#160; DBMS_AQ.ENQUEUE(queue_name =&gt; 'trade_queue' , enqueue_options =&gt; queue_options , message_properties =&gt; msg_props , payload =&gt; msg , msgid =&gt; msg_id);       <br />END;       <br />/       <br />CREATE OR REPLACE TRIGGER TradeAQTrigger AFTER INSERT OR UPDATE ON Trade       <br />FOR EACH row DECLARE xml_complete VARCHAR2(1000);       <br />BEGIN       <br />&#160;&#160;&#160; xml_complete := '&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;' ||       <br />&#160;&#160;&#160;&#160;&#160; '&lt;TradeElement xmlns:xsi=&quot;</font><a href="http://www.w3.org/2001/XMLSchema-instance&quot;"><font face="Courier New" color="#000080" size="2">http://www.w3.org/2001/XMLSchema-instance&quot;</font></a><font face="Courier New" color="#000080" size="2"> ' ||      <br />&#160;&#160;&#160;&#160;&#160; 'xsi:schemaLocation=&quot;</font><a href="http://www.oracle.com/coherenceaq"><font face="Courier New" color="#000080" size="2">http://www.oracle.com/coherenceaq</font></a><font face="Courier New" color="#000080" size="2"> src/aq-object.xsd&quot; ' ||      <br />&#160;&#160;&#160;&#160;&#160; 'xmlns=&quot;</font><a href="http://www.oracle.com/coherenceaq&quot;"><font face="Courier New" color="#000080" size="2">http://www.oracle.com/coherenceaq&quot;</font></a><font face="Courier New" color="#000080" size="2">&gt;' ||      <br />&#160;&#160;&#160; '&lt;Id&gt;' || :new.ID || '&lt;/Id&gt;' ||       <br />&#160;&#160;&#160; '&lt;Symbol&gt;' || :new.SYMBOL || '&lt;/Symbol&gt;' ||       <br />&#160;&#160;&#160; '&lt;Quantity&gt;' || :new.QUANTITY || '&lt;/Quantity&gt;' ||       <br />&#160;&#160;&#160; '&lt;Amount&gt;' || :new.AMOUNT || '&lt;/Amount&gt;' ||       <br />&#160;&#160;&#160; '&lt;Created&gt;' || :new.CREATED || '&lt;/Created&gt;' ||       <br />&#160;&#160;&#160; '&lt;/TradeElement&gt;';&#160;&#160;&#160; <br />&#160;&#160;&#160; testmessage(xml_complete);       <br />END;       <br />/       <br />SHOW ERRORS;</font></p>  <p>The Java code that runs in the background Coherence thread – started by the BackingMapListener – that reads messages from the queue looks like this:</p>  <p><font face="Courier New" color="#000080" size="2">.      <br />.       <br />. </font></p>  <p><font face="Courier New" color="#000080" size="2">/**      <br />* &lt;p&gt;AQ client interface&lt;/p&gt;       <br />*/       <br />public class AQClient       <br />{       <br />&#160; .       <br />&#160; .       <br />&#160; . </font></p>  <p><font face="Courier New" color="#000080" size="2">&#160; /**      <br />&#160;&#160; * Send an acknowledgement message for a received message. This enables the       <br />&#160;&#160; * message to be kept by the sender if client dies. An acknowledgement should only       <br />&#160;&#160; * be sent when the received message has been saved, e.g. in a cache       <br />&#160;&#160; *       <br />&#160;&#160; * @throws JMSException If an exception occurs sending an acknowledgement       <br />&#160;&#160; */       <br />&#160; public void aknowledgeMessage()       <br />&#160;&#160;&#160; throws JMSException       <br />&#160; {       <br />&#160;&#160;&#160; textMsg.acknowledge();       <br />&#160; } </font></p>  <p><font face="Courier New" color="#000080" size="2">&#160; /**      <br />&#160;&#160; * Reads XML text message from the queue and transforms it into a Trade       <br />&#160;&#160; * object using JAXB classes.       <br />&#160;&#160; *       <br />&#160;&#160; * @return a Trade object       <br />&#160;&#160; * @throws JMSException If an exception occurs sending an acknowledgement       <br />&#160;&#160; * @throws JAXBException If an exception occurs during JAXB processing       <br />&#160;&#160; */       <br />&#160; public Trade receiveMessage()       <br />&#160;&#160;&#160; throws JMSException, JAXBException       <br />&#160; {       <br />&#160;&#160;&#160; // Wait for a message to show up in the queue       <br />&#160;&#160;&#160; textMsg = (TextMessage) queueReciever.receive();       <br />&#160;&#160;&#160; System.out.println(&quot;Message is: &quot; + textMsg.getText()); </font></p>  <p><font face="Courier New" color="#000080" size="2">&#160;&#160;&#160; // Use JAXB to create object      <br />&#160;&#160;&#160; JAXBContext jc = JAXBContext.newInstance(&quot;com.oracle.demo.model&quot;);       <br />&#160;&#160;&#160; Unmarshaller u = jc.createUnmarshaller();       <br />&#160;&#160;&#160; JAXBElement&lt;Trade&gt; trade =       <br />&#160;&#160;&#160;&#160;&#160; (JAXBElement&lt;Trade&gt;) u.unmarshal(new StreamSource(new StringReader(textMsg.getText())));       <br />&#160;&#160;&#160; Trade t = trade.getValue();       <br />&#160;&#160;&#160; System.out.println(&quot;Trade created on: &quot; + t.toString());       <br />&#160;&#160;&#160; return t;       <br />&#160; }       <br />} </font></p>  <p>A full code example can be found <a href="http://blogs.oracle.com/felcey/2009/06/17/code/AQExample.zip">here</a>, including all the necessary PL/SQL scripts. All you need to try it out is <a href="http://www.oracle.com/technology/software/products/ias/htdocs/coherence.html">Coherence</a>, <a href="http://www.oracle.com/technology/software/products/database/xe/index.html">Oracle XE</a> and <a href="http://www.oracle.com/technology/software/products/ias/htdocs/coherence.html">Coherence .NET</a> – if you want to see the changes propagated to a .NET Coherence client.</p>  <p>If changes in the Coherence cache data also need to be written back to the database then something like a status field or flag would need to be added to the the cached objects and table, to ensure that a circular loop isn’t created. For instance the following logic could enable bi-directional synchronization:</p>  <ol>   <li>Propagate flag added to cached object (Trade) and database table (Trade) to signify if changes should be propagated by the after update trigger from the database to Coherence </li>    <li>Data changes propagated from Coherence to Database have propagate flag set to FALSE. </li>    <li>Introduce a new before insert/update trigger to reset the propagate flag to TRUE when it is FALSE. </li>    <li>When the after insert/update trigger fires only place the new value on the queue if the <u>old</u> value is not FALSE. </li> </ol>  <p>A modified example of the PL/SQL to add this functionality is in the <font face="Courier New">setup-queue2.sql</font> file, though you will need to add the additional column to the Trade table and attribute to the Trade object.</p>  <h3>Summary</h3>  <p>This approach is not the only mechanism for propagating changes from an Oracle Database to Coherence. Using a <a href="http://wiki.tangosol.com/display/COH34UG/Deliver+events+for+changes+as+they+occur#Delivereventsforchangesastheyoccur-Advanced%3ABackingMapEvents">BackingMapListener</a> to start the background queue client thread has an added benefit. If the node it is running on fails, Coherence will re-start the queue client on another node as part of its recovery process, i.e. when the queue configuration entry is failed-over and the new primary created it will cause a new background queue client thread to be started.</p>  <p>Alternative approaches to the one above might be to use <a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b28321/strms_capture.htm">Oracle Streams</a> or the <a href="http://www.oracle.com/technology/obe/11gr1_db/appdev/dcn/dcn.htm">Data Change Notification</a> mechanism in Oracle 11g</p>]]>
      
   </content>
</entry>

<entry>
   <title><![CDATA[Using Excel as a Real-Time client for Coherence &ndash; A Full Working Example]]></title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/felcey/2009/05/using_excel_as_a_realtime_clie_1.html" />
   <id>tag:blogs.oracle.com,2009:/felcey//1017.12309</id>
   
   <published>2009-05-16T23:26:31Z</published>
   <updated>2009-05-16T23:28:06Z</updated>
   
   <summary>On my previous posting about using Excel as a Coherence client I talked about how this could be done but gave no example code. In this posting I will explain how to do this in more detail and provide the...</summary>
   <author>
      <name>david.felcey</name>
      
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/felcey/">
      <![CDATA[<p>On my previous posting about using Excel as a Coherence client I talked about how this could be done but gave no example code. In this posting I will explain how to do this in more detail and provide the code to a working example that you can modify to use your own objects. In the example a .NET client loads Stock objects into a Coherence cache and then randomly updates the Stock prices. An Excel spreadsheet can then be opened that is a client for the Coherence cache, receiving changes to the Stock objects – the price changes. The prices can also be updated from the spreadsheet, so the communications is both ways.</p>  <p>&#160;</p>  <p><a href="http://blogs.oracle.com/felcey/WindowsLiveWriter/UsingExcelasaRealTimeclientforCoherenceA_21D/diagram_2.jpg"><img title="diagram" style="border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; border-left: 0px; margin-right: auto; border-bottom: 0px" height="345" alt="diagram" src="http://blogs.oracle.com/felcey/WindowsLiveWriter/UsingExcelasaRealTimeclientforCoherenceA_21D/diagram_thumb.jpg" width="522" border="0" /></a> </p>  <p>Stock price updates are pushed down to the Excel spreadsheet using the standard RTD (Read Time Data) server mechanism. As for the cache updates from Excel, they are send through a Coherence COM interface. VBA User Defined Functions (UDF’s) provide the interface in Excel for specifying where event data goes or which cell updates get mapped onto cache objects. These are added to Excel via the Add-in option from the Tools menu.</p>  <p>The UDF’s also hide some of the complexity of the interfaces from users. Here are he 3 UDF’s that provide the interface to Coherence:</p>  <ul>   <li>For updating properties of Stock objects in the cache</li>    <ul>     <li><em>UpdateDoubleProperty(&quot;dist-stocks&quot;,E4,&quot;ORCL&quot;,&quot;StockPrice&quot;)</em></li>      <li><em>UpdateStringProperty(&quot;dist-stocks&quot;,E4,&quot;ORCL&quot;,&quot;StockPrice&quot;)</em></li>   </ul>    <li>For receiving update events for Stock objects in the cache</li>    <ul>     <li><em>RealTimeData(&quot;dist-stocks&quot;,&quot;ORCL&quot;,&quot;StockPrice&quot;)</em></li>   </ul> </ul>  <p>In the UDF’s above “dist-stocks” is the name of the Coherence cache, “ORCL” is the key for the object you wish to update or receive change events from (this must be a string in the example) and “<em>StockPrice</em>” is the name of the property you want to update or get the latest value of. “E4” in the <em>UpdateDoubleProperty()</em> is the cell to take the new property value from – when it changes. </p>  <p>If properties of objects in the cache that you wish to receive updates about or change are in nested objects you can specify the target property via a “.” or if the target is in an object nested in a List or array you can use the “[ ]” operator. So for instance if the cache contained a Portfolio object with nested Stock objects in an array, you could specify the target Stock price for one of the nested Stocks as “<em>Stocks[2].StockPrice</em>”. This would get the 3rd Stock in a property of the Portfolio object called “<em>Stocks</em>” and from that Stock the “<em>StockPrice</em>” property. At the moment the UDF functions only support String and Double properties – but they could easily be enhanced to support other properties. This property specification method can also be nested as much as you like and provide as convenient way of specifying a target property as a string in Excel.</p>  <p>The easiest way to see how this all works in practice is to <a href="http://blogs.oracle.com/felcey/2009/05/16/code/CoherenceExcelExample.zip">download the example</a> and try it out – there is a readme.txt file in the example that explains how to set it up and try it out. Some of the things you will need to run the example are:</p>  <ul>   <li><a href="http://www.oracle.com/technology/software/products/ias/htdocs/coherence.html">Coherence for Java and .NET 3.4.2</a>. It should work with more recent versions, though this is the release I have tested the example against. </li>    <li><a href="http://www.oracle.com/technology/software/products/jrockit/index.html">Java JDK 1.4.2</a> (or above) </li>    <li><a href="http://msdn.microsoft.com/en-us/visualc/aa700831.aspx">Microsoft Visual Studio 2008</a> and .NET 3.5. I tried to build the example using <a href="http://www.microsoft.com/Express/">Visual Studio Express</a> and via the command line but was unable to specify that the Coherence configuration files be embedded resources. Also someone has successfully back-ported the example to Visual Studio 2005 (though I don’t have the code) </li>    <li>Excel 2003. It should work with later versions, though I am not sure when Excel started supporting the RTD mechanism. </li>    <li><a href="http://www.microsoft.com/downloads/details.aspx?familyid=3c9a983a-ac14-4125-8ba0-d36d67e0f4ad&amp;displaylang=en">Office XP Primary Interop Assemblies</a> (for Office 2003). This is need for the Excel integration assemblies.</li> </ul>  <p>Have fun trying this out and if anyone has any additional thoughts, recommendations or feedback I’d be keen to hear them.</p>]]>
      
   </content>
</entry>

<entry>
   <title>Using Coherence as a Cache from a J2EE Web Application</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/felcey/2009/05/using_coherence_as_a_cache_fro.html" />
   <id>tag:blogs.oracle.com,2009:/felcey//1017.12064</id>
   
   <published>2009-05-08T16:40:56Z</published>
   <updated>2009-05-08T18:01:37Z</updated>
   
   <summary>Although Coherence is often used to manage Servlet session state for J2EE applications – without changing the application code – it can also be used by J2EE Web applications to access data in a simple cache. This article discusses how...</summary>
   <author>
      <name>david.felcey</name>
      
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/felcey/">
      <![CDATA[<p>Although Coherence is often used to manage Servlet session state for J2EE applications – without changing the application code – it can also be used by J2EE Web applications to access data in a simple cache. This article discusses how to do this and how you should package your Web application so that it is a completely self contained Coherence client. Although the principles should work for all J2EE applications servers you will not be surprised to learn that I have only tested this on WebLogic Server (10.3).</p>  <p>The Web application outlined below is a <a href="http://coherence.oracle.com/display/COH34UG/Configuring+and+Using+Coherence+Extend#ConfiguringandUsingCoherenceExtend-ConfiguringandUsingCoherenceExtendTCP">Coherence*Extend Client</a>, that means that it connects over a TCP/IP connection to the Coherence cluster (which uses UDP for inter-node communications) holding the cache data. A <a href="http://coherence.oracle.com/display/COH34UG/Cluster+Services+Overview">Proxy</a> service run either on one or more of the cache nodes (or in a separate JVM) is used to pass requests and response between the client and the Coherence cluster – in a similar fashion to the way an Oracle Database listener works. </p>  <p><em>Note, the client could also be a <a href="http://coherence.oracle.com/display/COH34UG/The+Coherence+Ecosystem">Coherence Data Client</a>, which means that the Web client would actually be part of the Coherence cluster. In this case the client would need to be ‘<a href="http://coherence.oracle.com/display/COH34UG/distributed-scheme#distributed-scheme-localstorage">storage disabled</a>’ through a system property or through the <font face="Courier New"><a href="http://coherence.oracle.com/display/COH34UG/Operational+Configuration+Elements#OperationalConfigurationElements-OperationalOverrideFile">tangosol-coherence-override.xml</a></font> configuration file. This means that although it will be part of the cluster it will not actually hold any data, so when the client is deployed or un-deployed there will be no cluster overhead re-organising cache data.</em></p>  <h3>Accessing the configuration files</h3>  <p>You really have a choice here. put them in the packaged Web application or reference them externally through the CLASSPATH or <a href="http://coherence.oracle.com/display/COH34UG/configurable-cache-factory-config">via a system property</a>. Here I am going to package them with the Web application to make is completely self-contained. The code to do this is shown below:</p>  <blockquote>   <pre><pre><a name="56"><span style="color: black"><span style="mso-spacerun: yes">&#160;</span>56<span style="mso-spacerun: yes">&#160;&#160;&#160; </span></span><span style="color: #0033cc">/**</span></a><o:p></o:p></pre><pre><a name="57"><span style="color: black"> 57<span style="mso-spacerun: yes">&#160; </span></span><span style="color: #0033cc"><span style="mso-spacerun: yes">&#160;&#160; </span>* &lt;p&gt;Reference to ConfigurableCacheFactory that can be used to</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="58"><span style="color: black"> 58<span style="mso-spacerun: yes">&#160; </span></span><span style="color: #0033cc"><span style="mso-spacerun: yes">&#160;&#160; </span>* create a cache.&lt;/p&gt;</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="59"><span style="color: black"> 59<span style="mso-spacerun: yes">&#160; </span></span><span style="color: #0033cc"><span style="mso-spacerun: yes">&#160;&#160; </span>*/</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="60"><span style="color: black"> 60<span style="mso-spacerun: yes">&#160;&#160;&#160; </span></span><b><span style="color: #336699">private</span></b><span style="color: black"> ConfigurableCacheFactory factory = </span><span style="color: #996600">null</span><span style="color: black">;</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="61"><span style="color: black"> 61<span style="mso-spacerun: yes">&#160; </span></span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="62"><span style="color: black"><span style="mso-spacerun: yes">&#160;</span>62<span style="mso-spacerun: yes">&#160;&#160;&#160; </span></span><span style="color: #0033cc">/**</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="63"><span style="color: black"> 63<span style="mso-spacerun: yes">&#160; </span></span><span style="color: #0033cc"><span style="mso-spacerun: yes">&#160;&#160; </span>*<b> @inheritDoc</b></span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="64"><span style="color: black"> 64<span style="mso-spacerun: yes">&#160; </span></span><span style="color: #0033cc"><span style="mso-spacerun: yes">&#160;&#160; </span>*/</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="65"><span style="color: black"> 65<span style="mso-spacerun: yes">&#160;&#160;&#160; </span></span><b><span style="color: #336699">public</span></b><span style="color: black"> </span><b><span style="color: #336699">void</span></b><span style="color: black"> init(ServletConfig config)</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="66"><span style="color: black"> 66<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span></span><b><span style="color: #336699">throws</span></b><span style="color: black"> ServletException</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="67"><span style="color: black"> 67<span style="mso-spacerun: yes">&#160;&#160;&#160; </span>{</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="68"><span style="color: black"> 68<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span></span><b><span style="color: #336699">super</span></b><span style="color: black">.init(config);</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="69"><span style="color: black"> 69<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span></span><span style="color: gray">// Create DefaultConfigurableCacheFactory using cache configuration file</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="70"><span style="color: black"> 70<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span></span><span style="color: gray">// in classes dir</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="71"><span style="color: black"> 71<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span>factory =</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="72"><span style="color: black"> 72<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span></span><b><span style="color: #336699">new</span></b><span style="color: black"> DefaultConfigurableCacheFactory(</span><span style="color: #0033cc">&quot;/config/cache-config.xml&quot;</span><span style="color: black">,</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="73"><span style="color: black"> 73<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>getClass().getClassLoader());</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="74"><span style="color: black"> 74<span style="mso-spacerun: yes">&#160;&#160;&#160; </span>}</span></a><span style="color: black"><o:p></o:p></span></pre></pre>
</blockquote>

<p>Here a <font face="Courier New">DefaultConfigurableCacheFactory</font> is used to read the configuration file used to setup the Coherence client parameters. All the configuration files that the Coherence client needs will be stored in the <font face="Courier New">/WEB-INF/classes/config</font> directory of the Web application. These are:</p>

<ul>
  <li><font face="Courier New"><strong>cache-config.xml</strong></font> indicating where the Coherence cluster can be contacted </li>

<p>  <li><font face="Courier New"><strong>pof-config.xml</strong></font> indicating the mapping between client and server objects. As both the client and server are Java only one object needs to be defined. </li></p>

<p>  <li><font face="Courier New"><strong>tangosol-coherence-override.xml</strong></font> encapsulated many of the Coherence settings the are often specified as system properties. </li><br />
</ul></p>

<p>The cache is accessed in the <font face="Courier New">doGet(..)</font> method of Servlet&#160; as shown below:</p>

<blockquote>
  <pre><span style="color: black"><o:p></o:p></span></pre>

<p>  <pre><pre><a name="76"><span style="color: black"><span style="mso-spacerun: yes">&#160;</span>76<span style="mso-spacerun: yes">&#160; </span><span style="mso-spacerun: yes">&#160; </span></span><span style="color: #0033cc">/**</span></a><o:p></o:p></pre><pre><a name="77"><span style="color: black"> 77<span style="mso-spacerun: yes">&#160; </span></span><span style="color: #0033cc"><span style="mso-spacerun: yes">&#160;&#160; </span>*<b> @inheritDoc</b></span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="78"><span style="color: black"> 78<span style="mso-spacerun: yes">&#160; </span></span><span style="color: #0033cc"><span style="mso-spacerun: yes">&#160;&#160; </span>*/</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="79"><span style="color: black"> 79<span style="mso-spacerun: yes">&#160;&#160;&#160; </span></span><b><span style="color: #336699">public</span></b><span style="color: black"> </span><b><span style="color: #336699">void</span></b><span style="color: black"> doGet(HttpServletRequest request,</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="80"><span style="color: black"> 80<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>HttpServletResponse response)</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="81"><span style="color: black"> 81<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span></span><b><span style="color: #336699">throws</span></b><span style="color: black"> ServletException, IOException</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="82"><span style="color: black"> 82<span style="mso-spacerun: yes">&#160;&#160;&#160; </span>{</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="83"><span style="color: black"> 83<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span></span><span style="color: gray">// Create response</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="84"><span style="color: black"> 84<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span>response.setContentType(CONTENT_TYPE);</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="85"><span style="color: black"> 85<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span>PrintWriter out = response.getWriter();</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="86"><span style="color: black"> 86<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span>out.println(</span><span style="color: #0033cc">&quot;&lt;html&gt;&quot;</span><span style="color: black">);</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="87"><span style="color: black"> 87<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span>out.println(</span><span style="color: #0033cc">&quot;&lt;head&gt;&lt;title&gt;CoherenceServlet&lt;/title&gt;&lt;/head&gt;&quot;</span><span style="color: black">);</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="88"><span style="color: black"> 88<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span>out.println(</span><span style="color: #0033cc">&quot;&lt;body&gt;&quot;</span><span style="color: black">);</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="89"><span style="color: black"> 89<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span></span><span style="color: gray">// Get Coherence cache date</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="90"><span style="color: black"> 90<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span>NamedCache cache =</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="91"><span style="color: black"> 91<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>factory.ensureCache(</span><span style="color: #0033cc">&quot;stock-cache&quot;</span><span style="color: black">, getClass().getClassLoader());</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="92"><span style="color: black"> 92<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span></span><span style="color: gray">// Get Stock object from cache</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="93"><span style="color: black"> 93<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span>Stock s = (Stock) cache.get(</span><span style="color: #0033cc">&quot;ORCL&quot;</span><span style="color: black">);</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="94"><span style="color: black"> 94<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span></span><b><span style="color: #336699">double</span></b><span style="color: black"> price = </span><span style="color: #006600">0</span><span style="color: black">;</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="95"><span style="color: black"> 95<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span></span><b><span style="color: #336699">if</span></b><span style="color: black"> (s != </span><span style="color: #996600">null</span><span style="color: black">)</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="96"><span style="color: black"> 96<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span>{</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="97"><span style="color: black"> 97<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>price = s.getPrice();</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="98"><span style="color: black"> 98<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span>}</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="99"><span style="color: black"> 99<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span></span><span style="color: gray">// Output stock price in response</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="100"><span style="color: black">100<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span>out.println(</span><span style="color: #0033cc">&quot;&lt;p&gt;The latest Oracle Stock Price is: &lt;b&gt;&quot;</span><span style="color: black"> + price +</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="101"><span style="color: black">101<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span></span><span style="color: #0033cc">&quot;&lt;/b&gt;&lt;/p&gt;&quot;</span><span style="color: black">);</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="102"><span style="color: black">102<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span>out.println(</span><span style="color: #0033cc">&quot;&lt;/body&gt;&lt;/html&gt;&quot;</span><span style="color: black">);</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="103"><span style="color: black">103<span style="mso-spacerun: yes">&#160;&#160;&#160;&#160;&#160; </span>out.close();</span></a><span style="color: black"><o:p></o:p></span></pre><pre><a name="104"><span style="color: black">104<span style="mso-spacerun: yes">&#160;&#160;&#160; </span>}</span></a></pre></pre><br />
</blockquote></p>

<p>The other source file that needs to be deployed with the Servlet is the Stock object that is being cached – a separate Java application is used in this scenario to add a Stock object to the “stock-cache” and then continually update it. This means that if the content displayed by the Servlet is refreshed in a browser a new stock price will appear.</p>

<h3>Packaging it all up</h3>

<p>To package it all up you naturally wrap the Servlet and Stock classes – along with the Coherence configuration files and supporting web configuration files – in a WAR file. This WAR file then needs to be wrapped in an EAR file with the coherence.jar file and a reference to this JAR in the MANIFEST.MF file as follows:</p>

<blockquote>
  <p><em>Class-Path: lib/coherence.jar</em></p>
</blockquote>

<p>Note in the Eclipse project the coherence.jar file is in the base dir of the EAR file. The complete structure of the EAR file is shown below:</p>

<p>&#160;</p>

<p><a href="http://blogs.oracle.com/felcey/WindowsLiveWriter/UsingCoherenceasaCachefromaJ2EEWebApplic_DFF2/ear-structure_2.jpg"><img title="ear-structure" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="278" alt="ear-structure" src="http://blogs.oracle.com/felcey/WindowsLiveWriter/UsingCoherenceasaCachefromaJ2EEWebApplic_DFF2/ear-structure_thumb.jpg" width="609" border="0" /></a>&#160;</p>

<p>&#160;</p>

<p>When the application is deployed and run you should see something like this which if you keep refreshing should change.</p>

<p>&#160;</p>

<p><a href="http://blogs.oracle.com/felcey/WindowsLiveWriter/UsingCoherenceasaCachefromaJ2EEWebApplic_DFF2/image_2.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="268" alt="image" src="http://blogs.oracle.com/felcey/WindowsLiveWriter/UsingCoherenceasaCachefromaJ2EEWebApplic_DFF2/image_thumb.png" width="608" border="0" /></a> </p>

<p></p>

<p></p>

<h3>Summary</h3>

<p>That’s it. You should now be able to create a cache, put some data into it and then access it from the above Servlet. The full source code for this example can be found <a href="http://blogs.oracle.com/felcey/2009/05/08/code/coherencewebapplicationcode.zip">here</a>. There is a JDeveloper 11g project and an Eclipse Eurpoa project. There are some batch files to run-up a cache server and a separate client to insert and update Stock data, but unfortunately they are only in JDeveloper project – at the moment. See the readme.txt file for details of how to set things up.</p>]]>
      
   </content>
</entry>

<entry>
   <title>Using Excel as a Real-Time client for Coherence</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/felcey/2009/03/using_excel_as_a_realtime_clie.html" />
   <id>tag:blogs.oracle.com,2009:/felcey//1017.10785</id>
   
   <published>2009-03-13T22:10:01Z</published>
   <updated>2009-03-13T23:15:50Z</updated>
   
   <summary>Often Coherence is thought of as a Java data caching product, and the server side component – where the data is kept is. But the client can not only be a Java application, it can also be a native .NET...</summary>
   <author>
      <name>david.felcey</name>
      
   </author>
   
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/felcey/">
      <![CDATA[<p>Often Coherence is thought of as a Java data caching product, and the server side component – where the data is kept is. But the client can not only be a Java application, it can also be a native <a href="http://coherence.oracle.com/display/COH34UG/Coherence+for+.NET">.NET</a> or <a href="http://coherence.oracle.com/pages/viewpage.action?pageId=1343491">C++</a> application. The native C++ application can also run on Windows, Linux or Solaris. So getting back to .NET. Since the .NET client is just a native C# or VB.NET application (no Java) you can do some nice things, like use the <a href="http://msdn.microsoft.com/en-us/library/aa140061(office.10).aspx">Real Time Data (RTD) Server API</a> to integrate it with Excel, turning Excel into a real-time Coherence client. If you want to see a flash demonstration then click <a href="http://blogs.oracle.com/felcey/2009/03/13/demo/excel_demo_viewlet_swf.html">here</a> to view it in action.</p>  <p>The screen shot of the demonstration shows how a constantly updating graph (shown below) of stock price information can be displayed in Excel. The data which is constantly changing, in this case stock prices, is held in a Coherence cache. A separate client application is changing the stock prices and these changes in the data cache are then being pushed to the .NET Coherence client (RTD Server) and on to the Excel spreadsheet. </p>  <p>The RTD Server is a C# .NET client packaged as an .NET Assembly/DLL and then registered as a COM object. The example in the demonstration is pretty flexible but the next version will be enhanced to provide a great range of filtering.</p>  <p><a href="http://blogs.oracle.com/felcey/WindowsLiveWriter/CoherenceandExcel_F31A/screen-shot_2.jpg"><img title="screen-shot" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="356" alt="screen-shot" src="http://blogs.oracle.com/felcey/WindowsLiveWriter/CoherenceandExcel_F31A/screen-shot_thumb.jpg" width="522" border="0" /></a> </p>  <p>Now the example being shown in the demonstration is a first cut (developed with help from <a href="http://www.linkedin.com/ppl/webprofile?action=vmi&amp;id=3474375&amp;authToken=PbXz&amp;authType=name&amp;trk=ppro_viewmore&amp;lnk=vw_pprofile">Aleksandar Seovic</a>). An improved version will be published very soon with a fuller explanation about it works along with the code itself.</p>]]>
      
   </content>
</entry>

<entry>
   <title>Coherence - Up and running in 15 minutes!</title>
   <link rel="alternate" type="text/html" href="http://blogs.oracle.com/felcey/2009/01/coherence_up_and_running_in_15.html" />
   <id>tag:blogs.oracle.com,2009:/felcey//1017.9900</id>
   
   <published>2009-01-29T09:11:10Z</published>
   <updated>2009-02-21T09:05:28Z</updated>
   
   <summary>What is Coherence and why would you used it? Oracle Coherence stores data in-memory so access to it is very fast. Therefore, you would commonly use Coherence to provide fast access to data. Typically this is necessary in applications where...</summary>
   <author>
      <name>david.felcey</name>
      
   </author>
   
      <category term="Coherence" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="coherence" label="Coherence" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="en" xml:base="http://blogs.oracle.com/felcey/">
      <![CDATA[<h3>What is Coherence and why would you used it?    <br /></h3>  <p><strong></strong>Oracle Coherence stores data in-memory so access to it is very fast. Therefore, you would commonly use Coherence to provide fast access to data. Typically this is necessary in applications where performance and latency are key.</p>  <h3>How does it work?</h3>  <p>Oracle Coherence is a small Java programme that stores data in lookup tables, key/value pairs, or a Map of Java objects in memory (or a cache in Coherence terminology). Well I can do that myself I can hear you say, why do I need Coherence. Well if you do it yourself and crate a lookup table in your own Java program what happens if the Java program crashes?, all your data in-memory is lost. You could persist the data to disk or a database as soon as it changes, but then that would degrade performance. Another problem is what happens when you need to store more data than the Java program has access to (i.e. in its heap)?. Well you could increase the amount memory the Java program has available, but if you are running on a 32 Bit Operating System (OS) this will be limited to 2 GB and even if you are on a 64 Bit OS this can cause problems. Java programs which use large amounts of memory can suffer from un-predictable pauses, anything upwards from 1-2 seconds depending on the amount of memory used. This happens when the Java Virtual Machine (JVM) tidies up all the un-used data (or performs a full Garbage Collection (GC)). For applications that need to provide a consistent level of service, e.g. a customer facing web application, this is often unacceptable.</p>  <p>Oracle Coherence address both of these problems. When lots of Coherence Java programs (or cache servers) are started on one or more connected computers they 'glue' themselves together (to form a cluster) using mulit-cast (or a specified IP of addresses). The look-up table, or cache, can then be spread or partitioned across all the Coherence Java programs (nodes) in the cluster. More nodes can be started to increase the size of the cache ,you just have to start more nodes and they will automatically join the cluster – no re-start&#160; is required. Since a cache can be built from lots of nodes with a relatively small memory footprint processing outages, when the JVM is performing memory housekeeping chores (GC's), is also greatly reduced as you can run lots of JVM’s with a small memory footprint and the effect of any particular JVM GC is also diluted across the whole cluster.</p>  <p>To address the problem of loosing data, if a node or server running a number of nodes crashes, Coherence can keep backup copies of data on different nodes and servers. All changes to the primary copy of a value are synchronously made to the backup, to make sure they are always the same, and if either are lost a new primary or backup is created from the remaining value. Furthermore, Coherence will automatically re-organise the partitioned data in a cache if a failure occurs to ensure that it is re-balanced across the cluster and any in-flight client transactions or queries will still complete successfully.</p>  <p>So simplistically Coherence is just a in-memory lookup table. The clever thing that Coherence does is enable the lookup table to grow and be resilient.</p>  <h3>How do I use it?</h3>  <p>Well that's enough background information. To use Coherence you only need the Java runtime (1.4+). You can download the Oracle JRockit Java runtime and Coherence from the Oracle Technology Network.</p>  <ul>   <li>Coherence can be downloaded from <a href="http://www.oracle.com/technology/software/products/ias/htdocs/coherence.html">here</a>. To install Coherence you just unzip it - that's it!. </li>    <li>Oracle JRockit JVM can be downloaded from <a href="http://www.oracle.com/technology/software/products/jrockit/index.html">here</a> (if you do not already have Java installed) </li> </ul>  <p>In addition to being able to put data in a lookup table and look it up Coherence also supports queries, aggregations, transactions, events and other features. Here we will just concentrate on putting data in a cache and looking it up - to keep things quick and simple.</p>  <p>Coherence works in a sort of client-server mode. I say sort of because a client will make a direct request to the node in the cluster which has the data it wants, rather than go through a central server node or lookup service. This also means that Coherence has no 'single point of failure' or 'single point of bottleneck'. Every node in a cluster is effectively equal and is just responsible for its own data.</p>  <h3>So what does a Coherence client look like?</h3>  <p>Well the object we are going to cache looks like this:</p>  <blockquote>   <p><font face="Courier" color="#000080" size="2">package com.oracle.coherence.demo; </font></p>    <p><font face="Courier" color="#000080" size="2">import java.io.Serializable; </font></p>    <p><font face="Courier" color="#000080" size="2">import java.util.Date; </font></p>    <p><font face="Courier" color="#000080" size="2">/**        <br />* Order class representing an order for a shares         <br />*/         <br />public class Order         <br />&#160; implements Serializable         <br />{         <br />&#160; private String symbol;         <br />&#160; private int quantity;         <br />&#160; private double amount;         <br />&#160; private Date timeStamp; </font></p>    <p><font face="Courier" color="#000080" size="2">&#160; /**        <br />&#160;&#160; * Default constructor         <br />&#160;&#160; */         <br />&#160; public Order()         <br />&#160; {         <br />&#160; } </font></p>    <p><font face="Courier" color="#000080" size="2">&#160; /**        <br />&#160;&#160; * Constructor         <br />&#160;&#160; * @param symbol the Order symbol, e.g. ORCL         <br />&#160;&#160; * @param quantity the number of shares         <br />&#160;&#160; * @param amount the amount of the shares to buy at         <br />&#160;&#160; * @param timeStamp a time stamp         <br />&#160;&#160; */         <br />&#160; public Order(String symbol, int quantity, double amount, Date timeStamp)         <br />&#160; {         <br />&#160;&#160;&#160; this.symbol = symbol;         <br />&#160;&#160;&#160; this.quantity = quantity;         <br />&#160;&#160;&#160; this.amount = amount;         <br />&#160;&#160;&#160; this.timeStamp = timeStamp;         <br />&#160; } </font></p>    <p><font face="Courier" color="#000080" size="2">&#160; /**        <br />&#160;&#160; * Gets the symbol         <br />&#160;&#160; * @return the symbol         <br />&#160;&#160; */         <br />&#160; public String getSymbol()         <br />&#160; {         <br />&#160;&#160;&#160; return symbol;         <br />&#160; } </font></p>    <p><font face="Courier" color="#000080" size="2">&#160; /**        <br />&#160;&#160; * Sets the new symbol         <br />&#160;&#160; * @param symbol the new symbol value         <br />&#160;&#160; */         <br />&#160; public void setSymbol(String symbol)         <br />&#160; {         <br />&#160;&#160;&#160; this.symbol = symbol;         <br />&#160; } </font></p>    <p><font face="Courier" color="#000080" size="2">&#160; /**        <br />&#160;&#160; * Gets the quantity         <br />&#160;&#160; * @return the quantity         <br />&#160;&#160; */         <br />&#160; public int getQuantity()         <br />&#160; {         <br />&#160;&#160;&#160; return quantity;         <br />&#160; } </font></p>    <p><font face="Courier" color="#000080" size="2">&#160; /**        <br />&#160;&#160; * Sets the new quantity         <br />&#160;&#160; * @param quantity the new quantity         <br />&#160;&#160; */         <br />&#160; public void setQuantity(int quantity)         <br />&#160; {         <br />&#160;&#160;&#160; this.quantity = quantity;         <br />&#160; } </font></p>    <p><font face="Courier" color="#000080" size="2">&#160; /**        <br />&#160;&#160; * Gets the amount         <br />&#160;&#160; * @return the amount         <br />&#160;&#160; */         <br />&#160; public double getAmount()         <br />&#160; {         <br />&#160;&#160;&#160; return amount;         <br />&#160; } </font></p>    <p><font face="Courier" color="#000080" size="2">&#160; /**        <br />&#160;&#160; * Sets the amount         <br />&#160;&#160; * @param amount the new amount         <br />&#160;&#160; */         <br />&#160; public void setAmount(double amount)         <br />&#160; {         <br />&#160;&#160;&#160; this.amount = amount;         <br />&#160; } </font></p>    <p><font face="Courier" color="#000080" size="2">&#160; /**        <br />&#160;&#160; * Gets the time stamp         <br />&#160;&#160; * @return the time stamp         <br />&#160;&#160; */         <br />&#160; public Date getTimeStamp()         <br />&#160; {         <br />&#160;&#160;&#160; return timeStamp;         <br />&#160; } </font></p>    <p><font face="Courier" color="#000080" size="2">&#160; /**        <br />&#160;&#160; * Sets the new time stamp         <br />&#160;&#160; * @param timeStamp the new time stamp         <br />&#160;&#160; */         <br />&#160; public void setTimeStamp(Date timeStamp)         <br />&#160; {         <br />&#160;&#160;&#160; this.timeStamp = timeStamp;         <br />&#160; }         <br />}</font></p> </blockquote>  <p>The Coherence client application looks like this:</p>  <blockquote>   <p><font face="Courier" color="#000080" size="2">package com.oracle.coherence.demo; </font></p>    <p><font face="Courier" color="#000080" size="2">import com.tangosol.net.CacheFactory;        <br />import com.tangosol.net.NamedCache; </font></p>    <p><font face="Courier" color="#000080" size="2">import java.util.Date;        <br />import java.util.Iterator;         <br />import java.util.Set; </font></p>    <p><font face="Courier" color="#000080" size="2">/**        <br />* Simple Coherence cache client example         <br />*/         <br />public class SimpleCoherenceClient         <br />{         <br />&#160; /**         <br />&#160;&#160; * Main method         <br />&#160;&#160; * @param args not used         <br />&#160;&#160; */         <br />&#160; public static void main(String[] args)         <br />&#160; {         <br />&#160;&#160;&#160; // Get a handle/reference to a cache by name - which does not have to exist         <br />&#160;&#160;&#160; NamedCache namedCache = CacheFactory.getCache(&quot;test&quot;); </font></p>    <p><font face="Courier" color="#000080" size="2">&#160;&#160;&#160; // Create an object value to put in the cache        <br />&#160;&#160;&#160; Order value = new Order(&quot;ORCL&quot;, 400, 19.4, new Date()); </font></p>    <p><font face="Courier" color="#000080" size="2">&#160;&#160;&#160; // Create a key for the object        <br />&#160;&#160;&#160; Integer key = new Integer(0); </font></p>    <p><font face="Courier" color="#000080" size="2">&#160;&#160;&#160; // Put an item into the cache        <br />&#160;&#160;&#160; namedCache.put(key, value); </font></p>    <p><font face="Courier" color="#000080" size="2">&#160;&#160;&#160; // Retrieve the object based upon its key        <br />&#160;&#160;&#160; Order order = (Order) namedCache.get(key); </font></p>    <p><font face="Courier" color="#000080" size="2">&#160;&#160;&#160; System.out.println(&quot;------------------------------------------------------&quot;);        <br />&#160;&#160;&#160; System.out.println(&quot;Retrieved order: &quot; + &quot;symbol=&quot; +         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; order.getSymbol() + &quot;, amount=&quot; +         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; order.getAmount() + &quot;, quantity=&quot; +         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; order.getQuantity() + &quot;, timestamp=&quot; +         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; order.getTimeStamp());         <br />&#160;&#160;&#160; System.out.println(&quot;------------------------------------------------------&quot;); </font></p>    <p><font face="Courier" color="#000080" size="2">&#160;&#160;&#160; // Shutdown client connection to cache        <br />&#160;&#160;&#160; CacheFactory.shutdown();         <br />&#160; }         <br />}</font></p> </blockquote>  <p>As you can see the client code to add and retrieve an object from a Coherence cache is trivial. The above example can be downloaded from <a href="http://blogs.oracle.com/felcey/2009/01/31/SimpleCoherenceExample.zip">here</a>, with all the files ready to run it. Look at the readme.txt file for instructions.</code> </p>  <p>When you run a Coherence client all you need to do is include the Coherence Jar files in the CLASSPATH and either include the XML configuration file in the CLASSPATH or indicate its location through a system property. That's it. Through multi-cast it will locate the cluster on the default TCP port. Using a specific IP address etc. for clustering is simply a matter of overriding default configuration file settings.</p>  <h3>So how fast is Coherence? </h3>  <p>Well that depends on how much data you need to access, what your network is like, how fast your hardware is etc, but it is usually run on commodity hardware (blades and GBit Ethernet). For more information on performance and scalability see the results of our internal test <a href="http://wiki.tangosol.com/display/COH34UG/Evaluating+Performance+and+Scalability">here</a>.</p>  <h3>How much data can Coherence store? </h3>  <p>Some Coherence customers have caches with 100's of GB of data and 100's of nodes. Others only cache a few GB of data.</p>  <h3>Can I save cache entries to a database? </h3>  <p>Yes. Coherence provides the facility to persist cache data to any database (using JPA, Hibernate or Toplink) synchronously or asynchronously. Its also very easy to plug-in persistence to everything from a file system to a Mainframe.</p>  <h3>I use .NET of C++ not Java. Can I still use Coherence? </h3>  <p>Coherence also comes with native .NET and C++ client libraries. When using these technologies, .NET or C++ objects are created to map onto Java objects and Coherence then transforms the .NET or C++ objects to and from the Java objects when the clients communicate with the Java cache servers.</p>  <p>&#160;</p>  <p>There is obviously a lot more to Coherence than has been covered here, but hopefully this has given you a flavour of how to use it. For more information about the other features mentioned, examples and white papers etc,go to the <a href="http://www.oracle.com/technology/products/coherence/index.html">Coherence home page</a> on Oracle Technology Network.</p>]]>
      
   </content>
</entry>

</feed>
