<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8209914483781092632</id><updated>2011-11-09T04:41:56.874-08:00</updated><category term='GIS'/><category term='Job Scheduling'/><category term='Acceptance Testing'/><category term='Java IDE'/><category term='Development Methodology'/><category term='GWT'/><category term='Performance'/><category term='Java Compiler'/><category term='Java Language'/><category term='Free Text Search'/><category term='Unit Test'/><category term='Enterprise Java'/><category term='Java Security'/><category term='Java Monitoring'/><category term='Clustering'/><category term='Hibernate'/><category term='Java Concurrency'/><category term='IntelliJ IDEA'/><category term='Spring'/><category term='Code Quality'/><category term='displaytag'/><category term='Terracotta'/><category term='Tutorial'/><category term='Configuration'/><title type='text'>J2EE Blogger</title><subtitle type='html'>Well well... why another J2EE blog? I benefited from other people's technical blogs, and guess what, it's a good idea to contribute some of my works too. Hope it's helpful and useful, to all of your folks.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-8897023184997545305</id><published>2010-03-15T10:05:00.000-07:00</published><updated>2010-03-15T12:47:46.070-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='Performance'/><title type='text'>Improvement on Hibernate Query Cache</title><content type='html'>Cache improves performance by transparently storing data such that future  requests for that data can be served faster. Hibernate offers a session scope transactional cache which spans the scope of the session.  Hibernate also offers a configurable secondary level cache which spans across multiple sessions. Clustered/Distributed Caches can be configured so that it can be accessed across the entire application server cluster.&lt;br /&gt;&lt;br /&gt;Hibernate secondary cache offers pretty good entity cache. Entity cache speeds up entity loading by its primary key. For instance:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;select c from Cat c where c.id = :id&lt;/pre&gt;&lt;br /&gt;It supports query cache too, to enable query cache, you'll need to  specify the hibernate property:&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;hibernate.cache.use_query_cache true&lt;/pre&gt;&lt;br /&gt;Query cache caches Query result sets, so the cache can provide you an answer for the queries like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;select p from Person p where p.sin = :sin&lt;/pre&gt;&lt;br /&gt;Let's say, the SIN of a person is never gonna change, so cache the above query will be useful. &lt;br /&gt;&lt;br /&gt;Hibernate provides 'natural id' based on queries which can effectively solve the above problem. However, there are many other queries that hibernate cannot handle effectively. For instance, if we want to find all contact information (phone numbers only) for a person:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;select pn from PhoneNumbers pn where pn.person.id = :pid &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The primary problem for Query caches, is that hibernate will completely invalidated by any modification to the underlying table, even on entities that's totally unrelated to the query. In the above example, any insertion/update/deletion to the telephone table, on any record, will completely wipe out the entire cache for the above query.&lt;br /&gt;&lt;br /&gt;There needs to be a 'smart query cache' to solve this problem. Fortunately, this can be done by providing custom query cache, and we can then refreshes them by listening on hibernate 'entity modification' events. The listener will allow us to intercept any insertion/update/deletion to any telephone record, and then we can determine to only refresh the affected query cache.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-8897023184997545305?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/8897023184997545305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=8897023184997545305' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/8897023184997545305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/8897023184997545305'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2010/03/improvement-on-hibernate-query-cache.html' title='Improvement on Hibernate Query Cache'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-4568409859420787151</id><published>2009-02-15T16:10:00.001-08:00</published><updated>2009-02-15T16:14:35.833-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='displaytag'/><title type='text'>DisplayTag 1.2 Form Submission Problem</title><content type='html'>&lt;div&gt;Prior to 1.2, all the links generated by displaytag are Http Get only, which prevented it from being integrated into many web applications. Including ours. Those links includes paging/sorting and exporting links.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I had to solve the problem by using a customized TableTag along with custom javascript code. The solution was applied around the 1st week of December.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;DisplayTag 1.2, released Dec. 27, 2008, solves the form submission problem. Now The paging/sorting links can actually be Http Post instead of Get. Woot!&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, they must have forgot the export link - it's still get only... Another custom patch...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well one day I'll have to contribute it back to the open source project. Too busy recently.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-4568409859420787151?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/4568409859420787151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=4568409859420787151' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/4568409859420787151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/4568409859420787151'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2009/02/displaytag-12-form-submission-problem.html' title='DisplayTag 1.2 Form Submission Problem'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-2405743917877347343</id><published>2008-09-03T10:09:00.001-07:00</published><updated>2008-11-03T09:43:42.391-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Language'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Simple tip: Inject the nested class in Spring context</title><content type='html'>It's a simple tip and is not mentioned in Spring reference docs:&lt;div&gt;When you want create a bean in Spring which is a nested class of some owner class, use the "$" to separate the owner class name and the nested class name like following example:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 153);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 153);"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;bean class="org.balah.OwnerClass$NestedClass" &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 153);"&gt;&lt;bean class="org.balah.OwnerClass.NestedClass"&gt;&lt;/bean&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 153);"&gt;.....&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 153);"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 153);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Don't use the convention like "&lt;span class="Apple-style-span" style="color: rgb(0, 0, 153);"&gt;org.balah.OwnerClass.NestedClass&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0);"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 153);"&gt;" &lt;/span&gt;that is used in the source code usually. Because the Spring will use Class.forName() similar mechanism to find the class specified in the bean definition. As you use the Class.forName() to load a nested class, always use "$" to let the classloader locate the exact class file from your classpathes. The "." sperated convention just confused the class resolver anf finally throw a ClassNotFoundException.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-2405743917877347343?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/2405743917877347343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=2405743917877347343' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/2405743917877347343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/2405743917877347343'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/09/simple-tip-inject-nested-class-in.html' title='Simple tip: Inject the nested class in Spring context'/><author><name>Java Blues</name><uri>http://www.blogger.com/profile/02681848616646299865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-8113630246719401629</id><published>2008-04-24T00:54:00.000-07:00</published><updated>2008-04-28T10:35:23.903-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Language'/><title type='text'>Java7 new features: Personal View</title><content type='html'>Ref: &lt;a href="http://j2eeblogger.blogspot.com/2008/04/incoming-new-java-7-featuers.html"&gt;The incoming Java 7 new features&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;All about just one thing: Java is becoming a platform and heavier and heavier version by version.Losing its very authentic and original simple beauty purely from language perspective.&lt;br /&gt;&lt;br /&gt;Actually all the ideas are not quite new or very original innovative, they have already appeared in various libraries, components, frameworks and products. Sun is just collecting and refurbishing those ideas in name of JSR process then put them in its own JDK's shoes. Afterwards, MS will borrow the ideas but make it much easier to use in its monolithic .NET tools than  diverted java tools world.&lt;br /&gt;&lt;br /&gt;However, it's still a good news that the new changes on the heavier new "JAVA platform" will definitely drive the success of simpler and straightforward emerging dynamic 2G languages on top of Java, such as Groovy, which is just copying the same story Java replacing C/C++/Delphi 10 years ago!&lt;br /&gt;&lt;br /&gt;Let's see.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-8113630246719401629?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/8113630246719401629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=8113630246719401629' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/8113630246719401629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/8113630246719401629'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/java7-new-features-personal-view.html' title='Java7 new features: Personal View'/><author><name>Java Blues</name><uri>http://www.blogger.com/profile/02681848616646299865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-3911929461380079691</id><published>2008-04-24T00:29:00.000-07:00</published><updated>2008-04-28T10:21:52.726-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Concurrency'/><title type='text'>Inter-thread coordination: wait, notify and interrupt</title><content type='html'>&lt;span id="sler"  style="font-family:times new roman;"&gt;Just a sample code to test the inter-thread coordinating by using the object's wait and notify methods.  &lt;/span&gt;&lt;div id="slin" style="text-align: left;"&gt;&lt;span id="a_:x"  style="font-family:times new roman;"&gt;&lt;span id="z0g6" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="fn4r"  style="font-family:arial;"&gt;public class TestWaitAndNotify {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="hfu4" style="margin-left: 40px;"&gt;&lt;span id="hgnp"  style="font-family:times new roman;"&gt;&lt;span id="ros3" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="c44c"  style="font-family:arial;"&gt;      private final Object event = new Object();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;  &lt;span id="wp9a"  style="font-family:times new roman;"&gt;&lt;span id="e53u" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="wv7j"  style="font-family:arial;"&gt;      private final Task1 task1 = new Task1();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="d8s3"  style="font-family:times new roman;"&gt;&lt;span id="md8c" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="g52:"  style="font-family:arial;"&gt;      private final Task2 task2 = new Task2();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="l_y8"  style="font-family:times new roman;"&gt;&lt;span id="y672" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="bouu"  style="font-family:arial;"&gt;      private boolean stop;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;  &lt;span id="w_:1"  style="font-family:times new roman;"&gt;&lt;span id="j8.q" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="w_qe"  style="font-family:arial;"&gt;      public TestWaitAndNotify() {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="kf5u" style="margin-left: 40px;"&gt;&lt;span id="t44z"  style="font-family:times new roman;"&gt;&lt;span id="mqh2" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="vlsa"  style="font-family:arial;"&gt;                stop = false;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="a:ab"  style="font-family:times new roman;"&gt;&lt;span id="h5lc" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="e1lw"  style="font-family:arial;"&gt;      }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;  &lt;span id="fg-3"  style="font-family:times new roman;"&gt;&lt;span id="ulmn" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="o25s"  style="font-family:arial;"&gt;      public static void main(String[] args) throws InterruptedException {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="jl2g" style="margin-left: 40px;"&gt;&lt;span id="d0.v"  style="font-family:times new roman;"&gt;&lt;span id="bnd-" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="n36r"  style="font-family:arial;"&gt;         TestWaitAndNotify twan = new TestWaitAndNotify();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="oh0m"  style="font-family:times new roman;"&gt;&lt;span id="z.wz" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="xfkh"  style="font-family:arial;"&gt;         twan.doIt();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="t7m."  style="font-family:times new roman;"&gt;&lt;span id="e8so" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="jh:x"  style="font-family:arial;"&gt;      }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;  &lt;span id="rpuu"  style="font-family:times new roman;"&gt;&lt;span id="g0nv" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="omlz"  style="font-family:arial;"&gt;      void doIt() throws InterruptedException {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="uc_z" style="margin-left: 40px;"&gt;&lt;span id="fmxr"  style="font-family:times new roman;"&gt;&lt;span id="vqas" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="c3pi" style="color: rgb(0, 0, 153);font-family:arial;" &gt;                task2.start();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="s-9z"  style="font-family:times new roman;"&gt;&lt;span id="ftu0" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="x:oj" style="color: rgb(0, 0, 153);font-family:arial;" &gt;                task1.start();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="ol7:"  style="font-family:times new roman;"&gt;&lt;span id="q-hq" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="sqn:"  style="font-family:arial;"&gt;                stop = true;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="jl_w"  style="font-family:times new roman;"&gt;&lt;span id="iie8" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="c9mx"  style="font-family:arial;"&gt;                System.out.println("main:t [try to stop]");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="n3qe"  style="font-family:times new roman;"&gt;&lt;span id="fkf6" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="uozr" style="color: rgb(0, 0, 153);font-family:arial;" &gt;&lt;i id="sw9r"&gt;                synchronized (event){&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="n43j" style="margin-left: 40px;"&gt;&lt;span id="h6zy"  style="font-family:times new roman;"&gt;&lt;span id="i4ak" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="cjvk" style="color: rgb(0, 0, 153);font-family:arial;" &gt;&lt;i id="pu43"&gt;                        System.out.println("main:t [notify all waiting threads]");&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="kicq"  style="font-family:times new roman;"&gt;&lt;span id="laf2" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="x43v" style="color: rgb(0, 0, 153);font-family:arial;" &gt;&lt;i id="ea79"&gt;                        event.notifyAll();&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="b6wh"  style="font-family:times new roman;"&gt;&lt;span id="e5bb" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="b4br" style="color: rgb(0, 0, 153);font-family:arial;" &gt;&lt;i id="d8a6"&gt;               }&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="pra8"  style="font-family:times new roman;"&gt;&lt;span id="b_n9" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="td7e"  style="font-family:arial;"&gt;                System.out.println("main:t [quit]");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="nmgb"  style="font-family:times new roman;"&gt;&lt;span id="smnm" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="b.zo"  style="font-family:arial;"&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;  &lt;span id="rvs9"  style="font-family:times new roman;"&gt;&lt;span id="bjd8" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="lzgv"  style="font-family:arial;"&gt;      class Task1 extends Thread{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="ip12" style="margin-left: 40px;"&gt;&lt;span id="rh0e"  style="font-family:times new roman;"&gt;&lt;span id="fbr_" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="os.3"  style="font-family:arial;"&gt;                public void run(){&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="f64x" style="margin-left: 40px;"&gt;&lt;span id="b:oy"  style="font-family:times new roman;"&gt;&lt;span id="k68e" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="f1a-"  style="font-family:arial;"&gt;                            synchronized (event){&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="o-pj" style="margin-left: 40px;"&gt;&lt;span id="q2.0"  style="font-family:times new roman;"&gt;&lt;span id="wjs8" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="l-wp"  style="font-family:arial;"&gt;                                      System.out.println("task1 running.");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="h4cz"  style="font-family:times new roman;"&gt;&lt;span id="p-nt" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="yi95"  style="font-family:arial;"&gt;                                      while(!stop){&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="c3yt" style="margin-left: 40px;"&gt;&lt;span id="o_hk"  style="font-family:times new roman;"&gt;&lt;span id="joxw" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="wmlh"  style="font-family:arial;"&gt;                                                System.out.println("&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;task1 did");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="k0_l"  style="font-family:times new roman;"&gt;&lt;span id="x0q8" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="co1j"  style="font-family:arial;"&gt;                                                event.notifyAll();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="pn5c"  style="font-family:times new roman;"&gt;&lt;span id="j_q5" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="e1qh"  style="font-family:arial;"&gt;                                                 try {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="fxo1" style="margin-left: 40px;"&gt;&lt;span id="tq2g"  style="font-family:times new roman;"&gt;&lt;span id="b3cr" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="lzjf"  style="font-family:arial;"&gt;                                                          System.out.println("task1 waiting.");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="nfxk"  style="font-family:times new roman;"&gt;&lt;span id="rwty" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="vhub"  style="font-family:arial;"&gt;                                 event.wait(0);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="y4g5"  style="font-family:times new roman;"&gt;&lt;span id="beq3" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="o:2l"  style="font-family:arial;"&gt;                                 System.out.println("task1 wake");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="e3:_"  style="font-family:times new roman;"&gt;&lt;span id="a5cv" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="dbwq"  style="font-family:arial;"&gt;                                               } catch (InterruptedException e) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="w_pb" style="margin-left: 40px;"&gt;&lt;span id="t5:v"  style="font-family:times new roman;"&gt;&lt;span id="h0al" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="szq7"  style="font-family:arial;"&gt;                                 throw new RuntimeException(e);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="mo28"  style="font-family:times new roman;"&gt;&lt;span id="ybqa" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="f8le"  style="font-family:arial;"&gt;                                               }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="l-ia"  style="font-family:times new roman;"&gt;&lt;span id="lk71" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="qp_s"  style="font-family:arial;"&gt;                    }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="tfx3"  style="font-family:times new roman;"&gt;&lt;span id="p1zu" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="j4ed"  style="font-family:arial;"&gt;                              System.out.println("task1 quit");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="tevg"  style="font-family:times new roman;"&gt;&lt;span id="sqsk" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="kob."  style="font-family:arial;"&gt;                      }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="l.5e"  style="font-family:times new roman;"&gt;&lt;span id="bg9o" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="q:tp"  style="font-family:arial;"&gt;            }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="wj6-"  style="font-family:times new roman;"&gt;&lt;span id="i:te" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="ma95"  style="font-family:arial;"&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;  &lt;span id="g_ip"  style="font-family:times new roman;"&gt;&lt;span id="di95" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="bc6v"  style="font-family:arial;"&gt;    class Task2 extends Thread{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="qyu0" style="margin-left: 40px;"&gt;&lt;span id="ia62"  style="font-family:times new roman;"&gt;&lt;span id="lbpg" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="x-dq"  style="font-family:arial;"&gt;            public void run(){&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="juhb"  style="font-family:times new roman;"&gt;&lt;span id="neul" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="n3a3"  style="font-family:arial;"&gt;                      synchronized (event){&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="pwej" style="margin-left: 40px;"&gt;&lt;span id="kfua"  style="font-family:times new roman;"&gt;&lt;span id="c1hm" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="wp1h"  style="font-family:arial;"&gt;                              System.out.println("Task2 running.");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="x7-d"  style="font-family:times new roman;"&gt;&lt;span id="w-8r" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="ib2t"  style="font-family:arial;"&gt;                              while(!stop){&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="lsr_" style="margin-left: 40px;"&gt;&lt;span id="w_2v"  style="font-family:times new roman;"&gt;&lt;span id="qva-" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="cfjs"  style="font-family:arial;"&gt;                                      try {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="bszp" style="margin-left: 40px;"&gt;&lt;span id="xada"  style="font-family:times new roman;"&gt;&lt;span id="g7bm" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="k3bx"  style="font-family:arial;"&gt;                                              //Thread.sleep(10000);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="nbg2"  style="font-family:times new roman;"&gt;&lt;span id="zk7z" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="eoki"  style="font-family:arial;"&gt;                                              System.out.println("task2 waiting.");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="gpia"  style="font-family:times new roman;"&gt;&lt;span id="hzjm" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="jwzl"  style="font-family:arial;"&gt;                                              event.wait(0);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="pwwa"  style="font-family:times new roman;"&gt;&lt;span id="teov" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="m64e"  style="font-family:arial;"&gt;                                              System.out.println("task2 wake");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="nm_n"  style="font-family:times new roman;"&gt;&lt;span id="kxnt" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="ooh9"  style="font-family:arial;"&gt;                                      } catch (InterruptedException e) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;div id="ymzb" style="margin-left: 40px;"&gt;&lt;span id="vlp2"  style="font-family:times new roman;"&gt;&lt;span id="mfd8" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="s0ck"  style="font-family:arial;"&gt;                                              e.printStackTrace();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="a8pu"  style="font-family:times new roman;"&gt;&lt;span id="gbi6" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="yy-9"  style="font-family:arial;"&gt;                                      }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="yo8q"  style="font-family:times new roman;"&gt;&lt;span id="j588" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="xii1"  style="font-family:arial;"&gt;                                      System.out.println("&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;task2 did");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="suwu"  style="font-family:times new roman;"&gt;&lt;span id="o07l" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="a2me"  style="font-family:arial;"&gt;&lt;span id="wakb"  style="font-family:arial;"&gt;                                      event.notifyAll();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="g03d"  style="font-family:times new roman;"&gt;&lt;span id="tj65" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="u3q8"  style="font-family:arial;"&gt;&lt;span id="ql8p"  style="font-family:arial;"&gt;                              }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="c3s_"  style="font-family:times new roman;"&gt;&lt;span id="faup" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="g8aa"  style="font-family:arial;"&gt;&lt;span id="lukq"  style="font-family:arial;"&gt;                            System.out.println("task2 quit");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="geq:"  style="font-family:times new roman;"&gt;&lt;span id="ijzo" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="gz1a"  style="font-family:arial;"&gt;&lt;span id="tpr_"  style="font-family:arial;"&gt;                      }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span id="dl.y"  style="font-family:times new roman;"&gt;&lt;span id="wlsa" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="q2ye"  style="font-family:arial;"&gt;&lt;span id="v1-s"  style="font-family:arial;"&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="dn7u"  style="font-family:times new roman;"&gt;&lt;span id="mllm" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="dxmx"  style="font-family:arial;"&gt;&lt;span id="n.n."  style="font-family:arial;"&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="zq80"  style="font-family:times new roman;"&gt;&lt;span id="ei1o" style="color: rgb(102, 102, 102);font-size:85%;" &gt;&lt;span id="u4oc"  style="font-family:arial;"&gt;&lt;span id="feli"  style="font-family:arial;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span id="e5lx"  style="font-family:times new roman;"&gt;&lt;span id="v8vj" style="color: rgb(102, 102, 102);font-size:85%;" &gt; &lt;span id="qo5." style="color: rgb(0, 0, 0);font-size:130%;" &gt;&lt;span id="eu5l"  style="font-family:times new roman;"&gt;Conclusion:&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;ol id="c1cv"&gt;&lt;li id="t:wy"&gt;The order of threads starting is important in order to make sure the threads are waiting and notifying in sequence per our expectation.&lt;/li&gt;&lt;li id="q-vy"&gt;One object could be used as an event/signal to coordinate the threads behaviors by using wait and notify combination.&lt;/li&gt;&lt;li id="canb"&gt;Don't swallow or ignore the InterruptedException as you usually will do. Try to handle it properly, because someone might try to stop the blocking thread by interrupt it. Especially you are doing some common library which might be called by various unknown classes in various unknown conditions. Ignore it in your codes might cause other guy's attempts fail. &lt;/li&gt;&lt;li id="a7ph"&gt;Gracefully shutting down a thread by using an central control flag. However, a control thread or the main thread should try to call the coordinating object's notifyall before quit itself in order to wake up all the waiting threads and let them have a chance to shutdown gracefully.&lt;/li&gt;&lt;li id="h_g0"&gt;You can not always assume the call to the interrupt method of a blocking thread will work as your wish if you try to wake up it and let it quit. The probable failure case is:&lt;/li&gt;&lt;ul id="h.dd"&gt;&lt;li id="jznv"&gt;If the blocking of thread is caused by waiting for the monitor of a synchronized method, it can not release the lock. However, if it's the case that the thread is waiting for a synchronized object, it's possible the interrupt will release the lock.&lt;/li&gt;&lt;li id="u3o6"&gt;InterruptedException ignored by any codes is running in the  thread when its interrupt is called. &lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-3911929461380079691?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/3911929461380079691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=3911929461380079691' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/3911929461380079691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/3911929461380079691'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/just-sample-code-to-test-inter-thread.html' title='Inter-thread coordination: wait, notify and interrupt'/><author><name>Java Blues</name><uri>http://www.blogger.com/profile/02681848616646299865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-5130221008175923328</id><published>2008-04-22T15:30:00.000-07:00</published><updated>2008-04-23T15:12:30.746-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Language'/><title type='text'>Incoming new Java 7 Featuers</title><content type='html'>Alex Miller has an excellent summarize of the &lt;a href="http://tech.puredanger.com/java7"&gt;new Java 7 Featuers&lt;/a&gt;: &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Improved Modularity Support (superpackages)&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;   1. superpackage example.bar.lib {  &lt;br /&gt;   2.   &lt;br /&gt;   3.     // member packages  &lt;br /&gt;   4.     member package example.bar.lib;  &lt;br /&gt;   5.   &lt;br /&gt;   6.     // member superpackages  &lt;br /&gt;   7.     member superpackage example.bar.lib.net, example.bar.lib.xml;  &lt;br /&gt;   8.   &lt;br /&gt;   9.     // list of exported types  &lt;br /&gt;  10.     export example.bar.lib.Table;  &lt;br /&gt;  11.   &lt;br /&gt;  12.     export superpackage example.bar.lib.net;  &lt;br /&gt;  13. }  &lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Java Module System&lt;/span&gt;&lt;br /&gt;A distribution format and a repository for collections of Java code and related resources. It also defines the discovery, loading, and integrity mechanisms at runtime. Defines a new deployment archive called a JAM (Java Module). The Java Module is a JAR file that contains other JARs, resources, and metadata. JAMs can specify which portions of the module are public and which are hidden. JAMs can specify dependencies on other modules.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Java Kernel&lt;/span&gt;&lt;br /&gt;Implement Java as a small kernel, then load the rest of the platform and libraries as needed, with the goal of reducing startup time, memory footprint, installation, etc. In the past this has also been referred to as “Java Browser Edition”.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;NIO2&lt;/span&gt;&lt;br /&gt;APIs for filesystem access, scalable asynchronous I/O operations, socket-channel binding and configuration, and multicast datagrams.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Date and Time API&lt;/span&gt;&lt;br /&gt;A new and improved date and time API for Java. The main goal is to build upon the lessons learned from the first two APIs (Date and Calendar) in Java SE, providing a more advanced and comprehensive model for date and time manipulation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Units and Quantities&lt;/span&gt;&lt;br /&gt;one or more Java packages for the programmatic handling of physical quantities and their expression as numbers of units. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;JCache API&lt;/span&gt;&lt;br /&gt;Standardizes in process caching of Java objects in a way that allows an efficient implementation, and removes from the programmer the burden of implementing cache expiration, mutual exclusion, spooling, and cache consistency.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Concurrency Utilities&lt;/span&gt;&lt;br /&gt;New kind of BlockingQueue called TransferQueue and a fine-grained parallel computation framework based on divide-and-conquer and work-stealing.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;XQuery API&lt;/span&gt;&lt;br /&gt;An API for executing XQuery calls and working with results. XQJ is to XQuery what JDBC is to SQL. At a glance, the XQJ API intentionally shares many high-level concepts from JDBC (DataSource, Connection, etc) but supports XQuery specific concepts such as static and dynamic phases, XML-oriented retrieval, etc.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Resource Consumption Management API&lt;/span&gt;&lt;br /&gt;Allow for partitioning resources (constraints, reservations) among Java applications and for querying about resource availability (notifications). It will also provide means of exposing various kinds of resources. Example resources are heap memory size, CPU time, open JDBC connections, etc. The goal is to allow resources to be managed so that multiple applications might run simultaneously in a JVM and be given finite amounts of memory, cpu, etc. This JSR will build on top of JSR 121 Isolates.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Swing Application Framework&lt;/span&gt;&lt;br /&gt;A simple application framework for Swing applications. It will define infrastructure common to most desktop applications. In so doing, Swing applications will be easier to create.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Beans Binding&lt;/span&gt;&lt;br /&gt;An API that allows two properties of two beans to stay in sync. Formalizes an API for connecting JavaBeans.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Beans Validation&lt;/span&gt;&lt;br /&gt;Define a meta-data model and API for JavaBeanTM validation based on annotations, with overrides and extended meta-data through the use of XML validation descriptors.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Java Media Components&lt;/span&gt;&lt;br /&gt;Support for video to Java. It will initially address playback and ultimately will also cover capture and streaming. Video playback will provide support for both native players and a pure Java player.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;JMX 2.0&lt;/span&gt;&lt;br /&gt;Updates the JMX and JMX Remote APIs to improve usability of existing features and add new functionality such as annotations for ease of development, federated JMX servers, etc.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Web Services Connector for JMX&lt;/span&gt;&lt;br /&gt;A connector for the JMX Remote API that uses Web Services to make JMX instrumentation available remotely. Clients do not have to be Java applications, but can be.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Javadoc Technology Update&lt;/span&gt;&lt;br /&gt;New tags and generated Javadoc document representation aimed to increase readability, information richness, and make the Javadoc more approachable to developers learning and using the APIs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Reified Generics&lt;/span&gt;&lt;br /&gt;Currently, generics are implemented using erasure, which means that the generic type information is not available at runtime, which makes some kind of code hard to write. Generics were implemented this way to support backwards compatibility with older non-generic code. Reified generics would make the generic type information available at runtime, which would break legacy non-generic code. However, Neal Gafter has proposed making types reifiable only if specified, so as to not break backward compatibility.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Type Literals&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;   1. Type&amp;lt;List&amp;lt;String&amp;gt;&amp;gt; x = List&amp;lt;String&amp;gt;.class;   &lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Annotations on Java Types&lt;/span&gt;&lt;br /&gt;enriches the Java annotation system. For example, it permits annotations to appear in more places than Java 6 permits; one example is generic type arguments (List&lt;@NonNull Object&gt;). These enhancements to the annotation system require minor, backward-compatible changes to the Java language and classfile format.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Type Inference&lt;/span&gt;&lt;br /&gt;Constructor invocation can be changed from:&lt;br /&gt;&lt;pre&gt;   1. Map&amp;lt;String, List&amp;lt;String&amp;gt;&amp;gt; anagrams = new HashMap&amp;lt;String, List&amp;lt;String&amp;gt;&amp;gt;();  &lt;br /&gt;   2. to   &lt;br /&gt;   3. Map&amp;lt;String, List&amp;lt;String&amp;gt;&amp;gt; anagrams = new HashMap&amp;lt;&amp;gt;();  &lt;/pre&gt;&lt;br /&gt;and explicit type references can now be inferred changing:&lt;pre&gt;# timeWaitsFor(Collections.&amp;lt;Man&amp;gt;emptySet());  &lt;br /&gt;# to  &lt;br /&gt;# timeWaitsFor(Collections.emptySet());  &lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Closures&lt;/span&gt;&lt;br /&gt;A  closure is a function that captures the bindings of free variables in its lexical context. Closures support passing functions around and make many anonymous inner class use cases easier to use. In addition, they support additional high-level programming abstractions.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Automatic Resource Block Management&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;   1. // Start a block using two resources, which will automatically   &lt;br /&gt;   2. // be cleaned up when the block exits scope  &lt;br /&gt;   3. do (BufferedInputStream bis = ...; BufferedOutputStream bos = ...) {  &lt;br /&gt;   4.      ... // Perform action with bis and bos  &lt;br /&gt;   5. }  &lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Language level XML support&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;   1. elt.appendChild(  &lt;br /&gt;   2.     &amp;lt;muppet&amp;gt;&lt;br /&gt;   3.         &amp;lt;name&amp;gt;Kermit&amp;lt;/name&amp;gt;&lt;br /&gt;   4.     &amp;lt;/muppet&amp;gt;);  &lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;JavaBean Property Support&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;   1. public property String foo;   &lt;br /&gt;   2. a-&amp;gt;Foo = b-&amp;gt;Foo;  &lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;BigDecimal operator support&lt;/span&gt;&lt;br /&gt;Support for manipulating BigDecimal objects with arithmetic operators (just like other numeric primitives) instead of via method calls.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Strings in switch statements&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;# static boolean booleanFromString(String s) {  &lt;br /&gt;#     switch(s) {  &lt;br /&gt;#       case "true":  &lt;br /&gt;#         return true;  &lt;br /&gt;#       case "false":  &lt;br /&gt;#         return false;  &lt;br /&gt;#     }  &lt;br /&gt;#     throw new IllegalArgumentException(s);  &lt;br /&gt;# }  &lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Comparisons for Enums&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;   1. boolean isRoyalty(Rank r) {  &lt;br /&gt;   2.     return rank &amp;gt;= Rank.JACK &amp;&amp; rank != Rank.ACE;  &lt;br /&gt;   3. }  &lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Chained Invocation&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;   1. class Factory {  &lt;br /&gt;   2.      void setSomething(Something something) { ... }  &lt;br /&gt;   3.      void setOther(Other other) { ... }  &lt;br /&gt;   4.      Thing result() { ... }  &lt;br /&gt;   5.  }  &lt;br /&gt;   6.   &lt;br /&gt;   7.  Thing thing = new Factory()  &lt;br /&gt;   8.      .setSomething(something)  &lt;br /&gt;   9.      .setOther(other)  &lt;br /&gt;  10.      .result();  &lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Extension methods&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;   1. import static java.util.Collections.sort;  &lt;br /&gt;   2. List&amp;lt;String&amp;gt; list = ...;  &lt;br /&gt;   3. list.sort();    // looks like call to List.sort(), but really call to static Collections.sort().  &lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Improved Catch Clause&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;# try {  &lt;br /&gt;#      return klass.newInstance();  &lt;br /&gt;#  } catch (InstantiationException | IllegalAccessException e) {  &lt;br /&gt;#      throw new AssertionError(e);  &lt;br /&gt;#  } &lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;invokedynamic&lt;/span&gt;&lt;br /&gt;Introduces a new bytecode invokedynamic for support of dynamic languages.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Tiered compilation&lt;/span&gt;&lt;br /&gt;Tiered compilation uses a mix of the client (JIT) and server hot spot compilers - the client engine improves startup time by using JIT over interpreted and the server hot spot compiler gives better optimization for hot spots over time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;G1 Garbage Collector&lt;/span&gt;&lt;br /&gt;G1 (for “garbage first”) is a single collector that divides the entire space into regions and allows a set of regions to be collected, rather than split the space into an arbitrary young and old generation. Sun intends to make this new collector the default in Java 7. (This applies only to the Sun JDK.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;More Script Engine&lt;/span&gt;&lt;br /&gt;additional language interpreters to JSE. The JavaScript Rhino engine was added in Java 6. Leading candidates for Java 7 are: JRuby, Jython, and Beanshell.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-5130221008175923328?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/5130221008175923328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=5130221008175923328' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/5130221008175923328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/5130221008175923328'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/incoming-new-java-7-featuers.html' title='Incoming new Java 7 Featuers'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-2499498467879530207</id><published>2008-04-20T15:29:00.001-07:00</published><updated>2008-04-20T16:53:31.147-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GIS'/><title type='text'>GIS For Web Developers</title><content type='html'>Scott Davis on Seattle NFJS Java Conference&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;ACT1 - Free Data Available&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal; "&gt;- Raster Data, Google Satellite&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;- Vector Data, Google Map&lt;/div&gt;&lt;div&gt;- Hybrid, Google Satellite + Google Map Hybrid mode&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=""&gt;Type of Vectors&lt;/span&gt;&lt;/div&gt;&lt;div&gt;- Point&lt;/div&gt;&lt;div&gt;- Line&lt;/div&gt;&lt;div&gt;- Polygon&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Free Vectors: www.census.gov&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Shapefile: well documented proprietary ESRI standard, .shp, .shx, .dbf&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Downloadable States of America: &lt;a href="http://www.census.gov/geo/cob/bdy/st/st00shp/st99_d00_shp.zip"&gt;http://www.census.gov/geo/cob/bdy/st/st00shp/st99_d00_shp.zip&lt;/a&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;ESRI free viewer: &lt;a href="http://www.esri.com/software/arcexplorer/download.html"&gt;http://www.esri.com/software/arcexplorer/download.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;More data, please: &lt;a href="http://www.nationalatlas.gov"&gt;http://www.nationalatlas.gov&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Canada: &lt;a href="http://www.geobase.ca"&gt;http://www.geobase.ca&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For local data, most state and municipal government agencies offer free data as well. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;ACT2 - Projections&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Earth is round but maps are flat, projections take fundamentally 3d data and portraying it in 2-dimensions, this procedure introduce error for distance, direction, shape, area. On a Cartesian Planes, X and Y lines form perfect squares, however, on a globe, only the line of Latitude are perfectly parallel, line of Longitude converge at the poles. Different projections attempt to minimize map distortions, common projections are "State Plane" and "UTM".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Reprojection Utility available: &lt;a href="http://www.gdal.org"&gt;GDAL&lt;/a&gt; &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;EPSG Codes: &lt;a href="http://www.epsg.org"&gt;http://www.epsg.org&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;ACT3 - Spartial Databases&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Why bothers with a database?&lt;/div&gt;&lt;div&gt;- Centralize many scattered files&lt;/div&gt;&lt;div&gt;- Provide security&lt;/div&gt;&lt;div&gt;- Indexing&lt;/div&gt;&lt;div&gt;- Cross dataset queries&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;PostgreSQL + PostGIS: &lt;a href="http://postgis.refractions.net"&gt;http://postgis.refractions.net&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Visualizing the Data: &lt;a href="http://udig.refractions.net"&gt;uDig&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;ACT4 - Web Services&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;- Google Maps, undeniably cool, proprietary interface&lt;/div&gt;&lt;div&gt;- Open set of standards available: Open Geospatial Consortium (&lt;a href="http://ww.opengis.org"&gt;OGC&lt;/a&gt;)&lt;/div&gt;&lt;div&gt;- OGC Features: GetCapabilities, DescribeFeatureType, GetFeature&lt;/div&gt;&lt;div&gt;- Data Service: WFS (Web Feature Service), WMS (Web Mapping Service)&lt;/div&gt;&lt;div&gt;- Open standard, any one can implement them: &lt;a href="http://www.opengeospatial.org/resource/products"&gt;http://opengeospatial.org/resource/products&lt;/a&gt;&lt;/div&gt;&lt;div&gt;- &lt;a href="http://docs.codehaus.org/display/GEOS/Home"&gt;GeoServer&lt;/a&gt;: Java based, runs in a Servlet container, provides OGC web services&lt;/div&gt;&lt;div&gt;- &lt;a href="http://mapbuilder.sourceforge.net"&gt;MapBuilder&lt;/a&gt;: Pure Javascript web client for OGC, included with GeoServer&lt;/div&gt;&lt;div&gt;- &lt;a href="http://exploreourpla.net"&gt;Explore Our Planet&lt;/a&gt;&lt;/div&gt;&lt;div&gt;- &lt;a href="http://www.openlayers.org"&gt;OpenLayers&lt;/a&gt;: Pure javascript web client, supports OGC, Google Maps, Yahoo Maps, MS Virtual Earth and WorldWind&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-2499498467879530207?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/2499498467879530207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=2499498467879530207' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/2499498467879530207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/2499498467879530207'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/gis-for-web-developers.html' title='GIS For Web Developers'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-519204199234642710</id><published>2008-04-20T14:10:00.000-07:00</published><updated>2009-03-24T21:14:59.163-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development Methodology'/><category scheme='http://www.blogger.com/atom/ns#' term='Acceptance Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Unit Test'/><title type='text'>Acceptance Testing Application Behavior</title><content type='html'>Venkat Subramaniam on Seattle NFJS Java Conference&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How do you ensure your applications meet the expectations of your key customers?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Agile Development&lt;/span&gt;, it's all about building relevant working software by constantly getting feedback. Testing is a key ingredient in Agile development. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Type of tests and Level: &lt;/div&gt;&lt;div&gt;- UI/Presentation: Watir, Selenium&lt;/div&gt;&lt;div&gt;- Controls/Services: BDD/FIT&lt;/div&gt;&lt;div&gt;- Classes/Models: Unit Testing&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Gathering requirement is a challenge. Use case helps, but often tend to be heavy weight and in effective beyond certain point of diminishing returns. Agile development use User Stories. When creating User Stories, 3Cs is important: &lt;/div&gt;&lt;div&gt;- Card: Feature expressed in an index card&lt;/div&gt;&lt;div&gt;- Conversation: Use short description as starting point for useful discussions that promote exploration and understanding&lt;/div&gt;&lt;div&gt;- Confirmation: Tests are written as a way to confirm completion of feature development&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;INVEST in User Stories:&lt;/div&gt;&lt;div&gt;- Independent&lt;/div&gt;&lt;div&gt;- Negotiable&lt;/div&gt;&lt;div&gt;- Valuable&lt;/div&gt;&lt;div&gt;- Estimable&lt;/div&gt;&lt;div&gt;- Small&lt;/div&gt;&lt;div&gt;- Testable&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;FIT: Framework for Integration Testing&lt;/span&gt;&lt;/div&gt;&lt;div&gt;- General purpose open-ended framework for expressing tests&lt;/div&gt;&lt;div&gt;- Help focus on business perspectives&lt;/div&gt;&lt;div&gt;- Easy for non-programmers to use (Table represent tests)&lt;/div&gt;&lt;div&gt;- Automated checking and reporting of results&lt;/div&gt;&lt;div&gt;- Useful for Business Rules related to business calculation  and business process/workflow&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How does it FIT together?&lt;/div&gt;&lt;div&gt;- Table of Tests, expresses expectations by way of examples&lt;/div&gt;&lt;div&gt;- Fixture, check that the system satisfied the given tests&lt;/div&gt;&lt;div&gt;- Column Fixture, helps test calculations&lt;/div&gt;&lt;div&gt;- Action Fixture, helps test events or actions&lt;/div&gt;&lt;div&gt;- Row Fixture, helps test collections&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tables are in pure html, which includes the test that the fixture will be used to execute on. Fixture is glue code in java that extends from FIT abstract Fixtures.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;FitNesse provides a single web based UI for developing, running and viewing results of test. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;BDD - Behavior Driven Design &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- Each behavior is expressed as a test/exercise method&lt;/div&gt;&lt;div&gt;- It tells what the object should do &lt;/div&gt;&lt;div&gt;- Java Tools for BDD: JBehave, JDave, beanSpec, Instinct&lt;/div&gt;&lt;div&gt;- Groovy Tools for BDD: GSpect, easyb&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Reference:&lt;/div&gt;&lt;div&gt;&lt;a href="http://fit.c2.com/"&gt;http:/fit.c2.com&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.fitnesse.org/"&gt;http://www.fitnesse.org&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://behavior-driven.org/"&gt;http://behavior-driven.org&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://jbehave.org/"&gt;http://jbehave.org&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://codeforfun.wordpress.com/gspec"&gt;http://codeforfun.wordpress.com/gspec&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.easyb.com/"&gt;http://www.easyb.com&lt;/a&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-519204199234642710?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/519204199234642710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=519204199234642710' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/519204199234642710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/519204199234642710'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/acceptance-testing-application-behavior.html' title='Acceptance Testing Application Behavior'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-259327137637866053</id><published>2008-04-20T10:46:00.000-07:00</published><updated>2009-03-24T21:15:15.757-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development Methodology'/><title type='text'>Pragmatic Programmer</title><content type='html'>&lt;a href="http://www.codinghorror.com/blog/files/Pragmatic%20Quick%20Reference.htm"&gt;http://www.codinghorror.com/blog/files/Pragmatic%20Quick%20Reference.htm&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It summarizes the tips and checklists found in book &lt;a href="http://www.amazon.com/exec/obidos/ASIN/020161622X/codinghorror-20"&gt;The Pragmatic Programmer.&lt;/a&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-259327137637866053?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/259327137637866053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=259327137637866053' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/259327137637866053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/259327137637866053'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/pragmatic-programmer.html' title='Pragmatic Programmer'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-1650349317738012081</id><published>2008-04-20T10:32:00.000-07:00</published><updated>2008-04-20T12:09:52.671-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Clustering'/><category scheme='http://www.blogger.com/atom/ns#' term='Terracotta'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='Performance'/><category scheme='http://www.blogger.com/atom/ns#' term='Free Text Search'/><title type='text'>10 Ways to use Hibernate Effectively, by Brian Sam Bodden</title><content type='html'>Brian Sam Bodden on the Seattle NFJS Java Conference. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- Inheritance, Table per Concrete Class, Table per Class Hierarchy, Table per Subclass&lt;/div&gt;&lt;div&gt;- Identify and use Components in the Mapping&lt;/div&gt;&lt;div&gt;- Dynamic Data Filtering can be enabled in either HBM file or use Annotation&lt;/div&gt;&lt;div&gt;- While generated SQL is good enough in most case, Hibernate does support Customer SQL as well as native SQL with direct JDBC connection. iBATIS alike but you only require to customize the SQL when needed.&lt;/div&gt;&lt;div&gt;- Bulk Operations - Enable JDBC Batching &amp;amp; Be mindful of Session and 2nd Level Cache&lt;/div&gt;&lt;div&gt;- Cache - Session Cache &amp;amp; 2nd Level Cache, Read-Only, Read/Write &amp;amp; Query Cache&lt;/div&gt;&lt;div&gt;- Terracotta - Claims of performance gains in the range of 2-4x when integrating with second level cache&lt;/div&gt;&lt;div&gt;- Hibernate Search - Free text search with Lucene, Annotation driven, luceneQuery = parser.parse("name:beckham or name:galaxy")&lt;/div&gt;&lt;div&gt;- Profiling/Debugging - beware of the Write behind fact of Hibernate. p6spy, Jahia's SQL Profiler, Hibernate Statistics&lt;/div&gt;&lt;div&gt;- Hibernate/Jboss Tools - &lt;a href="http://www.hibernate.org/255.html"&gt;http://www.hibernate.org/255.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;- Hibernate Tips &amp;amp; Tricks Page: &lt;a href="http://www.hibernate.org/255.html"&gt;http://www.hibernate.org/118.html&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-1650349317738012081?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/1650349317738012081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=1650349317738012081' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/1650349317738012081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/1650349317738012081'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/10-ways-to-use-hibernate-effectively-by.html' title='10 Ways to use Hibernate Effectively, by Brian Sam Bodden'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-3936192350891713139</id><published>2008-04-20T10:06:00.000-07:00</published><updated>2008-04-20T10:10:22.065-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Job Scheduling'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Watch out for Lazy Initialization when you schedule a job</title><content type='html'>&lt;a href="http://www.jroller.com/habuma/entry/a_funny_thing_happened_while"&gt;http://www.jroller.com/habuma/entry/a_funny_thing_happened_while&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Spring should probably initialize those Job Scheduler more actively. Lazily initialize things like that sounds not a good idea.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-3936192350891713139?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/3936192350891713139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=3936192350891713139' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/3936192350891713139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/3936192350891713139'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/watch-out-for-lazy-initialization-when.html' title='Watch out for Lazy Initialization when you schedule a job'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-7914260219852841451</id><published>2008-04-20T09:09:00.000-07:00</published><updated>2008-04-20T23:23:23.250-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='Java Security'/><title type='text'>Spring Security by Craig Walls</title><content type='html'>&lt;div&gt;Craig Walls presented the Spring Security Session at the latest NFJS Java Conference in Seattle.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;What ACEGI Offers?&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- Declarative Security, keeps security details out of your code&lt;/div&gt;&lt;div&gt;- Authentication and Authorization, against virtually any user store&lt;/div&gt;&lt;div&gt;- Support for anonymous sessions, concurrent sessions, remember-me, channel enforcement, and much more&lt;/div&gt;&lt;div&gt;- Spring-based, but can be used for non-Spring web framework&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;ACEGI's moving parts:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- Security Interceptors, aspects for methods, filters for servlets&lt;/div&gt;&lt;div&gt;- Managers, Authentication, Access Decision, Run-As, After-Invocation&lt;/div&gt;&lt;div&gt;- Authentication Providers&lt;/div&gt;&lt;div&gt;- Access Voters&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Security Intercepter - First line of defense&lt;/div&gt;&lt;div&gt;Authentication Manager - Verifies user identity &lt;/div&gt;&lt;div&gt;Access Decision Manager - Determines if the authenticated user has authority to access the secured resource, by aggregating the result from the Voters&lt;/div&gt;&lt;div&gt;Run-As Manager - Temporarily replaces user's Authentication object for the duration of the current secure invocation&lt;/div&gt;&lt;div&gt;After Invocation Manager - Reviews the object returned from a secured invocation, allows for 'after-the-fact' security&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;The problem of ACEGI&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Every time you use Acegi... A fairy dies... It's a great framework but is very hard to use.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- Lots of moving parts&lt;/div&gt;&lt;div&gt;- Lots of options&lt;/div&gt;&lt;div&gt;- Everything is a &amp;lt;bean&amp;gt; with various options injected with &amp;lt;property&amp;gt;&lt;/div&gt;&lt;div&gt;- Requires lots of XML&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Spring Security 2.0&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- Released last week (Apr.15th)&lt;/div&gt;&lt;div&gt;- All the Same goodness with some new stuff with much less XML&lt;/div&gt;&lt;div&gt;- Provides a new security configuration namespace for Spring that hides &amp;lt;bean&amp;gt; &amp;lt;property&amp;gt;&lt;/div&gt;&lt;div&gt;- Provides auto-configuration&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Method Security&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- Intercepting method using Spring AOP&lt;/div&gt;&lt;div&gt;- Or, Annotation Driven&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-7914260219852841451?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/7914260219852841451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=7914260219852841451' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/7914260219852841451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/7914260219852841451'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/spring-security-by-craig-walls.html' title='Spring Security by Craig Walls'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-7042732444874798818</id><published>2008-04-19T18:11:00.000-07:00</published><updated>2008-04-19T18:16:39.236-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code Quality'/><title type='text'>How CRAP is your java source code?</title><content type='html'>Crap4j, a Java implementation of the CRAP (Change Risk Analysis and Predictions) software metric - a mildly offensive metric name to help protect you from truly offensive code.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I guess nobody likes it if his code's CRAP level is high. In fact I found this to be really useful when we talk about code quality. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Download from: &lt;a href="http://www.crap4j.org/"&gt;http://www.crap4j.org/&lt;/a&gt;. Ideally we'd like the build script to output a CRAP report automatically, just like it'll run the test cases automatically.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-7042732444874798818?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/7042732444874798818/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=7042732444874798818' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/7042732444874798818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/7042732444874798818'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/how-crap-is-your-java-source-code.html' title='How CRAP is your java source code?'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-6116659444593770146</id><published>2008-04-15T16:03:00.001-07:00</published><updated>2008-04-21T11:44:23.942-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='GWT'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>Spring, Hibernate, and GWT Tutorial</title><content type='html'>GWT is hot at client side but we still needs Spring/Hibernate to support it on the server side. Here is how. Courtesy of eggsylife blog.&lt;br /&gt;&lt;br /&gt;Part 1: &lt;a href="http://eggsylife.blogspot.com/2007/10/well-this-tutorial-aims-at-helping.html"&gt;http://eggsylife.blogspot.com/2007/10/well-this-tutorial-aims-at-helping.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Part 2: &lt;a href="http://eggsylife.blogspot.com/2007/11/hibernate-spring-google-web-toolkit.html"&gt;http://eggsylife.blogspot.com/2007/11/hibernate-spring-google-web-toolkit.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Part 3: &lt;a href="http://eggsylife.blogspot.com/2008/02/hibernate-spring-google-web-toolkit.html"&gt;http://eggsylife.blogspot.com/2008/02/hibernate-spring-google-web-toolkit.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And this GWT crash course is helpful too: &lt;a href="http://google.wikia.com/wiki/Jump_Start_Your_AJAX_Development_with_the_Google_Web_Toolkit"&gt;http://google.wikia.com/wiki/Jump_Start_Your_AJAX_Development_with_the_Google_Web_Toolkit&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A lot more here:&lt;br /&gt;&lt;a href="http://www.j2eeblogs.blogspot.com/2008/03/gwt-tutorials.html"&gt;http://www.j2eeblogs.blogspot.com/2008/03/gwt-tutorials.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-6116659444593770146?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/6116659444593770146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=6116659444593770146' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/6116659444593770146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/6116659444593770146'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/spring-hibernate-and-gwt-tutorial.html' title='Spring, Hibernate, and GWT Tutorial'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-6704759119575656374</id><published>2008-04-09T09:56:00.000-07:00</published><updated>2008-04-17T10:04:41.771-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='Java Language'/><title type='text'>Will it Compile?</title><content type='html'>This small sample project uses two libraries, apache-log4j-1.2.15 from www.apache.org and jpos-1.6.0-r2465 from www.jpos.org. Both are latest version as of the date I write this blog - freshly downloaded. The jpos library comes with no pre-packaged distribution jar file, thus we used ant to build the jar file from it's source files and the build.xml.&lt;br /&gt;&lt;br /&gt;Besides that, we have a source file of our own, A.java:&lt;br /&gt;&lt;pre&gt;import org.apache.log4j.Logger;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* A.java&lt;br /&gt;*/&lt;br /&gt;public class A {&lt;br /&gt;  static Logger logger = Logger.getLogger(A.class);&lt;br /&gt;&lt;br /&gt;  public static void main(String[] args){&lt;br /&gt;      logger.trace("blah blah");&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;It does nothing except log a message at trace level. The question here is, will this compile?&lt;br /&gt;&lt;br /&gt;The answer? Yes and No. Depends how you compile it.&lt;br /&gt;&lt;br /&gt;To demonstrate the problem, we'll just try to use the command line to compile it, instead of using apache-ant or any IDE. It helps us to identify the root of the problem. (Assume lib is where you put your libraries, also we have two version of j2sdk installed, 1.4.2_16 under c:\j2sdk1.4.2_16, 1.5.0_14 under c:\jdk1.5.0_14.)&lt;br /&gt;&lt;pre&gt;c:\j2sdk1.4.2_16\bin\javac -classpath lib\apache-log4j-1.2.15\log4j-1.2.15.jar;lib\jpos-1.6.0-r2465\build\jpos.jar src\*.java&lt;br /&gt;&lt;br /&gt;Result: Compile success.&lt;br /&gt;&lt;br /&gt;c:\jdk1.5.0_14\bin\javac -classpath lib\apache-log4j-1.2.15\log4j-1.2.15.jar;lib\jpos-1.6.0-r2465\build\jpos.jar src\*.java&lt;br /&gt;&lt;br /&gt;Result: Compile Success.&lt;/pre&gt;Now swap the classpath entries and try it again:&lt;br /&gt;&lt;pre&gt;c:\j2sdk1.4.2_16\bin\javac -classpath lib\jpos-1.6.0-r2465\build\jpos.jar;lib\apache-log4j-1.2.15\log4j-1.2.15.jar src\*.java&lt;br /&gt;&lt;br /&gt;Result: Compile success.&lt;br /&gt;&lt;br /&gt;c:\jdk1.5.0_14\bin\javac -classpath lib\jpos-1.6.0-r2465\build\jpos.jar;lib\apache-log4j-1.2.15\log4j-1.2.15.jar src\*.java&lt;br /&gt;&lt;br /&gt;Result:&lt;br /&gt;src\A.java:12: cannot find symbol&lt;br /&gt;symbol  : method trace(java.lang.String)&lt;br /&gt;location: class org.apache.log4j.Logger&lt;br /&gt;      logger.trace("blah blah");&lt;br /&gt;            ^&lt;br /&gt;1 error&lt;/pre&gt;Surprise, huh? Try it yourself.&lt;br /&gt;&lt;br /&gt;Everything comes with a reason. Since jdk1.5, both java and javac recurse the manifest classpath of a jar on the java classpath. Looking into jpos.jar, we found that its manifest file says to use log4j-1.2.8.jar and the trace method wasn't supported till log4j-1.2.12 or above.&lt;pre&gt;jpos.jar manifest file entry:&lt;br /&gt;&lt;br /&gt;Class-Path: lib/bsh-2.0b4.jar lib/commons-cli.jar lib/jdbm-1.0.jar lib&lt;br /&gt;/jdom-1.0.jar lib/log4j-1.2.8.jar lib/mx4j-impl.jar lib/mx4j-jmx.jar&lt;br /&gt;lib/mx4j-tools.jar lib/classes&lt;/pre&gt;&lt;br /&gt;That's the reason why the compilation error happened - javac was instructed to used log4j-1.2.8.jar come with the jpos distribution, instead of the the 1.2.15 that we want it to use.&lt;br /&gt;&lt;br /&gt;Conclusion? Well, I don't know what to say here, but this looks something similiar to the windows DLL hell problem. And it was called DLL 'Hell' for a reason.&lt;br /&gt;&lt;br /&gt;Further reading: &lt;a href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/findingclasses.html"&gt;How classes are found?&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-6704759119575656374?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/6704759119575656374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=6704759119575656374' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/6704759119575656374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/6704759119575656374'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/will-it-compile.html' title='Will it Compile?'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-8576142021148844318</id><published>2008-04-03T09:46:00.001-07:00</published><updated>2008-04-17T10:49:45.359-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Enterprise Java'/><title type='text'>Microsoft favours Enterprise Java Platform</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Microsoft is using Tomcat and JSP rather than IIS+.Net &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Today I happened to catch an error screen from MSN china.&lt;br /&gt;What an ironic screen of Microsoft WEB toolkits marketing policy!&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_C5USrHsffkE/R_UKvIH84xI/AAAAAAAADik/PeTn6vpJjWA/s1600-h/msn-tomcat-jsp.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_C5USrHsffkE/R_UKvIH84xI/AAAAAAAADik/PeTn6vpJjWA/s400/msn-tomcat-jsp.JPG" alt="" id="BLOGGER_PHOTO_ID_5185062350737957650" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Someone may say it's not true and it was a Fools day joke! O.K, see the further picture that what's the link of &lt;a href="http://msn.china.ynet.com/"&gt;http://msn.china.ynet.com&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_C5USrHsffkE/R_UUhoH84yI/AAAAAAAADis/oVP37abRWmY/s1600-h/msn-tomcat-jsp-chinamsn.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_C5USrHsffkE/R_UUhoH84yI/AAAAAAAADis/oVP37abRWmY/s400/msn-tomcat-jsp-chinamsn.jpg" alt="" id="BLOGGER_PHOTO_ID_5185073113926001442" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And more, you can right click any of the url on its page to see the detail of the link properties. What, something like:&lt;br /&gt;&lt;br /&gt;http://msn.china.ynet.com/view.jsp?oid=32306246&lt;br /&gt;&lt;br /&gt;Although you can say it's just a partner, who cares! Totally wrong, it's Microsoft's Chinese MSN portal which is branded as MSN and Microsoft!&lt;br /&gt;&lt;br /&gt;However, it may give Microsoft a chance to say "you see our demos of how unstable of a free software like Tomcat, JSP, Linux, MySql combination! We are considering migrate them to IIS2020+.NET2020+SqlServer2020!".&lt;br /&gt;&lt;br /&gt;Wait, one more footnote "until we can make even of MSN in China!".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-8576142021148844318?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/8576142021148844318/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=8576142021148844318' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/8576142021148844318'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/8576142021148844318'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/microsoft-is-using-tomcat-and-jsp.html' title='Microsoft favours Enterprise Java Platform'/><author><name>Java Blues</name><uri>http://www.blogger.com/profile/02681848616646299865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_C5USrHsffkE/R_UKvIH84xI/AAAAAAAADik/PeTn6vpJjWA/s72-c/msn-tomcat-jsp.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-7929829273312057502</id><published>2008-04-02T09:40:00.000-07:00</published><updated>2008-04-17T10:06:25.384-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Language'/><title type='text'>TypeSafe Enum and equals()</title><content type='html'>&lt;span style="font-weight: bold;"&gt;At first it seems a No Brainer Problem&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you assign the same pre-initialized instance of the same class to two variables, do they always equal to each other? Note that this is the typical pre-jdk1.5 typesafe enum pattern.&lt;br /&gt;&lt;pre&gt;public class ReagentType implements Serializable{&lt;br /&gt;private static final String PROTEIN_TYPE = "PROTEIN";&lt;br /&gt;// more types here&lt;br /&gt;&lt;br /&gt;public ReagentType PROTEIN = new ReagentType(PROTEIN_TYPE);&lt;br /&gt;// more pre-initialized instance here&lt;br /&gt;&lt;br /&gt;private String type;&lt;br /&gt;&lt;br /&gt;public String getType(){&lt;br /&gt;  return this.type;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private ReagentType(String type){&lt;br /&gt;    this.type = type;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void checkEquals(ReagentType a, ReagentType b){&lt;br /&gt;    System.out.println(a.equals(b));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static void main(String[] args){&lt;br /&gt;    ReagentType a = ReagentType.PROTEIN;&lt;br /&gt;    ReagentType b = ReagentType.PROTEIN;&lt;br /&gt;&lt;br /&gt;    checkEquals(a,b);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Sounds like a no brainer. The answer obviously should be yes. checkEquals() method will print out "true". Always. That is, in an ideal world.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;However...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In real world, assuming a &amp;amp; b are both assigned to ReagentType.PROTEIN, in many cases we will see checkEquals() method prints out "false". The standard java equals() compares object identity, which is nothing but the memory location of the object instance, which will most certainly fail in a real world deployment environment.&lt;br /&gt;&lt;ol style="text-align: left;"&gt;&lt;li&gt;Consider Distributed Computing. Either a or b has travelled the wire before checkEquals() method gets it, a.equals(b) is false.  They resides in two different memory location.&lt;/li&gt;&lt;li&gt;Even in a single server, after serializable/deserialization, it's guranteed that an object will have a different memory location. a equals() the serialize/deserialized copy of itself, is false.&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;Consider an EJB invoking a method in another EJB, if they're packaged in different deployment JARs and both contains the ReagentType class, depends how the class loading mechanism in app-server works, there might exists many pre-initialized instance of the REAGENT object and they have different memory location.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Solutions.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Oh yeah, there's always solutions. For one, implement the equals() method properly.&lt;br /&gt;&lt;pre&gt;public boolean equals(Object obj){&lt;br /&gt;  if (obj!=null &amp;amp;&amp;amp; obj instanceof ReagentType){&lt;br /&gt;      return getType().equals( ((ReagentType)obj).getType());&lt;br /&gt;  } else {&lt;br /&gt;      return false;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// hashcode() methods omitted here&lt;/pre&gt;For two, for those who're not big fan of the typesafe enum pattern, they can simply fall back to the good old set-of-static-primitive-values enumeration.&lt;br /&gt;&lt;br /&gt;A note is that while implementation of the RMI readResolve() method might seem to solve this problem, it actually will fail in scenario 3, since the container may decide not to perform serialize/deserialize if the EJBs resides in the same server. However the readResolve() solution should be safe in non-EJB situation where the class loading situation is simpler.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-7929829273312057502?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/7929829273312057502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=7929829273312057502' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/7929829273312057502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/7929829273312057502'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/04/typesafe-enum-and-equals.html' title='TypeSafe Enum and equals()'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-8391439726888829143</id><published>2008-03-31T17:08:00.000-07:00</published><updated>2008-04-20T16:07:21.502-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Language'/><title type='text'>Java Constructor Invocation and Instance Variable Initialization</title><content type='html'>This is a tricky one:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;abstract public class BasePayment {&lt;br /&gt;public BasePayment(){&lt;br /&gt; setFakeValue();&lt;br /&gt;}&lt;br /&gt;abstract public void setFakeValue();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public final class Payment extends BasePayment{&lt;br /&gt;private String property = null;&lt;br /&gt;public Payment(){&lt;br /&gt; super();&lt;br /&gt; System.out.println("after super(): " + this.getProperty());&lt;br /&gt;}&lt;br /&gt;public String getProperty() {&lt;br /&gt; return property;&lt;br /&gt;}&lt;br /&gt;public void setFakeValue() {&lt;br /&gt; System.out.println("Calling setFakeValue()");&lt;br /&gt; this.property = "property";&lt;br /&gt; System.out.println("After setFakeValue(), property: " + this.getProperty());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static void main(String[] args) throws Exception{&lt;br /&gt; Payment p = new Payment();&lt;br /&gt; System.out.println("'new'ed a Payment, property value: " + p.getProperty());&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;What the println in the main() method will output? null? "property"?&lt;br /&gt;&lt;br /&gt;It has something to do whether java will initialize the instance variable first, or will invoke the constructor of the super class first. The behaviour is fully documented (it better be!) at &lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.8.7.1"&gt;http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.8.7.1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And yes, the output is 'null'.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-8391439726888829143?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/8391439726888829143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=8391439726888829143' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/8391439726888829143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/8391439726888829143'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2008/03/java-construction-invocation-and.html' title='Java Constructor Invocation and Instance Variable Initialization'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-4790780457068715792</id><published>2007-12-11T17:51:00.001-08:00</published><updated>2008-04-17T10:04:07.690-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Language'/><title type='text'>Watch out for java SimpleDateFormat</title><content type='html'>&lt;p&gt;Look at this code, what it will come out?&lt;/p&gt;&lt;table unselectable="on" border="0" cellpadding="2" cellspacing="0" width="400"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="400"&gt;&lt;p&gt;import java.text.SimpleDateFormat;&lt;br /&gt;import java.util.Date; &lt;/p&gt;&lt;p&gt;public class Test{&lt;br /&gt;public static void main(String[] args){&lt;br /&gt;  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");&lt;br /&gt;  Date dt = null;&lt;br /&gt;  try{&lt;br /&gt;      dt = sdf.parse("2000999878-3454555-35344");&lt;br /&gt;      System.out.println(sdf.format(dt));&lt;br /&gt;  }catch (Exception e){&lt;br /&gt;      System.out.println("error");     &lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;The result is:&lt;/p&gt;&lt;table unselectable="on" border="0" cellpadding="2" cellspacing="0" width="400"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="400"&gt;&lt;strong&gt;247625706-07-03&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Is this what you expected? You thought it would have thrown an exception of invalid format of text you passed in.&lt;/p&gt;&lt;p&gt;It's very common for a developer do date and time data conversion from text and vice versa in different format. Will it breach your boundary validation if you purely rely on this stupid SimpleDateFormat class?&lt;/p&gt;&lt;p&gt;Work around so far like:&lt;/p&gt;&lt;table unselectable="on" border="0" cellpadding="2" cellspacing="0" width="400"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="400"&gt;&lt;p&gt;import java.text.SimpleDateFormat;&lt;br /&gt;import java.util.Date; &lt;/p&gt;&lt;p&gt;public class Test{&lt;br /&gt;public static void main(String[] args){&lt;br /&gt;SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");&lt;br /&gt;Date dt = null;&lt;br /&gt;try{&lt;br /&gt;  dt = sdf.parse("2000999878-3454555-35344");&lt;br /&gt;  String s = sdf.format(dt);&lt;br /&gt;  if(!s.equals("2000999878-3454555-35344"))&lt;br /&gt;    System.out.println("Data format wrong!");&lt;br /&gt;}catch (Exception e){&lt;br /&gt;  System.out.println("error");&lt;br /&gt;}&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Ugly codes, but works. &lt;/p&gt;&lt;p&gt;How many online Web systems relying on Java and J2EE have those codes?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-4790780457068715792?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/4790780457068715792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=4790780457068715792' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/4790780457068715792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/4790780457068715792'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2007/12/is-sun-developer-over-smart-or-just.html' title='Watch out for java SimpleDateFormat'/><author><name>Java Blues</name><uri>http://www.blogger.com/profile/02681848616646299865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-8970651656620753095</id><published>2007-11-07T11:13:00.001-08:00</published><updated>2008-04-20T15:34:08.873-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='Java Monitoring'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Manageable Spring Application - enable JMX in minutes</title><content type='html'>&lt;p&gt;We are keeping talking about manageability of an application. Why is it so important? Because at any stage of the application lifecycle, you need a way to probe the some key aspects of the application's internal status and take appropriate actions to change the application's behaviors as a consequence. Without it, you just guess the application's runtime status and never able to steer it per your needs.&lt;/p&gt; &lt;p&gt;But hold on, it's easy to talk about manageability. And it's really a great idea in the air until you want put it in a concrete base in your application. It's so cumbersome, tedious and error prone to make an implementation. There are couples of option you could choose to inject the manageability in your application:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Your own proprietary mechanism.&lt;/li&gt; &lt;li&gt;Standard SNMP&lt;/li&gt; &lt;li&gt;JMX&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Forget about option 1, smart as you, don't want invent any wheel. Well, SNMP (Simple Network Management Protocol) sounds good: standardized, bunch of tools and applications and really structured, until you dig in the details of all the ugly OID (Obejct Identification) definitions, binary format, pure data driven approach. And difficulties of debugging. Plus extra cost for those usable commercial SNMP tools and editors.&lt;/p&gt; &lt;p&gt;Fortunately,  we are in campus of Java, which is so far the only language and platform that put the serious crucial enterprise aspects intrinsically in the body, especially manageability in an offer as JMX. For the people working for .Net, either they just don't know what is the manageability, or struggling with various proprietary approaches or annoying SNMP stuffs.&lt;/p&gt; &lt;p&gt;Best of the best in Java application manageability is that we have the generous platform MBean Server as a gift from SUN in new version of JVM, which save your efforts looking for a MBean server; we have the JConsole as tool to directly craft your JMX management GUI frontend; and the offer from Spring's JMX supports. Combine them together, you can make any Java application JMX enabled in minutes. &lt;/p&gt; &lt;p&gt;Here is a simple example called MockServer. It's just a simple socket server for any mock testing purpose. With JMX, you can get the information and stop it in runtime.&lt;/p&gt; &lt;p&gt;Following is the partial code snippets, which is definitely the beautiful POJO. No any special MBean or MXBean stuffs in it, see!&lt;/p&gt; &lt;table unselectable="on" border="0" cellpadding="2" cellspacing="0" width="643"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="641"&gt; &lt;p&gt;/**&lt;br /&gt;* A mock Socket server.&lt;br /&gt;*/&lt;br /&gt;public class MockServer implements Runnable{&lt;br /&gt;private String name="";&lt;br /&gt;private int port = 80;&lt;br /&gt;private boolean bSSL = false;&lt;br /&gt;private int sotimeout = 2*60*1000;//2 minutes  &lt;/p&gt;&lt;p&gt;    private ServerSocket listeningSocket = null;&lt;br /&gt;private boolean bStop=false;&lt;br /&gt;private long connCounts = 0; //Ongoing total connection counter.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;public MockServer(String name, boolean isSSL, int port, int sotimeout){&lt;br /&gt;   this.name = name;&lt;br /&gt;   this.bSSL = isSSL;&lt;br /&gt;   this.port = port;&lt;br /&gt;   this.sotimeout = sotimeout;&lt;br /&gt;} &lt;/p&gt; &lt;p&gt;    public String getName(){&lt;br /&gt;   return name;&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    public int getPort(){&lt;br /&gt;   return port;&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    public boolean isSSL(){&lt;br /&gt;   return bSSL;&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    public int getSotimeout(){&lt;br /&gt;   return sotimeout;&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    public boolean isStopped(){&lt;br /&gt;   return bStop;&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    public void stop(){&lt;br /&gt;   bStop = true;&lt;br /&gt;   try {&lt;br /&gt;       listeningSocket.close();&lt;br /&gt;   } catch (IOException e) {&lt;br /&gt;       e.printStackTrace();&lt;br /&gt;   }&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    protected void createListeningSocket() throws IOException {&lt;br /&gt;   ServerSocketFactory factory = (bSSL? SSLServerSocketFactory.getDefault():ServerSocketFactory.getDefault());&lt;br /&gt;   listeningSocket = (ServerSocket) factory.createServerSocket(port);&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    public void run(){&lt;br /&gt;   System.out.println("Server: "+getName()+" started.");&lt;br /&gt;   try {&lt;br /&gt;       createListeningSocket();&lt;br /&gt;       while (!isStopped()){&lt;br /&gt;           Socket worker = listeningSocket.accept();&lt;br /&gt;           //Spawn a thread to handle the request.&lt;br /&gt;           fork(worker);&lt;br /&gt;       }&lt;br /&gt;   }catch (Exception e){&lt;br /&gt;       e.printStackTrace();&lt;br /&gt;   }finally {&lt;br /&gt;       if (null!=listeningSocket){&lt;br /&gt;           try {&lt;br /&gt;               listeningSocket.close();&lt;br /&gt;           } catch (IOException e) {&lt;br /&gt;               e.printStackTrace();&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;   System.out.println("Server: "+getName()+" stopped.");&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    protected void fork(Socket worker){&lt;br /&gt;   Thread wt = new Thread(new Worker(worker));&lt;br /&gt;   wt.start();&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    public long getConnCounts(){&lt;br /&gt;   return connCounts;&lt;br /&gt;}&lt;br /&gt;protected synchronized void addCount(){&lt;br /&gt;   this.connCounts++;&lt;br /&gt;}&lt;br /&gt;protected synchronized void minusCount(){&lt;br /&gt;   this.connCounts--;&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    protected class Worker implements Runnable {&lt;br /&gt;   private Socket socket=null;  &lt;/p&gt;&lt;p&gt;        protected Worker(Socket socket){&lt;br /&gt;       this.socket = socket;&lt;br /&gt;   }  &lt;/p&gt;&lt;p&gt;        public void run() {&lt;br /&gt;       addCount();&lt;br /&gt;       byte[] buf = new byte[1024*10];//10K buffer&lt;br /&gt;       InputStream is;&lt;br /&gt;       OutputStream os;&lt;br /&gt;       try {&lt;br /&gt;           //Read request from socket input stream.&lt;br /&gt;           is = socket.getInputStream();&lt;br /&gt;           int size = is.read(buf);&lt;br /&gt;           is.close();&lt;br /&gt;           //Process the request.&lt;br /&gt;           byte[] resp = processRequest(buf, size);  &lt;/p&gt;&lt;p&gt;                //Write back the response to socket output stream.&lt;br /&gt;           os = socket.getOutputStream();&lt;br /&gt;           os.write(resp);&lt;br /&gt;           os.flush();&lt;br /&gt;           os.close();&lt;br /&gt;       } catch (IOException e) {&lt;br /&gt;           e.printStackTrace();&lt;br /&gt;       }finally{&lt;br /&gt;           if(null != socket){&lt;br /&gt;               try {&lt;br /&gt;                   socket.close();&lt;br /&gt;               } catch (IOException e) {&lt;br /&gt;                   e.printStackTrace();&lt;br /&gt;               }&lt;br /&gt;           }&lt;br /&gt;           minusCount();&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    //Subclasses to override it.&lt;br /&gt;protected byte[] processRequest(byte[] buf, int size){&lt;/p&gt; &lt;p&gt;         return buf;//echo it.&lt;/p&gt; &lt;p&gt;   }&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="641"&gt; &lt;p&gt;/**&lt;br /&gt;* A mock server services to manage the mock servers.&lt;br /&gt;*/&lt;br /&gt;public class MockServerService {&lt;br /&gt;private Set&amp;lt;MockServer&amp;gt; servers = null;  &lt;/p&gt;&lt;p&gt;    public void setServers(Set&amp;lt;MockServer&amp;gt; servers){&lt;br /&gt;   this.servers = servers;&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    protected void init(){&lt;br /&gt;   if(null != servers){&lt;br /&gt;       for(MockServer server: servers){&lt;br /&gt;           new Thread(server).start();&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;   System.out.println("Service initialized.");&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    public Set&amp;lt;MockServer&amp;gt; getServers(){&lt;br /&gt;   return servers;&lt;br /&gt;}  &lt;/p&gt;&lt;p&gt;    public void stop(){&lt;br /&gt;   if(null != servers){&lt;br /&gt;       for(Server server: servers){&lt;br /&gt;           server.stop();&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;   System.out.println("Service stopped.");&lt;br /&gt;}&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="641"&gt;Then we need an application entry point and integrate with Spring.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="641"&gt; &lt;p&gt;public class MockServer {&lt;br /&gt;public static void main(String[] args){&lt;br /&gt;   AbstractApplicationContext ctxt = new ClassPathXmlApplicationContext("context-mockserver.xml");&lt;br /&gt;   ctxt.registerShutdownHook();&lt;br /&gt;   MockServerService service = (MockServerService) ctxt.getBean("mockServerService");&lt;br /&gt;   service.init();&lt;br /&gt;}&lt;br /&gt;}&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="641"&gt;the context file for Sring defining the beans.&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="641"&gt; &lt;p&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns="&lt;a href="http://www.springframework.org/schema/beans%22"&gt;http://www.springframework.org/schema/beans"&lt;/a&gt;&lt;br /&gt;  xmlns:xsi="&lt;a href="http://www.w3.org/2001/XMLSchema-instance%22"&gt;http://www.w3.org/2001/XMLSchema-instance"&lt;/a&gt;&lt;br /&gt;  xsi:schemaLocation="&lt;a href="http://www.springframework.org/schema/beans"&gt;http://www.springframework.org/schema/beans&lt;/a&gt; &lt;a href="http://www.springframework.org/schema/beans/spring-beans-2.0.xsd%22"&gt;http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"&lt;/a&gt;&amp;gt;&lt;br /&gt;&amp;lt;bean id="mockProcessor0" class="MockServer" &amp;gt;&lt;br /&gt;   &amp;lt;constructor-arg index="0" value="Server1"/&amp;gt;&lt;br /&gt;   &amp;lt;constructor-arg index="1" value="false"/&amp;gt;&lt;br /&gt;   &amp;lt;constructor-arg index="2" value="80"/&amp;gt;&lt;br /&gt;   &amp;lt;constructor-arg index="3" value="120000"/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;lt;bean id="mockProcessor1" class="MockServer" &amp;gt;&lt;br /&gt;   &amp;lt;constructor-arg index="0" value="Server2"/&amp;gt;&lt;br /&gt;   &amp;lt;constructor-arg index="1" value="false"/&amp;gt;&lt;br /&gt;   &amp;lt;constructor-arg index="2" value="90"/&amp;gt;&lt;br /&gt;   &amp;lt;constructor-arg index="3" value="120000"/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;lt;bean id="mockProcessor2" class="MockServer" &amp;gt;&lt;br /&gt;   &amp;lt;constructor-arg index="0" value="Server3"/&amp;gt;&lt;br /&gt;   &amp;lt;constructor-arg index="1" value="false"/&amp;gt;&lt;br /&gt;   &amp;lt;constructor-arg index="2" value="100"/&amp;gt;&lt;br /&gt;   &amp;lt;constructor-arg index="3" value="120000"/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;  &lt;/p&gt;&lt;p&gt;    &amp;lt;bean id="mockServerService" class="MockServerService"&amp;gt;&lt;br /&gt;   &amp;lt;property name="servers"&amp;gt;&lt;br /&gt;       &amp;lt;set&amp;gt;&lt;br /&gt;           &amp;lt;ref local="mockProcessor0"/&amp;gt;&lt;br /&gt;           &amp;lt;ref local="mockProcessor1"/&amp;gt;&lt;br /&gt;           &amp;lt;ref local="mockProcessor2"/&amp;gt;&lt;br /&gt;       &amp;lt;/set&amp;gt;&lt;br /&gt;   &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Until now, nothing to do with JMX. You can run it as a normal Spring application. You can use JConsole to connect with it locally, if you run the application in this command line:&lt;/p&gt; &lt;p&gt;java -cp . -D-Dcom.sun.management.jmxremote MockServer&lt;/p&gt; &lt;p&gt;This is the snapshot of JConsole MBeans tab. Besides the default threads, memory etc. JVM MXBeans, you can't do anything else to this application.&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_C5USrHsffkE/RzIPFAyJBUI/AAAAAAAADYg/9rqMhv3gLD4/s1600-h/JConsoleSna1.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_C5USrHsffkE/RzIPFAyJBUI/AAAAAAAADYg/9rqMhv3gLD4/s320/JConsoleSna1.jpg" alt="" id="BLOGGER_PHOTO_ID_5130179504312485186" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Now, let's just simply tweak the context file, then see what happens. Add this extra block just at the end of the context file.&lt;/p&gt; &lt;p&gt;... &lt;/p&gt;&lt;p&gt;    &amp;lt;bean id="mockServerService" class="MockServerService"&amp;gt;&lt;br /&gt;   &amp;lt;property name="servers"&amp;gt;&lt;br /&gt;       &amp;lt;set&amp;gt;&lt;br /&gt;           &amp;lt;ref local="mockProcessor0"/&amp;gt;&lt;br /&gt;           &amp;lt;ref local="mockProcessor1"/&amp;gt;&lt;br /&gt;           &amp;lt;ref local="mockProcessor2"/&amp;gt;&lt;br /&gt;       &amp;lt;/set&amp;gt;&lt;br /&gt;   &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;lt;bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"&amp;gt;&lt;br /&gt;   &amp;lt;property name="beans"&amp;gt;&lt;br /&gt;       &amp;lt;map&amp;gt;&lt;br /&gt;           &amp;lt;entry key="bean:name=MockProcessor0" value-ref="mockProcessor0"/&amp;gt;&lt;br /&gt;           &amp;lt;entry key="bean:name=MockProcessor1" value-ref="mockProcessor1"/&amp;gt;&lt;br /&gt;           &amp;lt;entry key="bean:name=MockProcessor2" value-ref="mockProcessor2"/&amp;gt;&lt;br /&gt;           &amp;lt;entry key="bean:name=MockServerService" value-ref="mockServerService"/&amp;gt;&lt;br /&gt;       &amp;lt;/map&amp;gt;&lt;br /&gt;   &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;... &lt;/p&gt;&lt;p&gt;Here it is! The new JConsole MBeans tab populated with your beans. Now you can see the name of each bean and stop it just by invoking the corresponding stop() method of that bean. Done! You can manage your Spring application now!&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_C5USrHsffkE/RzIP-wyJBVI/AAAAAAAADYo/VQFgYOnN8E4/s1600-h/JConsoleSna2.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_C5USrHsffkE/RzIP-wyJBVI/AAAAAAAADYo/VQFgYOnN8E4/s400/JConsoleSna2.jpg" alt="" id="BLOGGER_PHOTO_ID_5130180496449930578" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_C5USrHsffkE/RzIP_wyJBWI/AAAAAAAADYw/oKtJx8ApiT0/s1600-h/JConsoleSna3.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_C5USrHsffkE/RzIP_wyJBWI/AAAAAAAADYw/oKtJx8ApiT0/s400/JConsoleSna3.jpg" alt="" id="BLOGGER_PHOTO_ID_5130180513629799778" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_C5USrHsffkE/RzIQAgyJBXI/AAAAAAAADY4/bnGsg0hfYi8/s1600-h/JConsoleSna4.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_C5USrHsffkE/RzIQAgyJBXI/AAAAAAAADY4/bnGsg0hfYi8/s400/JConsoleSna4.jpg" alt="" id="BLOGGER_PHOTO_ID_5130180526514701682" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;In a nutshell, following this pattern, you can tweak any of your applications to be manageable in minutes:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Define the management interfaces for your Object.&lt;/li&gt; &lt;li&gt;Spring your application and expose the object as MBean you want control. Nevertheless, Spring is a extremely noninvasive container, don't be afraid. The things need you Springlize is just make a context file for beans, add less than 5 lines of code to create the application context and put the spring.jar in your classpath. Everything is so familiar to you in a POJO world.&lt;/li&gt; &lt;li&gt;Enable the JVM JMX platform MBean server in command line with -Dcom.sun.management.jmxremote and run it. &lt;/li&gt; &lt;li&gt;Launch the JConsole and connect to the application then control it in your hands. &lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-8970651656620753095?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/8970651656620753095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=8970651656620753095' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/8970651656620753095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/8970651656620753095'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2007/11/manageable-spring-application-enable.html' title='Manageable Spring Application - enable JMX in minutes'/><author><name>Java Blues</name><uri>http://www.blogger.com/profile/02681848616646299865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_C5USrHsffkE/RzIPFAyJBUI/AAAAAAAADYg/9rqMhv3gLD4/s72-c/JConsoleSna1.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-1034233532976834900</id><published>2007-11-06T09:37:00.000-08:00</published><updated>2008-04-19T18:18:17.368-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Security'/><title type='text'>1.5 &amp; 2 Factor Authentication</title><content type='html'>1.5 factors:&lt;br /&gt;&lt;br /&gt;The Grid data solution:&lt;br /&gt;&lt;a href="http://www.brianmadden.com/blog/iForum07/Grid-Data-Security-introduces-really-cool-15-factor-authentication-for-Citrix"&gt;http://www.brianmadden.com/blog/iForum07/Grid-Data-Security-introduces-really-cool-15-factor-authentication-for-Citrix&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Passmark Security's (acquired by RSA):&lt;br /&gt;&lt;a href="http://www.rsa.com/node.aspx?id=3072"&gt;http://www.rsa.com/node.aspx?id=3072&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2 factors:&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Two-factor_authentication"&gt;http://en.wikipedia.org/wiki/Two-factor_authentication&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;However, don't trust these too much because 2 factor authentication does not work:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.washingtonpost.com/securityfix/2006/07/citibank_phish_spoofs_2factor_1.html"&gt;http://blog.washingtonpost.com/securityfix/2006/07/citibank_phish_spoofs_2factor_1.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.schneier.com/blog/archives/2005/03/the_failure_of.html"&gt;http://www.schneier.com/blog/archives/2005/03/the_failure_of.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.vnunet.com/vnunet/news/2139253/two-factor-authentication"&gt;http://www.vnunet.com/vnunet/news/2139253/two-factor-authentication&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.channelregister.co.uk/2005/03/15/2-factor_auth_is_pants/"&gt;http://www.channelregister.co.uk/2005/03/15/2-factor_auth_is_pants/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.cafeid.com/art-sitekey.shtml"&gt;http://www.cafeid.com/art-sitekey.shtml&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Man-in-the-middle attack:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;An attacker puts up a fake bank website and entices user to that website. User types in his password, and the attacker in turn uses it to access the bank's real website. Done right, the user will never realize that he isn't at the bank's website. Then the attacker either disconnects the user and makes any fraudulent transactions he wants, or passes along the user's banking transactions while making his own transactions at the same time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Trojan-horse attack:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Attacker gets Trojan installed on user's computer. When user logs into his bank's website, the attacker piggybacks on that session via the Trojan to make any fraudulent transaction he wants.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;To fight these type of attack:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;The problem here is that the bank's website doesn't authenticate the message source. The attacker's computer sends the transaction request to the bank, and the bank trusted it blindly during and after the authentication process.  The message source, i.e. both the hardware and the software sending the message, must include itself as part of the authentication token as well as in the following transaction requests.&lt;br /&gt;&lt;br /&gt;In the trojan-horse attack, the trojan software is not the original software that generates the request. It will try to generate the exact same transaction request the original software will be generating, but ultimitally, it is still not the original software and cannot predict the behaviour of the original software in a full scale. As long as the original software is properly protected against reverse-engineering and have a way to generate some ever-changing additional piece of information that the server can use to validate it's authenticity, (better, this piece of information has something to do with the transaction request itself), it makes it more difficult for the trojan to generate his own transaction request for his own benefit.&lt;br /&gt;&lt;br /&gt;In the man-in-the-middle attack, the hacker does not own the user's computer, he cannot overcome this obfuscate without physical involvement. Serial number of the CPU of user's computer? MAC of one of his network card? Some secret signature on user's hard-disk? The problem is that the cient and the server must, separately, has a way to obtain this piece of information independent of each other. This can be quite a difficult problem.&lt;br /&gt;&lt;br /&gt;In case of http request, one way I can think of is to use the REMOTE_ADDR cgi variable.  Server can get this from the http header, client can get this, by performing a lookup to sites like&lt;br /&gt;&lt;a href="http://www.whatismyip.org/"&gt;http://www.whatismyip.org/&lt;/a&gt; or some similar service provided by the bank.&lt;br /&gt;&lt;br /&gt;The client can use REMOTE_ADDR to salt the authentication token as well as future requests. The server can decrypt it using the REMOTE_ADDR variable in the request. Thus, if the man-in-the-middle intercepted the communication and try to relay it to the server,  the authentication will be invalid  because the REMOTE_ADDR is different as in the original request.&lt;br /&gt;&lt;br /&gt;In order to defeat this, the man-in-the-middle will need to not only intercept the communication to the bank, but also to intercept the client's request to get the REMOTE_ADDR and respond with the REMOTE_ADDR of the phishing website. This will require a network device very close to the  user's computer, and is quite difficult for most phishing sites.&lt;br /&gt;&lt;br /&gt;Another method the man-in-the-middle can try is to decrypt the communication and re-encrypt it with his own REMOTE_HOST environment setting. The way we can fight against this is to use a strong encryption algorithm that needs some good amount of time to be defeated. Thus, by the time the communication is decrypted and re-encrypted, the ever-changing part is already invalid and useless.  RSA? SHA? RIPEND? &lt;a href="http://www.keylength.com/"&gt;http://www.keylength.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Do they work?&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;Unfortunately, the above solution also does not work. the attacker, being his first step, is to analyze the site/application he's going to phish, and because of the openess of the web page, any code generating the hardware/software identification token will be discovered sooner or later, and he'll incorporate them in the phishing website/trojan software. It'll be more difficult for him if it's a obfuscated standalone application and/or webpages with their source code protected (&lt;a href="http://www.antssoft.com/htmlprotector/index.htm"&gt;http://www.antssoft.com/htmlprotector/index.htm&lt;/a&gt;), but not at all impossible.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-1034233532976834900?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/1034233532976834900/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=1034233532976834900' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/1034233532976834900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/1034233532976834900'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2007/11/15-2-factor-authentication.html' title='1.5 &amp; 2 Factor Authentication'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-7019038014658648867</id><published>2007-11-06T09:26:00.000-08:00</published><updated>2008-04-17T10:47:47.096-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Spring Property Placeholder Configurer</title><content type='html'>A way to separate configuration parameters: &lt;a href="http://almaer.com/blog/spring-propertyplaceholderconfigurer-a-nice-clean-way-to-share"&gt;http://almaer.com/blog/spring-propertyplaceholderconfigurer-a-nice-clean-way-to-share&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-7019038014658648867?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/7019038014658648867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=7019038014658648867' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/7019038014658648867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/7019038014658648867'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2007/11/spring-property-placeholder-configurer.html' title='Spring Property Placeholder Configurer'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-6067533940942647018</id><published>2007-10-25T14:44:00.000-07:00</published><updated>2008-07-10T14:56:54.411-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Concurrency'/><category scheme='http://www.blogger.com/atom/ns#' term='Java Language'/><title type='text'>Singleton vs. Multiton &amp; Synchronization</title><content type='html'>&lt;p style="font-weight: bold;"&gt;1. The classic java singleton synchronization problem&lt;/p&gt;&lt;pre&gt;public class Singleton{&lt;br /&gt;private static Singleton instance;&lt;br /&gt;&lt;br /&gt;/** Prevents instantiating by other classes. */&lt;br /&gt;private Singleton(){}&lt;br /&gt;&lt;br /&gt;public static synchronized Singleton getInstance()&lt;br /&gt; if (instance == null){&lt;br /&gt;     instance = new Singleton();&lt;br /&gt; }&lt;br /&gt; return instance;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div style="text-align: left;"&gt;The synchronized keyword on the getInstance() method is the evil. In a multi-thread environment, every thread will be blocked by each other when trying to grab the singleton instance. This is the classic java singleton synchronization problem. &lt;/div&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;2. The traditional solution using a static variable&lt;/span&gt; &lt;/p&gt;&lt;pre&gt;public class Singleton {&lt;br /&gt;private final static Singleton instance = new Singleton();&lt;br /&gt;&lt;br /&gt;/** Prevents instantiating by other classes. */&lt;br /&gt;private Singleton() {}&lt;br /&gt;&lt;br /&gt;public static Singleton getInstance() {&lt;br /&gt; return instance;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div style="text-align: left;"&gt;The singleton instance is initialized during the class loading time. No synchronization is necessary on the getInstance level&lt;/div&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;3. The Classic synchronized Multiton&lt;/span&gt; &lt;/p&gt;&lt;pre&gt;public class Multiton{&lt;br /&gt;private static final HashMap&amp;lt;Object, Multiton&amp;gt; instances = new HashMap&amp;lt;Object, Multiton&amp;gt;();&lt;br /&gt;&lt;br /&gt;private Multiton(){}&lt;br /&gt;&lt;br /&gt;public static Multiton getInstance(Object key){&lt;br /&gt; synchronized (instances) {&lt;br /&gt;     // Our "per key" singleton&lt;br /&gt;     Multiton instance;&lt;br /&gt;     if ((instance = instances.get(key)) == null) {&lt;br /&gt;         // Lazily create instance and add it to the map&lt;br /&gt;         instance = new Multiton();&lt;br /&gt;         instances.put(key, instance);&lt;br /&gt;     }&lt;br /&gt;     return instance;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div style="text-align: left;"&gt;The Multiton pattern begins with the concept of the Singleton pattern and expands it into an object pool of keys to objects. Instead of having a single instance per runtime, the Multiton pattern ensures a single instance per key. It simplifies retrieval of shared objects in an application.&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;As we noticed from the above scriptlet, the access to the getInstance() method is synchronized to ensure the uniqueness of instance per key. This, again, is a performance bottleneck in multi-thread environment. The traditional 'static' solution for Singleton pattern can't be used here since the keys are passed into the Multiton on-the-fly. We have no way to predict how many keys will be passed into the Multiton during the runtime. &lt;/div&gt;&lt;p style="font-weight: bold;"&gt;4. The double-checked locking solution&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;public class Multiton {&lt;br /&gt;private static final HashMap&amp;lt;Object, Multiton&amp;gt; instances = new HashMap&amp;lt;Object, Multiton&amp;gt;();&lt;br /&gt;&lt;br /&gt;public static Multiton getInstance(Object key) {&lt;br /&gt; // Our "per key" singleton&lt;br /&gt; Multiton instance;&lt;br /&gt; if ((instance = instances.get(key)) == null){&lt;br /&gt;     synchronized(instances){&lt;br /&gt;         if ((instance = instances.get(key)) == null){&lt;br /&gt;             instance = new Multiton();&lt;br /&gt;             instances.put(key, instance);&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt; return instance;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div style="text-align: left;"&gt;Yes the double-checked locking does &lt;strong&gt;not&lt;/strong&gt; work for Singleton (&lt;a href="http://www.cs.umd.edu/%7Epugh/java/memoryModel/DoubleCheckedLocking.html"&gt;http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html&lt;/a&gt;), but it &lt;strong&gt;does&lt;/strong&gt; work for our Multiton pattern. Reason? We have our intermediate HashMap object sits in between. Actually we can use the HashMap to solve the Singleton double-checked locking problem as well, if we don't already have the more elegant solution using a static variable. &lt;/div&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;5. An alternative solution: Using the Java 5 ConcurrentMap&lt;/span&gt; &lt;/p&gt;&lt;pre&gt;public class Multiton {&lt;br /&gt;private static final ConcurrentMap&amp;lt;Object, Multiton&amp;gt; instances = new ConcurrentHashMap&amp;lt;Object, Multiton&amp;gt;();&lt;br /&gt;&lt;br /&gt;public static Multiton getInstance(Object key) {&lt;br /&gt; // Our "per key" singleton&lt;br /&gt; if (instances.get(key) == null){&lt;br /&gt;     // Lazily create instance and try to add it to the map&lt;br /&gt;     Multiton instance = new Multiton();&lt;br /&gt;     instances.putIfAbsent(key, instance);&lt;br /&gt; }&lt;br /&gt; return instances.get(key);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div style="text-align: left;"&gt;The Java 5 ConcurrentMap.putIfAbsent(), being an atomic operation, returns the previous value associated with the key instead of the new suggested value. This ensures the uniqueness of the Multiton instance inside the ConcurrentMap.&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;In this solution, before a key object has been associated with a Multiton object, if two or more threads are trying to retrieve the instance with the same key object, it's possible that multiple Multiton instance will be created inside the if() block. However, the ConcurrentMap ensures that a same Multiton instance is  to be returned to the caller. Extra instances are eligible for Garbage Collection as soon as the method returns. You may not want to use this solution if the creation of the Multiton instance is an expensive operation, as in certain situation. &lt;/div&gt;&lt;p style="font-weight: bold;"&gt;6. Afterwords&lt;/p&gt;&lt;div style="text-align: left;"&gt;&lt;div style="text-align: left;"&gt;Synchronization and double-checked locking is such an interesting classic java topic, I'm so much wanting to participating in any sort of discussion, it'll always be interesting :)&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-6067533940942647018?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/6067533940942647018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=6067533940942647018' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/6067533940942647018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/6067533940942647018'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2007/10/singleton-vs-multiton-synchronization.html' title='Singleton vs. Multiton &amp; Synchronization'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-6800563968305909734</id><published>2007-10-24T15:36:00.000-07:00</published><updated>2008-04-17T10:07:02.899-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Performance'/><title type='text'>Java Performance - ALL Tips</title><content type='html'>Oh yes, this is a complete list of &lt;span style="font-weight: bold;"&gt;ALL&lt;/span&gt; Java perfomance tips. Thanks for www.javaperformancetuning.com&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.javaperformancetuning.com/tips/rawtips.shtml"&gt; http://www.javaperformancetuning.com/tips/rawtips.shtml&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-6800563968305909734?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/6800563968305909734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=6800563968305909734' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/6800563968305909734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/6800563968305909734'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2007/10/java-performance-all-tips.html' title='Java Performance - ALL Tips'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-3866523245885416252</id><published>2007-10-23T23:56:00.001-07:00</published><updated>2008-04-17T10:50:20.865-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Bean Definitions Tip1: Avoid Circular References</title><content type='html'>&lt;p&gt;Spring is a really powerful framework, which is not only providing the JEE similar or much better and lighter container services, but also providing a straightforward declarative and configuration driven bean definition model. With the flexibility and capability of bean definition mechanism, especially when you unleashing the power of XML schema based context file introduced since Spring 2.0, you can almost do any sorts of bean wiring, parameter configuration, application assembling tasks. After you use it, I bet you will forget all the unpleasant and cumbersome JEE configuration files and the coarse grained Enterprise Beans. However, when dealing with bean definitions, it's still very tricky and the similar problems probably happen as in your traditional programmatic approach.&lt;/p&gt;  &lt;p&gt;One typical problem is that the bean definition circular referencing. This is the circumstance under which there are beans relying on each others instance before they could be instantiated by Spring container. &lt;/p&gt;  &lt;p&gt;For below example:&lt;/p&gt;  &lt;table border="0" cellpadding="2" cellspacing="0" width="683"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="681"&gt;         &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;public class BeanA {               &lt;br /&gt;    BeanB b;                &lt;br /&gt;    public BeanA(BeanB beanB){                &lt;br /&gt;        b = beanB;                &lt;br /&gt;    }                &lt;br /&gt;    public void print(String s) {                &lt;br /&gt;        System.out.print(s);                &lt;br /&gt;    }                &lt;br /&gt;    public void foo(){                &lt;br /&gt;        b.foo();                &lt;br /&gt;    }                &lt;br /&gt;}&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;public class BeanB {               &lt;br /&gt;    private BeanA a;                &lt;br /&gt;    public BeanB(BeanA beanA){                &lt;br /&gt;        a = beanA;                &lt;br /&gt;    } &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;    public void print(String s){               &lt;br /&gt;        a.print(s);                &lt;br /&gt;    } &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;    public void foo() {               &lt;br /&gt;        System.out.print("foo!");                &lt;br /&gt;    }                &lt;br /&gt;}&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;public class TestStub {               &lt;br /&gt;    public static void main(String[] args){                &lt;br /&gt;        AbstractApplicationContext ctxt= new ClassPathXmlApplicationContext("beandef.xml");                &lt;br /&gt;    }                &lt;br /&gt;}&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;...bean definitions in beandef.xml ...&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="color:#000080;"&gt;&lt;span style="font-size:85%;"&gt;&lt;em&gt;    &amp;lt;bean id="beanA" class="BeanA"&amp;gt;                 &lt;br /&gt;        &amp;lt;constructor-arg ref="beanB" /&amp;gt;                  &lt;br /&gt;    &amp;lt;/bean&amp;gt;                  &lt;br /&gt;    &amp;lt;bean id="beanB" class="BeanB"&amp;gt;                  &lt;br /&gt;        &amp;lt;constructor-arg ref="beanA"/&amp;gt;                  &lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;/em&gt;&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;When you run TestStub, it will show following exception (pay attention to the underline):&lt;/p&gt;  &lt;table border="0" cellpadding="2" cellspacing="0" width="683"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="681"&gt;         &lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;em&gt;Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanA' defined in class path resource [beandef.xml]: Cannot resolve reference to bean 'beanB' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanB' defined in class path resource [beandef.xml]: Cannot resolve reference to bean 'beanA' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA':&lt;/em&gt; &lt;em&gt;&lt;u&gt;&lt;span style="color:#000080;"&gt;Requested bean is currently in creation:&lt;/span&gt;&lt;/u&gt;&lt;/em&gt; &lt;em&gt;&lt;span style="color:#000080;"&gt;&lt;u&gt;Is there an unresolvable circular reference&lt;/u&gt;&lt;/span&gt;?                &lt;br /&gt;Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanB' defined in class path resource [beandef.xml]: Cannot resolve reference to bean 'beanA' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?                &lt;br /&gt;Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': &lt;u&gt;&lt;span style="color:#000080;"&gt;Requested bean is currently in creation:&lt;/span&gt;&lt;/u&gt; &lt;span style="color:#000080;"&gt;Is there an unresolvable circular reference?&lt;/span&gt;&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;It's a simple sample of bean circular reference. Specifically, the container tried to instantiate "beanA" first, then it found "beanA" need a reference of "beanB" as constructor argument; subsequently, it tried to create an instance of "BeanB" as "beanB", but this time the "beanB" need a "beanA" instance as a constructor reference argument that is still creation pending waiting for "beanB". This situation confused the container and it can not resolve all the bean references. Then it came the complains of exception. This circular reference problem was caused by circular references of bean by means of &lt;u&gt;Constructor Injection&lt;/u&gt;.&lt;/p&gt;  &lt;p&gt;To solve this issue, one option is that replace constructor reference to "beanA" of "beanB" with a setter injection.  Then the container will not try to create the "beanB" with the "beanB" reference at same time. Instead, it will defer this by injecting the "beanA" reference latter on via "setter" method of "BeanB" after the "beanA" has been created. The same changes happen to "BeanA". It needs some tweaks to the code and bean definitions as well.&lt;/p&gt;  &lt;table border="0" cellpadding="2" cellspacing="0" width="690"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="688"&gt;         &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;public class BeanA {              &lt;br /&gt;    BeanB b;               &lt;br /&gt;    public BeanA(){               &lt;br /&gt;    }               &lt;br /&gt;    public void setBeanB(BeanB b){               &lt;br /&gt;        this.b = b;               &lt;br /&gt;    }               &lt;br /&gt;    public void print(String s) {               &lt;br /&gt;        System.out.print(s);               &lt;br /&gt;    }               &lt;br /&gt;    public void foo(){               &lt;br /&gt;        b.foo();               &lt;br /&gt;    }               &lt;br /&gt;}&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;         &lt;br /&gt;         &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;public class BeanB {              &lt;br /&gt;    private BeanA a;               &lt;br /&gt;    public BeanB(){               &lt;br /&gt;    } &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;    public void setBeanA(BeanA a){              &lt;br /&gt;        this.a = a;               &lt;br /&gt;    }               &lt;br /&gt;    public void print(String s){               &lt;br /&gt;        a.print(s);               &lt;br /&gt;    } &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;    public void foo() {              &lt;br /&gt;        System.out.print("foo!");               &lt;br /&gt;    }               &lt;br /&gt;}&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;         &lt;br /&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;...            &lt;br /&gt;&lt;/em&gt;&lt;/span&gt;          &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;&amp;lt;bean id="beanA" class="BeanA"&amp;gt;              &lt;br /&gt;    &amp;lt;property name="beanB" ref="beanB"/&amp;gt;               &lt;br /&gt;&amp;lt;/bean&amp;gt;               &lt;br /&gt;&amp;lt;bean id="beanB" class="BeanB"&amp;gt;               &lt;br /&gt;    &amp;lt;property name="beanA" ref="beanA"/&amp;gt;               &lt;br /&gt;&amp;lt;/bean&amp;gt; &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;         &lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;...&lt;/em&gt;&lt;/span&gt;         &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;This time, the Sping was very happy to create all the beans. &lt;/p&gt;  &lt;p&gt;An alternative option is still workable for this case but a lit bit tricky related with bean instantiating order. We can ask "beanA" injected "beanB" by setter, whereas "beanB" can still use the constructor injection. But wait, the order of bean definition is very important. You can not let constructor injected "beanB" defined before setter injected "beanA".&lt;/p&gt;  &lt;table border="0" cellpadding="2" cellspacing="0" width="692"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="690"&gt;         &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;public class BeanA {              &lt;br /&gt;    BeanB b;               &lt;br /&gt;    public BeanA(){               &lt;br /&gt;    }               &lt;br /&gt;    public void setBeanB(BeanB b){               &lt;br /&gt;        this.b = b;               &lt;br /&gt;    }               &lt;br /&gt;    public void print(String s) {               &lt;br /&gt;        System.out.print(s);               &lt;br /&gt;    }               &lt;br /&gt;    public void foo(){               &lt;br /&gt;        b.foo();               &lt;br /&gt;    }               &lt;br /&gt;}&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;public class BeanB {              &lt;br /&gt;    private BeanA a;               &lt;br /&gt;   public BeanB(BeanA a){               &lt;br /&gt;        this.a = a;               &lt;br /&gt;    } &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;    public void print(String s){              &lt;br /&gt;        a.print(s);               &lt;br /&gt;    } &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;    public void foo() {              &lt;br /&gt;        System.out.print("foo!");               &lt;br /&gt;    }               &lt;br /&gt;}&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&lt;em&gt;...&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#000080;"&gt;&lt;em&gt;&lt;span style="font-size:85%;color:#000080;"&gt;&amp;lt;bean id="beanA" class="BeanA"&amp;gt;                  &lt;br /&gt;    &amp;lt;property name="beanB" ref="beanB"/&amp;gt;                   &lt;br /&gt;&amp;lt;/bean&amp;gt;                   &lt;br /&gt;&lt;/span&gt;&amp;lt;bean id="beanB" class="BeanB"&amp;gt;                 &lt;br /&gt;    &amp;lt;constructor-arg ref="beanA"/&amp;gt;                 &lt;br /&gt;&amp;lt;/bean&amp;gt; &lt;/em&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#000080;"&gt;&lt;em&gt;...                &lt;br /&gt;&lt;/em&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;This works very well. If you move the "beanB" definition before "beanA", it will not work because the "beanA" will need a creating "beanB".&lt;/p&gt;  &lt;p&gt;In a nutshell, the circular reference problem is very typical for a sophisticated "Spring" application if you did not cook it very well. It will cost you time to debug and fix it. But not just that. Because the nature of configuration driven of "Spring", the same bean definition file itself could have huge chances to be manipulated by different personnel, thus, more chances of introducing new errors regarding the "Spring" competency level. I will talk about in future sessions how to address this issue by establishing your project or organization level bean definition schema extended from "Spring" base schema. In this way, it mandates some of important project wise constraints for bean definition, such as available tags, bean types, data types etc. Thus, it could reduce some errors caused by arbitrary string parameters or typos in bean definition files for your project.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;It's strongly recommended to use setter injection for bean wiring and bean reference injection&lt;/strong&gt;. If it's very necessary to do constructor based reference injection, and unfortunately involved with circular reference, please well comment or document the bean definition and put notices for future maintaining people. You don't just want someone else happened to ruin your whole fragile bean constructor injection hierarchy someday, do you?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-3866523245885416252?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/3866523245885416252/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=3866523245885416252' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/3866523245885416252'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/3866523245885416252'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2007/10/bean-definitions-tip1-avoid-circular.html' title='Bean Definitions Tip1: Avoid Circular References'/><author><name>Java Blues</name><uri>http://www.blogger.com/profile/02681848616646299865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-6584199171808629803</id><published>2007-10-17T09:40:00.000-07:00</published><updated>2008-05-07T16:30:26.407-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IntelliJ IDEA'/><category scheme='http://www.blogger.com/atom/ns#' term='Java IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='Performance'/><title type='text'>IntelliJ IDEA Performance</title><content type='html'>There're some concerns about IntelliJ IDEA Performance. And here is the tips that I used to make mine run fast. Some of them come from my own experience, some of them come from the know-everything internet.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Make sure you have all your libraries on your local harddrive (as opposed to mounted network drive). After I moved all my libraries from a network drive to local harddrive, the time for a 'make' on the project is reduced from around 60 seconds to just 5-7 seconds!&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Defragment your Disk and reboot your computer. IDEA creates lots of small files and too much fragmentation is a nightmare.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Turn off Anti Virus completely. Yes I mean completely. It affects the performance dramatically.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Turning off Local History or even reducing the number of history days improved the performance significantly.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Adjust VM settings. Here is my idea.exe.vmoptions file (on windows):&lt;/li&gt;&lt;/ul&gt;-Xms512m&lt;br /&gt;-Xmx512m&lt;br /&gt;-XX:MaxPermSize=99m&lt;br /&gt;-ea&lt;br /&gt;&lt;br /&gt;Change it as you see fit per your hardware configuration.&lt;br /&gt;&lt;br /&gt;More information is available at &lt;a href="http://blogs.jetbrains.com/idea/2006/04/configuring-intellij-idea-vm-options/"&gt;http://blogs.jetbrains.com/idea/2006/04/configuring-intellij-idea-vm-options/&lt;/a&gt;.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="jive-description"&gt;The Debugger in &lt;span class="jive-search-term"&gt;IDEA&lt;/span&gt; may work slowly if the Force classic VM option is not selected in the File  Project Properties  Debugger dialog. Using Method Breakpoints may also slow down the debugging process. I had two breakpoints on the method name instead of the first line of the method. It was taking a half hour to get to the breakpoint Changing these to line breakpoints gave me two orders of magniture&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;You may notice IDEA hang for several seconds when you switch to it from other applicationDisable Settings  General  &lt;b&gt;Synchronize files on frame activation&lt;/b&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Disable windows paging file if you have enough memory. Get more memory if you don't have enough. Swapping is a performance nightmare.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Turn off windows indexing services, either set it to Disabled or Manual unless you do lots of file system search (even you do, I recommend Google Desktop Search). IDEA use lots of small files so background indexing can have a big negative effect on it's performance.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Control Panel/System/Properties/Advanced/Visual Effcts, Adjust for best performance. Unless you're willing to sacrify performance for visual effects like windows animation, fading/sliding etc.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-6584199171808629803?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/6584199171808629803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=6584199171808629803' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/6584199171808629803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/6584199171808629803'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2007/10/intellij-idea-performance.html' title='IntelliJ IDEA Performance'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-3559707974924743099</id><published>2007-10-12T16:23:00.001-07:00</published><updated>2008-04-17T10:00:14.994-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>Hibernate Mapping Cheat Sheet</title><content type='html'>Here's a nice hibernate mapping cheat sheet. Good reference when programming.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ndpsoftware.com/HibernateMappingCheatSheet.html"&gt;http://ndpsoftware.com/HibernateMappingCheatSheet.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-3559707974924743099?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/3559707974924743099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=3559707974924743099' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/3559707974924743099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/3559707974924743099'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2007/10/hibernate-mapping-cheat-sheet.html' title='Hibernate Mapping Cheat Sheet'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-6392508893646491957</id><published>2007-10-12T11:28:00.001-07:00</published><updated>2008-04-17T09:59:33.245-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Test'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>SpringContextAware JUnit TestCase</title><content type='html'>In order to run Junit test case outside of a J2EE container, the test case need to initialize the Spring framework properly. I created this abstract class SpringContextAware, which extends from junit.framework.TestCase and initialize the Spring framework in it's setUp() method. User Test Cases that extends from this class will be running with Spring context loaded already.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;public abstract class SpringContextAware extends TestCase {&lt;br /&gt;   public SpringContextAware(String name){&lt;br /&gt;       super(name);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public void setUp() throws Exception{&lt;br /&gt;       if (SpringApplicationContext.getApplicationContext()==null) {&lt;br /&gt;           AbstractApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{&lt;br /&gt;                   // list your context files here&lt;br /&gt;                   "context-service.xml",&lt;br /&gt;                   "context-hibernate.xml"&lt;br /&gt;           });&lt;br /&gt;       ctx.registerShutdownHook();&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public void tearDown() throws Exception{&lt;br /&gt;   }&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here is the SpringApplicationContext class, basically it allows java classes not defined as a spring bean to be able to access the Spring Application Context.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;public class SpringApplicationContext implements ApplicationContextAware {&lt;br /&gt;&lt;br /&gt;   private static ApplicationContext context;&lt;br /&gt;&lt;br /&gt;   public static ApplicationContext getApplicationContext() {&lt;br /&gt;       return SpringApplicationContext.context;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;   * This method is called from within the ApplicationContext once it is&lt;br /&gt;   * done starting up, it will stick a reference to itself into this bean.&lt;br /&gt;   *&lt;br /&gt;   * @param context a reference to the ApplicationContext.&lt;br /&gt;   */&lt;br /&gt;   public void setApplicationContext(ApplicationContext context) throws BeansException {&lt;br /&gt;       SpringApplicationContext.context = context;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    *This is about the same as context.getBean("beanName"), except it has its&lt;br /&gt;    * own static handle to the Spring context, so calling this method statically&lt;br /&gt;    * will give access to the beans by name in the Spring application context.&lt;br /&gt;    * As in the context.getBean("beanName") call, the caller must cast to the&lt;br /&gt;    * appropriate target class. If the bean does not exist, then a Runtime error&lt;br /&gt;    * will be thrown.&lt;br /&gt;    *&lt;br /&gt;    * @param beanName the name of the bean to get.&lt;br /&gt;    * @return an Object reference to the named bean.&lt;br /&gt;    */&lt;br /&gt;   public static Object getBean(String beanName) {&lt;br /&gt;       return context.getBean(beanName);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This bean itself however, needs to be defined in the Spring Context XML file:&lt;span style="font-style: italic;"&gt;&lt;!-- provide access to spring application context --&gt;&lt;br /&gt;  &lt;bean id="springApplicationContext" class="com.paypros.blackpearl.util.SpringApplicationContext"&gt;&lt;br /&gt;   &amp;lt;!-- provide access to spring application context --&amp;gt;&lt;br /&gt;  &amp;lt;bean id="springApplicationContext" class="com.blah.blah.SpringApplicationContext"&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/bean&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Any comments are welcome :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-6392508893646491957?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/6392508893646491957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=6392508893646491957' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/6392508893646491957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/6392508893646491957'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2007/10/springcontextaware-junit-testcase.html' title='SpringContextAware JUnit TestCase'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8209914483781092632.post-2586040816665546380</id><published>2007-10-12T10:56:00.000-07:00</published><updated>2008-04-19T18:17:55.747-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='Java Security'/><title type='text'>EHCache Singleton CacheManager</title><content type='html'>Here's the problem, when we enable the hibernate secondary cache using &lt;span style="font-style: italic;"&gt;org.hibernate.cache.EHCacheProvider,&lt;/span&gt; and enable ACEGI user cache using&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&amp;lt;property name="userCache"&amp;gt;&lt;br /&gt;          &amp;lt;bean class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"&amp;gt;&lt;br /&gt;              &amp;lt;property name="cache"&amp;gt;&lt;br /&gt;                  &amp;lt;bean class="org.springframework.cache.ehcache.EhCacheFactoryBean"&amp;gt;&lt;br /&gt;                      &amp;lt;property name="cacheName" value="AcegiUserCache"&amp;gt;&lt;br /&gt;                  &amp;lt;/property&amp;gt;&lt;br /&gt;              &amp;lt;/bean&amp;gt;&lt;br /&gt;          &amp;lt;/property&amp;gt;&lt;br /&gt;      &amp;lt;/bean&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;They belongs to two different cache manager.&lt;br /&gt;&lt;br /&gt;Instead of have to configure 2 different cache manager separately, have to have separate cache invalidating thread etc, we can fall back to the EHCache Singleton CacheManager.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;hibernate.cache.provider_class=net.sf.ehcache.hibernate.SingletonEhCacheProvider&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;Now ACEGI will use the same EHCache CacheManager. They can be configured in the same ehcache.xml file. Yup!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8209914483781092632-2586040816665546380?l=j2eeblogger.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://j2eeblogger.blogspot.com/feeds/2586040816665546380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8209914483781092632&amp;postID=2586040816665546380' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/2586040816665546380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8209914483781092632/posts/default/2586040816665546380'/><link rel='alternate' type='text/html' href='http://j2eeblogger.blogspot.com/2007/10/ehcache-singleton-cachemanager.html' title='EHCache Singleton CacheManager'/><author><name>J2EE Blogger</name><uri>http://www.blogger.com/profile/07246396095757518448</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
