<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DEcGSHg9cCp7ImA9WhRVEUs.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976</id><updated>2012-01-09T19:27:09.668-08:00</updated><category term="Struts" /><category term="TDD" /><category term="Development Best Practice" /><title>Shawn on Java</title><subtitle type="html">Not a blog for those that want a 'High Level' view of technology.  Interesting posts about the finer details of Java in real applications.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://java.shawncrosby.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>32</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ShawnOnJava" /><feedburner:info uri="shawnonjava" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>ShawnOnJava</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry gd:etag="W/&quot;C0UBQXY_fSp7ImA9WhdUFU0.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-7736087137109959169</id><published>2011-10-01T13:34:00.000-07:00</published><updated>2011-10-01T13:34:10.845-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-01T13:34:10.845-07:00</app:edited><title>Double Checking Locks for Singletons</title><content type="html">I'm not going to argue the benefits of factories and singletons in this article. &amp;nbsp;The jury is in on these topics and yes, it makes sense to spend time making boiler plate code in an effort to decouple implementations from your code.&lt;br /&gt;
&lt;br /&gt;
The issue with lazy loading singletons is that there are times when singletons don't behave as you expect and in my experience, this usually indicates that you may not have a singleton after all. &amp;nbsp;Consider the following code:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;public class AFactory&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; private static final Map&amp;lt;TYPE,ISomething&amp;gt; cache =&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;new HashMap&amp;lt;TYPE,ISomething&amp;gt;();&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; public static ISomething getInstance(TYPE type) {&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ISomething ret = cache.get(type);&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if ( ret == null ) {&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = new SimpleSomething();&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cache.put(TYPE,ret);&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The benefits of this pattern are simple. &amp;nbsp;I can now code to the interface instead of the implementation, so if I want to hijack this factory for testing, I can simply add code like:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;public static void setInstance(TYPE type, ISomething imp) {&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; cache.put(type,imp);&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
and then I can put a mock in the cache for testing. &amp;nbsp;Other benefits may be to open a single connection and reuse it over and over again, or whatever.&lt;br /&gt;
&lt;br /&gt;
The problem with this type of pattern is that I can get into a spot where two threads might go looking for an instance of ISomething in the cache at the same time...if no instance is there, then two separate instances can get created and the last one put in the map will be persisted. &amp;nbsp;This can cause unexpected results in some cases...especially if your SimpleSomething instance has some initialization that implements a listener, or registers with a management server or some other magic.&lt;br /&gt;
&lt;br /&gt;
We could avoid this simply by synchronizing the call to getInstance, but this is needless in most cases and will cause the system to slow down as threads have to wait in line to get an instance from your cache.&lt;br /&gt;
&lt;br /&gt;
The solution is somewhere in the middle. &amp;nbsp;I've heard the idea referred to in a couple of ways, but I like to call it a double checking lock. &amp;nbsp;Have a look at the slight modification to the factory method:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;public static ISomething getInstance(TYPE type) {&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;ISomething ret = cache.get(type);&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if ( ret == null ) {&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; synchronized(cache) {&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = cache.get(type);&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if ( ret == null ) {&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ret = new SimpleSomething();&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cache.put(TYPE,ret);&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return ret;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
By adding a synchronized block on a cache miss, and then checking again, this forces threads accessing the factory before the cache is initialized with the implementation you are looking for to synchronize and give the application time to populate the cache. &amp;nbsp;Once it is populated, no synchronization is required since subsequent calls will hit the cache for the implementation.&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-7736087137109959169?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TN2awNs8kj9QYg_yDi3mBm_1pkM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TN2awNs8kj9QYg_yDi3mBm_1pkM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TN2awNs8kj9QYg_yDi3mBm_1pkM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TN2awNs8kj9QYg_yDi3mBm_1pkM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/7736087137109959169/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=7736087137109959169" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/7736087137109959169?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/7736087137109959169?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/BYciQNRmiYY/double-checking-locks-for-singletons.html" title="Double Checking Locks for Singletons" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2011/10/double-checking-locks-for-singletons.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcBQnk_fyp7ImA9Wx5QGUQ.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-7327085050458055895</id><published>2010-09-08T17:26:00.001-07:00</published><updated>2010-09-08T17:27:33.747-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-08T17:27:33.747-07:00</app:edited><title>Java SSL Connections</title><content type="html">&lt;p&gt;A while back I wrote a post on how to use the apache web client to connect to an SSL server without a globally recognized certificate.&amp;nbsp; The easy way is just to import the certificate authority certificate into your cacerts file in $JAVA_HOME/jre/lib/security but in some cases you can’t do this, so I showed how I created a custom socket factory and then registered the socket factory with the Protocol class.&lt;/p&gt; &lt;p&gt;While trying to get an XHTML rendering library to work today, I had an issue with untrusted certificates that I needed to get working, but since the library wasn’t using the apache web client, I was a bit stuck.&amp;nbsp; As it turns out, there is much lower level you can get to to make this work:&lt;/p&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 542px; padding-right: 5px; height: 323px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;TrustManagerFactory tmFactory = &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;InputStream is = ClassLoader.getSystemResourceAsStream("&lt;span style="color: #8b0000"&gt;my.truststore&lt;/span&gt;");&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;trustStore.load(is, "&lt;span style="color: #8b0000"&gt;password&lt;/span&gt;".toCharArray());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;TrustManager[] tm = tmFactory.getTrustManagers();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;KeyManagerFactory kmFactory = &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;KeyStore keyStore = KeyStore.getInstance("&lt;span style="color: #8b0000"&gt;pkcs12&lt;/span&gt;");&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;InputStream kis = ClassLoader.getSystemResourceAsStream("&lt;span style="color: #8b0000"&gt;keystore.p12&lt;/span&gt;");&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;keyStore.load(kis, "&lt;span style="color: #8b0000"&gt;password&lt;/span&gt;".toCharArray());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;KeyManager[] km = kmFactory.getKeyManagers();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;SSLContext sc = SSLContext.getInstance("&lt;span style="color: #8b0000"&gt;TLS&lt;/span&gt;");&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;sc.init(km, tm, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;I like this way a lot better because it uses classes only from the javax.net.ssl package and work perfectly for all java based network connections.&amp;nbsp; All you have to do is create your keystore/truststore files and make them available to this code somewhere in the classpath.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-7327085050458055895?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/XPstNmrqnR6s0AcQePq32ImEfYg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XPstNmrqnR6s0AcQePq32ImEfYg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/XPstNmrqnR6s0AcQePq32ImEfYg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XPstNmrqnR6s0AcQePq32ImEfYg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/7327085050458055895/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=7327085050458055895" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/7327085050458055895?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/7327085050458055895?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/D1vCIwZexkg/java-ssl-connections.html" title="Java SSL Connections" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2010/09/java-ssl-connections.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMNQ3Y8eip7ImA9WxFVGEU.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-1536724236894380885</id><published>2010-06-18T10:51:00.001-07:00</published><updated>2010-06-18T10:51:32.872-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-18T10:51:32.872-07:00</app:edited><title>Mocking Frameworks – Mockito</title><content type="html">&lt;p&gt;In order to do any kind of useful testing, you always have to make the odd Simulator or &lt;a class="zem_slink" title="Mock object" href="http://en.wikipedia.org/wiki/Mock_object" rel="wikipedia"&gt;Mock object&lt;/a&gt; so that you don’t have to worry about the dependencies that are needed by the particular component you are trying to test.&amp;nbsp; As long as you take the time to build your code using best practices, you should be able to put your mock object in place during the test without having to change your code for deployment.&amp;nbsp; I typically use Factory classes to help me do this, but there are other patterns that you can use just as effectively.&amp;nbsp; A good rule of thumb is to always code to the interface and avoid using the ‘new’ keyword for your implementations in classes that you need to test.&amp;nbsp; A simple way to do this might be:&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; Class SomeThing {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; SomeThing() {}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; ISomeThing instance;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; ISomeThing getInstance() {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ( instance == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ) {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;      instance = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SpecificSomeThing();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; instance;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; setInstance(ISomeThing someThing) {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    instance = something;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;When I want to use an instance of ISomeThing, I just call:&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;final&lt;/span&gt; ISomeThing someThing = SomeThing.getInstance();&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Assuming that you are comfortable with this idea, you’ve now decoupled your dependency ISomeThing from your code and now you can test whatever calls an ISomeThing without having to manipulate the world that your dependant ISomeThing lives in…you can simply Mock it.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Lets assume that your ISomeThing looks like this:&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; ISomeThing {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;boolean&lt;/span&gt; isTheAnswer(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; answer);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;To create a Mock implementation of ISomeThing, you could create something like this:&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MockSomeThing &lt;span style="color: #0000ff"&gt;implements&lt;/span&gt; ISomeThing {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;   &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;boolean&lt;/span&gt; isTheAnswer(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; answer) {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;      &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; answer == 64;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;So now before you test, you just make your factory return your Mock object instead of the regular implementation of the object. &lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;SomeThing.setInstance(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MockSomeThing());&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;What will happen is that when your class uses the ISomeThing instance declared in the code by the factory class, it will return true if it is supplied with the input of 64, otherwise it will return false…(hitch-hiker metaphor intended)&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; testMock() {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  SomeThing.setInstance(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MockSomeThing());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; ISomeThing s = SomeThing.getInstance();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  assertTrue(s.isTheAnswer(64));&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  assertFalse(s.isTheAnswer(99));&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;The only issue is that now I have a really useless class in my code base that tells me that 64 is the answer.&amp;nbsp; If I use a mocking framework&amp;nbsp; I could do this without actually creating a mock implementation:&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;import&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; org.mockito.Mockito.*;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; testMock(){&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; ISomeThing s = mock(ISomeThing.&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  when(s.isTheAnswer(64)).thenReturn(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  assertTrue(s.isTheAnswer(64));&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;  assertFalse(s.isTheAnswer(99));&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;This gives me the behavior I need without actually implementing the interface.&amp;nbsp; Clean and simple.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-1536724236894380885?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8QVmttAFPf7EA_DqWNkx9M-Aw30/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8QVmttAFPf7EA_DqWNkx9M-Aw30/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8QVmttAFPf7EA_DqWNkx9M-Aw30/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8QVmttAFPf7EA_DqWNkx9M-Aw30/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/1536724236894380885/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=1536724236894380885" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/1536724236894380885?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/1536724236894380885?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/7Ix3P_utqpY/mocking-frameworks-mockito.html" title="Mocking Frameworks – Mockito" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2010/06/mocking-frameworks-mockito.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUBRH89eCp7ImA9WxFVFkQ.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-2086450857078813732</id><published>2010-06-16T06:50:00.001-07:00</published><updated>2010-06-16T06:50:55.160-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-16T06:50:55.160-07:00</app:edited><title>How to avoid Design – The ‘*.common.util’ package</title><content type="html">&lt;p&gt;I’ve seen a lot of code that makes use of a ‘util’ package; in a limited domain, I guess I don’t really have an issue with this.&amp;nbsp; A utility package would likely contain some static classes that do things like parsing strings, formatting, sorting, certain calculations…the list is endless.&amp;nbsp; There are just some things that need to be static and available and rather than think about design, we pop it into a class called ‘StringFormatUtils’ and pop it into the util package so that we can remember to look for it in six month’s time.&lt;/p&gt; &lt;p&gt;The fatal flaw here is that looking for some obscure little function that worked once among a sea of formatters and parsers is just not going to happen.&amp;nbsp; Instead what is likely to happen is that the next developer that needs the function will create another version of the function and pop it into that or another utility package and eventually you end up with an unmanageable pile of odds and ends in the code base.&lt;/p&gt; &lt;p&gt;Instead, the developer needs to take the time to think about the problem they are trying to solve from an abstract point of view.&amp;nbsp; What is it that you are trying to do? Never mind how you intend to do it.&amp;nbsp; If you are parsing data, think about a parsing architecture, ignore the details initially and then see if you have access to someone else’s wheel that they’ve already invented.&amp;nbsp; Moving from how to what is the way to re-use code.&amp;nbsp; If you need to make your own, then build it in the abstract and put it in its own domain that can be expanded and re-used.&lt;/p&gt; &lt;p&gt;I vote for a complete ban on any package named ‘util’ in favor of software that is written for a specific problem domain.&amp;nbsp; If you have static analysis in your build process, I recommend a rule to root it out and eliminate it…you’ll have cleaner code.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-2086450857078813732?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yNQI11poLjFJ0-TwDfY7oJxp4eE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yNQI11poLjFJ0-TwDfY7oJxp4eE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yNQI11poLjFJ0-TwDfY7oJxp4eE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yNQI11poLjFJ0-TwDfY7oJxp4eE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/2086450857078813732/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=2086450857078813732" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/2086450857078813732?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/2086450857078813732?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/OB7PzXmuNus/how-to-avoid-design-commonutil-package.html" title="How to avoid Design – The ‘*.common.util’ package" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2010/06/how-to-avoid-design-commonutil-package.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cDQH4zeSp7ImA9WxFWFko.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-9150968448021135788</id><published>2010-01-06T11:50:00.001-08:00</published><updated>2010-06-04T12:17:51.081-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-04T12:17:51.081-07:00</app:edited><title>Oracle’s Strange way of Dealing with LOB’s</title><content type="html">&lt;p&gt;A LOB is a database term for a data type that is very big; a Large Object so to speak.&amp;nbsp; There are times when you want to create a record that has one of these LOBs but for some reason, Oracle has some strange limitations when it comes to the size of one of these objects when you ‘insert’ them into the database.&lt;/p&gt; &lt;p&gt;For JDBC calls it looks like there is a max of 4Kbytes.&amp;nbsp; If your insert will never be bigger than this, then stop reading, you’re fine.&amp;nbsp; You can get around this limitation by using PL/SQL (wrap your insert in a BEGIN INSERT…; END;) as long as you don’t need to insert anything greater than 32Kbytes.&lt;/p&gt; &lt;p&gt;If you need to go higher than this, you need to do something a little strange.&lt;/p&gt; &lt;p&gt;Basically you need to insert a blank LOB into the record, then select the record for update and then write your data to the LOB you selected.&amp;nbsp; Here’s how it goes.&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;InputStream is = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ByteArrayInputStream("&lt;span style="color: #8b0000"&gt;hello world&lt;/span&gt;".getBytes());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;PreparedStatement insert = &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;   conn.prepareStatement(&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;      "&lt;span style="color: #8b0000"&gt;INSERT INTO test_table (id, data) values (?, empty_blob())&lt;/span&gt;");&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;insert.setLong(1, 1L);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;insert.execute();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;insert.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;PreparedStatement select = &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;   conn.prepareStatement(&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;      "&lt;span style="color: #8b0000"&gt;SELECT * FROM test_table WHERE id = ? FOR UPDATE&lt;/span&gt;");&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;select.setLong(1, 1L);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;ResultSet rs = select.executeQuery();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;rs.next();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;Blob blob = rs.getBlob("&lt;span style="color: #8b0000"&gt;data&lt;/span&gt;");&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;OutputStream os = blob.setBinaryStream(0L);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[] buf = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[1024];&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; len = 0;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;while&lt;/span&gt; ((len = is.read()) &amp;gt; 0)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	os.write(buf, 0, len);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;is.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;os.flush();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;os.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;select.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Not a whole lot of fun, but it gets the job done.&amp;nbsp; I managed to find a way to get it done in a single statement but it requires PL/SQL&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;InputStream is = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ByteArrayInputStream("&lt;span style="color: #8b0000"&gt;hello world&lt;/span&gt;".getBytes());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;CallableStatement insert = &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;   conn.prepareCall(&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;      "&lt;span style="color: #8b0000"&gt;BEGIN &lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;         INSERT INTO test_table (id, data) values (?, empty_blob()) &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;         RETURNING data INTO ?; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;       END;"&lt;span style="color: #8b0000"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;insert.registerOutParameter(2, Types.BLOB);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;insert.setLong(1, 1L);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;insert.execute();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;Blob blob = insert.getBlob(2);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;OutputStream os = blob.setBinaryStream(0L);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[] buf = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[1024];&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; len = 0;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;while&lt;/span&gt; ((len = is.read()) &amp;gt; 0)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	os.write(buf, 0, len);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;is.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;os.flush();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;os.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;insert.close();&lt;/pre&gt;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-9150968448021135788?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Z4mZLB7EyqgJkdZKhRyE0gcq3e0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Z4mZLB7EyqgJkdZKhRyE0gcq3e0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Z4mZLB7EyqgJkdZKhRyE0gcq3e0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Z4mZLB7EyqgJkdZKhRyE0gcq3e0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/9150968448021135788/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=9150968448021135788" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/9150968448021135788?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/9150968448021135788?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/Nh2EnGaMOmA/oracles-strange-way-of-dealing-with.html" title="Oracle’s Strange way of Dealing with LOB’s" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2010/01/oracles-strange-way-of-dealing-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4CRXsyfCp7ImA9WxNVEk4.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-4835753725469819257</id><published>2009-10-22T10:02:00.001-07:00</published><updated>2009-10-22T10:02:44.594-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-22T10:02:44.594-07:00</app:edited><title>VarArgs in Java 5</title><content type="html">&lt;p&gt;I know this has been around for a while.&amp;#160; I’ve seen it, but didn’t really know what it was.&amp;#160; Turns out its a short hand for using arrays as an argument to a method.&lt;/p&gt;  &lt;p&gt;If you are creating a method that takes variable arguments, it is common to supply the arguments in some sort of array.&amp;#160; Take for instance the MessageFormat type classes:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;MessageFormat.format(String format, Object[] args);&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In order to use this method, the caller would have to make the call something like:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;MessageFormat.format(“Hello {0}, isn’t life {1}”, new Object[]{“world”,”swell”});&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;VarArgs allows you to shorthand this by declaring your method like:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;MessageFormat.format(String format, Object… args);&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Which can then be called like:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;MessageFormat.format(“Hello {0}, isn’t life {1}”, “world”, “swell”);&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The only stipulation is that your vararg argument is the last in the parameter list.&amp;#160; Java then autoboxes your arguments into an Object array for you.&lt;/p&gt;  &lt;p&gt;Nice!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-4835753725469819257?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ro0ZQxxUHOjP9ghQhU87wHh1K24/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ro0ZQxxUHOjP9ghQhU87wHh1K24/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ro0ZQxxUHOjP9ghQhU87wHh1K24/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ro0ZQxxUHOjP9ghQhU87wHh1K24/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/4835753725469819257/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=4835753725469819257" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/4835753725469819257?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/4835753725469819257?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/vkErAi7X5Gc/varargs-in-java-5.html" title="VarArgs in Java 5" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/10/varargs-in-java-5.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYCQn85cSp7ImA9WxFWFkU.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-5692159025986502339</id><published>2009-08-20T03:29:00.001-07:00</published><updated>2010-06-04T12:36:03.129-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-04T12:36:03.129-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="TDD" /><category scheme="http://www.blogger.com/atom/ns#" term="Struts" /><title>Why Test Driven Bug Fixing is Better #tdd #struts</title><content type="html">&lt;p&gt;Its often difficult to convince developers that aren’t doing Test Driven Development (TDD) that its worth the little bit of extra effort to write failing tests first before touching the code.&amp;nbsp; Most times, the dissenters complain about tight timelines and lack of end user benefit to ‘be bothered’ with it.&lt;/p&gt; &lt;p&gt;Although I am relatively new to TDD, I’ve adopted the method in every aspect of code development I can think of…especially bug fixing.&lt;/p&gt; &lt;h4&gt;A Case Study&lt;/h4&gt; &lt;p&gt;This is an actual example where I used TDD to fix a bug (the names have been changed to protect the ..um.. innocent).&lt;/p&gt; &lt;p&gt;QA reports a bug in newly developed software.&amp;nbsp; In this case, the application is a struts web application and there is a radio button on a form that doesn’t have a default set; the analyst believes that it should be set to value ‘x’ by default.&lt;/p&gt; &lt;p&gt;The radio button is backed by a form bean class with the property ‘theRadioOption’ in the class MyFormBean which is scoped to the request for the struts action in question.&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyFormBean &lt;span style="color: #0000ff"&gt;extends&lt;/span&gt; ActionForm&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; string theRadioOption;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; String getTheRadioOption(){&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; theRadioOption;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; setTheRadioOption(String value){&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		theRadioOption = value;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Given this snapshot of information, many experienced struts developers would say “OK, so I’ll go and set the default value in the bean…its one line of code, no need for a test.”&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Before touching the code however, I created a test by extending &lt;a href="http://strutstestcase.sourceforge.net/"&gt;MockStrutsTestCase&lt;/a&gt; and coded a very simple test:&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; FormActionTest &lt;span style="color: #0000ff"&gt;extends&lt;/span&gt; MockStrutsTestCase&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; testFormDefaults()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		setRequestPathInfo("&lt;span style="color: #8b0000"&gt;/GetForm.do&lt;/span&gt;");&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		actionPerform();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		&lt;span style="color: #0000ff"&gt;final&lt;/span&gt; MyFormBean form = (MyFormBean) getActionForm();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;		assertEquals("&lt;span style="color: #8b0000"&gt;Wrong Default&lt;/span&gt;","&lt;span style="color: #8b0000"&gt;x&lt;/span&gt;", form.getTheRadioOption());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Running the test, of course, it fails…perfect…now to fix the code.&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; string theRadioOption = "&lt;span style="color: #8b0000"&gt;x&lt;/span&gt;";&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;There, that was easy, now before we build the application and deploy the thing, I run the test again to see if it indeed passes.&amp;nbsp; Surprisingly, it fails…so much for my “one line of code.”&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Upon further examination, I looked in the action class that forwards to the web page.&amp;nbsp; What I found was that the developer that made the form was explicitly clearing the values in the form by setting the property to null.&amp;nbsp; My little ‘fix’ wasn’t seeing the light of day because the action was ‘undoing’ my default.&lt;/p&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ActionForward execute(ActionMapping mapping, ActionForm form, ...etc){&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;final&lt;/span&gt; MyActionform myForm = (MyActionForm) form;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	form.setTheRadioOption(&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;	&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; mapping.findForward("&lt;span style="color: #8b0000"&gt;SHOWFORM&lt;/span&gt;");&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;The real fix is to get rid of the explicit set to null in the action class or set it to the desired default instead of null.&amp;nbsp; After setting the default in the action and running my test again I can then see that the test passes.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This test becomes part of the project now and is run during the build process every night…the issue will never return undetected.&amp;nbsp; How much time did I save here?&amp;nbsp; Developer builds and deploys only once instead of two or three times, QA didn’t have to re-open the bug and therefore test the feature three times instead of two, the next developer didn’t have to ask “what should this be set to by default anyway” since it is well documented in the test.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;My question is how can you justify NOT putting in the little extra effort to do Test Driven Bug Fixing?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-5692159025986502339?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kBwrYlExt7e9EkTb2y0c7TacUjw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kBwrYlExt7e9EkTb2y0c7TacUjw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kBwrYlExt7e9EkTb2y0c7TacUjw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kBwrYlExt7e9EkTb2y0c7TacUjw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/5692159025986502339/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=5692159025986502339" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/5692159025986502339?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/5692159025986502339?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/_5jHoTCVdAI/why-test-driven-bug-fixing-is-better.html" title="Why Test Driven Bug Fixing is Better #tdd #struts" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/08/why-test-driven-bug-fixing-is-better.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8HRXk7cCp7ImA9WxJaFko.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-98891255451360691</id><published>2009-08-07T12:53:00.001-07:00</published><updated>2009-08-07T12:53:54.708-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-07T12:53:54.708-07:00</app:edited><title>The Puf Principle: Online burndown chart generator</title><content type="html">&lt;p&gt;Simple but handy… this little script creates a burndown chart for your sprint. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://frank.vanpuffelen.net/2007/08/online-burndown-chart-generator.html"&gt;The Puf Principle: Online burndown chart generator&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-98891255451360691?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-qyxzJAi5pOm4mvj1UXx21aAnnk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-qyxzJAi5pOm4mvj1UXx21aAnnk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-qyxzJAi5pOm4mvj1UXx21aAnnk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-qyxzJAi5pOm4mvj1UXx21aAnnk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/98891255451360691/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=98891255451360691" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/98891255451360691?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/98891255451360691?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/ij6YaCcyRfo/puf-principle-online-burndown-chart.html" title="The Puf Principle: Online burndown chart generator" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/08/puf-principle-online-burndown-chart.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IDQXk9fSp7ImA9WxJaGUw.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-2698360396664798634</id><published>2009-08-06T03:43:00.001-07:00</published><updated>2009-08-10T06:39:30.765-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-10T06:39:30.765-07:00</app:edited><title>Tiles Enabling your Struts Project</title><content type="html">&lt;p&gt;Tiles is a tag library framework that allows you to create templates for your JSP pages and greatly simplifies the creation of Web front ends and overall maintainability of the view layer in a JEE project.&lt;/p&gt;  &lt;p&gt;Tiles is an Apache project, not a struts project, so it can be used with other frameworks as well.&amp;#160; Our project is based on Struts so I’ll limit my post to how we integrate tiles with struts.&amp;#160; If you want more information, I encourage you to check out the &lt;a href="http://tiles.apache.org/"&gt;project website&lt;/a&gt; at the apache foundation where you can download the library, see examples and read documentation to your hearts content.&lt;/p&gt;  &lt;p&gt;There are a number of ways to use tiles, we typically use a separate tiles definition xml file to define our screens and use the Tiles Plug-in in the struts-config file.&lt;/p&gt;  &lt;p&gt;Struts comes bundled with Tiles, so if you are using struts, you already have what you need to get started.&lt;/p&gt;  &lt;h4&gt;The Request Processor&lt;/h4&gt;  &lt;p&gt;Since tiles basically intercepts forward processing in struts, you have to use an extension of the struts request processor class that handles this.&amp;#160; This is easy to do in your struts configuration file:&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 686px; padding-right: 5px; height: 149px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;?&lt;/span&gt;xml version=&amp;quot;1.0&amp;quot;&lt;span style="color: #0000ff"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;struts&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;config&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  ...&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;controller&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;      &lt;span style="color: #ff0000"&gt;processorClass&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;org.apache.struts.tiles.TilesRequestProcessor&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  ...&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;struts&lt;/span&gt;-config&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This request processor class deals with parsing the tiles configuration and putting all the pieces together, it intercepts the ‘findForward’ method to see if the forward is a tile definition or if it is just a regular forward.&amp;#160; You can mix tiles with simple forwards in the same implementation of struts, for instance &lt;em&gt;&amp;lt;forward name=”success” path=”/WEB-INF/jsp/SuccessPage.jsp” /&amp;gt;&lt;/em&gt; and &lt;em&gt;&amp;lt;forward name=”failure” path=”MyFailureTileDef” /&amp;gt;&lt;/em&gt; works just fine.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;The Plug-in&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The other part to configure in struts-config.xml is the Tiles plug-in which basically allows you to configure tiles for each struts module and initializes the factory for the module. &lt;br /&gt;  &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;?&lt;/span&gt;xml version=&amp;quot;1.0&amp;quot;&lt;span style="color: #0000ff"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;struts&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;config&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  ...&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;plug&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;in&lt;/span&gt; &lt;span style="color: #ff0000"&gt;className&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;org.apache.struts.tiles.TilesPlugin&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;set&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;property&lt;/span&gt; &lt;span style="color: #ff0000"&gt;property&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;definitions-config&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/WEB-INF/tiles-defs.xml&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;plug&lt;/span&gt;-in&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  ...&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;struts&lt;/span&gt;-config&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This is where you can set some of the properties of the tiles request processor.&amp;#160; Once you have this in place, you’re all set to begin creating tiles.&amp;#160; In this example, I set the location of the tiles definition file that I want to use in this module.&amp;#160; Since this is the default location, it isn’t required, but in case you want to use a different file, or more likely, multiple definition files, this is how you do it. (comma separate multiple file names).&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;The Template&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Tiles is based on JSP files that are put together at run time.&amp;#160; Note that I said JSP files and not JSPF files.&amp;#160; I had some trouble initially when I tried using tiles, thinking it would be good to call the template files JSP files and the pieces would be JSPF…this didn’t work and switched to using JSP for everything and just organized using folders.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Every tile has a template file, the template then uses the tiles tag library to insert page components using the configuration file which we’ll discuss shortly.&amp;#160; Here is a simple template:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;%@ page %&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;%@ taglib uri=&amp;quot;/WEB-INF/struts-tiles.tld&amp;quot; prefix=&amp;quot;tiles&amp;quot; %&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Simple Tile&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  Page Header&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;hr&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;tiles&lt;/span&gt;:&lt;span style="color: #800000"&gt;insert&lt;/span&gt; &lt;span style="color: #ff0000"&gt;attribute&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;body&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;hr&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  Page Footer&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;as you can see, the template just defines a nice little placeholder for an attribute called ‘body’ which is referenced from the configuration file.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;The Configuration File&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;A simple tiles definition looks something like this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;?&lt;/span&gt;xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;windows-1252&amp;quot; &lt;span style="color: #0000ff"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;!DOCTYPE tiles-definitions PUBLIC &amp;quot;-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN&amp;quot; &amp;quot;http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd&amp;quot;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;tiles&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;definitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;definition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;simpletile&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;page&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/WEB-INF/jsp/layout.jsp&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;put&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;body&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/WEB-INF/jsp/Simple.jsp&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;definition&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;tiles&lt;/span&gt;-definitions&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This simple definition takes your layout.jsp file and inserts a small Simple.jsp in the body marker.&amp;#160; This file isn’t a complete HTML page, in fact it is likely just a table or a paragraph or something that gets inserted in.&amp;#160; It makes life a whole lot easier when you want to change the navigation menu, or the header or something, you don’t have to change every file…just the layout file.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Where the definitions get interesting though is if you have a hierarchy of page ‘types’ that you want to configure, consider this definition file:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;?&lt;/span&gt;xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;windows-1252&amp;quot; &lt;span style="color: #0000ff"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;!DOCTYPE tiles-definitions PUBLIC &amp;quot;-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN&amp;quot; &amp;quot;http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd&amp;quot;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;tiles&lt;/span&gt;-&lt;span style="color: #ff0000"&gt;definitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;definition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;BaseDef&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;path&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/WEB-INF/jsp/layout.jsp&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;put&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;header&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/WEB-INF/jsp/PageHeader.jsp&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;put&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;footer&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/WEB-INF/jsp/PageFooter.jsp&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;put&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;menu&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/WEB-INF/jsp/Blank.jsp&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;put&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;body&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/WEB-INF/jsp/Blank.jsp&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;definition&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;definition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;ClientPage&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;extends&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;BaseDef&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;put&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;menu&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/WEB-INF/jsp/ClientMenu.jsp&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;definition&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;definition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;SupplierPage&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;extends&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;BaseDef&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;put&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;menu&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/WEB-INF/jsp/SupplierMenu.jsp&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;definition&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;definition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;ClientOrderForm&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;extends&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;ClientPage&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;put&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;body&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/WEB-INF/jsp/OrderForm.jsp&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;definition&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;tiles&lt;/span&gt;-definitions&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This definition takes the basic page layout that is common to all pages in the “BaseDef” definition and puts in the header and footer components, presumably, the layout.jsp in this definition has an insert for “header”, “footer”, “menu” and “body” such as:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;%@ page %&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;%@ taglib uri=&amp;quot;/WEB-INF/struts-tiles.tld&amp;quot; prefix=&amp;quot;tiles&amp;quot; %&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;My WebSite&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;tiles&lt;/span&gt;:&lt;span style="color: #800000"&gt;insert&lt;/span&gt; &lt;span style="color: #ff0000"&gt;attribute&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;header&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;tiles&lt;/span&gt;:&lt;span style="color: #800000"&gt;insert&lt;/span&gt; &lt;span style="color: #ff0000"&gt;attribute&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;menu&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;tiles&lt;/span&gt;:&lt;span style="color: #800000"&gt;insert&lt;/span&gt; &lt;span style="color: #ff0000"&gt;attribute&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;body&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;tiles&lt;/span&gt;:&lt;span style="color: #800000"&gt;insert&lt;/span&gt; &lt;span style="color: #ff0000"&gt;attribute&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;footer&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;html&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Once I have all the high level parts such as the menu, header and footer coded, if I want to add an order form, I simply create a definition that extends the high level page type and then insert my body using the &amp;lt;put&amp;gt; element.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Conclusion&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;There are lots of ways to use tiles, this is just they way that I have always used it.&amp;#160; It provides me with a mechanism to quickly generate the view layer and easily maintain the look and feel of my entire application by reducing all of the html overhead to one layout page and simple component pages that I can easily change when needed.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Newer versions of tiles are available and all work basically the same way, but I know that some of the architecture has changed over several iterations.&amp;#160; If you know of newer, better ways to use tiles, I invite you to comment and share.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-2698360396664798634?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/iOTTjxMD02X9Nz_lWE1XHIuUpIc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iOTTjxMD02X9Nz_lWE1XHIuUpIc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/iOTTjxMD02X9Nz_lWE1XHIuUpIc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iOTTjxMD02X9Nz_lWE1XHIuUpIc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/2698360396664798634/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=2698360396664798634" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/2698360396664798634?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/2698360396664798634?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/mw5eRBFzfNs/tiles-enabling-your-struts-project.html" title="Tiles Enabling your Struts Project" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/08/tiles-enabling-your-struts-project.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYGQ3c4eSp7ImA9WxJUGEk.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-6339035909686933377</id><published>2009-07-16T13:10:00.001-07:00</published><updated>2009-07-17T08:05:22.931-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-17T08:05:22.931-07:00</app:edited><title>Getting Started with MockEJB</title><content type="html">&lt;p&gt;I spent a little time recently trying to get a lightweight framework for some basic EJB unit testing with the goal in mind to reduce the number of times that I had to deploy to the application server to test new code.&amp;#160; I had been using MockRunner for a while to test tag classes, so I thought I would try to use the EJB component which uses MockEJB as a base for testing.&lt;/p&gt;  &lt;p&gt;The hardest part of the whole thing was really figuring out how to get the finders to work, but as usual, I was likely making it a bit harder than I had to, this is how I did it.&lt;/p&gt;  &lt;h4&gt;MyEJBTestCaseAdapter&lt;/h4&gt;  &lt;p&gt;MockRunner provides a base class for doing an EJB Test Case called EJBTestCaseAdapter, the setUp() method does pretty much everything to do with setting up your context and creating the basic environment, all you have to do is deploy your EJB classes.&amp;#160; The base class has methods for deploying both entity and session interfaces, but I found that the deploy(BasicEjbDescriptor) method worked best for me, giving me the flexibility to deploy local and remote interfaces from multiple packages.&amp;#160; The deploySession and deployEntity methods the the MockRunner class just provide a wrapper for the deploy method to reduce some of the complexity.&amp;#160; So as long as you don’t have a complicated project, they should work fine for you.&lt;/p&gt;  &lt;p&gt;I extended this test case adapter class to make my life a little easier and implemented my own deploy methods since my entity and session classes are in different packages.&amp;#160; This just makes life a little easier because now I just have to use deployMyEntity(“Tblwhatever”):&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  1: &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; deployMyEntity(String name) &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; Exception&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  2: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  3:     &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String interfaceName = &amp;quot;&lt;span style="color: #8b0000"&gt;my.entity.package.&lt;/span&gt;&amp;quot; + name;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  4:     ejbModule.deploy( &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EntityBeanDescriptor(&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  5:         &amp;quot;&lt;span style="color: #8b0000"&gt;java:comp/env/ejb/local/&lt;/span&gt;&amp;quot; + name,&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  6:         Class.forName(interfaceName + &amp;quot;&lt;span style="color: #8b0000"&gt;LocalHome&lt;/span&gt;&amp;quot;),&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  7:         Class.forName(interfaceName + &amp;quot;&lt;span style="color: #8b0000"&gt;Local&lt;/span&gt;&amp;quot;),&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  8:         Class.forName(interfaceName + &amp;quot;&lt;span style="color: #8b0000"&gt;Bean&lt;/span&gt;&amp;quot;)));&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  9: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Sessions are a little bit more complicated because our naming convention for Remote and Local Interfaces are a bit different:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  1: &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; deployMySession(String name, &lt;span style="color: #0000ff"&gt;boolean&lt;/span&gt; local) &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; Exception&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  2: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  3:     &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String myPackage = &amp;quot;&lt;span style="color: #8b0000"&gt;my.session.package.&lt;/span&gt;&amp;quot;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  4:     &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String interfaceName = myPackage + name;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  5:     &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String jndiName = name;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  6:         &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  7:     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ( local )&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  8:     {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  9:         jndiName = &amp;quot;&lt;span style="color: #8b0000"&gt;java:comp/env/ejb/local/&lt;/span&gt;&amp;quot; + name;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 10:         interfaceName = interfaceName + &amp;quot;&lt;span style="color: #8b0000"&gt;Local&lt;/span&gt;&amp;quot;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 11:     }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 12:       &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 13:     ejbModule.deploy( &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SessionBeanDescriptor(&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 14:         jndiName,&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 15:         Class.forName(interfaceName + &amp;quot;&lt;span style="color: #8b0000"&gt;Home&lt;/span&gt;&amp;quot;),&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 16:         Class.forName(interfaceName),&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 17:         Class.forName(myPackage + name + &amp;quot;&lt;span style="color: #8b0000"&gt;Bean&lt;/span&gt;&amp;quot;)), TransactionPolicy.REQUIRED);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 18: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Both of these classes make reference to an ejbModule which are provided by a method in the EJBTestCase Adapter.&amp;#160; I set this up in my setUp() method:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  1: &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; EJBTestModule ejbModule;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  2: &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; JDBCTestModule jdbcModule;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  3: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  4: @Override&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  5: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; setUp() &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; Exception&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  6: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  7:     &lt;span style="color: #0000ff"&gt;super&lt;/span&gt;.setUp();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  8:         &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  9:     jdbcModule = createJDBCTestModule();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 10:     ejbModule = createEJBTestModule();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; height: 15px; font-size: 12px"&gt; 11:     ejbModule.bindToContext(&amp;quot;&lt;span style="color: #8b0000"&gt;jdbc/MyDS&lt;/span&gt;&amp;quot;, &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 12:         getJDBCMockObjectFactory().getMockDataSource());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 13: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Creating a Test&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;My TestCase simply extends this class where I deploy the sessions and entities that I will need during my test.&amp;#160; For simplicity, I have a simple entity that has an id field that I want to update&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  1: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyTest &lt;span style="color: #0000ff"&gt;extends&lt;/span&gt; MyEJBTestCaseAdapter&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  2: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  3:   @Override&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  4:   &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; setUp() &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; Exception&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  5:   {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  6:     &lt;span style="color: #0000ff"&gt;super&lt;/span&gt;.setUp();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  7: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  8:     deployMySession(&amp;quot;&lt;span style="color: #8b0000"&gt;MySessionEJB&lt;/span&gt;&amp;quot;, &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  9:     deployMyEntity(&amp;quot;&lt;span style="color: #8b0000"&gt;Tblsomething&lt;/span&gt;&amp;quot;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 10:   }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 11: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 12:   &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; testSomething() &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; Exception&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 13:   {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 14:     &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; MySessionEJB session = EjbHomeFactory.lookup(&amp;quot;&lt;span style="color: #8b0000"&gt;MySessionEJB&lt;/span&gt;&amp;quot;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 15:     session.updateSomething(1L);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 16: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 17:     &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; Tblsomething t = findByPrimaryKey(1L);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 18:     assertEquals(1L, t.getId());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 19:   }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 20: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Dealing with Aspects&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Assuming that your session just creates the Tblsomething entity, you likely will not have a problem running this test.&amp;#160; But if you are looking up an entity, you will have to implement an Aspect that will intercept your finder and return something for you to play with.&amp;#160; Here is a simple Aspect that intercepts a findByPrimaryKey method and returns a new entity that is probably suitable for a simple test:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  1: &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; FinderHandler &lt;span style="color: #0000ff"&gt;implements&lt;/span&gt; Aspect&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  2: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  3:     FinderHandler(String entity, String finderMethod, Object[] createParams, Object pk)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  4:     {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  5: 	targetEntity = entity;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  6: 	targetFinder = finderMethod;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  7: 	entityToReturn = &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  8:           createEntityBean(&amp;quot;&lt;span style="color: #8b0000"&gt;java:comp/env/ejb/local/&lt;/span&gt;&amp;quot; + entity, &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  9:              createParams, pk);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 10:     }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 11: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 12:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String targetEntity;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 13:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String targetFinder;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 14:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; Object entityToReturn;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 15: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 16:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Pointcut getPointcut()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 17:     {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 18: 	&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MethodPatternPointcut(&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 19:                targetEntity + &amp;quot;&lt;span style="color: #8b0000"&gt;.*&lt;/span&gt;&amp;quot; + targetFinder);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 20:     }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 21: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 22:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; intercept(InvocationContext invocationContext)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 23:     {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 24: 	invocationContext.setReturnObject(entityToReturn);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 25:     }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 26: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This aspect class will basically create an entity that you define using the parameters of your create method as an Object[].&amp;#160; The EJBTestCaseAdapter class provides this handy utility for creating an entity by looking up the class and using Reflection to find the create method and invoking it and then persisting the entity in an in memory data source that can then be retrieved using the findByPrimaryKey(Object) method in your test case.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Conclusion&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Obviously, this kind of test does nothing to attempt to test the actual EJB platform with all of its intricate dependencies and configurations, but it does allow a developer to execute EJB code on their development workstations and apply TDD principles when developing EJB code.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-6339035909686933377?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ujra9kFF27BPafBHa8HI-uWejY4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ujra9kFF27BPafBHa8HI-uWejY4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ujra9kFF27BPafBHa8HI-uWejY4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ujra9kFF27BPafBHa8HI-uWejY4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/6339035909686933377/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=6339035909686933377" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/6339035909686933377?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/6339035909686933377?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/jW8XMo7Wbfs/getting-started-with-mockejb.html" title="Getting Started with MockEJB" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/07/getting-started-with-mockejb.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUNRXs9fCp7ImA9WxJUEUg.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-5225436076239489097</id><published>2009-07-09T07:55:00.001-07:00</published><updated>2009-07-09T08:11:34.564-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-09T08:11:34.564-07:00</app:edited><title>Creating Testable Web UI Components</title><content type="html">&lt;p&gt;Until recently, I always thought that the only way to test the UI components in an application was to create an end-to-end test using some kind of robot user.&amp;#160; The reason being is that much of the UI is created using JSP pages or custom tags…these are sometimes hard to run separately outside the application, so we’ve created tests for them before but running front end tests and hoping for good results.&lt;/p&gt;  &lt;p&gt;Since this is painful to do any detailed testing on, we generally resort to good old human testing in our QA department to make sure that the UI comes out right…obviously a bad practice.&lt;/p&gt;  &lt;p&gt;This article goes through a case study on how to create a testable UI component using a custom tag and shows the various tests I use to validate the code.&lt;/p&gt;  &lt;h2&gt;The Tag Class&lt;/h2&gt;  &lt;p&gt;If you look at some of my old code for tag classes, you end up with some very complicated presentation logic to try and follow.&amp;#160; My thought on this at the time was to put the complicated logic in a tag class instead of using struts logic tags and scriptlets in my JSP page.&amp;#160; Although using a tag class is preferred to this, I now view my tag class as simply being the ‘glue’ between the data that I am trying to present and how it is presented.&lt;/p&gt;  &lt;p&gt;What I mean by this is that, the tag class should really be used for getting a reference to the data that you want to display and passing it to the components which render the output and then passing that output to the browser.&amp;#160; The actual tag reference is just a place holder to get that output in the right spot on the page.&amp;#160; This model makes for cleaner, easily testable code.&amp;#160; When you want to test the functionality of a tag class, you simply need to write a test that validates that when you pass a reference to the tag, it can find the data it needs and render an output, you don’t have to try and test all of the possible output issues involved.&lt;/p&gt;  &lt;h2&gt;The Renderer&lt;/h2&gt;  &lt;p&gt;Our application uses Struts, so a renderer is not technically part of the framework at this point as it is in say JSF.&amp;#160; The concept is that of a component that can convert a data structure into some form of visual representation, as in say HTML.&amp;#160; I use the term ‘renderer’ to refer to any software component that does this type of translation.&lt;/p&gt;  &lt;p&gt;I usually start with a renderer interface since it is likely that I may need to render this component in one of many ways.&amp;#160;&amp;#160; I pass off the responsibility of selecting the appropriate renderer to the tag class this way I can make configurable outputs.&amp;#160; The renderer is specific enough to be able to perform simple presentation logic, this makes the testing of a renderer component fairly straight forward.&lt;/p&gt;  &lt;p&gt;Consider this interface:&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  1: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; ClientRenderer&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  2: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  3:     String output(Client client);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  4: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;I love using interfaces in this case because I don’t have to worry about what my output will look like to get it all wired together.&amp;#160; I can make a very simple implementation that will just output the clients name for starters&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  1: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SimpleClientRenderer&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  2: 	&lt;span style="color: #0000ff"&gt;implements&lt;/span&gt; ClientRenderer&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  3: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  4: 	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; String output(Client client)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  5: 	{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  6: 		&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; client.getOrganizationName();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  7: 	}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  8: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;A test for this class is very simple to do and doesn’t require that you use a whole bunch of mock framework classes:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  1: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SimpleClientRendererTest&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  2: 	&lt;span style="color: #0000ff"&gt;extends&lt;/span&gt; TestCase&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  3: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  4: 	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; testOutput() &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; Exception&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  5: 	{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  6: 		&lt;span style="color: #0000ff"&gt;final&lt;/span&gt; Client cl = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Client();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  7: 		cl.setOraganizationName(&amp;quot;&lt;span style="color: #8b0000"&gt;testme&lt;/span&gt;&amp;quot;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  8: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  9: 		&lt;span style="color: #0000ff"&gt;final&lt;/span&gt; ClientRenderer r = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SimpleClientRenderer();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 10: 		&lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String out = r.output(cl);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 11: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 12: 		assertEquals(&amp;quot;&lt;span style="color: #8b0000"&gt;Unexpected Output&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;testme&lt;/span&gt;&amp;quot;, out);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 13: 	}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 14: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Obviously, this is a very simple example that would likely be handled with a bean:write tag, but the idea is that this renderer class doesn’t have any framework dependencies to test.&amp;#160; It is simply a class that outputs in a predictable (and therefore testable) manner.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Testing the Tag Class&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;JSP Tag classes run within a framework and require references to a pageContext, a request and a response.&amp;#160; I use MockRunner for testing tag classes since they can run within the context of my build server and don’t have to be deployed anywhere.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Since I’ve already tested the fact that my client will render the correct way, all I need to test now is that I can get the correct reference to my renderer.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  1: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ClientOutputTag&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  2: 	&lt;span style="color: #0000ff"&gt;extends&lt;/span&gt; TagSupport&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  3: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  4: 	&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Client clientRef;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  5: 	&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; String attribute;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  6: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  7: 	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; doStartTag() &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; JspException&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  8: 	{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  9: 		... &lt;span style="color: #008000"&gt;// get client ref from whereever&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 10: 	}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 11: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 12: 	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; doEndTag() &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; JspException&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 13: 	{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 14: 		&lt;span style="color: #0000ff"&gt;final&lt;/span&gt; ClientRenderer r = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SimpleClientRenderer();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 15: 		&lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String out = r.output(clientRef);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 16: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 17: 		&lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 18: 		{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 19: 			pageContext.getOut().write(out);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 20: 		}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 21: 		&lt;span style="color: #0000ff"&gt;catch&lt;/span&gt;(IOException e)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 22: 		{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 23: 			&lt;span style="color: #008000"&gt;// error&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 24: 		}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 25: 	}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 26: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 27: 	... &lt;span style="color: #008000"&gt;// req'd accessors&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 28: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;As you can see by this implementation, the tag class is responsible only for getting the reference and calling the renderer, you test would look something like:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  1: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ClientOutputTagTest&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  2: 	&lt;span style="color: #0000ff"&gt;extends&lt;/span&gt; BasicTagTestCaseAdapter&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  3: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  4: 	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; testTag() &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; Exception&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  5: 	{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  6: 		&lt;span style="color: #0000ff"&gt;final&lt;/span&gt; Client cl = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Client();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  7: 		cl.setOrganization(&amp;quot;&lt;span style="color: #8b0000"&gt;testme&lt;/span&gt;&amp;quot;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  8: 		&lt;span style="color: #0000ff"&gt;final&lt;/span&gt; ClientOutputTag tag = &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  9: 			(ClientOutputTag) createTag(ClientOutputTag.&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 10: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 11: 		tag.setAttribute(&amp;quot;&lt;span style="color: #8b0000"&gt;client&lt;/span&gt;&amp;quot;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 12: 		setRequestAttribute(&amp;quot;&lt;span style="color: #8b0000"&gt;client&lt;/span&gt;&amp;quot;, cl);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 13: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 14: 		tag.doStartTag();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 15: 		tag.doEndTag();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 16: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 17: 		&lt;span style="color: #0000ff"&gt;final&lt;/span&gt; String out = getOutput();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 18: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 19: 		assertEquals(&amp;quot;&lt;span style="color: #8b0000"&gt;Unexpected Output&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;testme&lt;/span&gt;&amp;quot;, out);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 20: 	}&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt; 21: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This is a simple example, so there isn’t much to test here.&amp;#160; I may want to test to make sure that if I’m outputting html, that it will be valid or something like that; I would use a sax parser for that.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-5225436076239489097?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FGDEr-axfs-htDvJXBU6WAkGVPU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FGDEr-axfs-htDvJXBU6WAkGVPU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FGDEr-axfs-htDvJXBU6WAkGVPU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FGDEr-axfs-htDvJXBU6WAkGVPU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/5225436076239489097/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=5225436076239489097" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/5225436076239489097?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/5225436076239489097?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/3ktrXwOQdJQ/creating-testable-web-ui-components.html" title="Creating Testable Web UI Components" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/07/creating-testable-web-ui-components.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEMRnc9cCp7ImA9WxJUEEk.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-1615758519149706331</id><published>2009-07-08T03:23:00.001-07:00</published><updated>2009-07-08T03:24:47.968-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-08T03:24:47.968-07:00</app:edited><title>Why are We Embarrassed to Admit That We Don’t Know How to Write Tests? | Javalobby</title><content type="html">&lt;p&gt;I found this excellent article today on writing testable code.&amp;#160; I find one of the big problems in our organization is that we know we need to test code, and it sounds like a simple thing to do, but it is difficult thing to get your head around.&lt;/p&gt;  &lt;p&gt;This article talks about making your code testable.&amp;#160; It is important to differentiate between writing unit tests and writing end-to-end tests.&amp;#160; An end to end test is a test that acts like the user for your application, and it is good for finding wiring bugs.&amp;#160; Unit tests on the other hand, handle much simpler form of bug and a more common form of bug.&lt;/p&gt;  &lt;p&gt;I recommend this article for all developers were not currently writing unit tests for all of their code.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://java.dzone.com/articles/why-are-we-embarrassed-admit"&gt;Why are We Embarrassed to Admit That We Don’t Know How to Write Tests? | Javalobby&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-1615758519149706331?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kttYI_fMKAIT6Aq2PSOfksxfXEc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kttYI_fMKAIT6Aq2PSOfksxfXEc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kttYI_fMKAIT6Aq2PSOfksxfXEc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kttYI_fMKAIT6Aq2PSOfksxfXEc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/1615758519149706331/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=1615758519149706331" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/1615758519149706331?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/1615758519149706331?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/2H5-InR_s5M/why-are-we-embarrassed-to-admit-that-we.html" title="Why are We Embarrassed to Admit That We Don’t Know How to Write Tests? | Javalobby" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/07/why-are-we-embarrassed-to-admit-that-we.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08HQX89fCp7ImA9WxJXFUo.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-6983602544260604851</id><published>2009-06-09T12:30:00.001-07:00</published><updated>2009-06-09T12:30:30.164-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-09T12:30:30.164-07:00</app:edited><title>Updating the User Interface</title><content type="html">&lt;p&gt;As a java developer, I’ve found the best way to actually create software is to create functionality from the software point of view.&amp;#160; Too often, I see software that has been built from the User Interface perspective which creates a dependency on the UI for the software.&amp;#160; Dependency on the UI is generally a bad thing because it makes it hard to test, hard to change and generally hard to understand.&lt;/p&gt;  &lt;p&gt;I’ve made it a rule of mine to build software that does not depend on whether it is a web application, swing application, javafx application or any other environment specific application.&amp;#160; I also try to even limit my software’s dependency on where the model is stored.&amp;#160; I do this generally by creating an interface and more than likely a factory class to hide the implementation.&amp;#160; This way, I can code my software to utilize the interface through the controller, rather than starting with a specific implementation that will manipulate my software component and inevitably lock me into using the implementation forevermore.&lt;/p&gt;  &lt;p&gt;Lets say for example that I have a software component that has a counter in it.&amp;#160; I know that I want the counter displayed to the user, but I’m not sure how yet.&amp;#160; I also want to stick to my rule about not depending on any specific display implementation.&amp;#160; If I follow the herd on this one, its likely that I would get a handle on my HttpServletRequest object, get the count and set it as an attribute and then create a tag to show it as an HTML element.&amp;#160; Personally, I’ve done this hundreds of times…the struts action get the count from the counter and puts it in the request or session.&lt;/p&gt;  &lt;p&gt;But then what happens if I want to run my software in JavaFX?&amp;#160; I have to change the way my software works, which means that if I want to stay compatible with my current solution, I need to add a bunch of logic that says “If we are running in JavaFX do this…otherwise, do that.”&amp;#160; This idea is really fragile and likely to be riddled with defects.&amp;#160; Worse than that, I may re-implement the logic to run on another platform…this creates serious maintenance issues.&lt;/p&gt;  &lt;p&gt;In another approach, lets say that I want my software to just update an appropriate display.&amp;#160; My software doesn’t need to know about what kind of display it is, so I just add a bit of abstraction to my code that allows me to decide later how I want my display updated and then carry on writing my counter code.&amp;#160; To do that, I create an interface:&lt;/p&gt;  &lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  1: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; CounterDisplay&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  2: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  3:    &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; updateDisplay(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; value);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  4: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;OK.&amp;#160; That was easy, now I may use a factory to give this Little piece to my counter software, or I may just hard code it depending on how flexible I need to be.&amp;#160; The main thing is, that my software just knows that there is a counter display to deal with…it might be a JOptionPane message box, a JSF page or a JavaFX Scene.&amp;#160; How we update the display isn’t important to the software component.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  1: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; incrementCounter(CounterDisplay display)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  2: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  3:   counter++;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  4:   display.updateDisplay(counter);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  5: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In a struts application, I may have my CounterDisplay as an action form.&amp;#160; In this case, I could simply implement my CounterDisplay interface on the action form and then allow struts to do its thing:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  1: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyForm &lt;span style="color: #0000ff"&gt;extends&lt;/span&gt; ActionForm &lt;span style="color: #0000ff"&gt;implements&lt;/span&gt; CounterDisplay&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  2: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  3:    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; counter;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  4:    ...&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  5:    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; getCounter()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  6:    {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  7:       &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; counter;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  8:    }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  9: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 10:    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; updateDisplay(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; value)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 11:    {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 12:       counter = value;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 13:    }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 14: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This way, we separate the UI from the software and we can implement it anywhere.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-6983602544260604851?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GY33Cz_6Pm6EQUugOHEPB0sxAIo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GY33Cz_6Pm6EQUugOHEPB0sxAIo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GY33Cz_6Pm6EQUugOHEPB0sxAIo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GY33Cz_6Pm6EQUugOHEPB0sxAIo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/6983602544260604851/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=6983602544260604851" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/6983602544260604851?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/6983602544260604851?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/8FWhk73xO_M/updating-user-interface.html" title="Updating the User Interface" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/06/updating-user-interface.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQNRng8cCp7ImA9WxJQFUk.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-5904448323868954569</id><published>2009-05-28T11:28:00.001-07:00</published><updated>2009-05-28T15:06:37.678-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-28T15:06:37.678-07:00</app:edited><title>Creating a Custom Client Server Application in JAVA</title><content type="html">&lt;p&gt;I recently had a need to do something a little different from my usual J2EE thing that required me to do a little local networking directly between two clients.&amp;#160; I needed to split a task between two users without creating a bunch of infrastructure.&lt;/p&gt;  &lt;p&gt;Since the task was a data entry task, we were using an applet to get some data from a web service, copy that data to the users clipboard, and then call a javascript function to open a web page where the user could paste in the data.&amp;#160; I wanted to split the task so that one user could get the data from the web service and then pass it to another user to do the javascript and pasting part.&lt;/p&gt;  &lt;p&gt;If you read this, you will notice right off hand that there are a few things to get past here before you even get to do the client server part.&amp;#160; Number one is that if you are running an applet and want access to the clipboard, you first have to either modify the client policy to allow this, or sign the jar file…I opted to sign the jar file.&amp;#160; Secondly, if you want an applet to run javascript, you have to add the ‘mayscript’ parameter to your applet tag in your html page.&amp;#160; I’m not planning on covering these topics here, but I may blog about them later.&lt;/p&gt;  &lt;p&gt;Java Networking&lt;/p&gt;  &lt;h3&gt;The Client&lt;/h3&gt;  &lt;p&gt;A client just has to create a new instance of a Socket which has a handle to an input and output stream.&amp;#160; All your client does is write to an InputStream and read the server response from the OutputStream.&amp;#160; This is really quite trivial to do by using a Reader and Writer class.&amp;#160; I used a PrintWriter to write to the server and a BufferedReader to read the response.&amp;#160; I use another BufferedReader to get an input from the command line:&lt;/p&gt;  &lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  1: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SimpleClient&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  2: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  3:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; Socket clientSocket;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  4:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; enum ServerState{ READY, DONE };&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  5:     &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  6:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; SimpleTransferClient(String server, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; port) &lt;span style="color: #0000ff"&gt;throws&lt;/span&gt; UnknownHostException, IOException&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  7:     {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  8:         clientSocket = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Socket(server, port);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  9:     }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 10: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 11:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; start()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 12:     {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 13:         PrintWriter out;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 14:         BufferedReader response;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 15:         BufferedReader commandLine;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 16:         ServerState state = ServerState.READY;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 17:         &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 18:         &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 19:         {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 20:             out = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PrintWriter(clientSocket.getOutputStream(), &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 21:             response = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BufferedReader(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; InputStreamReader(clientSocket.getInputStream()));&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 22:             commandLine = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BufferedReader(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; InputStreamReader(System.in));&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 23:             &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 24:             String message;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 25:             &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 26:             &lt;span style="color: #0000ff"&gt;while&lt;/span&gt;( ( message = response.readLine() ) != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; )&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 27:             {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 28:                 state = TransferState.valueOf(message);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 29:                 &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 30:                 &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt;(state)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 31:                 {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 32:                     &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; READY:&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 33:                         out.println(commandLine.readLine());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 34:                         &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 35:                     &lt;span style="color: #0000ff"&gt;default&lt;/span&gt;:&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 36:                         out.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 37:                         response.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 38:                         &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 39:                 }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 40:             }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 41:             &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 42:             clientSocket.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 43:         }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 44:         &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (IOException e)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 45:         {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 46:             &lt;span style="color: #008000"&gt;// noop&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 47:         }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 48:     }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 49: }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 50: &lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Making this work involves creating an instance of the SimpleClient using the server ip address and port in the constructor.&amp;#160; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Listener&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Although a listener is not necessarily required, I thought that it would be better to launch a thread to handle the networking stuff and hand off the request to a server instance.&amp;#160; This way, I could allow multiple clients to connect simultaneously instead of in a queue.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The listener simply creates a ServerSocket and just accepts client requests.&amp;#160; Once it gets a client socket request, it just passes the socket off to a server thread and then goes back to listening for another client.&amp;#160; I took a simplistic approach to this, you may want to limit the number of processes, etc to ensure that you don’t get DDOS’d to death, but in my case, this wasn’t really an issue.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  1: &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; ServerSocket listener = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ServerSocket(4567);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  2: &lt;span style="color: #0000ff"&gt;while&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  3: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  4:     &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ServerThread(listener.accept()).start();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  5: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;As I said, this isn’t fancy, but it sets up the service, loops forever and accepts clients as quickly as it can spin off a thread.&amp;#160; Since I was running this inside an applet and wanted some user interaction, I also put this in its own thread.&amp;#160; Obviously, depending on what you are trying to do, this may not be necessary, but this will work in any case.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  1: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Listener&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  2: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  3:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Thread listenerThread;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  4:     &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  5:     &lt;span style="color: #008000"&gt;/**&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  6:      * Static method to start the thread&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  7:      */&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  8:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; start()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  9:     {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 10:         listenerThread = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ListenerThread();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 11:         listenerThread.start();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 12:     }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 13:     &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 14:     &lt;span style="color: #008000"&gt;/**&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 15:      * Static method to stop the thread&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 16:      */&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 17:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; stop()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 18:     {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 19:         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ( listenerThread != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; )&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 20:             listenerThread.interrupt();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 21:     }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 22:     &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 23:     &lt;span style="color: #008000"&gt;/**&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 24:      * The actual thread class&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 25:      */&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 26:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ListenerThread &lt;span style="color: #0000ff"&gt;extends&lt;/span&gt; Thread&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 27:     {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 28:         &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;boolean&lt;/span&gt; listening = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 29:         &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; ServerSocket listener = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 30:         &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 31:         &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; run()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 32:         {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 33:             &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 34:             {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 35:                 listener = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ServerSocket(4567);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 36:                 listening = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 37:                 &lt;span style="color: #0000ff"&gt;while&lt;/span&gt;(listening)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 38:                 {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 39:                     &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ServerThread(listener.accept()).start();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 40:                     &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 41:                     {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 42:                         &lt;span style="color: #008000"&gt;// be nice and sleep once in a while&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 43:                         Thread.sleep(1000);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 44:                     }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 45:                     &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (InterruptedException e)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 46:                     {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 47:                         listening = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 48:                     }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 49:                 }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 50:                 listener.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 51:             }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 52:             &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (IOException e)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 53:             {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 54:                 listening = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 55:             }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 56:             &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 57:         }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 58:         &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 59:         &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; interrupt()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 60:         {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 61:             &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 62:             {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 63:                 &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ( listener != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; )&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 64:                     listener.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 65:             }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 66:             &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (IOException e)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 67:             {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 68:                 &lt;span style="color: #008000"&gt;// noop&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 69:             }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 70:             &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 71:             listening = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 72:         }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 73:     }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 74: }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;So then firing up the listener would just be a static call to Listener.start();&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Server&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In order to make sure that client requests don’t get queued up, we implement the actual server as a thread as well.&amp;#160; This way, when a client connects, the listener creates a new ServerThread and then goes back to listening.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The server is almost identical to the client in terms of code.&amp;#160; Both sides use a plain old Socket and read and write from an output stream.&amp;#160; I used a PrintWriter for my output and a BufferedReader for my input:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  1: &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ServerThread&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  2: {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  3:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; Socket clientSocket;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  4:     &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  5:     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; enum ServerState{ READY, DONE };&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  6: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  7:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ServerThread(Socket socket)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  8:     {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  9:         &lt;span style="color: #0000ff"&gt;super&lt;/span&gt;(&amp;quot;&lt;span style="color: #8b0000"&gt;ServerThread&lt;/span&gt;&amp;quot;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 10:         clientSocket = socket;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 11:     }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 12: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 13:     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; run()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 14:     {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 15:         PrintWriter output;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 16:         BufferedReader response;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 17:         &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 18:         &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 19:         {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 20:             output = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PrintWriter(clientSocket.getOutputStream(), &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 21:             response = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BufferedReader(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; InputStreamReader(clientSocket.getInputStream()));&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 22:             &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 23:             ServerState state = ServerState.READY;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 24:             String message;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 25:             output.println(state.toString());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 26:             &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 27:             &lt;span style="color: #0000ff"&gt;while&lt;/span&gt;(! state.equals(ServerState.DONE) &amp;amp;&amp;amp; (message = response.readLine()) != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; )&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 28:             {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 29:                 &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ( &amp;quot;&lt;span style="color: #8b0000"&gt;quit&lt;/span&gt;&amp;quot;.equalsIgnoreCase(message) )&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 30:                     state = ServerState.DONE;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 31: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 32:                 output.println(&amp;quot;&lt;span style="color: #8b0000"&gt;You Said: &lt;/span&gt;&amp;quot; + message);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 33:                 output.println(state.toString());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 34:             }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 35:             output.println(&amp;quot;&lt;span style="color: #8b0000"&gt;Closing Connection...&lt;/span&gt;&amp;quot;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 36:             output.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 37:             response.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 38:             clientSocket.close();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 39:         }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 40:         &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (IOException e)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 41:         {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 42:             &lt;span style="color: #008000"&gt;// noop&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 43:         }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 44:     }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 45: }&lt;/pre&gt;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-5904448323868954569?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yjOlBja0W9VnIGEU6RdGxzJTE7s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yjOlBja0W9VnIGEU6RdGxzJTE7s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yjOlBja0W9VnIGEU6RdGxzJTE7s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yjOlBja0W9VnIGEU6RdGxzJTE7s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/5904448323868954569/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=5904448323868954569" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/5904448323868954569?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/5904448323868954569?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/lW1Bt1Oj_xI/creating-custom-client-server.html" title="Creating a Custom Client Server Application in JAVA" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/05/creating-custom-client-server.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMNQ3o5fCp7ImA9WxJTFUQ.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-4008821796507371067</id><published>2009-04-24T10:18:00.001-07:00</published><updated>2009-04-24T10:18:12.424-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-24T10:18:12.424-07:00</app:edited><title>Java Applets and Javascript</title><content type="html">&lt;p&gt;Everyone knows that you can use javascript to manipulate java applets.&lt;/p&gt;  &lt;p&gt;Take for example, I have an applet with a public method called doSomething().&amp;#160; All one has to do to execute this method from javascript is to get a handle on the applet and call the method:&lt;/p&gt;  &lt;p&gt;&amp;lt;applet id=”test” …&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;script type=”text/javascript”&amp;gt;   &lt;br /&gt;document.getElementById(‘test’).doSomething();    &lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/p&gt;  &lt;p&gt;I found out today that you can use java applets to fire javascript functions and manipulate the DOM in the browser with a little extra tweaking.&amp;#160; The Java plugin comes with some classes in the ‘netscape’ package that allows for this interaction…(yes it works in IE also)…All you have to do is get a handle on the window that holds the current applet.&amp;#160; Consider the following example:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;public class SomeApplet extends JApplet     &lt;br /&gt;{      &lt;br /&gt;&amp;#160; public void init()      &lt;br /&gt;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; final JSObject jso = JSObject.getWindow(this);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; final Object out = jso.call(“someFunction”,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; new Object[]{ “testParam” });      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.out.println(“Output from function: “ + out);      &lt;br /&gt;&amp;#160; }      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;script type=”text/javascript”&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160; function someFunction(msg) {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; alert(msg);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return “the output”;      &lt;br /&gt;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This simple example calls the javascript function from within the applet and read back the output of the function as an Object.&amp;#160; The one thing that you must do is enable scripting of the applet:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;applet … mayscript /&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;If you don’t add the mayscript parameter to your applet, you will get a JSException that tells you nothing.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-4008821796507371067?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5GT31Mp_YlcF5mhUlmfQLYggFd8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5GT31Mp_YlcF5mhUlmfQLYggFd8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5GT31Mp_YlcF5mhUlmfQLYggFd8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5GT31Mp_YlcF5mhUlmfQLYggFd8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/4008821796507371067/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=4008821796507371067" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/4008821796507371067?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/4008821796507371067?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/6zqzqeIzEkA/java-applets-and-javascript.html" title="Java Applets and Javascript" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/04/java-applets-and-javascript.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4ERXY9eSp7ImA9WxVXF08.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-6488917778110348404</id><published>2009-02-13T13:45:00.001-08:00</published><updated>2009-02-15T11:58:24.861-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-15T11:58:24.861-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development Best Practice" /><title>InfoQ: Craftsmanship and Ethics</title><content type="html">&lt;p&gt;This is a fabulous video on good practices as a software developer and as a software development organization.&amp;#160; It&amp;#160; highlights a number of Do’s and Don’ts that all developers should follow.&lt;/p&gt;  &lt;p&gt;If you are a developer, you need to watch this.&lt;/p&gt;  &lt;p&gt;The video discusses concepts such as Discipline in software development such as:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Short Iterations; design-build-refactor-repeat&lt;/li&gt;    &lt;li&gt;Don’t Wait for Definition; be part of the requirements definition by releasing executable code&lt;/li&gt;    &lt;li&gt;Abstract away Volatility; separate things that are likely to change from things that are not likely to change&lt;/li&gt;    &lt;li&gt;Decouple; build interfaces and build to the interfaces&lt;/li&gt;    &lt;li&gt;Find ways around Blocks; continuously remove impediments&lt;/li&gt;    &lt;li&gt;Keep architectures simple; I had to look up what ‘turgid viscous’ meant, but make architectures solve problems that are within the scope of the present project.&lt;/li&gt;    &lt;li&gt;Improve Incrementally; fix problems a little at a time.&lt;/li&gt;    &lt;li&gt;Avoid Grand Re-designs; don’t confuse this with incremental improvement, this just means that you leverage old product to make new product.&lt;/li&gt;    &lt;li&gt;Progressive Widening &amp;amp; Progressive Deepening; I love these two terms.&amp;#160; Widening is creating fully functioning features one at a time and deepening is a form of refactoring to add the layers required to limit dependencies. “First make it work, then make it right, then make it fast.”&lt;/li&gt;    &lt;li&gt;Don’t write bad code; take the time to get the code right, don’t speed through to make a release.&lt;/li&gt;    &lt;li&gt;Clean your code; messy code exists over a long term and causes problems with people working on it later and causes productivity to drop. “Every line of Code is what you expect it to be.”&amp;#160; Keep functions small and simple, name things well, use proper formatting, etc.&lt;/li&gt;    &lt;li&gt;Test Driven Development; three rules (1) Don’t write any production code until you’ve written a test for it, (2) don’t write any more test than is likely to fail, (3) then don’t write any more code than what would pass the test.&amp;#160; This cycle ensures that you’ve always got testable code.&lt;/li&gt;    &lt;li&gt;QA Should not find anything; don’t use QA to find our defects.&lt;/li&gt;    &lt;li&gt;100% code coverage; make sure all code is considered tested.&lt;/li&gt;    &lt;li&gt;Avoid debugging; using test driven development helps this, debugging is a way of helping you understand how your own code works.&amp;#160; Using a test to do this is a better and more persistent method of doing this.&lt;/li&gt;    &lt;li&gt;Manual Test Scripts are Immoral; Automate test scripts and make them part of the deliverable.&lt;/li&gt;    &lt;li&gt;Define Done; Make sure software id done at the end of an iteration.&amp;#160; Use “all tests pass” as a default definition.&lt;/li&gt;    &lt;li&gt;Test Through the right Interface; Make sure that you don’t need the GUI to test your application.&lt;/li&gt;    &lt;li&gt;Apprenticeship; make sure new programmers are not left to develop their own bad habits.&lt;/li&gt;    &lt;li&gt;Use Good Tools; this goes without saying.&amp;#160; If you’ve ever done any woodworking you know that good tools make all the difference in the final product.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://www.infoq.com/presentations/craftmanship-ethics"&gt;InfoQ: Craftsmanship and Ethics&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-6488917778110348404?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/vVKjjcGWjpETZ3PatXutn5y-ho0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vVKjjcGWjpETZ3PatXutn5y-ho0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/vVKjjcGWjpETZ3PatXutn5y-ho0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vVKjjcGWjpETZ3PatXutn5y-ho0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/6488917778110348404/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=6488917778110348404" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/6488917778110348404?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/6488917778110348404?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/vsCNoACPyck/infoq-craftsmanship-and-ethics.html" title="InfoQ: Craftsmanship and Ethics" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/02/infoq-craftsmanship-and-ethics.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQERHs9eip7ImA9WxVXE0g.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-6430598454180374275</id><published>2009-02-11T03:55:00.001-08:00</published><updated>2009-02-11T03:55:05.562-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-11T03:55:05.562-08:00</app:edited><title>Web Security via web.xml</title><content type="html">&lt;p&gt;I think web.xml is often overlooked for a great many configuration options.&amp;#160; Personally, I’m guilty of limiting my use of the deployment descriptor to servlet, filter and tag configuration.&amp;#160; I don’t like to see the file get messy I guess.&lt;/p&gt;  &lt;p&gt;This article talks about the authentication configuration options that can be used in web.xml.&amp;#160; This was something that I usually took care of in the web server configuration, not so much in the application server layer…but it looks like there are quite a few options here.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://java.dzone.com/articles/understanding-web-security"&gt;Understanding Web Security Using web.xml Via Use Cases | Javalobby&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-6430598454180374275?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yxHQY-l5xfyUzauFo3zeZmscHaU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yxHQY-l5xfyUzauFo3zeZmscHaU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yxHQY-l5xfyUzauFo3zeZmscHaU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yxHQY-l5xfyUzauFo3zeZmscHaU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/6430598454180374275/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=6430598454180374275" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/6430598454180374275?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/6430598454180374275?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/OMH1JT-wOOk/web-security-via-webxml.html" title="Web Security via web.xml" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/02/web-security-via-webxml.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEASXk4fSp7ImA9WxJQFUk.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-489288368311467007</id><published>2009-02-03T17:40:00.001-08:00</published><updated>2009-05-28T15:10:48.735-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-28T15:10:48.735-07:00</app:edited><title>Using HttpClient with Unique SSL Requirements</title><content type="html">&lt;p&gt;In looking at the &lt;a href="http://htmlunit.sourceforge.net/"&gt;HtmlUnit&lt;/a&gt; library as a means to do headless front end testing as part of our build process.&amp;#160; I quickly ran into to very large problems that I had to overcome.&lt;/p&gt;  &lt;p&gt;Firstly, the default &lt;a href="http://hc.apache.org"&gt;HttpClient&lt;/a&gt; behaviour when dealing with un-trusted server certificates is to throw an exception when connecting.&amp;#160; Since our development server doesn’t have a trusted certificate and its a waste to buy one for development, I needed a way to be able to get my build server to trust my homemade server certificate.&amp;#160; Luckily, I can tell the webclient to use insecure ssl, but I thought perhaps that this might be a little shot-gunnish.&lt;/p&gt;  &lt;p&gt;Secondly, many of our modules require a client side certificate to be able to connect from the web browser…another behaviour which isn’t the default from the &lt;a href="http://hc.apache.org"&gt;HttpClient&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;After a little hunting, I found the SSL guide on the HttpClient project site…(image finding it there of all places).&amp;#160; I found that the explanation wasn’t so good on the page except it links to the source file of an &lt;a href="http://svn.apache.org/viewvc/httpcomponents/oac.hc3x/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/AuthSSLProtocolSocketFactory.java?view=markup"&gt;AuthSSLProtocolSocketFactory.java&lt;/a&gt; that made things quite a bit clearer.&amp;#160; Allow me to explain.&lt;/p&gt;  &lt;p&gt;HtmlUnit uses the commons HttpClient to download pages.&amp;#160; The client uses the Protocol class when making connections to servers.&amp;#160; In order for me to be able to change the behavior of a connection, the easiest way to do this is to supply the client with an alternate protocol class to use when connecting with a server…this is a lot easier to do than you think.&lt;/p&gt;  &lt;p&gt;I basically replicated the AuthSSLProtocolSocketFactory class mentioned earlier and then I used it to construct an instance of a Protocol class.&amp;#160; Then I registered my new Protocol to handle “https” requests.&amp;#160; I had a bit of trouble using the java keystore for my client certificate, so I had to add a small change to allow me to handle PKCS12 keystore instead, which works just fine.&lt;/p&gt;  &lt;p&gt;Once you have the socket factory created, then all you do is create a ‘new’ protocol to handle https and register it with the framework:&lt;/p&gt;  &lt;div&gt;   &lt;pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  1: &lt;span style="color: #0000ff"&gt;final&lt;/span&gt; Protocol authhttps = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Protocol(&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  2:     &amp;quot;&lt;span style="color: #8b0000"&gt;https&lt;/span&gt;&amp;quot;, &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  3:     &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AuthSSLProtocolSocketFactory(&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  4:         keystoreUrl,&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  5:         &amp;quot;&lt;span style="color: #8b0000"&gt;password&lt;/span&gt;&amp;quot;,&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  6:         truststoreUrl,&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  7:         &amp;quot;&lt;span style="color: #8b0000"&gt;password&lt;/span&gt;&amp;quot;), &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  8:     443);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt;  9: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; background-color: #fbfbfb"&gt; 10: Protocol.registerProtocol(&amp;quot;&lt;span style="color: #8b0000"&gt;https&lt;/span&gt;&amp;quot;, authhttps);&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;div class="csharpcode"&gt;Once this is done, you simply code your unit test.&amp;#160; See the ‘Getting Started’ link at &lt;a href="http://htmlunit.sourceforge.net"&gt;http://htmlunit.sourceforge.net&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://hc.apache.org/httpclient-3.x/sslguide.html"&gt;HttpClient - HttpClient SSL Guide&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-489288368311467007?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/eF_wPHa-obiw5o_LoxNf_kksdzs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eF_wPHa-obiw5o_LoxNf_kksdzs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/eF_wPHa-obiw5o_LoxNf_kksdzs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eF_wPHa-obiw5o_LoxNf_kksdzs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/489288368311467007/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=489288368311467007" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/489288368311467007?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/489288368311467007?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/YNz7DUcBwZU/using-httpclient-with-unique-ssl.html" title="Using HttpClient with Unique SSL Requirements" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/02/using-httpclient-with-unique-ssl.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YDRX49eCp7ImA9WxVQEUs.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-8013846116333808178</id><published>2009-01-28T09:52:00.001-08:00</published><updated>2009-01-28T09:52:54.060-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-28T09:52:54.060-08:00</app:edited><title>Other Media By Object Mentor People</title><content type="html">&lt;p&gt;Some more videos from the Object Mentor folks… &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.objectmentor.com/resources/otherMedia.html"&gt;Other Media By Object Mentor People&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-8013846116333808178?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zDrknZwp_-V_8dGkV-qFNshpY00/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zDrknZwp_-V_8dGkV-qFNshpY00/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zDrknZwp_-V_8dGkV-qFNshpY00/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zDrknZwp_-V_8dGkV-qFNshpY00/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/8013846116333808178/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=8013846116333808178" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/8013846116333808178?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/8013846116333808178?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/z2V0rvbr2kE/other-media-by-object-mentor-people.html" title="Other Media By Object Mentor People" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/01/other-media-by-object-mentor-people.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMGR3s7fyp7ImA9WxVQEUs.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-3032132008032425813</id><published>2009-01-28T09:07:00.001-08:00</published><updated>2009-01-28T09:07:06.507-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-28T09:07:06.507-08:00</app:edited><title>InfoQ: The Principles of Agile Design</title><content type="html">&lt;p&gt; Interesting video about OO design…should see it.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.infoq.com/presentations/principles-agile-oo-design"&gt;InfoQ: The Principles of Agile Design&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-3032132008032425813?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Fr_0V2o4QG1OMMOWallculLb0R0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Fr_0V2o4QG1OMMOWallculLb0R0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Fr_0V2o4QG1OMMOWallculLb0R0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Fr_0V2o4QG1OMMOWallculLb0R0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/3032132008032425813/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=3032132008032425813" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/3032132008032425813?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/3032132008032425813?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/4E9QXFZ_GlM/infoq-principles-of-agile-design.html" title="InfoQ: The Principles of Agile Design" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/01/infoq-principles-of-agile-design.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMGR3wycCp7ImA9WxVQEUk.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-5516134605302233627</id><published>2009-01-28T05:13:00.001-08:00</published><updated>2009-01-28T05:13:46.298-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-28T05:13:46.298-08:00</app:edited><title>Open source Java projects: Terracotta - JavaWorld</title><content type="html">&lt;p&gt;Terracotta is an open source clustering system for Java that supports Tomcat and Weblogic (mentioned specifically) but I imagine it would support any Java Server implementation.&amp;#160; It uses bytecode instrumentation to examine shared attributes and submits only changed values to the terracotta server.&lt;/p&gt;  &lt;p&gt;Its a decent strategy for performing replication, as out of the box, Oracle’s OC4J will do replication either at the end of each request or on attribute update.&amp;#160; Depending on how developers update session attributes, you may be forced to replicate everything at the end of every request…very expensive.&lt;/p&gt;  &lt;p&gt;Terracotta seems to have an optimized method of doing it.&amp;#160; I’ve never implemented it, but I may give it a shot and see what it can do.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.javaworld.com/javaworld/jw-01-2009/jw-01-osjp-terracotta.html"&gt;Open source Java projects: Terracotta - JavaWorld&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-5516134605302233627?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/SeNWRiCq_j8izNWJ2pLLry2Yo7A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SeNWRiCq_j8izNWJ2pLLry2Yo7A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/SeNWRiCq_j8izNWJ2pLLry2Yo7A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SeNWRiCq_j8izNWJ2pLLry2Yo7A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/5516134605302233627/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=5516134605302233627" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/5516134605302233627?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/5516134605302233627?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/Zx45h86uQK0/open-source-java-projects-terracotta.html" title="Open source Java projects: Terracotta - JavaWorld" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/01/open-source-java-projects-terracotta.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cHRno4fip7ImA9WxVQEEo.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-348348427393200272</id><published>2009-01-27T07:43:00.001-08:00</published><updated>2009-01-27T07:43:57.436-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-27T07:43:57.436-08:00</app:edited><title>Essential Java resources</title><content type="html">&lt;p&gt;Here is a list of blogs, packages, websites, books and tools that should be on the list of all java developers everywhere.&amp;#160; Comments on the original blog are welcome and encouraged. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.ibm.com/developerworks/java/library/j-javaresources.html?ca=dgr-jw22JavaList&amp;amp;S_TACT=105AGX59&amp;amp;S_CMP=grsitejw22"&gt;Essential Java resources&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-348348427393200272?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tz2QF2_nsZ5SFXF4orBE4NFNz20/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tz2QF2_nsZ5SFXF4orBE4NFNz20/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tz2QF2_nsZ5SFXF4orBE4NFNz20/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tz2QF2_nsZ5SFXF4orBE4NFNz20/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/348348427393200272/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=348348427393200272" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/348348427393200272?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/348348427393200272?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/rYo-OBxQ93Q/essential-java-resources.html" title="Essential Java resources" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/01/essential-java-resources.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AARngycSp7ImA9WxVQEEs.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-5925364019570996444</id><published>2009-01-27T06:15:00.001-08:00</published><updated>2009-01-27T06:15:47.699-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-27T06:15:47.699-08:00</app:edited><title>Enterprise Java Community: Java Pseudo Transactions With Non-Transactional Resources</title><content type="html">&lt;p&gt;This article talks about implementing transactions without JTA aware resources in a pseudo transaction.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.theserverside.com/tt/articles/article.tss?l=JavaPseudoTransactions"&gt;Enterprise Java Community: Java Pseudo Transactions With Non-Transactional Resources&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-5925364019570996444?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tdUteHV4mT9Bl1ix2cHGzNT1gP4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tdUteHV4mT9Bl1ix2cHGzNT1gP4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tdUteHV4mT9Bl1ix2cHGzNT1gP4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tdUteHV4mT9Bl1ix2cHGzNT1gP4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/5925364019570996444/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=5925364019570996444" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/5925364019570996444?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/5925364019570996444?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/tsulC_rv98E/enterprise-java-community-java-pseudo.html" title="Enterprise Java Community: Java Pseudo Transactions With Non-Transactional Resources" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/01/enterprise-java-community-java-pseudo.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIHSHg9fSp7ImA9WxVRF0w.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-7792334136319580816</id><published>2009-01-23T03:35:00.001-08:00</published><updated>2009-01-23T03:35:39.665-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-23T03:35:39.665-08:00</app:edited><title>Rich Internet Applications</title><content type="html">&lt;p&gt;Podcast compares several RIA platforms. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://javaposse.com/index.php?post_id=423843#"&gt;The Java Posse&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-7792334136319580816?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5uV1HVrd9S8OkT50RhEZf9hIvNs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5uV1HVrd9S8OkT50RhEZf9hIvNs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5uV1HVrd9S8OkT50RhEZf9hIvNs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5uV1HVrd9S8OkT50RhEZf9hIvNs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/7792334136319580816/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=7792334136319580816" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/7792334136319580816?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/7792334136319580816?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/CekQwbDnfII/rich-internet-applications.html" title="Rich Internet Applications" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/01/rich-internet-applications.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEFQ34_fyp7ImA9WxVRFU4.&quot;"><id>tag:blogger.com,1999:blog-7752011408427894976.post-2275823777595896070</id><published>2009-01-21T03:16:00.000-08:00</published><updated>2009-01-21T03:16:52.047-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-21T03:16:52.047-08:00</app:edited><title>An Overview of Servlet 3.0</title><content type="html">&lt;a href="http://java.dzone.com/articles/an-overview-servlet-30"&gt;An Overview of Servlet 3.0 Javalobby&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Looks like java EE 6 will have a new Servlet class that is intended to simplify servlet and filter deployment as well as add some async functionality to help support web services.&lt;br /&gt;&lt;br /&gt;The web.xml file will still be around, but you will be able to choose between one big xml file and several 'fragment' files. You will also be able to configure your servlets using annotations instead of the standard descriptor file. This may be handy for implementing listeners where you will be able to define a context listener by adding @WebServletContextListener.&lt;br /&gt;&lt;br /&gt;Async calls and enhanced security are in the mix too and will be available in Java EE 6.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7752011408427894976-2275823777595896070?l=java.shawncrosby.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LxZXevfRAkkvkdd1GW3MBJ8spa4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LxZXevfRAkkvkdd1GW3MBJ8spa4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LxZXevfRAkkvkdd1GW3MBJ8spa4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LxZXevfRAkkvkdd1GW3MBJ8spa4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="related" href="http://java.dzone.com/articles/an-overview-servlet-30" title="An Overview of Servlet 3.0" /><link rel="replies" type="application/atom+xml" href="http://java.shawncrosby.com/feeds/2275823777595896070/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7752011408427894976&amp;postID=2275823777595896070" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/2275823777595896070?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7752011408427894976/posts/default/2275823777595896070?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ShawnOnJava/~3/smwfgSvO6IU/overview-of-servlet-30.html" title="An Overview of Servlet 3.0" /><author><name>Shawn Crosby</name><uri>http://www.blogger.com/profile/12093823138737535996</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/__S14ux89bFY/Soabhg77_pI/AAAAAAAAAqs/N84Ol381kTA/S220/Picture+6.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://java.shawncrosby.com/2009/01/overview-of-servlet-30.html</feedburner:origLink></entry></feed>

