<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cacheonix Blog</title>
	<atom:link href="http://www.cacheonix.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cacheonix.com/blog</link>
	<description>Direct Connection to Cacheonix Developers</description>
	<lastBuildDate>Mon, 08 Oct 2012 02:01:04 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>Using Distributed ConcurrentHashMap</title>
		<link>http://www.cacheonix.com/blog/2012/09/using-distributed-concurrenthashmap/</link>
		<comments>http://www.cacheonix.com/blog/2012/09/using-distributed-concurrenthashmap/#comments</comments>
		<pubDate>Fri, 21 Sep 2012 20:49:00 +0000</pubDate>
		<dc:creator>simeshev</dc:creator>
				<category><![CDATA[Distributed Caching]]></category>

		<guid isPermaLink="false">http://www.cacheonix.com/blog/?p=36</guid>
		<description><![CDATA[Before, if you wanted to make atomic modifications to the distributed hash table provided by Cacheonix, you could use the distributed locks, such as in the example below: Cacheonix cacheonix = Cacheonix.getInstance(); ReadWriteLock readWriteLock = cacheonix.getCluster().getReadWriteLock(); Map map = cacheonix.getCache(mapName); Lock lock = readWriteLock.writeLock(); lock.lock(); try { if (!map.containsKey(key)) { return map.put(key, value); } else [...]]]></description>
			<content:encoded><![CDATA[<p>Before, if you wanted to make atomic modifications to the distributed hash table provided by Cacheonix, you could use the distributed locks, such as in the example below:</p>
<pre style="background-color: #eeeeee;  line-height: 125%">

      Cacheonix cacheonix = Cacheonix.getInstance();
      ReadWriteLock readWriteLock = cacheonix.getCluster().getReadWriteLock();
      Map map = cacheonix.getCache(mapName);
      Lock lock = readWriteLock.writeLock();
      lock.lock();
      try {
         if (!map.containsKey(key)) {
            return map.put(key, value);
         } else {
            return map.get(key);
         }
      } finally {
         lock.unlock();
      }

</pre>
<p>That approach worked but it required multiple network round trips to get things done. The <a href="http://downloads.cacheonix.com">latest Cacheonix release</a> adds a <a href="http://downloads.cacheonix.com">distributed implementation of ConcurrentHashMap</a>. Now you can modify distributed hash maps atomically, with minimal latency, by using the new JDK-compatible distributed ConcurrentMap API:</p>
<pre style="background-color: #eeeeee;  line-height: 125%">

     Cacheonix cacheonix = Cacheonix.getInstance();
     java.util.concurrent.ConcurrentMap concurrentMap = cacheonix.getCache(mapName);
     return concurrentMap.putIfAbsent(key, value);


</pre>
<p>Distributed ConcurrentMap by Cacheonix supports all four methods of ConcurrentMap: </p>
<ul>
<li>V putIfAbsent(K key, V value); </li>
<li>boolean remove(Object key, Object value);</li>
<li>boolean replace(K key, V oldValue, V newValue);</li>
<li>V replace(K key, V value);</li>
</ul>
<p>Hope this helps.</p>
<p>&#8212;</p>
<p>Regards,</p>
<p>Slava Imeshev<br />
<a href="http://www.cacheonix.com/products/cacheonix/index.htm">Cacheonix Open Source Distributed Data Management Framework</a></p>
<p>&#8212;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cacheonix.com/blog/2012/09/using-distributed-concurrenthashmap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Presenting on Scaling Java Applications at Code Camp 2012</title>
		<link>http://www.cacheonix.com/blog/2012/09/developing-scalable-java-apllications-with-cacheonix-at-code-camp-2012/</link>
		<comments>http://www.cacheonix.com/blog/2012/09/developing-scalable-java-apllications-with-cacheonix-at-code-camp-2012/#comments</comments>
		<pubDate>Fri, 21 Sep 2012 20:06:06 +0000</pubDate>
		<dc:creator>simeshev</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cacheonix.com/blog/?p=35</guid>
		<description><![CDATA[This is a great chance to meet developers of open source distributed cache Cacheonix in person. I will be presenting on scaling Java applications horizontally at two separate times on Sunday, October 7 at Silicon Valley Code Camp. Click on the links below to register: Architecture for scaling Java applications to multiple servers Developing scalable [...]]]></description>
			<content:encoded><![CDATA[<p>This is a great chance to meet developers of open source <a href="http://www.cacheonix.com/products/cacheonix/index.htm">distributed cache Cacheonix</a> in person. I will be presenting on scaling Java applications horizontally at two separate times on Sunday, October 7 at Silicon Valley Code Camp. Click on the links below to register:</p>
<ol>
<li><a href="http://www.siliconvalley-codecamp.com/Sessions.aspx?OnlyOne=true&#038;id=1054">Architecture for scaling Java applications to multiple servers</a></li>
<li><a href="http://www.siliconvalley-codecamp.com/Sessions.aspx?OnlyOne=true&#038;id=1055">Developing scalable Java applications with open source clustered cache Cacheonix</a></li>
</ol>
<p>Silicon Valley Code Camp is a new type of community event where developers learn from fellow developers. It is totally free and will occur on October 6 and 7.</p>
<p>See you at Code Camp 2012!</p>
<p>&#8212;<br />
Regards,</p>
<p>Slava Imeshev<br />
Main committer, Cacheonix</p>
<p>&#8212;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cacheonix.com/blog/2012/09/developing-scalable-java-apllications-with-cacheonix-at-code-camp-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Resolving Java Performance Problems in Production</title>
		<link>http://www.cacheonix.com/blog/2012/01/solving-urgent-java-performance-problems/</link>
		<comments>http://www.cacheonix.com/blog/2012/01/solving-urgent-java-performance-problems/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 00:31:23 +0000</pubDate>
		<dc:creator>simeshev</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cacheonix.com/blog/?p=31</guid>
		<description><![CDATA[Performance problems in production can be tricky. This post describes a proven sequence for resolving urgent production performance problems for Java. Sources of Performance Problems The main sources of the performance problems in production are: coding errors internal and external bottlenecks garbage collection (GC) Coding errors are places in the code where the application acts [...]]]></description>
			<content:encoded><![CDATA[<p>Performance problems in production can be tricky. This post describes a proven sequence for resolving urgent production performance problems for Java.</p>
<h1>Sources of Performance Problems</h1>
<p>The main sources of the performance problems in production are: </p>
<ul>
<li>coding errors</li>
<li>internal and external bottlenecks</li>
<li>garbage collection (GC)</li>
</ul>
<p>Coding errors are places in the code where the application acts in a way that leads to significant reduction of speed such as heavy repeated calculations inside a loop. Internal bottlenecks are improper, excessive synchronization, exhausted thread pools and connection pools. External bottlenecks are serially accessed data sources such as databases, file and socket I/O.  </p>
<h1>Manifestation of Performance Problems</h1>
<p>Performance problems in production usually manifest themselves as users complaining about the application being &#8216;slow&#8217;. While &#8216;slow&#8217; may be a matter of perception, generally it means that the application is <strong>abnormally</strong> slow. Performance problems may seriously damage your company business and must be resolved as soon as possible. The problem resolution sequence below worked well for me for many years.</p>
<h1>Sequence for Resolving Performance Problems</h1>
<p>1. <strong>Make sure JVM has correct heap settings</strong>. The maximum and minimum head should be set to the same value. Example: <code>-Xmx1000k -Xms1000k</code>.</p>
<p>2. <strong>Check memory consumption on the server</strong>. Make sure that the system is not swapping. Run <code>top</code> or <code>ps</code> to check if the server as a whole and the application itself is not swapping. Increase memory on the server if it doesn&#8217;t have enough memory or move some applications out.</p>
<p>3. <strong>Check server CPU usage</strong>. If the server is underloaded, this is usually an indication of an internal or external bottleneck. Thread dumps, heap dumps and profiling must help to identify the bottlenecks.</p>
<p>4. <strong>Take and analyze thread dumps</strong>. This method is great because it doesn&#8217;t require any instrumentation, takes a minute, and often is enough to isolate the problem.  During the periods of slowness, take 5-6 thread dumps. Just send <em>kill -3
<process ID></em> if your application is running under *nix. Separate each thread dump by a 10 second interval. Check the thread dumps for places where threads remain within the same execution stack for extended periods of time. Most of the times the problem stack traces will contain application classes. Watch for thread pools all stuck in file or network I/O. Watch for exhausted thread pools. Watch for execution threads blocked on the same objects. Fix found problems.</p>
<p>5. <strong>Take and analyze heap dumps</strong>. Take 2-3 heap dumps during normal operation  using <a href="http://docs.oracle.com/javase/6/docs/technotes/tools/share/jmap.html">JMap</a> and during the system slowing down or JVM being completely unresponsive. Analyze the heap dumps using JProfiler for objects having large number of instances. Also, compare a normal heap dump with the one taken during the slowdown. Find objects counts that grew significantly since the period of normal operation. Such objects strongly indicate a memory leak. Find and fix the problem in the code. </p>
<p>6. <strong>Profile while running a load test</strong>. In the QA environment, run a load test the simulates the same sequence of user actions that production users are having a problem with. Use a profiler such as JProfiler to identify CPU and allocation hot spots. Fix found problems.</p>
<p>7. <strong>Profile in production</strong>. Profiling adds some overhead, so the application will run slower than normally. Use a single server to profile if running a cluster. To minimize overhead, configure JProfiler properly:</p>
<ul>
<li>Use sampling instead of instrumentation</li>
<li>Add a narrow list of packages that are interesting from a user-perspective</li>
<li>Do not record allocations</li>
<li>Only record CPU when there are reports from users about performance issues</li>
</ul>
<p>8. <strong>Tune GC</strong>. Enable GC in production by using command line option <code>–XX:+PrintGCDetails</code>. Watch for major GCs occurring abnormally often. The main causes of frequent major GCs are the application running out of heap due to memory leaks and excessive object creation and incorrect GC parameters. Profile the application for memory leaks and excessive object creation. Fix found problems. Adjust GC parameters for better performance. Tuning GC should be the last thing to do. Check our <a href="http://wiki.cacheonix.com/display/CCHNX/Useful+Resources+for+Tuning+Java+Garbage+Collection">collection of useful resources on tuning Java GC</a>.  </p>
<p>9. <strong>Cache hard to get data</strong>. If the performance bottleneck is found and it is a database or other serially accessed data source or a hard-to-compute data source, cache that data. Here are a few <a href="http://www.cacheonix.com/articles/index.htm">articles on how to approach caching</a>. Or drop a message in <a href="http://forums.cacheonix.com/viewforum.php?f=2">Cacheonix support forum</a>; we&#8217;ll try to help.</p>
<p>Hope this helps</p>
<p>Slava Imeshev</p>
<p><a title="Cacheonix In-memory Data Grid" href="http://www.cacheonix.com/products/cacheonix/index.htm">Cacheonix In-memory Data Grid</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.cacheonix.com/blog/2012/01/solving-urgent-java-performance-problems/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cacheonix as Distributed DataNucleus L2 Cache</title>
		<link>http://www.cacheonix.com/blog/2011/09/cacheonix-datanucleus-l2-cache/</link>
		<comments>http://www.cacheonix.com/blog/2011/09/cacheonix-datanucleus-l2-cache/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 22:40:46 +0000</pubDate>
		<dc:creator>simeshev</dc:creator>
				<category><![CDATA[Distributed Caching]]></category>

		<guid isPermaLink="false">http://www.cacheonix.com/blog/?p=28</guid>
		<description><![CDATA[DataNucleus can now use Cacheonix as a distributed L2 Cache. DataNuclues access platform is an open source standards-based JPA API that provides persistence and query services for  a wide set of datastores. Andy Jefferson, the project lead at DataNucleus.org, has let me know today that DataNucleus Access Platform has added support for Cacheonix. Now DataNucleus [...]]]></description>
			<content:encoded><![CDATA[<p>DataNucleus can now use Cacheonix as a distributed L2 Cache.</p>
<p>DataNuclues access platform is an open source standards-based JPA API that provides persistence and query services for  a wide set of datastores. Andy Jefferson, the project lead at DataNucleus.org, has let me know today that DataNucleus Access Platform has added support for Cacheonix. Now DataNucleus applications can scale out with ease by using Cacheonix as a distributed L2 cache.</p>
<p>It&#8217;s great to see growing adoption of Cacheonix by persistence frameworks and we are looking forward to further collaboration with DataNucleus.</p>
<p>See Also:</p>
<ul>
<li><a href="http://wiki.cacheonix.com/display/CCHNX20/Configuring+Distributed+DataNucleus+L2+Cache">Configuring Cacheonix DataNucleus L2 Cache</a></li>
<li><a href="http://www.datanucleus.org/products/accessplatform/index.html">DataNucleus Access Platform Home</a></li>
</ul>
<p>Regards,</p>
<p>Slava Imeshev</p>
<p><a title="Cacheonix | Reliable Clustered Java Cache" href="http://www.cacheonix.com/products/cacheonix/index.htm">Cacheonix | Reliable Clustered Java Cache</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cacheonix.com/blog/2011/09/cacheonix-datanucleus-l2-cache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Store a List in a Cache</title>
		<link>http://www.cacheonix.com/blog/2011/09/how-to-store-a-list-in-a-cache/</link>
		<comments>http://www.cacheonix.com/blog/2011/09/how-to-store-a-list-in-a-cache/#comments</comments>
		<pubDate>Sat, 03 Sep 2011 07:03:23 +0000</pubDate>
		<dc:creator>simeshev</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cacheonix.com/blog/?p=24</guid>
		<description><![CDATA[Storing a list in a cache and getting it from the cache is easy. Here is how. The simplest way is just to put the list to the cache. Note that if you want to use a strongly typed cache, you need to provide a concrete list type: import java.util.ArrayList; import cacheonix.Cacheonix; import cacheonix.cache.Cache; ... [...]]]></description>
			<content:encoded><![CDATA[<p>Storing a list in a cache and getting it from the cache is easy. Here is how.</p>
<p>The simplest way is just to put the list to the cache. Note that if you want to use a strongly typed cache, you need to provide a concrete list type:</p>
<pre style="background-color: #eeeeee;  line-height: 125%">

import java.util.ArrayList;
import cacheonix.Cacheonix;
import cacheonix.cache.Cache;

...

   /**
    * Puts a list to the cache.
    *
    * @param key  a key identifying the list.
    * @param list the list to cache.
    */
   public void putListToCache(String key, ArrayList&lt;String&gt; list) {

      final Cache&lt;String, ArrayList&lt;String&gt;&gt; listCache = Cacheonix.getInstance().getCache("listCache");
      listCache.put(key, list);
   }


   /**
    * Gets a list from the cache.
    *
    * @param key a key identifying the list.
    * @return the cached list or null if the list wasn't found in the cache or if the list is null.
    */
   public ArrayList&lt;String&gt; getListFromCache(String key) {

      final Cache&lt;String, ArrayList&lt;String&gt;&gt; listCache = Cacheonix.getInstance().getCache("listCache");
      final ArrayList&lt;String&gt; list = listCache.get(key);
      return list;
   }
</pre>
<p>While the above works, there is a better way, which is creating a first-class object for the cached list. </p>
<p>Usually lists don&#8217;t come alone and are accompanied by some metadata. For example, if you are caching a database result set, in future you might want to cache time it took to retrieve the result set in addition to the result set itself. Wrapping the list into a class  provides an ability to maintain a stable signature of the cached object. If you need to add more fields in the future, you don&#8217;t have to change all places where a cached list is put to and retrieved from the cache. </p>
<p>A cached result set object that contains a list would then look like the following. Note that it declares a signature interface Immutable that signals the cache that this object can be passed by reference:</p>
<pre style="background-color: #eeeeee;  line-height: 125%">

import java.io.Externalizable
import cacheonix.cache.Immutable;

...

  public class CachedResultSet implements Externalizable, Immutable {

    private List&lt;String&gt; list = null;


    public CachedResultSet(List&lt;String&gt; list) {
      this.list = new ArrayList&lt;String&gt;(list);
    }


    /**
     * Required by Externalizable.
     */
    public CachedResultSet() {
    }

    public List<String> getList() {
      return new ArrayList(list);
    }

    public void writeExternal(ObjectOutput objectOutput) throws IOException {

      if (list == null) {

        objectOutput.writeBoolean(true);
      } else {

        objectOutput.writeInt(list.size());
        for (int i = 0; i < list.size(); i++) {

          objectOutput.writeUTF(list.get(i));
        }
      }
    }


    public void readExternal(ObjectInput objectInput) throws IOException, ClassNotFoundException {

      if (!objectInput.readBoolean()) {

        int size = objectInput.readInt();
        list = new ArrayList&lt;String&gt;(size);
        for (int i = 0; i < size; i++) {

          list.add(objectInput.readUTF());
        }
      }
    }
  }

</pre>
<p>Getting the cached result set would look like this:</p>
<pre style="background-color: #eeeeee;  line-height: 125%">
   public CachedResultSet getListFromCache(String key) {

      final Cache&lt;String, CachedResultSet&gt; listCache = Cacheonix.getInstance().getCache("listCache");
      final CachedResultSet list = listCache.get(key);
      return list;
   }
</pre>
<p>Regards,</p>
<p>Slava Imeshev</p>
<p><a title="Cacheonix | Reliable Clustered Java Cache" href="http://www.cacheonix.com/products/cacheonix/index.htm">Cacheonix | Reliable Clustered Java Cache</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cacheonix.com/blog/2011/09/how-to-store-a-list-in-a-cache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Per-select Caching for MyBatis</title>
		<link>http://www.cacheonix.com/blog/2011/08/per-select-caching-for-mybatis/</link>
		<comments>http://www.cacheonix.com/blog/2011/08/per-select-caching-for-mybatis/#comments</comments>
		<pubDate>Sun, 21 Aug 2011 22:06:36 +0000</pubDate>
		<dc:creator>simeshev</dc:creator>
				<category><![CDATA[Distributed Caching]]></category>

		<guid isPermaLink="false">http://www.cacheonix.com/blog/?p=23</guid>
		<description><![CDATA[Good news: We&#8217;ve just added support for per-select caching for MyBatis to our open source cache Cacheonix that addresses major problems with default MyBatis caching. Problems With Default MyBatis Caching There are a few problems with the way caching works in MyBatis: MyBatis keeps results of all selects in a single, namespace-wide, cache. This means [...]]]></description>
			<content:encoded><![CDATA[<p>Good news: We&#8217;ve just added support for per-select caching for MyBatis to our <a href="http://www.cacheonix.com/products/cacheonix/index.htm">open source cache Cacheonix</a> that addresses major problems with default MyBatis caching.</p>
<p>
<b>Problems With Default MyBatis Caching</b>
</p>
<p>There are a few problems with the way caching works in MyBatis:</p>
<ul>
<li>MyBatis keeps results of all selects in a single, namespace-wide, cache. This means any invalidation caused by inserts or updates will flush cached results of all selects, including those that are really not affected by the changes.</li>
<li>It is impossible to ignore invalidation completely and to have pure time-only expiration for some selects.</li>
<li>It is impossible to have different cache configurations for particular selects.</li>
</ul>
<p>
<b>Benefits of Cacheonix Adapter for MyBatis</b>
</p>
<p>Cacheonix have addressed these concerns by adding the following features:</p>
<ol>
<li><strong>Per-select MyBatis caches</strong></li>
<li><strong>Ability to turn off invalidation</strong></li>
<li><strong><strong>Ability to turn off namespace cache</strong></strong></li>
<li><strong><strong></strong>Cache templates for select caches</strong></li>
</ol>
<p>For more information and examples check Cacheonix documentation: <a title="Documentation: Configuring MyBatis Cache Adapter" href="http://wiki.cacheonix.com/display/CCHNX20/Configuring+Distributed+MyBatis+Cache">Configuring MyBatis Cache Adapter</a>.</p>
<p>Enjoy!</p>
<p>Regards,</p>
<p>Slava Imeshev<br />
<a title="Cacheonix | Reliable Distributed Java Cache" href="http://www.cacheonix.com/products/cacheonix/index.htm">Cacheonix | Reliable Distributed Java Cache</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cacheonix.com/blog/2011/08/per-select-caching-for-mybatis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing Private Methods in Java</title>
		<link>http://www.cacheonix.com/blog/2011/08/testing-private-methods-in-java/</link>
		<comments>http://www.cacheonix.com/blog/2011/08/testing-private-methods-in-java/#comments</comments>
		<pubDate>Fri, 19 Aug 2011 20:36:02 +0000</pubDate>
		<dc:creator>simeshev</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cacheonix.com/blog/?p=20</guid>
		<description><![CDATA[Java 5 provides vargargs API that allows to test private methods in a very concise way. Here is how. Yesterday, during a meetup at Loopt, a question of an API for testing private methods was brought up. I used to use JUnit add-on PrivateAccessor [1] when I was testing private methods. The problem was that [...]]]></description>
			<content:encoded><![CDATA[<p>Java 5 provides vargargs API that allows to test private methods in a very concise way. Here is how.</p>
<p>Yesterday, during a meetup at Loopt, a question of an API for testing private methods was brought up. I used to use JUnit add-on PrivateAccessor [1] when I was testing private methods. The problem was that applying PrivateAccessor produced prohibitively verbose code, so you had to think really hard to understand what the test was doing.</p>
<h3>invoke() with varargs</h3>
<p>Luckily, Java 5 provides vargargs API that allows to write really concise code for invoking private methods and return results. Here is the invoke() method that makes use of vargargs. Feel free to use it in your code:</p>
<pre style="background-color: #eeeeee;">
   /**
    * Invokes a private method on an object.
    *
    * @param obj        the object on what to invoke the method.
    * @param methodName the name of the method to invoke.
    * @param parameters a list of parameter
    * @return the result of dispatching the method represented by the object.
    */
   public static &lt;T&gt; T invoke(Object obj, String methodName, Object... parameters) {

      try {

         // Create a list of parameter classes
         final Class[] parameterTypes = new Class[parameters.length];
         for (int i = 0; i < parameters.length; i++) {
            parameterTypes[i] = parameters[i].getClass();
         }

         // Get method
         Class<?> clazz = obj.getClass();
         Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
         method.setAccessible(true);

         // Call method
         return (T)method.invoke(obj, parameters);
      } catch (RuntimeException e) {

         throw e;
      } catch (Exception e) {

         throw new IllegalArgumentException(e);
      }
   }
</pre>
<h3>Complete Example</h3>
<p>Below is a complete JUnit tests that tests StringBuilder&#8217;s private method append(). Notice how neatly the invocation of append() fits into a short single line:</p>
<pre  style="background-color: #eeeeee;">
import java.lang.reflect.Method;
import junit.framework.TestCase;

public final class StringBuilderTest extends TestCase {


   /**
    * Object under test
    */
   private StringBuilder object;


   /**
    * Tests String's private method 'append(StringBuilder sb)'.
    */
   public void testAppend() {
      
      StringBuilder toAppend = new StringBuilder("Test");
      StringBuilder result = invoke(object, "append", toAppend);
      assertEquals("Test", result.toString());
   }


   /**
    * Invokes a private method on an object.
    *
    * @param obj        the object on what to invoke the method.
    * @param methodName the name of the method to invoke.
    * @param parameters a list of parameter
    * @return the result of dispatching the method represented by the object.
    */
   public static &lt;T&gt; T invoke(Object obj, String methodName, Object... parameters) {

      try {

         // Create a list of parameter classes
         final Class[] parameterTypes = new Class[parameters.length];
         for (int i = 0; i < parameters.length; i++) {
            parameterTypes[i] = parameters[i].getClass();
         }

         // Get method
         Class<?> clazz = obj.getClass();
         Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
         method.setAccessible(true);

         // Call method
         return (T)method.invoke(obj, parameters);
      } catch (RuntimeException e) {

         throw e;
      } catch (Exception e) {

         throw new IllegalArgumentException(e);
      }
   }


   public void setUp() throws Exception {

      super.setUp();

      object = new StringBuilder(10);
   }
}

</pre>
<h3>Making invoke() reusable</h3>
<p>To make invoke() reusable, I suggest to move it to a separate utility class or at least to create a super class for all your tests that extends junit.TestCase and move invoke() there.</p>
<p>Regards,</p>
<p>Slava Imeshev<br />
<a href="http://www.cacheonix.com/products/cacheonix/index.htm" title="Cacheonix: Reliable Distributed Java Cache">Cacheonix: Reliable Distributed Java Cache</a></p>
<h3>References</h3>
<p>1. <a href="http://junit-addons.sourceforge.net/junitx/util/PrivateAccessor.html" title="JUnit Add-on Private Accessor">JUnit Add-On PrivateAccessor</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cacheonix.com/blog/2011/08/testing-private-methods-in-java/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Testing Keys and Values for Distributed Java Caching</title>
		<link>http://www.cacheonix.com/blog/2011/07/testing-objects-for-distributed-caching/</link>
		<comments>http://www.cacheonix.com/blog/2011/07/testing-objects-for-distributed-caching/#comments</comments>
		<pubDate>Sat, 23 Jul 2011 04:01:05 +0000</pubDate>
		<dc:creator>simeshev</dc:creator>
				<category><![CDATA[Distributed Caching]]></category>

		<guid isPermaLink="false">http://www.cacheonix.com/blog/?p=15</guid>
		<description><![CDATA[In distributed caching, cache keys and cached values routinely travel across the network. That&#8217;s why it is critical to write proper unit tests for keys and values in order to avoid unpleasant production surprises. This post tells how to test keys and values for distributed caching. Distributed caching imposes an additional requirement towards unit tests [...]]]></description>
			<content:encoded><![CDATA[<p>In distributed caching, cache keys and cached values routinely travel across the network. That&#8217;s why <strong>it is critical to write proper unit tests for keys and values in order to avoid unpleasant production surprises</strong>. This post tells how to test keys and values for distributed caching.</p>
<p>Distributed caching imposes an additional requirement towards unit tests for cache keys and cached values. Particularly, you must ensure that the object that was received at another end is the object that was sent. Here is how to tests it:</p>
<p><strong>First, serialize an object to a byte array and then deserialize the byte array back to an object</strong></p>
<pre style="background-color: #dddddd; line-height: 125%">      // Serialize the object
      ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
      ObjectOutputStream oos = new ObjectOutputStream(baos);
      oos.writeObject(originalInvoiceKey);
      oos.close();

      // Deserialize the object in serialized form
      final byte[] serializedInvoiceKey = baos.toByteArray();
      ByteArrayInputStream bais = new ByteArrayInputStream(serializedInvoiceKey);
      ObjectInputStream ois = new ObjectInputStream(bais);
      final InvoiceKey deserializedInvoiceKey = (InvoiceKey) ois.readObject();
      ois.close();</pre>
<p><strong>Second, assert that the deserialized object and the original object are equal:</strong></p>
<pre style="background-color: #dddddd; line-height: 125%">
      assertEquals(originalInvoiceKey, deserializedInvoiceKey);
</pre>
<p>While you have already implemented methods equals() and hashCode() for the key, cached values need to have that methods added. For value objects, equals() and hashCode() need to satisfy a requirement for &#8216;literal equality&#8217;. In other words, to test that a value object can be serialized and deserialized, its equals() and hashCode() should include all non-transient fields:</p>
<pre style="background-color: #dddddd; line-height: 125%">public final class Invoice implements Externalizable {

   private int invoiceID;
   private Date invoiceDate = null;
   private int invoiceNumber;
   private int customerID;

...

   public boolean equals(final Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;
      final Invoice invoice = (Invoice) o;
      if (invoiceID != invoice.invoiceID) return false;
      if (invoiceNumber != invoice.invoiceNumber) return false;
      if (customerID != invoice.customerID) return false;
      if (invoiceDate != null ? !invoiceDate.equals(invoice.invoiceDate) : invoice.invoiceDate != null) return false;
      return true;
   }

   public int hashCode() {
      int result = invoiceID;
      result = 31 * result + (invoiceDate != null ? invoiceDate.hashCode() : 0);
      result = 31 * result + invoiceNumber;
      result = 31 * result + customerID;
      return result;
   }
}</pre>
<p>If adding equals() and hashCode() to the cached value is impossible, use explicit assertEquals() for object&#8217;s fields:</p>
<pre style="background-color: #dddddd; line-height: 125%">      assertEquals(invoiceID, deserializedInvoiceKey.getInvoiceID());</pre>
<p>Regards,</p>
<p>Slava Imeshev<br />
<a href="http://www.cacheonix.com/products/cacheonix/index.htm" title="Cacheonix | Reliable Clustered Java Cache">Cacheonix | Reliable Clustered Java Cache</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cacheonix.com/blog/2011/07/testing-objects-for-distributed-caching/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Freeing Desk Space with Docking Stand</title>
		<link>http://www.cacheonix.com/blog/2011/06/freeing-desk-space-with-docking-stand/</link>
		<comments>http://www.cacheonix.com/blog/2011/06/freeing-desk-space-with-docking-stand/#comments</comments>
		<pubDate>Mon, 13 Jun 2011 06:09:48 +0000</pubDate>
		<dc:creator>simeshev</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.cacheonix.com/blog/?p=5</guid>
		<description><![CDATA[My laptop takes quite some space on my  desk. The good news, there is a neat solution that allows to reduce its footprint almost 10 times. I am using Mac Pro and MacBook Pro as development machines while working on Cacheonix. The Mac Pro is tucked under my desk and is practically invisible. Yet, the [...]]]></description>
			<content:encoded><![CDATA[<p>My laptop takes quite some space on my  desk. The good news, there is  a neat solution that allows to reduce its footprint almost 10 times.</p>
<p>I am using Mac Pro and MacBook Pro as development machines while working on<strong> <a title="Cacheonix Distributed Cache Data Grid" href="../../">Cacheonix</a></strong>.  The Mac Pro is tucked under my desk and is practically invisible. Yet,  the MacBook has been occupying a noticeable chunk of the desk surface,  which is not nice:</p>
<p><a href="http://www.cacheonix.com/blog/wp-content/uploads/2011/06/macbook_taking_disk_space11.jpg"><img class="alignnone size-full wp-image-14" title="Macbook Taking Space on the Table" src="http://www.cacheonix.com/blog/wp-content/uploads/2011/06/macbook_taking_disk_space11.jpg" alt="Macbook Taking Space on the Table" width="400" height="300" /></a></p>
<p>The obvious solution was to set it upright, but how? My requirements  to the solution were: simple; stable; good-looking.  An extensive  research fetched a winner – Power Support’s Docking Stand for MacBook.  This neat device satisfies all my requirements. The assembly includes  pads to prevent scratching. The aluminum color that matches my MacBook’s  body is a nice bonus. $40 price tag is a steal.</p>
<p>Assembly has taken 2 minutes and after getting it all together the  MacBook has practically disappeared from the surface of the desk freeing  about 50 sq. in:</p>
<p><a href="http://www.cacheonix.com/blog/wp-content/uploads/2011/06/macbook_standing_upright1.jpg"><img class="size-full wp-image-13  alignnone" title="Macbook with Docking Stand" src="http://www.cacheonix.com/blog/wp-content/uploads/2011/06/macbook_standing_upright1.jpg" alt="Macbook with Docking Stand" width="400" height="300" /></a></p>
<p>Too bad PowerSupport stopped making those.  <a href="http://www.hengedocks.com/">Henge Docks</a> now makes a more advanced and a bit more expensive model that allows to really dock your Macbook.</p>
<p>Regards,</p>
<p>Slava Imeshev<br />
<a href="http://www.cacheonix.com/products/cacheonix/index.htm" title="Cacheonix: Reliable Distributed Java Cache">Cacheonix: Reliable Distributed Java Cache</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cacheonix.com/blog/2011/06/freeing-desk-space-with-docking-stand/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
