<?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-9699730</id><updated>2011-12-14T18:38:14.299-08:00</updated><title type='text'>objectissues</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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>35</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9699730.post-7347416570466710755</id><published>2009-07-07T17:08:00.000-07:00</published><updated>2009-07-07T17:10:55.717-07:00</updated><title type='text'>ESB Key functions</title><content type='html'>&lt;span style="font-weight: bold;"&gt;1) Route messages between different service providers&lt;br /&gt;&lt;/span&gt;Example: A message arrives in oracle AQ and a Java service is called as a result&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;2) Convert the transport protocols&lt;br /&gt;      &lt;/span&gt; Example: Convert a PL/SQl to Java method call &lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;3) Transform the message&lt;br /&gt;&lt;/span&gt;        Example: Oracle AQ payload could be a text message, the  Java call will take an object parameter, so the ESB should do the transformation&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;4) Handle business events from different sources&lt;br /&gt;&lt;/span&gt;       Example: Same Java service can be invoked as a result of a message from oracle AQ or a call from another Java service&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-7347416570466710755?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/7347416570466710755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=7347416570466710755&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/7347416570466710755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/7347416570466710755'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2009/07/esb-key-functions.html' title='ESB Key functions'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-6704652949944021224</id><published>2008-03-23T07:05:00.000-07:00</published><updated>2008-12-09T22:21:04.915-08:00</updated><title type='text'>A simple index test using Oracle 10g free edition</title><content type='html'>&lt;strong&gt;Background&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I downloaded oracle 10g express edition from &lt;a href="http://www.oracle.com/technology/products/database/xe/index.html"&gt;http://www.oracle.com/technology/products/database/xe/index.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I have a Pentium 4 winxp machine with 1gb ram and 320 gb hdd. &lt;br /&gt;&lt;br /&gt;The download and install was a breeze. &lt;br /&gt;&lt;br /&gt;It installs as a service and does start up with windows. However it can be stopped from starting up with windows, by using the services tool in the control panel.&lt;br /&gt;&lt;br /&gt;When up and running the oracle 10g took around 250 mb ram on my pc.&lt;br /&gt;&lt;br /&gt;I do not have toad, but the 10g express edition install comes with SQL command line and also a HTML based UI. The HTML UI though not comparable to Toad, does work alright with the basic tasks.&lt;br /&gt;&lt;br /&gt;I wanted to test out a single column index and see if it mad any difference in searches.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The database and data setup&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The test table and sequence is as below:-&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Sequence details&lt;br /&gt;&lt;br /&gt;CREATE SEQUENCE   "TASK_LIST_SEQ"  &lt;br /&gt;MINVALUE 1 MAXVALUE 999999999999999999999999999 &lt;br /&gt;INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER  NOCYCLE&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;Table details&lt;br /&gt;&lt;br /&gt;CREATE TABLE  "TASK_LIST" &lt;br /&gt;   (    "TASK_ID" NUMBER(18,0) NOT NULL ENABLE, &lt;br /&gt;        "TASK_NAME" VARCHAR2(100) NOT NULL ENABLE, &lt;br /&gt;        "TASK_STATUS" NUMBER(1,0) NOT NULL ENABLE, &lt;br /&gt;         CONSTRAINT "TASK_LIST_PK" PRIMARY KEY ("TASK_ID") ENABLE&lt;br /&gt;   )&lt;br /&gt;/&lt;br /&gt;CREATE OR REPLACE TRIGGER  "BI_TASK_LIST" &lt;br /&gt;  before insert on "TASK_LIST"               &lt;br /&gt;  for each row  &lt;br /&gt;begin   &lt;br /&gt;    select "TASK_LIST_SEQ".nextval into :NEW.TASK_ID from dual; &lt;br /&gt;end; &lt;br /&gt;&lt;br /&gt;/&lt;br /&gt;ALTER TRIGGER  "BI_TASK_LIST" ENABLE&lt;br /&gt;/&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;1) The table holds tasks with their id's, name and status.&lt;br /&gt;2) The id is the primary key.&lt;br /&gt;3) The sequence helps with the id generation automatically with the help of a trigger.&lt;br /&gt;4) The column of interest is TASK_STATUS. I have decided to have status of 1 as complete and 0 as not complete.&lt;br /&gt;&lt;br /&gt;Now we will do the following with the help of a pl/sql block.&lt;br /&gt;&lt;br /&gt;1) Insert 200000 tasks with status 1(complete)&lt;br /&gt;2) Insert 30000 tasks with status 0(not complete).&lt;br /&gt;&lt;br /&gt;The code to do so is as below:-&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;--Insert 200000 tasks with status 1(complete)&lt;br /&gt;declare&lt;br /&gt;   task_name_var varchar2(100);&lt;br /&gt;begin&lt;br /&gt;   for i in 1..200000 loop&lt;br /&gt;      task_name_var := 'Task ' || i;&lt;br /&gt;      --DBMS_OUTPUT.PUT_LINE('task_name_var : ' || task_name_var);&lt;br /&gt;      Insert into &lt;br /&gt;      task_list(task_name, task_status) &lt;br /&gt;      values(task_name_var,1);&lt;br /&gt;   end loop;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;--Insert 30000 tasks with status 0(not complete)&lt;br /&gt;declare&lt;br /&gt;   task_name_var varchar2(100);&lt;br /&gt;begin&lt;br /&gt;   for i in 200001..230000 loop&lt;br /&gt;      task_name_var := 'Task ' || i;&lt;br /&gt;      --DBMS_OUTPUT.PUT_LINE('task_name_var : ' || task_name_var);&lt;br /&gt;      Insert into &lt;br /&gt;      task_list(task_name, task_status) &lt;br /&gt;      values(task_name_var,1);&lt;br /&gt;   end loop;&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Tests without any index&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Test not complete tasks&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;do a select count for all task not complete&lt;br /&gt;&lt;br /&gt;select count(*) from task_list tl where tl.task_status = 0;&lt;br /&gt;&lt;br /&gt;The explain plan (click on the image for greater resolution)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_7DAVU2WEoxA/R-ZpkJuaXDI/AAAAAAAAAJU/RikIWGglZfc/s1600-h/Single+column+status+0+-+without+index.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_7DAVU2WEoxA/R-Zp6puaXFI/AAAAAAAAAJk/d9BGUYt2EVE/s320/Single+column+status+0+-+with+index.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Test complete tasks&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;do a select count for all task complete&lt;br /&gt;&lt;br /&gt;select count(*) from task_list tl where tl.task_status =1;&lt;br /&gt;&lt;br /&gt;The explain plan (click on the image for greater resolution)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_7DAVU2WEoxA/R-Zpw5uaXEI/AAAAAAAAAJc/hoRMKsI4_gU/s1600-h/Single+column+status+1+-+without+index.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_7DAVU2WEoxA/R-Zpw5uaXEI/AAAAAAAAAJc/hoRMKsI4_gU/s320/Single+column+status+1+-+without+index.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5180944710186458178" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Tests with index&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Add the Index &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;create index "TASK_STATUS_IDX1"&lt;br /&gt; on "TASK_LIST" ("TASK_STATUS")&lt;br /&gt;/   &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Test not complete tasks&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;do a select count for all task not complete&lt;br /&gt;&lt;br /&gt;select count(*) from task_list tl where tl.task_status = 0;&lt;br /&gt;&lt;br /&gt;The explain plan (click on the image for greater resolution)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_7DAVU2WEoxA/R-Zp6puaXFI/AAAAAAAAAJk/d9BGUYt2EVE/s1600-h/Single+column+status+0+-+with+index.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_7DAVU2WEoxA/R-Zp6puaXFI/AAAAAAAAAJk/d9BGUYt2EVE/s320/Single+column+status+0+-+with+index.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5180944877690182738" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Test complete tasks&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;do a select count for all task complete&lt;br /&gt;&lt;br /&gt;select count(*) from task_list tl where tl.task_status =1;&lt;br /&gt;&lt;br /&gt;The explain plan (click on the image for greater resolution)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_7DAVU2WEoxA/R-ZqBJuaXGI/AAAAAAAAAJs/Nf3FatyKMHM/s1600-h/Single+column+status+1+-+with+index.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_7DAVU2WEoxA/R-ZqBJuaXGI/AAAAAAAAAJs/Nf3FatyKMHM/s320/Single+column+status+1+-+with+index.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5180944989359332450" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Note:- The number of rows for task complete(task_status - 1) was 200000 and for task not complete(task_status - 0) was 30000.&lt;br /&gt;&lt;br /&gt;1) Without the index the time taken by both searches was 3 and cost was 234&lt;br /&gt;2) With the index the time taken by the task complete(task_status - 1) search was 2 and cost was 131&lt;br /&gt;3) With the index the time taken by the task not complete(task_status - 0) search was 1 and cost was 61.&lt;br /&gt;4) The index on task_status column did improve performance. &lt;br /&gt;5) The performance gain was greater for the task_status value with less number of rows i.e. task not complete(task_status - 0).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-6704652949944021224?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/6704652949944021224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=6704652949944021224&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/6704652949944021224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/6704652949944021224'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2008/03/simple-index-test-using-oracle-10g-free.html' title='A simple index test using Oracle 10g free edition'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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://1.bp.blogspot.com/_7DAVU2WEoxA/R-Zp6puaXFI/AAAAAAAAAJk/d9BGUYt2EVE/s72-c/Single+column+status+0+-+with+index.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9699730.post-2994979065434372375</id><published>2007-08-31T16:26:00.000-07:00</published><updated>2007-08-31T16:30:39.722-07:00</updated><title type='text'>EJB3 local bean access in servlet using glassfish</title><content type='html'>I was trying out Glassfish.&lt;br /&gt;&lt;br /&gt;I made a separate ear with a stateless bean and a war with a servlet that accesses the stateless bean using @EJB injection. I deployed the ejb jar file and also the servlet war file. It did not work. The error was that the servlet did not find the ejb.&lt;br /&gt;&lt;br /&gt;Reading the glassfish docs I came across this question in the glassfish faq.&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------------------------&lt;br /&gt;--------------------------------------------------------------------------------------------&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;Question: I have an EJB with a Local interface.  Can I access it from a web component in a different application?&lt;br /&gt;&lt;br /&gt;Answer: No, not in our implementation.  The EJB spec only requires local ejb access from within the same application in the same JVM.  &lt;/span&gt;&lt;br /&gt;--------------------------------------------------------------------------------------------&lt;br /&gt;--------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Actually that makes a lot of sense.&lt;br /&gt;&lt;br /&gt;All I needed to do was to have an ear file with both the war and ear as modules. That way the local EJB could be found by the servlet.&lt;br /&gt;&lt;br /&gt;Since the servlet needed to access the local interface I also packaged the interface in WEB-INF/lib/ejbinterfaces.jar folder.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-2994979065434372375?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/2994979065434372375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=2994979065434372375&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/2994979065434372375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/2994979065434372375'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2007/08/ejb3-local-bean-access-in-servlet-using.html' title='EJB3 local bean access in servlet using glassfish'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-6430996167040023169</id><published>2007-08-31T16:21:00.000-07:00</published><updated>2007-08-31T16:24:49.542-07:00</updated><title type='text'>serialVersionUID from java 5</title><content type='html'>I started using eclipse with java 5. I got this a compilation warning in one of the realizable class, which said something to the effect that it needs a 'serialVersionUID' field.&lt;br /&gt; &lt;br /&gt;&lt;a href="http://www.doc.ic.ac.uk/csg/java/1.5.0docs/api/java/io/Serializable.html"&gt;&lt;br /&gt;http://www.doc.ic.ac.uk/csg/java/1.5.0docs/api/java/io/Serializable.html&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;The 'serialVersionUID' field helps with making sure that the version of the class that has been serialized, is the same as the version of the class that is de-serialized and if it is not the a invalidClassException is thrown.&lt;br /&gt; &lt;br /&gt;The field looks like 'private static final long serialVersionUID = 42L'.&lt;br /&gt; &lt;br /&gt;Since it needs to be a static field, i guess each class and it's subclasses will need have one field per class declared if there is a heirarchy of classes that need to be serialized.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-6430996167040023169?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/6430996167040023169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=6430996167040023169&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/6430996167040023169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/6430996167040023169'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2007/08/serialversionuid-from-java-5.html' title='serialVersionUID from java 5'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-342183841635738639</id><published>2007-08-21T09:26:00.000-07:00</published><updated>2007-08-21T09:27:42.871-07:00</updated><title type='text'>Some notes on the new java 1.5 concurrent api</title><content type='html'>In the new java 1.5 Concurrent api, there is a lock.tryLock method, which returns false if the lock is already acquired by some other thread. &lt;br /&gt;&lt;br /&gt;I have been in situations where I needed to know if an object lock(via synchronized(object a)) had already been acquired or not. &lt;br /&gt;&lt;br /&gt;I guess it  is simple now with the above 1.5 api.&lt;br /&gt;&lt;br /&gt;However the other important thing to know is, if an object lock is in wait state or not before calling wait or notify on the lock. The 1.5 api has a Condition interface, but i did not see any kind of isWaiting method. &lt;br /&gt;&lt;br /&gt;In java 1.4 i have achieved this by using volatile booleans, setting the boolean just before calling wait and then unsetting the boolean just after the notify. &lt;br /&gt;&lt;br /&gt;Since wait and notify need to happen in synchronized blocks, this method has worked. However i would like to have an isWaiting api for locks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-342183841635738639?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/342183841635738639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=342183841635738639&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/342183841635738639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/342183841635738639'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2007/08/some-notes-on-new-java-15-concurrent.html' title='Some notes on the new java 1.5 concurrent api'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-7682390887579316620</id><published>2006-11-30T03:11:00.000-08:00</published><updated>2006-11-30T03:13:57.987-08:00</updated><title type='text'>Big 'O' notation and Java Constant time performance</title><content type='html'>&lt;strong&gt;Big 'O' notation and Java Constant time performance&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Collection Constant time performance, in a line is "The same amount of time taken for a certain operation(method) regardless of the number of elements in the collection"&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Big 'O' notation&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The Big O notation is used to indicate the time taken by algorithms to run :-&lt;br /&gt;&lt;br /&gt;For example:-&lt;br /&gt;(N is the number of elements) &lt;br /&gt;&lt;br /&gt;O(N):- The time taken is linerarly dependent to the number of elements.&lt;br /&gt;&lt;br /&gt;O(log N):- The time taken is logarithmic to the number of elements.&lt;br /&gt;&lt;br /&gt;O(1):- The time taken is constant time, regardless of the number of elements.&lt;br /&gt;&lt;br /&gt;Please read here to find out about the big O notation:-&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Big_O_notation"&gt;http://en.wikipedia.org/wiki/Big_O_notation&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;In java collections &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Sets&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;1) The HashSet offers constant time performance for basic operations (add, remove, contains and size).&lt;br /&gt;&lt;br /&gt;2) The TreeSet provides guaranteed log(n) time cost for the basic operations (add, remove and contains).&lt;br /&gt;&lt;br /&gt;3) Like HashSet, the LinkedHashSet provides constant-time performance for the basic operations (add, contains and remove)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Lists&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;4) The ArrayList offers constant time performance in the size, isEmpty, get, set, iterator, and listIterator operations. The add operation runs in linear time. All of the other operations run in linear time (roughly speaking). &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Maps&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;5) The HashMap provides constant-time performance for the basic operations (get and put).&lt;br /&gt;&lt;br /&gt;6) The TreeMap provides guaranteed log(n) time cost for the containsKey, get, put and remove operations. &lt;br /&gt;&lt;br /&gt;7) Like HashMap, the LinkedHashMap provides constant-time performance for the basic operations (add, contains and remove), assuming the the hash function disperses elements properly among the buckets.&lt;br /&gt;&lt;br /&gt;If you need a List you could use the ArrayList.&lt;br /&gt;&lt;br /&gt;If you need a Set use the HashSet or for a sorted set use the TreeSet or an insertion ordered set use the LinkedHashSet.&lt;br /&gt;&lt;br /&gt;If you need a Map use the HashMap or for a key sorted map use the TreeMap or a key insertion ordered map use the LinkedHashMap.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-7682390887579316620?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/7682390887579316620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=7682390887579316620&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/7682390887579316620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/7682390887579316620'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2006/11/big-o-notation-and-java-constant-time.html' title='Big &apos;O&apos; notation and Java Constant time performance'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-4454081124101063486</id><published>2006-11-27T09:30:00.000-08:00</published><updated>2006-11-27T09:42:35.198-08:00</updated><title type='text'>Sring 1.1 and map element</title><content type='html'>Sring 1.1 and map element&lt;br /&gt;&lt;br /&gt;In Spring 1.1 the map element has a key and value like this&lt;br /&gt;&lt;br /&gt;&amp;lt;map&amp;gt;&lt;br /&gt; &amp;lt;entry key="event"&amp;gt;&lt;br /&gt;  &amp;lt;value&amp;gt;ss&amp;lt;/value&amp;gt;&lt;br /&gt;  &amp;lt;ref&amp;gt;ref1&amp;lt;/ref&amp;gt;&lt;br /&gt; &amp;lt;/entry&amp;gt;&lt;br /&gt;&amp;lt;/map&amp;gt;&lt;br /&gt;&lt;br /&gt;In the above code there is no way to specify the "key" as an object, it must be a "String" object !&lt;br /&gt;&lt;br /&gt;However from spring 1.2x onwards we can do do this&lt;br /&gt;&lt;br /&gt;&amp;lt;map&amp;gt;&lt;br /&gt; &amp;lt;entry&amp;gt;&lt;br /&gt;  &amp;lt;key-ref&amp;gt;ref1&amp;lt;/key-ref&amp;gt;&lt;br /&gt;  &amp;lt;value-ref&amp;gt;ref2&amp;lt;/value-ref&amp;gt;&lt;br /&gt; &amp;lt;/entry&amp;gt;&lt;br /&gt;&amp;lt;map&amp;gt;&lt;br /&gt;&lt;br /&gt;In many cases the above is what one would need of a java map.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-4454081124101063486?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/4454081124101063486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=4454081124101063486&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/4454081124101063486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/4454081124101063486'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2006/11/sring-11-and-map-element.html' title='Sring 1.1 and map element'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-116112074829074713</id><published>2006-10-17T14:31:00.000-07:00</published><updated>2006-10-17T15:44:46.470-07:00</updated><title type='text'>Java 5, EJB 3 Persistence and Hibernate annotations</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;Java 5, EJB 3 Persistence and Hibernate annotations&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I finally decided to try out some code with Java 5 annonations. For this I chose to try hibernate annotations implementation, which implements EJB 3 persistence with some enhanced annotations of its own.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Pre -requisites&lt;/strong&gt;&lt;br /&gt;1) Java 5 SDK&lt;br /&gt;2) Latest Hibernate jar with dependent libraries from the lib folder of the download.&lt;br /&gt;3) Latest Hibernate annotation jar with dependent libraries from the lib folder of the download.&lt;br /&gt;4) Ant&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Domain Objects&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The domain objects are Person and Child. The relationship is one-to-many from person to child and many-to-one from Child to person. The java POJO's are fairly straight forward for this, so I will share the xml here.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Person.hbm.xml&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE hibernate-mapping PUBLIC&lt;br /&gt;"-//Hibernate/Hibernate Mapping DTD 3.0//EN"&lt;br /&gt;"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;hibernate-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;class name="test.suchak.hibernatetest.domainobjects.Person" table="Person"&amp;gt;&lt;br /&gt;&amp;lt;id&lt;br /&gt;name="ID"&lt;br /&gt;column="ID"&lt;br /&gt;&amp;gt;&lt;br /&gt;&amp;lt;generator class="sequence"&amp;gt;&lt;br /&gt;&amp;lt;param name="sequence"&amp;gt;PERSONIDSEQUENCE&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;lt;/generator&amp;gt;&lt;br /&gt;&amp;lt;/id&amp;gt;&lt;br /&gt;&amp;lt;property name="firstName"&amp;gt;&lt;br /&gt;&amp;lt;column name="FirstName"/&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;property name="lastName"&amp;gt;&lt;br /&gt;&amp;lt;column name="LastName"/&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;list name="children" cascade="all" inverse="true"&amp;gt;&lt;br /&gt;&amp;lt;key column="parent_id"/&amp;gt;&lt;br /&gt;&amp;lt;index column="child_id"/&amp;gt;&lt;br /&gt;&amp;lt;one-to-many class="test.suchak.hibernatetest.domainobjects.Child"/&amp;gt;&lt;br /&gt;&amp;lt;/list&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/class&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/hibernate-mapping&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;strong&gt;Child.hbm.xml&lt;/strong&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE hibernate-mapping PUBLIC&lt;br /&gt;"-//Hibernate/Hibernate Mapping DTD 3.0//EN"&lt;br /&gt;"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;hibernate-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;class name="test.suchak.hibernatetest.domainobjects.Child" table="Child"&amp;gt;&lt;br /&gt;&amp;lt;id&lt;br /&gt;name="child_id"&lt;br /&gt;column="child_id"&lt;br /&gt;&amp;gt;&lt;br /&gt;&amp;lt;generator class="sequence"&amp;gt;&lt;br /&gt;&amp;lt;param name="sequence"&amp;gt;CHILDIDSEQUENCE&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;lt;/generator&amp;gt;&lt;br /&gt;&amp;lt;/id&amp;gt;&lt;br /&gt;&amp;lt;property name="name"&amp;gt;&lt;br /&gt;&amp;lt;column name="name"/&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;property name="age"&amp;gt;&lt;br /&gt;&amp;lt;column name="age"/&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;many-to-one name="person"&lt;br /&gt;column="parent_id"&lt;br /&gt;class="test.suchak.hibernatetest.domainobjects.Person"&lt;br /&gt;cascade="all"&lt;br /&gt;/&amp;gt;&lt;br /&gt;&amp;lt;/class&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/hibernate-mapping&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;XML Session factory configuration&lt;/strong&gt;&lt;br /&gt;The session factry configuration here is prettty simple. Just read the hbm files and pass them to the hibernate configugation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public class MyHibernateSessionFactory {&lt;br /&gt;......&lt;br /&gt;private void buildSessionFactory(String[] fileNames) { &lt;br /&gt;&lt;br /&gt;Configuration config = new Configuration();&lt;br /&gt;&lt;br /&gt;for(int i=0;i&amp;lt;filenames.length;i++){&lt;br /&gt;config.addFile(hbmDir + File.separator + fileNames[i]); &lt;br /&gt;} &lt;br /&gt;sessionFactory = config.buildSessionFactory();&lt;br /&gt;} ....&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now the sessionFactory.openSession() method will retun the sessions we need. Using the session we can now do CRUD on the child and person POJO's, in the traditional hibernate world.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Annotations&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Now instead of the xml files we will use annotations for the same two POJO's person and child.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Person.java&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;package test.suchak.hibernatetest.domainobjects;&lt;br /&gt;&lt;br /&gt;import java.util.List;&lt;br /&gt;//import javax.persistence.*;&lt;br /&gt;import javax.persistence.Entity;&lt;br /&gt;import javax.persistence.Table;&lt;br /&gt;import javax.persistence.Column;&lt;br /&gt;import javax.persistence.GeneratedValue;&lt;br /&gt;import javax.persistence.OneToMany;&lt;br /&gt;import javax.persistence.Id;&lt;br /&gt;import org.hibernate.annotations.GenericGenerator;&lt;br /&gt;import org.hibernate.annotations.Parameter;&lt;br /&gt;import org.hibernate.annotations.MapKey;&lt;br /&gt;import javax.persistence.CascadeType;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* @author Suchak.Jani&lt;br /&gt;*&lt;br /&gt;* TODO To change the template for this generated type comment go to&lt;br /&gt;* Window - Preferences - Java - Code Style - Code Templates&lt;br /&gt;*&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;@Entity&lt;br /&gt;@Table(name="Person")&lt;br /&gt;public class Person {&lt;br /&gt;private Integer ID;&lt;br /&gt;private String firstName;&lt;br /&gt;private String lastName;&lt;br /&gt;private List&lt;child&gt; children;&lt;br /&gt;&lt;br /&gt;public Person(){&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;/**&lt;br /&gt;* @param firstName2&lt;br /&gt;* @param lastName2&lt;br /&gt;*&lt;br /&gt;*/&lt;br /&gt;public Person(String firstName, String lastName) {&lt;br /&gt;this.firstName=firstName;&lt;br /&gt;this.lastName=lastName;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* @return Returns the firstName.&lt;br /&gt;*/&lt;br /&gt;@Column(name = "FirstName")&lt;br /&gt;public String getFirstName() {&lt;br /&gt;return firstName;&lt;br /&gt;}&lt;br /&gt;/**&lt;br /&gt;* @return Returns the iD.&lt;br /&gt;*/&lt;br /&gt;@Id @GeneratedValue(generator="sequence")&lt;br /&gt;@GenericGenerator(name="sequence", strategy = "sequence",&lt;br /&gt;parameters = {&lt;br /&gt;@Parameter(name="sequence", value="PERSONIDSEQUENCE")&lt;br /&gt;}&lt;br /&gt;)&lt;br /&gt;public Integer getID() {&lt;br /&gt;return ID;&lt;br /&gt;}&lt;br /&gt;/**&lt;br /&gt;* @return Returns the lastName.&lt;br /&gt;*/&lt;br /&gt;@Column(name = "LastName")&lt;br /&gt;public String getLastName() {&lt;br /&gt;return lastName;&lt;br /&gt;}&lt;br /&gt;/**&lt;br /&gt;* @param firstName The firstName to set.&lt;br /&gt;*/&lt;br /&gt;public void setFirstName(String firstName) {&lt;br /&gt;this.firstName = firstName;&lt;br /&gt;}&lt;br /&gt;/**&lt;br /&gt;* @param id The iD to set.&lt;br /&gt;*/&lt;br /&gt;public void setID(Integer id) {&lt;br /&gt;ID = id;&lt;br /&gt;}&lt;br /&gt;/**&lt;br /&gt;* @param lastName The lastName to set.&lt;br /&gt;*/&lt;br /&gt;public void setLastName(String lastName) {&lt;br /&gt;this.lastName = lastName;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* @return Returns the children.&lt;br /&gt;*/&lt;br /&gt;@OneToMany(mappedBy="person", cascade=CascadeType.ALL)&lt;br /&gt;//@OneToMany(mappedBy="person")&lt;br /&gt;@MapKey(columns=@Column(name="child_id"))&lt;br /&gt;public List&lt;child&gt; getChildren() {&lt;br /&gt;return children;&lt;br /&gt;}&lt;br /&gt;/**&lt;br /&gt;* @param children The children to set.&lt;br /&gt;*/&lt;br /&gt;public void setChildren(List&lt;child&gt; children) {&lt;br /&gt;this.children = children;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Child.java&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;package test.suchak.hibernatetest.domainobjects;&lt;br /&gt;&lt;br /&gt;//import javax.persistence.*;&lt;br /&gt;import javax.persistence.Entity;&lt;br /&gt;import javax.persistence.Table;&lt;br /&gt;import javax.persistence.Column;&lt;br /&gt;import javax.persistence.GeneratedValue;&lt;br /&gt;import javax.persistence.ManyToOne;&lt;br /&gt;import javax.persistence.JoinColumn;&lt;br /&gt;import javax.persistence.Id;&lt;br /&gt;import org.hibernate.annotations.GenericGenerator;&lt;br /&gt;import org.hibernate.annotations.Parameter;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * @author Suchak.Jani&lt;br /&gt; *&lt;br /&gt; * TODO To change the template for this generated type comment go to&lt;br /&gt; * Window - Preferences - Java - Code Style - Code Templates&lt;br /&gt; */&lt;br /&gt;@Entity&lt;br /&gt;@Table(name="Child")&lt;br /&gt;public class Child {&lt;br /&gt;&lt;br /&gt; private Integer child_id; // ID&lt;br /&gt; private String name;&lt;br /&gt; private Integer age;&lt;br /&gt; private Person person;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; // need a default cosntructor for hibernate to be able to read for this object&lt;br /&gt; public Child() {&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * @param parent_id2&lt;br /&gt;  * @param name2&lt;br /&gt;  * @param age2&lt;br /&gt;  */&lt;br /&gt; public Child(Person person,String name, Integer age) {&lt;br /&gt;&lt;br /&gt;  this.setPerson(person);&lt;br /&gt;  this.setName(name);&lt;br /&gt;  this.setAge(age);&lt;br /&gt; }&lt;br /&gt; /**&lt;br /&gt;  * @return Returns the age.&lt;br /&gt;  */&lt;br /&gt; @Column(name = "age")&lt;br /&gt; public Integer getAge() {&lt;br /&gt;  return age;&lt;br /&gt; }&lt;br /&gt; /**&lt;br /&gt;  * @param age The age to set.&lt;br /&gt;  */&lt;br /&gt; public void setAge(Integer age) {&lt;br /&gt;  this.age = age;&lt;br /&gt; }&lt;br /&gt; /**&lt;br /&gt;  * @return Returns the child_id.&lt;br /&gt;  */&lt;br /&gt; @Id @GeneratedValue(generator="sequence")&lt;br /&gt;    @GenericGenerator(name="sequence", strategy = "sequence",&lt;br /&gt;  parameters = {&lt;br /&gt;   @Parameter(name="sequence", value="CHILDIDSEQUENCE")&lt;br /&gt;  }&lt;br /&gt; )&lt;br /&gt; public Integer getChild_id() {&lt;br /&gt;  return child_id;&lt;br /&gt; }&lt;br /&gt; /**&lt;br /&gt;  * @param child_id The child_id to set.&lt;br /&gt;  */&lt;br /&gt; public void setChild_id(Integer child_id) {&lt;br /&gt;  this.child_id = child_id;&lt;br /&gt; }&lt;br /&gt; /**&lt;br /&gt;  * @return Returns the name.&lt;br /&gt;  */&lt;br /&gt; @Column(name = "name")&lt;br /&gt; public String getName() {&lt;br /&gt;  return name;&lt;br /&gt; }&lt;br /&gt; /**&lt;br /&gt;  * @param name The name to set.&lt;br /&gt;  */&lt;br /&gt; public void setName(String name) {&lt;br /&gt;  this.name = name;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * @return Returns the person.&lt;br /&gt;  */&lt;br /&gt;    @ManyToOne&lt;br /&gt;    @JoinColumn(name="parent_id",nullable=false)&lt;br /&gt; public Person getPerson() {&lt;br /&gt;  return person;&lt;br /&gt; }&lt;br /&gt; /**&lt;br /&gt;  * @param person The person to set.&lt;br /&gt;  */&lt;br /&gt; public void setPerson(Person person) {&lt;br /&gt;  this.person = person;&lt;br /&gt; }&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Annotation Session factory configuration &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The session factry configuration here is different than the xml session factory as shown below.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;public class AnnotationHibernateSessionFactory {&lt;br /&gt;....&lt;br /&gt; /**&lt;br /&gt;  * @param files&lt;br /&gt;  */&lt;br /&gt; private void buildSessionFactory() {&lt;br /&gt;  try {&lt;br /&gt;    sessionFactory = new AnnotationConfiguration()&lt;br /&gt;        .addAnnotatedClass(Person.class)&lt;br /&gt;        .addAnnotatedClass(Child.class)&lt;br /&gt;        .buildSessionFactory();&lt;br /&gt;   } catch (Throwable ex) {&lt;br /&gt;    // Log exception!&lt;br /&gt;    throw new ExceptionInInitializerError(ex);&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Key Points&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;1) XML files not needed.&lt;br /&gt;2) An import per annotation used in the POJO.&lt;br /&gt;3) (inverse="true") is now equivalent to mappedBy.&lt;br /&gt;4) Most annotations are in javax.persistence package.&lt;br /&gt;5) The new AnnotationConfiguration class is to be used instead of the Configuartion class.&lt;br /&gt;6) The xml tags class and class name are not necessary.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Code&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The working code is available for download below.&lt;br /&gt;&lt;br /&gt;&lt;table style="BORDER-RIGHT: #353535 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #353535 1px solid; PADDING-LEFT: 0px; FONT-SIZE: 11px; PADDING-BOTTOM: 0px; BORDER-LEFT: #353535 1px solid; PADDING-TOP: 0px; BORDER-BOTTOM: #353535 1px solid; FONT-FAMILY: Arial, Helvetica, sans-serif; BACKGROUND-COLOR: #5d7cba" cellspacing="0" cellpadding="0" border="0"&gt;&lt;tbody&gt;&lt;tr style="BACKGROUND-COLOR: #ffffff"&gt;&lt;td style="PADDING-RIGHT: 5px; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; PADDING-TOP: 5px" align="middle"&gt;&lt;a href="http://www.esnips.com/doc/ab56ac26-814a-41d4-b279-a61f9db15a8b/hibernatejdk5test.zip/?widget=documentIcon&amp;forceView=true"&gt;&lt;img title="click to Viewhibernatejdk5test" alt="hibernatejdk5test" src="http://www.esnips.com//images/thumbs/thumb.zip.gif" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="BACKGROUND-COLOR: #ffffff"&gt;&lt;td style="PADDING-RIGHT: 5px; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; PADDING-TOP: 5px" align="middle"&gt;&lt;strong&gt;&lt;a style="COLOR: #333333" href="http://www.esnips.com/doc/ab56ac26-814a-41d4-b279-a61f9db15a8b/hibernatejdk5test.zip/?widget=documentIcon&amp;forceView=true"&gt;hibernatejdk5test....&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="PADDING-RIGHT: 5px; PADDING-LEFT: 5px; FONT-SIZE: 9px; PADDING-BOTTOM: 5px; COLOR: #ffffff; PADDING-TOP: 5px" valign="bottom"&gt;Hosted by &lt;a style="COLOR: #ffffff" href="http://www.esnips.com"&gt;eSnips&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-116112074829074713?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/116112074829074713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=116112074829074713&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/116112074829074713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/116112074829074713'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2006/10/java-5-ejb-3-persistence-and-hibernate.html' title='Java 5, EJB 3 Persistence and Hibernate annotations'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-116111323938584990</id><published>2006-10-17T12:16:00.000-07:00</published><updated>2006-10-17T12:37:39.730-07:00</updated><title type='text'>Java and unsigned numbers</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Java and unsigned numbers&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Recently there was a requirement for some binnary data read/write work. I started out with some java code. I used the nio ByteBuffer to read and write data.&lt;br /&gt;&lt;br /&gt;Something was not right. Whenever i tried to read some sample data the values were right at times and wrong(negative) at other times.&lt;br /&gt;&lt;br /&gt;Then a senior consultant colleague, reminded me that all java numbers are 2's complement. In short the MSB(most significant bit) is used to indicate positive or negative number. For further details on 2's complement, please read &lt;a href="http://en.wikipedia.org/wiki/Two%27s_complement"&gt;http://en.wikipedia.org/wiki/Two's_complement&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;That sent me on a trail to firgure out how could i read/write an unsigned number using java.&lt;br /&gt;&lt;br /&gt;The basic understanding is that you use a bigger number to store the smaller signed number. That way the bigger signed number becomes the unsigned smaller number.&lt;br /&gt;&lt;br /&gt;For example a byte is 8 bits. Its range in java is +127 to -128. (Please read up on the 2's complement bit to understand how we get the negative number)&lt;br /&gt;&lt;br /&gt;0111 1111 = 127&lt;br /&gt;1000 0000 = - 128 (2's complement)&lt;br /&gt;&lt;br /&gt;So in order to convert this byte to unsinged byte we will incease the byte to a short.&lt;br /&gt;&lt;br /&gt;A short in java is 16 bits&lt;br /&gt;&lt;br /&gt;0000 0000 0000 0000 0111 1111 = 127&lt;br /&gt;0000 0000 0000 0000 1000 0000 = 128&lt;br /&gt;&lt;br /&gt;Here is some code to test this&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public class Test {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      public static void main(String args[]) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        byte b = -128;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        short s = (short)(0x00FF &amp; b);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   System.out.println("Byte b = " + b);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.out.println("Short s = " + s);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Result is&lt;br /&gt;D:\&gt;java Test&lt;br /&gt;Byte b = -128&lt;br /&gt;Short s = 128&lt;br /&gt;&lt;br /&gt;Please note that i have not directly casted to a short, instead i have done a bit and operation with all 1's (F in hex is 1111 in binary). That way the number is preserved at the byte level. If i had just cast it to a short then java would have treated it as a neagtive number i.e. it still would be -128.&lt;br /&gt;&lt;br /&gt;Here is a link that explains clearly how to use binary opreations to achieve this for all number types - &lt;a href="http://www.darksleep.com/player/JavaAndUnsignedTypes.html"&gt;http://www.darksleep.com/player/JavaAndUnsignedTypes.html&lt;/a&gt; and also Java's integer sizes - &lt;a href="http://www.scism.sbu.ac.uk/jfl/Appa/appa1.html"&gt;http://www.scism.sbu.ac.uk/jfl/Appa/appa1.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Why does java have no unsigned numbers ?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Sean R. Owens at &lt;a href="http://www.darksleep.com/player/JavaAndUnsignedTypes.html"&gt;http://www.darksleep.com/player/JavaAndUnsignedTypes.html&lt;/a&gt;, digs up old emails and interviews about Java and Oak where James Gosling explains this :-&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.gotw.ca/publications/c_family_interview.htm"&gt;http://www.gotw.ca/publications/c_family_interview.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Gosling:&lt;/span&gt; For me as a language designer, which I don't really count myself as these days, what "simple" really ended up meaning was could I expect J. Random Developer to hold the spec in his head. That definition says that, for instance, Java isn't -- and in fact a lot of these languages end up with a lot of corner cases, things that nobody really understands. &lt;span style="font-style: italic;"&gt;Quiz any C developer about unsigned, and pretty soon you discover that &lt;span style="font-weight: bold;"&gt;almost no C developers actually understand what goes on with unsigned, what unsigned arithmetic is.&lt;/span&gt; Things like that made C complex. The language part of Java is, I think, pretty simple. The libraries you have to look up&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Finally &lt;span style="font-weight: bold;"&gt;Java has no unsigned numbers&lt;/span&gt; and when dealing with binary data which might contain unsigned numbers, one has to keep this fact in mind.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-116111323938584990?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/116111323938584990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=116111323938584990&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/116111323938584990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/116111323938584990'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2006/10/java-and-unsigned-numbers.html' title='Java and unsigned numbers'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-115208986793325488</id><published>2006-07-05T01:50:00.000-07:00</published><updated>2006-07-05T01:57:47.946-07:00</updated><title type='text'>EJB 3 Interceptors: Aspect orientation in EJB spec</title><content type='html'>&lt;p&gt;&lt;strong&gt;EJB 3 Interceptors: Aspect orientation in EJB spec&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;By now most people in the java community have heard about Spring, Dependency Injection, Aspect oriented programming and other such terms&lt;br /&gt;&lt;br /&gt;For those who have not, if i were to put this in a single line it would say "An aspect is a common function that can be used across an application".&lt;br /&gt;&lt;br /&gt;Examples of this would be things like Security, Auditing, Transactions, Logging, etc..&lt;br /&gt;&lt;br /&gt;It is definitely useful to abstract out common aspects of an application in order that you do not have to write the same code in many places.&lt;br /&gt;&lt;br /&gt;The Spring container is very popular in the java community as of now for this particular reason. Also the Spring container externalizes the configuration of the dependency injected aspect objects so that the behaviour, as well as implementations of the aspect objects, can be varied as needed without much code change.&lt;br /&gt;&lt;br /&gt;EJB 2 also did some of this with regards to EJB Transactions, EJB Reference, Connection pools, etc.&lt;br /&gt;&lt;br /&gt;However With EJB 3 and Annotations a new term has been added. It is called "EJB Interceptors". They apply only on session and message driven beans.&lt;br /&gt;&lt;br /&gt;EJB3 Interceptors can act on a bean level like lifecycle callback interceptors or on a specific method level or on all methods or on certain number of methods. Also there could be multiple interceptors that also could have exclusion rules for certain methods.&lt;br /&gt;&lt;br /&gt;We will try and see this in a bit more detail.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What are lifecycle callback interceptors?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;EJB2 had an EJB Lifecycle for each of the EJB types i.e. Stateless Session bean, StateFull Session Bean, Entity Bean and MDBs. They are described in detail here: -&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/EJBConcepts9.html&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The particular lifecycle state can be "Does Not exist", "Pooled", "Ready". Between these states there are methods that the container calls on the EJB such as create,&lt;br /&gt;setSessionContext, ejbCreate etc..&lt;br /&gt;&lt;br /&gt;Now In EJB3 since we have EJB's we also have EJB lifecycles and related methods. However for us to be bale to do anything at the time of a lifecycle method invocation we have to define it as a lifecycle call-back interceptor method.&lt;br /&gt;&lt;br /&gt;For example: -&lt;br /&gt;&lt;br /&gt;Session beans have the following interceptor methods&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;• PostConstruct&lt;br /&gt;• PreDestroy&lt;br /&gt;• PostActivate&lt;br /&gt;• PrePassivate&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;So we could have a session bean like this&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;@Stateless public class BusinessServiceBean implements BusinessService {&lt;br /&gt;&lt;br /&gt;            public void doService(){...};&lt;br /&gt;            ...        &lt;br /&gt;&lt;br /&gt;            @PostActivate&lt;br /&gt;            initializeDB() {...};&lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What is a method interceptor?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Business method Interceptor for all methods&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;(-- this is from the EJB spec&lt;br /&gt;Business method interceptor methods are denoted by the AroundInvoke annotation. Only one AroundInvoke method may be present on the bean class or on any given interceptor class. An&lt;br /&gt;AroundInvoke method must not be a business method.&lt;br /&gt;&lt;br /&gt;The business method invocation is intercepted by the AroundInvoke methods of the bean class and interceptor classes. AroundInvoke methods must always call InvocationContext.proceed() or neither the business method will be invoked nor any subsequent interceptor AroundInvoke methods.&lt;br /&gt;&lt;br /&gt;InvocationContext&lt;br /&gt;&lt;br /&gt;The InvocationContext object provides the metadata that is required for interceptor methods:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public interface InvocationContext {&lt;br /&gt;&lt;br /&gt;public Object getBean();&lt;br /&gt;public Method getMethod();&lt;br /&gt;public Object[] getParameters();&lt;br /&gt;public void setParameters(Object[]);&lt;br /&gt;public java.util.Map getContextData();&lt;br /&gt;public Object proceed() throws Exception;&lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt; --)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Now how do we use this?&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Here is a sample code that uses a Business method Interceptor&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;@Stateless public class BusinessServiceBean implements BusinessService {&lt;br /&gt;&lt;br /&gt;            public void doService(){...};&lt;br /&gt;            ...        &lt;br /&gt;&lt;br /&gt;            @PostActivate&lt;br /&gt;            initializeDB() {...};&lt;br /&gt;&lt;br /&gt;            @AroundInvoke&lt;br /&gt;            doChecks() {&lt;br /&gt;                        checkDBAccess;&lt;br /&gt;                        checkSecurity;&lt;br /&gt;                        .....&lt;br /&gt;            };&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This would mean that when a user calls doService the call is intercepted and doChecks method is called first instead.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Business method Interceptor for specific methods&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;A business method interceptor method may be defined to apply to a specific business method invocation, rather than to all of the business methods of the bean class.&lt;br /&gt;&lt;br /&gt;This is done by using interceptor annotations.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;@Stateless public class BusinessServiceBean implements BusinessService {&lt;br /&gt;&lt;br /&gt;            @Interceptors(test.TestInterceptor.class)&lt;br /&gt;            public void doService(){...};&lt;br /&gt;            ...        &lt;br /&gt;&lt;br /&gt;            @PostActivate&lt;br /&gt;            initializeDB() {...};&lt;br /&gt;&lt;br /&gt;            @AroundInvoke&lt;br /&gt;            doChecks() {&lt;br /&gt;                        checkDBAccess;&lt;br /&gt;                        checkSecurity;&lt;br /&gt;                        .....&lt;br /&gt;            };&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;As i understand, there can be more than one method level interceptor. If that is the case the interceptors are invoked in the order they are specified. Also method level interceptors are invoked in addition to any other interceptors defined at the bean level.&lt;br /&gt;&lt;br /&gt;I need to get to an EJB 3 implementation to test out a few permutations and combinations of the above code.&lt;br /&gt;&lt;br /&gt;To conclude, EJB3 now looks more and more like other popular java frameworks, for aspect oriented programming, like Spring. Also EJB 3 persistence now looks like OR tools namely Toplink, Hibernate, etc.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-115208986793325488?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/115208986793325488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=115208986793325488&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/115208986793325488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/115208986793325488'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2006/07/ejb-3-interceptors-aspect-orientation.html' title='EJB 3 Interceptors: Aspect orientation in EJB spec'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-114768499284656701</id><published>2006-05-15T01:56:00.000-07:00</published><updated>2006-05-15T02:28:03.026-07:00</updated><title type='text'>A sample sax parser</title><content type='html'>I thought of writing a sax parser, just to see how it would work with the web.xml file for the ajaz example.&lt;br /&gt;&lt;br /&gt;Here is the XML file.(This is the file that this line of code picks up &lt;span style="font-family:courier new;"&gt;'m.parseXml("C:/temp/ajaxtest/web.xml&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;");&lt;/span&gt;')&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;NOTE&lt;/strong&gt;:- Blogger tries to render HTML tags in a blog. So where you see [] in tags, please read them as &lt;&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[?xml version="1.0" encoding="UTF-8"?]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[web-app testAttribute="test1"]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[servlet] &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[servlet-name]SimpleTestServlet[/servlet-name] &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[servlet-class]suchak.ajax.test.SimpleTestServlet[/servlet-class] &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[/servlet]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[servlet] &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[servlet-name]AnotherSimpleTestServlet[/servlet-name] &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[servlet-class]suchak.ajax.test.AnotherSimpleTestServlet[/servlet-class] &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[/servlet] &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[servlet-mapping] &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[servlet-name]SimpleTestServlet[/servlet-name] &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[url-pattern]*.cmd[/url-pattern] &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[/servlet-mapping]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[/web-app]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;The ContentHandler interface is the key interface for sax parsing api. It has an implementation called DefaultHandler which can be used for simplicity. One can just choose to overide methods one wants. Just to add, I also thought of using the fully qualified names so that there would be clarity as to where the classes come from at a first glance rather than looking up the import.&lt;br /&gt;&lt;br /&gt;I am using the apache xeres parser. So if you try this out you might want to include the apache xerces libraries in your classpath.&lt;br /&gt;&lt;br /&gt;Here is the class. Please note the ContentHandler itself is an inner class called TestContentHandler.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;import java.io.File;&lt;br /&gt;&lt;br /&gt;public class Main {&lt;br /&gt;&lt;br /&gt; public static void main(String [] args){&lt;br /&gt;  Main m = new Main();&lt;br /&gt;  m.parseXml("C:/temp/ajaxtest/web.xml");&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private void parseXml(String file) {&lt;br /&gt;  try {&lt;br /&gt;   org.xml.sax.InputSource is = new org.xml.sax.InputSource(&lt;br /&gt;     new java.io.FileInputStream(file));&lt;br /&gt;   org.xml.sax.XMLReader reader =&lt;br /&gt;    org.xml.sax.helpers.XMLReaderFactory.createXMLReader(&lt;br /&gt;      "org.apache.xerces.parsers.SAXParser");&lt;br /&gt;   reader.setContentHandler(new Main.TestContentHandler()); &lt;br /&gt;   log(" -- Staring XML Parsing ! --");&lt;br /&gt;   reader.parse(is);&lt;br /&gt;   log(" -- Finished XML Parsing ! --");&lt;br /&gt;  } catch (java.io.FileNotFoundException e) {&lt;br /&gt;   e.printStackTrace();&lt;br /&gt;  } catch (org.xml.sax.SAXException e) {&lt;br /&gt;   e.printStackTrace();&lt;br /&gt;  } catch (java.io.IOException e) {&lt;br /&gt;   e.printStackTrace();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public class TestContentHandler extends org.xml.sax.helpers.DefaultHandler {&lt;br /&gt;&lt;br /&gt;  String currentElement = null;&lt;br /&gt;  java.util.HashMap elementValues = new java.util.HashMap();&lt;br /&gt;&lt;br /&gt;  public void startElement(&lt;br /&gt;    String namespaceURI,&lt;br /&gt;    String localName,&lt;br /&gt;    String qName,&lt;br /&gt;    org.xml.sax.Attributes attributes)&lt;br /&gt;  throws org.xml.sax.SAXException {&lt;br /&gt;    log(&lt;br /&gt;      " Start element " +&lt;br /&gt;      " ---- qName :::: '" + qName + "'"  &lt;br /&gt;    );&lt;br /&gt;    // Element is starting to be read, so name it as the current element and&lt;br /&gt;    currentElement = qName;&lt;br /&gt;    elementValues.put(currentElement, new StringBuffer());&lt;br /&gt;  &lt;br /&gt;    int noofattributes = attributes.getLength();&lt;br /&gt;  &lt;br /&gt;    for(int i=0;i(less than)noofattributes;i++){&lt;br /&gt;     log(&lt;br /&gt;     " Attribute found for element :: '" + qName + "'" +&lt;br /&gt;     " att qname :: " + attributes.getQName(i) +&lt;br /&gt;     " att type :: " + attributes.getType(i) +&lt;br /&gt;     " att value :: " + attributes.getValue(i));&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void characters(&lt;br /&gt;    char[] ch,&lt;br /&gt;    int start,&lt;br /&gt;    int length)&lt;br /&gt;  throws org.xml.sax.SAXException {&lt;br /&gt;   log( "Current element being processed in chars :: '" +&lt;br /&gt;     currentElement + "'");&lt;br /&gt;   String tempString = new String(ch,start,length);&lt;br /&gt;   //log( "Value of the above element is :: '" + tempString + "'"); &lt;br /&gt;   if(tempString.trim().equals("")){&lt;br /&gt;    // if emply string just log it and do nothing&lt;br /&gt;    log( " -- White space -- ");&lt;br /&gt;   }else{&lt;br /&gt; &lt;br /&gt;     /* this part of the code add the strings to the current element.&lt;br /&gt;   * as per http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/&lt;br /&gt;   * ContentHandler.html#characters(char[],%20int,%20int)&lt;br /&gt;   * The Parser will call this method to report each chunk of character&lt;br /&gt;   * data. SAX parsers may return all contiguous character data in a&lt;br /&gt;   * single chunk, or they may split it into several chunks; however,&lt;br /&gt;   * all of the characters in any single event must come from the same&lt;br /&gt;   * external entity so that the Locator provides useful information.&lt;br /&gt;   * The application must not attempt to read from the array outside of&lt;br /&gt;   * the specified range.&lt;br /&gt;   */ &lt;br /&gt;   ((StringBuffer)(elementValues.get(currentElement))).append(tempString); &lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void endElement(&lt;br /&gt;    String namespaceURI,&lt;br /&gt;    String localName,&lt;br /&gt;    String qName)&lt;br /&gt;  throws org.xml.sax.SAXException {&lt;br /&gt;   log(&lt;br /&gt;     "End element " +&lt;br /&gt;     " ---- qName :: '" + qName +  "'"  &lt;br /&gt;   );&lt;br /&gt;   /*&lt;br /&gt;    * Current element is fully read, so it is ok to&lt;br /&gt;    * remove the element value from the map&lt;br /&gt;    *&lt;br /&gt;    */&lt;br /&gt; &lt;br /&gt;   String value = ((StringBuffer)(elementValues.get(qName))).toString();&lt;br /&gt;   // Print the value out of it is not am epty string&lt;br /&gt;   if(!value.equals("")){&lt;br /&gt;    log(" Value of the above current element :: " + qName +&lt;br /&gt;      " is :: "+ value);&lt;br /&gt;   }&lt;br /&gt;   elementValues.remove(qName);&lt;br /&gt;   /*&lt;br /&gt;    * We do not reset the current element here as the startElement&lt;br /&gt;    * method should do that at the start of an element&lt;br /&gt;    *&lt;br /&gt;    */&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private void log(String s){&lt;br /&gt;  System.out.println(s);&lt;br /&gt; }&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As seen above the characters method can span multiple calls depending on the buffer size for the same element.&lt;br /&gt;&lt;br /&gt;Here is the output:-&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;-- Staring XML Parsing ! --&lt;br /&gt;&lt;br /&gt;Start element ---- qName :::: 'web-app'&lt;br /&gt;Attribute found for element :: 'web-app' att qname :: testAttribute att type :: CDATA att value :: test1&lt;br /&gt;Current element being processed in chars :: 'web-app'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;Start element ---- qName :::: 'servlet'&lt;br /&gt;Current element being processed in chars :: 'servlet'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;Start element ---- qName :::: 'servlet-name'&lt;br /&gt;Current element being processed in chars :: 'servlet-name'&lt;br /&gt;End element ---- qName :: 'servlet-name'&lt;br /&gt;Value of the above current element :: servlet-name is :: SimpleTestServlet&lt;br /&gt;&lt;br /&gt;Current element being processed in chars :: 'servlet-name'&lt;br /&gt;-- White space --&lt;br /&gt;Start element ---- qName :::: 'servlet-class'&lt;br /&gt;&lt;br /&gt;Current element being processed in chars :: 'servlet-class'&lt;br /&gt;End element ---- qName :: 'servlet-class'&lt;br /&gt;Value of the above current element :: servlet-class is :: suchak.ajax.test.SimpleTestServlet&lt;br /&gt;&lt;br /&gt;Current element being processed in chars :: 'servlet-class'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;Current element being processed in chars :: 'servlet-class'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;End element ---- qName :: 'servlet'&lt;br /&gt;Current element being processed in chars :: 'servlet-class'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;Start element ---- qName :::: 'servlet'&lt;br /&gt;Current element being processed in chars :: 'servlet'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;Start element ---- qName :::: 'servlet-name'&lt;br /&gt;Current element being processed in chars :: 'servlet-name'&lt;br /&gt;End element ---- qName :: 'servlet-name'&lt;br /&gt;Value of the above current element :: servlet-name is :: AnotherSimpleTestServlet&lt;br /&gt;&lt;br /&gt;Current element being processed in chars :: 'servlet-name'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;Start element ---- qName :::: 'servlet-class'&lt;br /&gt;Current element being processed in chars :: 'servlet-class'&lt;br /&gt;End element ---- qName :: 'servlet-class'&lt;br /&gt;Value of the above current element :: servlet-class is :: suchak.ajax.test.AnotherSimpleTestServlet&lt;br /&gt;&lt;br /&gt;Current element being processed in chars :: 'servlet-class'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;Current element being processed in chars :: 'servlet-class'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;End element ---- qName :: 'servlet'&lt;br /&gt;Current element being processed in chars :: 'servlet-class'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;Current element being processed in chars :: 'servlet-class'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;Start element ---- qName :::: 'servlet-mapping'&lt;br /&gt;Current element being processed in chars :: 'servlet-mapping'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;Start element ---- qName :::: 'servlet-name'&lt;br /&gt;Current element being processed in chars :: 'servlet-name'&lt;br /&gt;End element ---- qName :: 'servlet-name'&lt;br /&gt;Value of the above current element :: servlet-name is :: SimpleTestServlet&lt;br /&gt;&lt;br /&gt;Current element being processed in chars :: 'servlet-name'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;Start element ---- qName :::: 'url-pattern'&lt;br /&gt;Current element being processed in chars :: 'url-pattern'&lt;br /&gt;End element ---- qName :: 'url-pattern'&lt;br /&gt;Value of the above current element :: url-pattern is :: *.cmd&lt;br /&gt;&lt;br /&gt;Current element being processed in chars :: 'url-pattern'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;Current element being processed in chars :: 'url-pattern'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;End element ---- qName :: 'servlet-mapping'&lt;br /&gt;&lt;br /&gt;Current element being processed in chars :: 'url-pattern'&lt;br /&gt;-- White space --&lt;br /&gt;&lt;br /&gt;End element ---- qName :: 'web-app'-- Finished XML Parsing ! --&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As seen, all white spaces, including CR's are also outputted by the characters method. I did not see a way to tell the apache xeres parser to not read the white spaces in the characters method.&lt;br /&gt;&lt;br /&gt;However Oracle has a neat XML parser in which one can do this :-&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SAXParser parser = new SAXParser(); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;parser.setPreserveWhitespace(false);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here are more details :- &lt;a href="http://www.oracle.com/technology/pub/articles/wang-whitespace.html"&gt;http://www.oracle.com/technology/pub/articles/wang-whitespace.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;All in all it seems pretty simple to write up a custom sax parser whith current tools.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-114768499284656701?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/114768499284656701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=114768499284656701&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/114768499284656701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/114768499284656701'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2006/05/sample-sax-parser.html' title='A sample sax parser'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-114656370791172464</id><published>2006-05-02T02:30:00.000-07:00</published><updated>2006-05-02T02:55:07.933-07:00</updated><title type='text'>EJB 3 - a basic study</title><content type='html'>EJB 3 is such a radical departure from EJB 2.&lt;br /&gt;&lt;br /&gt;To begin with there is no need for the developer to define local or remote and localhome or remotehome interfaces.&lt;br /&gt;&lt;br /&gt;All of the above is achieved by an intelliginet mix of default behaviour and annotations.&lt;br /&gt;&lt;br /&gt;Here is an example&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;@Stateless&lt;br /&gt;public class GreetingBean implements Greeting {&lt;br /&gt;            public String hello (String personName) {&lt;br /&gt;                        return "Hello " + personName + "!";&lt;br /&gt;            }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface Greeting{&lt;br /&gt;            public String hello (String personName);&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The above bean is a stateless bean with local accaess as the defualt. So no need to implement EJBLocalObject, EJBLocalHome, etc....&lt;br /&gt;&lt;br /&gt;How do we make this a remote bean ?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;@Stateless @Remote&lt;br /&gt;public class GreetingBean implements Greeting {&lt;br /&gt;            public String hello (String personName) {&lt;br /&gt;                        return "Hello " + personName + "!";&lt;br /&gt;            }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface Greeting{&lt;br /&gt;            public String hello (String personName);&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;How do we get access to this bean, if there is no Home Interface ?&lt;br /&gt;&lt;br /&gt;Via "&lt;em&gt;Dependency Injection&lt;/em&gt;" just like Spring.&lt;br /&gt;&lt;br /&gt;The difference is, unlike Spring, EJB3 does not use an exteranl XML configuration file, what is used instead is,  again an annotation !&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;@EJB Greeting greeting;&lt;br /&gt;...&lt;br /&gt;String helloString = greeting.hello("Krishna");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Webservices can be defined as annotations on session bean methods.&lt;br /&gt;&lt;br /&gt;Also i hear that Entity bean persistence is much like an OR tool i.e. Hibernate et all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-114656370791172464?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/114656370791172464/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=114656370791172464&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/114656370791172464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/114656370791172464'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2006/05/ejb-3-basic-study.html' title='EJB 3 - a basic study'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-114563074516312290</id><published>2006-04-21T07:14:00.000-07:00</published><updated>2006-04-21T07:45:45.186-07:00</updated><title type='text'>STAX:The new Streaming API for XML</title><content type='html'>I was reading up something on JAXB which was pretty long winded, when i came accross this "STAX" or "Streaming API for XML".&lt;br /&gt;&lt;br /&gt;It is a bit unique in it's design from both SAX and DOM, but it still is closer to SAX.&lt;br /&gt;&lt;br /&gt;It is a parser and hence can be used to read up xml documents but additionally like DOM can also be used to write up XML.&lt;br /&gt;&lt;br /&gt;It is a streaming parser like SAX and like SAX it works from start to finish, and can not work backwards from a certain point in an xml file.&lt;br /&gt;&lt;br /&gt;SAX uses push style of streaming i.e. it reads up the entire xml file from start to finish and logs events which the user can use.&lt;br /&gt;&lt;br /&gt;STAX uses pull style of streaming i.e like an iterator which checks for hasNext()  and the uses next() to get the next Object, STAX also checks for hasNext()  and the uses next() to get the next Element.&lt;br /&gt;&lt;br /&gt;Why do we need a new style of parser ?&lt;br /&gt;&lt;br /&gt;I guess the main reason is performance.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;1) Threads&lt;/em&gt;&lt;br /&gt;With sax style parsers the application thread control is  with the sax parser and thus one application thread can read one document at a time.&lt;br /&gt;&lt;br /&gt;With stax style parsers that the application thread control is with the application code that calls the parser and thus one application thread can multiple document at a time.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;2) Smaller libraries&lt;/em&gt;&lt;br /&gt;Sun tutorial claims that pull parsing libraries, can be much smaller than push libraies&lt;br /&gt;&lt;br /&gt;&lt;em&gt;3) Filters&lt;/em&gt;&lt;br /&gt;StAX supports building of filters and thus xml content not needed, can be ignored by the parser.&lt;br /&gt;&lt;br /&gt;Here is a quote from the Sun Tutorial:-&lt;br /&gt;&lt;br /&gt;"&lt;em&gt;Why StAX?&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;The StAX project was spearheaded by BEA with support from Sun Microsystems, and the JSR 173 specification passed the Java Community Process final approval ballot in March, 2004 (&lt;/em&gt;&lt;a href="http://jcp.org/en/jsr/detail?id=173"&gt;&lt;em&gt;http://jcp.org/en/jsr/detail?id=173&lt;/em&gt;&lt;/a&gt;&lt;em&gt;). The primary goal of the StAX API is to give “parsing control to the programmer by exposing a simple iterator based API. This allows the programmer to ask for the next event (pull the event) and allows state to be stored in procedural fashion.”&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;StAX was created to address limitations in the two most prevalent parsing APIs, SAX and DOM."&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Note that BEA and Sun are both involved in this. So I guess for the future of java xml in general and java web services in particular STAX parsers are here to stay.&lt;br /&gt;&lt;br /&gt;There are two kinds of STAX api&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Cursor API&lt;/em&gt;&lt;br /&gt;This is a light weight and fast api, used for projects like J2ME and projects where performance is essential.&lt;br /&gt;&lt;br /&gt;It is implemented by XMLStreamReader and XMLStreamWriter interfaces.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Iterator API&lt;/em&gt;&lt;br /&gt;In this api the Events generated can be used by the application even after the parser has moved on to subsequent Events.  It is much more flexible when you want to add or remove Events, extend Events, etc..&lt;br /&gt;&lt;br /&gt;It is implemented by XMLEventReader and XMLEventWriter interfaces.&lt;br /&gt;&lt;br /&gt;Please see these links for more information:-&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.oracle.com/technology/oramag/oracle/03-sep/o53devxml.html"&gt;http://www.oracle.com/technology/oramag/oracle/03-sep/o53devxml.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://java.sun.com/webservices/docs/2.0/tutorial/doc/StAX.html#wp69937"&gt;http://java.sun.com/webservices/docs/2.0/tutorial/doc/StAX.html#wp69937&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now back to JAXB.....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-114563074516312290?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/114563074516312290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=114563074516312290&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/114563074516312290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/114563074516312290'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2006/04/staxthe-new-streaming-api-for-xml.html' title='STAX:The new Streaming API for XML'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-114539126689317536</id><published>2006-04-18T12:38:00.000-07:00</published><updated>2006-04-18T13:50:56.983-07:00</updated><title type='text'>AJAX JSP and Direct Web Remoting</title><content type='html'>I wanted to try out Ajax with Java for some time now. I was clueless as to where to start. I came across this tool called "Direct Web Remoting" at &lt;a href="http://getahead.ltd.uk/dwr/index"&gt;http://getahead.ltd.uk/dwr/index&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;I decided to give it a try with the assumtions:-&lt;br /&gt;&lt;br /&gt;1) I should have a simeple java jsp/servlet which does some simple validation.&lt;br /&gt;2) This JSP/Servlet will invariable go back to the server and reload the jsp Page.&lt;br /&gt;3) The AJAX code must be able to perform the same simple validation.&lt;br /&gt;4) The AJAX code must go back to the server but must not reload the jsp Page.&lt;br /&gt;&lt;br /&gt;So i went ahead and first wrote a simple JSP/Servlet with Weblogic 8.1 and JDK 1.4.&lt;br /&gt;&lt;br /&gt;NOTE:- Blogger tries to render HTML tags in a blog. So where you see [] in tags read them as &lt;&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The traditional Servlet/JSP code&lt;/strong&gt;:-&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;package suchak.ajax.test;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;&lt;br /&gt;import javax.servlet.ServletException;&lt;br /&gt;import javax.servlet.http.HttpServlet;&lt;br /&gt;import javax.servlet.http.HttpServletRequest;&lt;br /&gt;import javax.servlet.http.HttpServletResponse;&lt;br /&gt;&lt;br /&gt;import org.apache.log4j.Logger;&lt;br /&gt;&lt;br /&gt;public class SimpleTestServlet extends HttpServlet {&lt;br /&gt;&lt;br /&gt;// Initialize th log4j logger&lt;br /&gt;private Logger log = Logger.getLogger(SimpleTestServlet.class);&lt;br /&gt;&lt;br /&gt;// The default String in the all jsp form action attributes.&lt;br /&gt;private final static String COMMANDENDSTRING = ".cmd";&lt;br /&gt;&lt;br /&gt;/* Using service method so that the servlet will work with a get as&lt;br /&gt;* well as a port&lt;br /&gt;*/&lt;br /&gt;public void service(HttpServletRequest req, HttpServletResponse res)&lt;br /&gt;throws IOException, ServletException{&lt;br /&gt;&lt;br /&gt;log.debug("the command asked for is : " +&lt;br /&gt;req.getRequestURI() );&lt;br /&gt;&lt;br /&gt;if(isCommand("processFullForm",req)){&lt;br /&gt;try{&lt;br /&gt;processFullForm(req,res);&lt;br /&gt;req.setAttribute("iSANumber","iSANumber");&lt;br /&gt;}catch(NumberFormatException e){&lt;br /&gt;req.setAttribute("NotANumber","NotANumber");&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;req.getRequestDispatcher("jsp/welcome.jsp").forward(req,res);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* The process method does the does the full form processing test.&lt;br /&gt;*&lt;br /&gt;*&lt;br /&gt;*/&lt;br /&gt;private void processFullForm(HttpServletRequest req, HttpServletResponse res)&lt;br /&gt;throws NumberFormatException, ServletException {&lt;br /&gt;//Set the done attribute for the screen&lt;br /&gt;String number = req.getParameter("number");&lt;br /&gt;Double.parseDouble(number);&lt;br /&gt;req.setAttribute("done","done");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/* This method tests the URI to see which command was asked for.&lt;br /&gt;* The command is the same as the action attribute of the form tag in the&lt;br /&gt;* jsp. This way multiple JSP's can use the same servlet.&lt;br /&gt;*&lt;br /&gt;* @param command the string value of the command i.e the action attribute&lt;br /&gt;* of the form tag in the jsp.&lt;br /&gt;* @param req the http request object&lt;br /&gt;*&lt;br /&gt;* @return boolean returns true if the command is same as the req uri or&lt;br /&gt;* false otherwise&lt;br /&gt;*/&lt;br /&gt;private boolean isCommand(String command, HttpServletRequest req){&lt;br /&gt;log.debug("URI will be compared with :: " +&lt;br /&gt;req.getContextPath()+ "/" + command + COMMANDENDSTRING);&lt;br /&gt;return req.getRequestURI().&lt;br /&gt;equals(req.getContextPath()+ "/" + command + COMMANDENDSTRING);&lt;br /&gt;}}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Traditional JSP&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[html]&lt;br /&gt;[head]&lt;br /&gt;[title]Welcome[/title]&lt;br /&gt;[/head]&lt;br /&gt;[body]&lt;br /&gt;[h1]&lt;br /&gt;Welcome to the AJAX Test&lt;br /&gt;[/h1]&lt;br /&gt;[br /]&lt;br /&gt;[br /]&lt;br /&gt;[!-- Start : Section for full form processing --]&lt;br /&gt;&lt;br /&gt;[hr]&lt;br /&gt;&lt;br /&gt;[h4]Full JSP reload test[h4]&lt;br /&gt;&lt;br /&gt;[FORM name="JSPReload" action="/ajaxtest/processFullForm.cmd" method="post"]&lt;br /&gt;[h4]Please enter a number here : [/h4]&lt;br /&gt;&lt;br /&gt;[INPUT type="text" name="number" value="&lt;br /&gt;[%if(request.getAttribute("number") !=null){&lt;br /&gt;out.println(request.getAttribute("number"));&lt;br /&gt;}else{&lt;br /&gt;out.println("");&lt;br /&gt;}%]&lt;br /&gt;"]&lt;br /&gt;&lt;br /&gt;[%if(request.getAttribute("NotANumber") != null){%]&lt;br /&gt;[h4]Please Enter a Valid Number ![/h4]&lt;br /&gt;[%}else if(request.getAttribute("iSANumber") != null) {%]&lt;br /&gt;[h4]That was a valid Number ![/h4]&lt;br /&gt;[%}%]&lt;br /&gt;&lt;br /&gt;[INPUT type="submit" name="submit" value="Click to get check whether the value entered is a number"]&lt;br /&gt;&lt;br /&gt;[/FORM]&lt;br /&gt;&lt;br /&gt;[!-- Start : Section for output values --]&lt;br /&gt;[%if(request.getAttribute("done") != null){%]&lt;br /&gt;[h4]Done[/h4]&lt;br /&gt;[%}%]&lt;br /&gt;[!-- END : Section for output values --]&lt;br /&gt;&lt;br /&gt;[!-- End : Section for full form processing --]&lt;br /&gt;&lt;br /&gt;[/body]&lt;br /&gt;[/html]&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;strong&gt;Traditional Web.xml&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[?xml version="1.0" encoding="UTF-8"?]&lt;br /&gt;[!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"]&lt;br /&gt;&lt;br /&gt;[web-app]&lt;br /&gt;[servlet]&lt;br /&gt;[servlet-name]SimpleTestServlet[/servlet-name]&lt;br /&gt;[servlet-class]suchak.ajax.test.SimpleTestServlet[/servlet-class]&lt;br /&gt;[/servlet]&lt;br /&gt;&lt;br /&gt;[servlet-mapping]&lt;br /&gt;[servlet-name]SimpleTestServlet[/servlet-name]&lt;br /&gt;[url-pattern]*.cmd[/url-pattern]&lt;br /&gt;[/servlet-mapping]&lt;br /&gt;&lt;br /&gt;[/web-app]&lt;br /&gt;&lt;/WEB-APP&gt;&lt;br /&gt;&lt;/span&gt;The above code works in the traditional way, and outputs wether the user entered a number on the jsp or not. Also it does the traditional JSP reload as expected&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The AJAX JSP code:-&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The test bean code&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;package suchak.ajax.test;&lt;br /&gt;&lt;br /&gt;public class TestAjx {&lt;br /&gt;&lt;br /&gt;public boolean isNumber(String number){&lt;br /&gt;System.out.println("In Server side Test Ajax");&lt;br /&gt;try{&lt;br /&gt;Double.parseDouble(number);&lt;br /&gt;System.out.println("In Server side Test Ajax : Before return true");&lt;br /&gt;return true;&lt;br /&gt;}catch(NumberFormatException e){&lt;br /&gt;System.out.println("In Server side Test Ajax NumberFormatException: " +&lt;br /&gt;"Before return false");&lt;br /&gt;return false;&lt;br /&gt;}&lt;br /&gt;}}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Modified AJAX JSP&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[html]&lt;br /&gt;[head]&lt;br /&gt;[title]Welcome[/title]&lt;br /&gt;[script type='text/javascript' src='/ajaxtest/dwr/interface/TAjx.js'][/script]&lt;br /&gt;[script type='text/javascript' src='/ajaxtest/dwr/engine.js'][/script]&lt;br /&gt;[script type='text/javascript' src='/ajaxtest/dwr/util.js'][/script]&lt;br /&gt;[/head]&lt;br /&gt;[body]&lt;br /&gt;[h1]&lt;br /&gt;Welcome to the AJAX Test&lt;br /&gt;[/h1]&lt;br /&gt;[br /]&lt;br /&gt;[br /]&lt;br /&gt;[!-- Start : Section for full form processing --]&lt;br /&gt;&lt;br /&gt;[hr]&lt;br /&gt;&lt;br /&gt;[h4]Full JSP reload test[h4]&lt;br /&gt;&lt;br /&gt;[FORM name="JSPReload" action="/ajaxtest/processFullForm.cmd" method="post"]&lt;br /&gt;[h4]Please enter a number here : [/h4]&lt;br /&gt;&lt;br /&gt;[INPUT type="text" name="number" value="&lt;br /&gt;[%if(request.getAttribute("number") !=null){&lt;br /&gt;out.println(request.getAttribute("number"));&lt;br /&gt;}else{&lt;br /&gt;out.println("");&lt;br /&gt;}%]&lt;br /&gt;"]&lt;br /&gt;&lt;br /&gt;[%if(request.getAttribute("NotANumber") != null){%]&lt;br /&gt;[h4]Please Enter a Valid Number ![/h4]&lt;br /&gt;[%}else if(request.getAttribute("iSANumber") != null) {%]&lt;br /&gt;[h4]That was a valid Number ![/h4]&lt;br /&gt;[%}%]&lt;br /&gt;&lt;br /&gt;[INPUT type="submit" name="submit" value="Click to get check whether the value entered is a number"]&lt;br /&gt;&lt;br /&gt;[/FORM]&lt;br /&gt;&lt;br /&gt;[!-- Start : Section for output values --]&lt;br /&gt;[%if(request.getAttribute("done") != null){%]&lt;br /&gt;[h4]Done[/h4]&lt;br /&gt;[%}%]&lt;br /&gt;[!-- END : Section for output values --]&lt;br /&gt;&lt;br /&gt;[!-- End : Section for full form processing --]&lt;br /&gt;&lt;br /&gt;[br][br][br][br][br]&lt;br /&gt;&lt;br /&gt;[!-- Start : Section for ajax form processing --]&lt;br /&gt;&lt;br /&gt;[hr]&lt;br /&gt;&lt;br /&gt;[h4]Ajax test : Not full form Refresh[h4]&lt;br /&gt;&lt;br /&gt;[h4]Please enter a number here : [/h4]&lt;br /&gt;&lt;br /&gt;[FORM name="AJAXTest" onsubmit="showMessage()" method="post"]&lt;br /&gt;[INPUT type="text" name="AjxNumber" value=""]&lt;br /&gt;[INPUT type="submit" name="submit" value="Click to get check whether the value entered is a number"]&lt;br /&gt;[/FORM]&lt;br /&gt;[script language="javascript" type="text/javascript"]&lt;br /&gt;&lt;br /&gt;var bool = false&lt;br /&gt;&lt;br /&gt;var reply0 = function(data){&lt;br /&gt;bool = data&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function showMessage() {&lt;br /&gt;TAjx.isNumber(document.AJAXTest.AjxNumber.value,reply0)&lt;br /&gt;&lt;br /&gt;alert(bool)&lt;br /&gt;&lt;br /&gt;if(&lt;br /&gt;document.AJAXTest.AjxNumber.value != null&lt;br /&gt;&amp;&amp;amp; document.AJAXTest.AjxNumber.value != ''&lt;br /&gt;&amp;&amp;amp; bool&lt;br /&gt;)&lt;br /&gt;{&lt;br /&gt;alert('That was a valid number!');&lt;br /&gt;}&lt;br /&gt;else{&lt;br /&gt;alert('Please enter a Valid Number!');&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[/script]&lt;br /&gt;&lt;br /&gt;[!-- End : Section for ajax form processing --]&lt;br /&gt;&lt;br /&gt;[/body]&lt;br /&gt;[/html]&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;The Modified AJAX Web.xml &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[?xml version="1.0" encoding="UTF-8"?]&lt;br /&gt;[!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"]&lt;br /&gt;&lt;br /&gt;[web-app]&lt;br /&gt;[servlet]&lt;br /&gt;[servlet-name]SimpleTestServlet[/servlet-name]&lt;br /&gt;[servlet-class]suchak.ajax.test.SimpleTestServlet[/servlet-class]&lt;br /&gt;[/servlet]&lt;br /&gt;&lt;br /&gt;[servlet]&lt;br /&gt;[servlet-name]dwr-invoker[/servlet-name]&lt;br /&gt;[display-name]DWR Servlet[/display-name]&lt;br /&gt;[servlet-class]uk.ltd.getahead.dwr.DWRServlet[/servlet-class]&lt;br /&gt;[init-param]&lt;br /&gt;[param-name]debug[/param-name]&lt;br /&gt;[param-value]true[/param-value]&lt;br /&gt;[/init-param]&lt;br /&gt;[/servlet]&lt;br /&gt;&lt;br /&gt;[servlet-mapping]&lt;br /&gt;[servlet-name]SimpleTestServlet[/servlet-name]&lt;br /&gt;[url-pattern]*.cmd[/url-pattern]&lt;br /&gt;[/servlet-mapping]&lt;br /&gt;&lt;br /&gt;[servlet-mapping]&lt;br /&gt;[servlet-name]dwr-invoker[/servlet-name]&lt;br /&gt;[url-pattern]/dwr/*[/url-pattern]&lt;br /&gt;[/servlet-mapping]&lt;br /&gt;&lt;br /&gt;[/web-app]&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;strong&gt;The new AJAX DWR.xml &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[!DOCTYPE dwr PUBLIC&lt;br /&gt;"-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"&lt;br /&gt;"http://www.getahead.ltd.uk/dwr/dwr10.dtd"]&lt;br /&gt;&lt;br /&gt;[dwr]&lt;br /&gt;[allow]&lt;br /&gt;[create creator="new" javascript="TAjx" scope="session"]&lt;br /&gt;[param name="class" value="suchak.ajax.test.TestAjx"/]&lt;br /&gt;[/create]&lt;br /&gt;[create creator="new" javascript="JDate" scope="session"]&lt;br /&gt;[param name="class" value="java.util.Date"/]&lt;br /&gt;[/create]&lt;br /&gt;[/allow]&lt;br /&gt;[/dwr]&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;This works as assumed above with the output :-&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;In Server side Test Ajax&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;In Server side Test Ajax NumberFormatException: Before return false&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;In Server side Test Ajax&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;In Server side Test Ajax : Before return true&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Problems i faced were :-&lt;br /&gt;&lt;br /&gt;1) The dwr.jar (&lt;a href="http://getahead.ltd.uk/dwr/download"&gt;http://getahead.ltd.uk/dwr/download&lt;/a&gt;) is needed to be in the web-inf/lib dir, along with the bean class suchak.ajax.test.TestAjx. I had place everthing in APP-inf/lib dir which was not working. I found out that this was a known issue with DWR in weblogic 8.1.&lt;br /&gt;2) The javascript was a bit difficult to figure out initially, but looking at the code in the example war it came out to be pretty straightforward.&lt;br /&gt;&lt;br /&gt;The issues i think are :-&lt;br /&gt;&lt;br /&gt;1) There is a dependency on DWR for this to work.&lt;br /&gt;2) The Ajax page sends gives alerts instead of messages on the page like the JSP/Servlet solution, which i think is better than alerts. There is a javascript document.write but that can not write to a portion of the page.&lt;br /&gt;&lt;br /&gt;But all said and done the HTML Java AJAX solution does work, with little effort using DWR. Also it does server side validations without page refresh.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-114539126689317536?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/114539126689317536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=114539126689317536&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/114539126689317536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/114539126689317536'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2006/04/ajax-jsp-and-direct-web-remoting.html' title='AJAX JSP and Direct Web Remoting'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-114538905378778405</id><published>2006-04-18T12:22:00.000-07:00</published><updated>2006-04-18T12:37:33.800-07:00</updated><title type='text'>Java DateFormat is not threadsafe</title><content type='html'>Java DateFormat and SimpleDate classes are not threadsafe.&lt;br /&gt;&lt;br /&gt;When an application has a few common date formats it seems natural to have them in some common place like static variables or in some kind of singleton.&lt;br /&gt;&lt;br /&gt;However as per this bug report last updated in 2001, date format is not thread safe :-&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4228335"&gt;http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4228335&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Also the sun java doc for 1.4 and 1.5 confirms the same :-&lt;br /&gt;&lt;br /&gt;&lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/text/DateFormat.html"&gt;http://java.sun.com/j2se/1.4.2/docs/api/java/text/DateFormat.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/text/DateFormat.html"&gt;http://java.sun.com/j2se/1.5.0/docs/api/java/text/DateFormat.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="synchronization"&gt;&lt;em&gt;&lt;strong&gt;Synchronization&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;What does that impact ?&lt;br /&gt;&lt;br /&gt;Well if the methods of dateformat do not use instance variables like most servlets, i guess we should be ok, even if multiple threads access the dateformat,  just like servlets.&lt;br /&gt;&lt;br /&gt;However since the javadoc "&lt;em&gt;recommends to create separate format instances for each thread&lt;/em&gt;"  we might use thread local variables to store the DateFormats. That way instead of creating a new DateFormat each time it is needed, we will get only as many DateFormats as there are threads using them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-114538905378778405?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/114538905378778405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=114538905378778405&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/114538905378778405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/114538905378778405'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2006/04/java-dateformat-is-not-threadsafe.html' title='Java DateFormat is not threadsafe'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-114538804256433674</id><published>2006-04-18T12:01:00.000-07:00</published><updated>2006-04-18T12:20:42.580-07:00</updated><title type='text'>Java Timezone class</title><content type='html'>I was looking at java.util.TimeZone class. I guessed this could be important in places like the USA where there are three or more timezones.&lt;br /&gt;&lt;br /&gt;However in addition to being usefull for places with different timezones it also seems to cater to places with daylight savings time.  For the uninformed, especially from places like india where there is no daylight savings this link gives a lot of information :-&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Daylight_saving_time"&gt;http://en.wikipedia.org/wiki/Daylight_saving_time&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The javadoc is at :-&lt;br /&gt;&lt;br /&gt;&lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/TimeZone.html"&gt;http://java.sun.com/j2se/1.4.2/docs/api/java/util/TimeZone.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The interesting methods to use are the getOffset Methods :-&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public abstract int getOffset(int era,int year,int month,int day,int dayOfWeek,int milliseconds)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Gets the time zone offset, for current date, modified in case of daylight savings. This is the offset to add to UTC to get local time. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;This method returns a historically correct offset if an underlying TimeZone implementation subclass supports historical Daylight Saving Time schedule and GMT offset changes.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One can use this method in this fashion :-&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;TimeZone tz = timeZone.getTimeZone("America/Los_Angeles");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;long actualDate = (new Date().getTime() ) + timeZone.getOffset(new Date().getTime() )&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-114538804256433674?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/114538804256433674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=114538804256433674&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/114538804256433674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/114538804256433674'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2006/04/java-timezone-class.html' title='Java Timezone class'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-112954199764833854</id><published>2005-10-17T02:13:00.000-07:00</published><updated>2005-10-17T04:55:20.180-07:00</updated><title type='text'>java NIO allocate vs allocateDirect</title><content type='html'>Java NIO (new IO) came up with JDK 1.4.&lt;br /&gt;&lt;br /&gt;As of now there is only one book out there that deals with it :-&lt;br /&gt;&lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0596002882/104-4162257-7590320?v=glance"&gt;http://www.amazon.com/exec/obidos/tg/detail/-/0596002882/104-4162257-7590320?v=glance&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I wanted to have a look at some of the new stuff, and looked at some material on the net.&lt;br /&gt;&lt;br /&gt;Buffers are to pimitive types what collections are to Objects.&lt;br /&gt;&lt;br /&gt;What interests me is that the new java nio ByteBuffer class has two ways to create a new ByteBuffer i.e the static methods allocate and allocateDirect.&lt;br /&gt;&lt;br /&gt;As i understand allocateDirect, will allocate it directly in the OS memory space and not in the JVM space. It has the primary advantage of not using up too much JVM memory for large files or other hige primitive type data.&lt;br /&gt;&lt;br /&gt;Here are the common method used for the code below:-&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;static void logTime(String seq){&lt;br /&gt;System.out.println(seq + " : " + new Date(System.currentTimeMillis()));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;static void showBufferProperties( Buffer buf,String name){&lt;br /&gt;&lt;br /&gt;System.out.println( "Buffer Properties for " + name + "\n capacity=" + buf.capacity() + " limit=" + buf.limit() + " position=" + buf.position());&lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I tried out the following :-&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;logTime("1"); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;ByteBuffer buf5 = ByteBuffer.allocate(300000000); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;logTime("1a"); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for(int i = 0; i&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;buf5.putDouble(1.0/3.0). &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;putFloat((float)(1.0/6.0)). &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;putLong(Long.MAX_VALUE); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;} &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;showBufferProperties(buf5,"buf5"); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;logTime("2");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And got this result.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;1 : Mon Oct 17 10:20:19 BST 2005&lt;br /&gt;java.lang.OutOfMemoryError&lt;br /&gt;Exception in thread "main"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then i tried this :-&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;logTime("3"); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;ByteBuffer buf6 = ByteBuffer.allocateDirect(300000000); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;logTime("3a"); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for(int i = 0; i&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;buf6.putDouble(1.0/3.0). &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;putFloat((float)(1.0/6.0)). &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;putLong(Long.MAX_VALUE); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;} &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;showBufferProperties(buf6,"buf6"); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;logTime("4");&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And got this result:-&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;3 : Mon Oct 17 10:22:53 BST 2005&lt;br /&gt;3a : Mon Oct 17 10:23:00 BST 2005&lt;br /&gt;Buffer Properties for buf6&lt;br /&gt;capacity=300000000 limit=300000000 position=60000000&lt;br /&gt;4 : Mon Oct 17 10:23:09 BST 2005&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So clearly for huge files allocateDirect does work well as compared to allocate which give an out of memory error.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here is what the java doc says :-&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Direct vs. non-direct buffers&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;A byte buffer is either direct or non-direct. Given a direct byte buffer, the Java virtual machine will make a best effort to perform native I/O operations directly upon it. That is, it will attempt to avoid copying the buffer's content to (or from) an intermediate buffer before (or after) each invocation of one of the underlying operating system's native I/O operations.&lt;br /&gt;A direct byte buffer may be created by invoking the &lt;/em&gt;&lt;a href="http://www.doc.ic.ac.uk/csg/java/1.4.0docs/api/java/nio/ByteBuffer.html#allocateDirect(int)"&gt;&lt;em&gt;allocateDirect&lt;/em&gt;&lt;/a&gt;&lt;em&gt; factory method of this class. The buffers returned by this method typically have somewhat higher allocation and deallocation costs than non-direct buffers. It is therefore recommended that such buffers be used primarily for large, long-lived buffers that are subject to the underlying system's native &lt;/em&gt;&lt;br /&gt;&lt;em&gt;I/O operations.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;A direct byte buffer may also be created by &lt;/em&gt;&lt;a href="http://www.doc.ic.ac.uk/csg/java/1.4.0docs/api/java/nio/channels/FileChannel.html#map(java.nio.channels.FileChannel.MapMode,"&gt;&lt;em&gt;mapping&lt;/em&gt;&lt;/a&gt;&lt;em&gt; a region of a file directly into memory. An implementation of the Java platform may optionally support the creation of direct byte buffers from native code via JNI. If an instance of one of these kinds of buffers refers to an inaccessible region of memory then an attempt to access that region will either return an arbitrary value, have no visible effect, or cause an unspecified exception to be thrown. &lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;br /&gt;Whether a byte buffer is direct or non-direct may be determined by invoking its &lt;/em&gt;&lt;a href="http://www.doc.ic.ac.uk/csg/java/1.4.0docs/api/java/nio/ByteBuffer.html#isDirect()"&gt;&lt;em&gt;isDirect&lt;/em&gt;&lt;/a&gt;&lt;em&gt; method. &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So it is as good as reading or writing to system memory directy using JNI and then wrapping it with java code. The additional advantage is it does not use the JVM memory space.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I can also see the advantage of using this if there are many smaller files all open at the same time for a application. It could use up the jvm heap space very fast. JVM is a heap space meant for objects. To use it up for reading or writing files would not be so good.&lt;br /&gt;&lt;br /&gt;Also i guess it is better if we use the OS for what it does best i.e handle files.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I can see that this new bytebuffer class will go a long way to help with the above.&lt;br /&gt;&lt;br /&gt;Also the other advantage v/s doing the same with JNI is that this is platform neutral. Just say allocateDirect and the java code will use the OS memory. JNI code might have to be coded for each OS on which you will deploy the application.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Note:-&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;It seems that for direct buffers hasArray method returns true meaning that it does have a array behind it , and for non-direct buffers the hasArray method returns false that is it does not have a backing array. The array can be retrieved by invoking the the array() method on ByteBuffer class.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-112954199764833854?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/112954199764833854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=112954199764833854&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/112954199764833854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/112954199764833854'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2005/10/java-nio-allocate-vs-allocatedirect.html' title='java NIO allocate vs allocateDirect'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-112921824035892039</id><published>2005-10-13T08:16:00.000-07:00</published><updated>2005-10-13T08:46:23.853-07:00</updated><title type='text'>JDK 1.4 VS Log4J Logging</title><content type='html'>JDK 1.4 has a java.util.logging package. It is based on JSR047.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.swzoo.org/documents/miscellaneous/jsr047/"&gt;http://www.swzoo.org/documents/miscellaneous/jsr047/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I just tried to have a look and see how it is different from Log4j that i have used over the years.&lt;br /&gt;&lt;br /&gt;As per ..\j2sdk1.4.2_03\docs\api\java\util\logging\Level.html it has following levels :-&lt;br /&gt;&lt;br /&gt;"&lt;br /&gt;&lt;em&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;The levels in descending order are:&lt;br /&gt;SEVERE (highest value)&lt;br /&gt;WARNING&lt;br /&gt;INFO&lt;br /&gt;CONFIG&lt;br /&gt;FINE&lt;br /&gt;FINER&lt;br /&gt;FINEST (lowest value) In addition there is a level OFF that can be used to turn off logging, and a level ALL that can be used to enable logging of all messages.&lt;/span&gt;&lt;/em&gt;&lt;br /&gt;"&lt;br /&gt;&lt;br /&gt;I guess ALL and OFF could be used as they are provided , but why would one logically use them is the question.&lt;br /&gt;&lt;br /&gt;Also Fine, Finer and Finest seem a bit .... Odd i would say. What is wrong with log4j's - FATAL, ERROR, WARN, INFO and DEBUG.&lt;br /&gt;&lt;br /&gt;What is CONFIG anyway ?&lt;br /&gt;&lt;br /&gt;From the same API page&lt;br /&gt;&lt;br /&gt;"&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;em&gt;CONFIGpublic static final &lt;/em&gt;&lt;/span&gt;&lt;a title="class in java.util.logging" href="file:///C:/NewBACS/j2sdk1.4.2_03/docs/api/java/util/logging/Level.html"&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;em&gt;Level&lt;/em&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;em&gt; CONFIG&lt;br /&gt;CONFIG is a message level for static configuration messages.&lt;br /&gt;CONFIG messages are intended to provide a variety of static configuration information, to assist in debugging problems that may be associated with particular configurations. For example, CONFIG message might include the CPU type, the graphics depth, the GUI look-and-feel, etc. This level is initialized to 700.&lt;/em&gt;&lt;/span&gt;&lt;br /&gt;"&lt;br /&gt;&lt;br /&gt;So there is a level for just for configuration type log messages ? Interesting !&lt;br /&gt;&lt;br /&gt;Then i found out what a developer of Log4j has to say here :-&lt;br /&gt;&lt;a href="http://www.ingrid.org/jajakarta/log4j/jakarta-log4j-1.1.3/docs/critique.html"&gt;http://www.ingrid.org/jajakarta/log4j/jakarta-log4j-1.1.3/docs/critique.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;and also a discussion on theserverside here&lt;br /&gt;&lt;a href="http://www.theserverside.com/news/thread.tss?thread_id=7177"&gt;http://www.theserverside.com/news/thread.tss?thread_id=7177&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;What they seem to saying in gist is :-&lt;br /&gt;&lt;br /&gt;&lt;em&gt;At first glance, this might look like a mundane implementation detail but it is actually quite fundamental. &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;&lt;strong&gt;Configuration order matters&lt;br /&gt;&lt;/strong&gt;In JSR47, when you set the level of a logger, say wombat, JSR47 traverses the tree below wombat. In other words, the levels for all the loggers descending from wombat are overwritten. This can be a very expensive operation for large trees. In particular, for the most common case where one sets the level of the root logger. However, performance is not the point I am trying to make.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;In log4j, changing the priority of a category involves the change of a single field. Children categories dynamically inherit the priority of their parent by traversing the hierarchy tree upwards.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;It follows that with JSR47 if you configure the level for logger "foo.bar1" before configuring the level for "foo", then the latter instruction will overwrite the first exactly as if the first instruction for configuring "foo.bar1" had never existed. Configuration order dependence is not a show stopper but it is something that will bite you time and again.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;In contrast, in log4j categories can be configured in any order. You never have to worry about configuration order. &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;&lt;strong&gt;Limited inheritance&lt;br /&gt;&lt;/strong&gt;In JSR47, a logger does not walk the hierarchy to inherit its level but possesses a copy of it.&lt;br /&gt;Unfortunately, in the JSR47 API, handlers cannot be inherited because it would be prohibitively expensive to let each logger to contain a distinct Vector of all inherited handlers, especially in large trees.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;To circumvent this problem by JSR47 defines global handlers. A logger logs to global handlers and to the handlers attached to itself directly. It does not inherit any handlers from the hierarchy.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;In log4j, appenders are inherited additively from the hierarchy. A category will log to the appenders attached to itself as well as the appenders attached to its ancestors. This might not seem like much until the day you need handler inheritance; probably a week after you decide to adopt a logging API.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;Similarly, in log4j resource bundles are inherited from the hierarchy. In JSR47, a resource bundle must be attached to each logger individually. There is no resource bundle inheritance in JSR47. In practice, this means that you have to choose between internationalization and the benefits of the named logger hierarchy. It's one or the other. This limitation is particularly surprising because support for internationalization is advocated as one of the primary advantages of the JSR47 API. &lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;strong&gt;&lt;em&gt;Limited functionality&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;&lt;em&gt;Log4j has appenders capable of logging to the console, to files, to Unix Syslog daemons, to Microsoft NT EventLoggers, remote servers, to JMS channels, automatically generate email etc. It can roll log files by size or date and log asynchronously.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;JSR47 can log to the console, to files, to sockets and to a memory buffer.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;Log4j has an extensible and powerful layout called the PatternLayout. JSR47 offers the much weaker SimpleFormatter as an alternative.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;Log4j supports configuration through property files as well as XML documents. JSR47 currently admits only property files. Moreover, the language of JSR47 configuration files is very weak. In particular, you can only configure one instance of a given handler class. This means that you can log to just one file at a time. &lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;strong&gt;&lt;em&gt;Error Handling&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;&lt;em&gt;In JSR 47 when an error occurs then either a RunTimeException is thrown to the user or (in handlers only) an internal field is set. In the first case, the RunTimeException will cause your application to crash. In the latter case, you can retrieve the last caught exception in the handler by querying the getException method of that handler. The former is totally unacceptable while the latter is impractical.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;In log4j, under no circumstances are exceptions thrown at the user. However, all appenders have an associated ErrorHandler. This ErrorHandler is invoked by the appender whenever a handler-specific error occurs. By default, log4j appenders are associated with an OnlyOnceErrorHandler which emits a message on the console for the first error in an appender and ignoring all following errors.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;An ErrorHandler can implement an arbitrary error handling policy. For example, after a failure to write to a database a JDBCAppender can be redirected to fall back on a FileAppender. This functionality is supported in XML configuration files. You do not need to change a single line of client code.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;But again who cares about errors, right?&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;strong&gt;Performance&lt;br /&gt;&lt;/strong&gt;Logging performance must be studied in three distinct cases: when logging is turned off, when turned on but due to priority comparison logic not enabled, and when actually logging. Please refer to the &lt;/em&gt;&lt;a href="http://www.ingrid.org/jajakarta/log4j/jakarta-log4j-1.1.3/docs/manual.html#performance"&gt;&lt;em&gt;log4j manual&lt;/em&gt;&lt;/a&gt;&lt;em&gt; for a more detailed discussion of logging performance.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;When logging is turned on, log4j will be about three times slower to decide whether a log statement is enabled or not. This is due to the dynamic nature of log4j which requires it to walk the hierarchy. To give you an idea about the figures involved, we are talking about 90 nanoseconds instead of 30 nanoseconds on a 800Mhz Intel processor. In other words, one million disabled logging requests will cost under a second in both environments.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;In a shipped binary, you can turn off logging entirely and both APIs will perform identically. Note that if one is not careful, the cost of parameter construction before invoking a disabled log statement will overwhelm any other performance consideration. Regardless of the API you decide to use, logging statements should never be placed in tight loops, for example, before or after an element swap instruction in a sort algorithm.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;In log4j, caller localization information is optional whereas in JSR47 it is always extracted. Since &lt;/em&gt;&lt;br /&gt;&lt;em&gt;the extraction of caller localization is a very slow operation, in the common case where caller information is not needed, log4j will log the same information 4 to 100 times faster. &lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;strong&gt;Lastly as of now the new logging mechanism will work only with JDK 1.4 and above.&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Then i looked at 1.5 api here :-&lt;br /&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/index.html"&gt;http://java.sun.com/j2se/1.5.0/docs/api/index.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Logging levels at least seem to be the same. They seem to have added a interface "LoggingMXBean" &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/logging/LoggingMXBean.html"&gt;http://java.sun.com/j2se/1.5.0/docs/api/java/util/logging/LoggingMXBean.html&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;It is a&lt;br /&gt;"&lt;em&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;The management interface for the logging facility.&lt;br /&gt;There is a single global instance of the LoggingMXBean&lt;/span&gt;&lt;/em&gt;"&lt;br /&gt;&lt;br /&gt;The LogManager class in java.uti.logging package now has a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/logging/LogManager.html#getLoggingMXBean()"&gt;LogManager.getLoggingMXBean()&lt;/a&gt; method which returns this interface used for managing the logging facility.&lt;br /&gt;&lt;br /&gt;Ansyway as of now i will stick with Log4j.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-112921824035892039?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/112921824035892039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=112921824035892039&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/112921824035892039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/112921824035892039'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2005/10/jdk-14-vs-log4j-logging.html' title='JDK 1.4 VS Log4J Logging'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-111530363640428734</id><published>2005-05-05T07:14:00.000-07:00</published><updated>2005-05-05T07:51:57.126-07:00</updated><title type='text'>Hibernate 3 with Microsoft ms access 2000 odbc</title><content type='html'>&lt;strong&gt;&lt;span style="color:#3366ff;"&gt;Hibernate 3 with Microsoft ms access 2000 odbc&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;MS access is a kind of low feature DB to be found on most windoz PC's today.&lt;br /&gt;&lt;br /&gt;My view is that to check out a few features of hibernate one need not have oracle, db2 or other such high end db.&lt;br /&gt;&lt;br /&gt;To know what is hibernate please visit &lt;a href="http://www.hibernate.org"&gt;www.hibernate.org&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;Now for using Hibernate, one must set up certain mandatory properties in a file generally called hibernate.properties file.&lt;br /&gt;&lt;br /&gt;One of such a property is dialect :&lt;em&gt; hibernate.dialect&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;There are several out of the box dialects given by hibernate that support Oracle, Db2 , MySQL etc.&lt;br /&gt;&lt;br /&gt;However there is no out of the box support for MS Access.&lt;br /&gt;&lt;br /&gt;What hibernate has though is an exellent plugglabe architechture, that allows users to specify new dialects by subclassing from org.hibernate.dialect.Dialect class.&lt;br /&gt;&lt;br /&gt;So i tried to write up a class called MSAccessDialect.&lt;br /&gt;&lt;br /&gt;The main issues i faced were mostly with Inserts and identitiy columns.&lt;br /&gt;&lt;br /&gt;To know what an identity column in hibernate means please see here:-&lt;br /&gt;&lt;a href="http://www.hibernate.org/hib_docs/reference/en/html/mapping.html"&gt;http://www.hibernate.org/hib_docs/reference/en/html/mapping.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I have got it working with Hibernate with Microsoft ms access odbc, including inserts and reads with identity.&lt;br /&gt;I am using hibernate 3.0 , JDK 1.4 and Microsoft ms access 200.&lt;br /&gt;&lt;br /&gt;Here is the dialect class:-&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#3333ff;"&gt;package org.hibernate.dialect;&lt;br /&gt;&lt;br /&gt;import java.sql.Types;&lt;br /&gt;&lt;br /&gt;import org.hibernate.cfg.Environment;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* @author Suchak.Jani&lt;br /&gt;*/&lt;br /&gt;public class MSAccessDialect extends Dialect {&lt;br /&gt;public MSAccessDialect() {&lt;br /&gt;super();&lt;br /&gt;registerColumnType( Types.BIT, "BIT" );&lt;br /&gt;registerColumnType( Types.BIGINT, "INTEGER" );&lt;br /&gt;registerColumnType( Types.SMALLINT, "SMALLINT" );&lt;br /&gt;registerColumnType( Types.TINYINT, "BYTE" );&lt;br /&gt;registerColumnType( Types.INTEGER, "INTEGER" );&lt;br /&gt;registerColumnType( Types.CHAR, "VARCHAR(1)" );&lt;br /&gt;registerColumnType( Types.VARCHAR, "VARCHAR($l)" );&lt;br /&gt;registerColumnType( Types.FLOAT, "DOUBLE" );&lt;br /&gt;registerColumnType( Types.DOUBLE, "DOUBLE" );&lt;br /&gt;registerColumnType( Types.DATE, "DATETIME" );&lt;br /&gt;registerColumnType( Types.TIME, "DATETIME" );&lt;br /&gt;registerColumnType( Types.TIMESTAMP, "DATETIME" );&lt;br /&gt;registerColumnType( Types.VARBINARY, "VARBINARY($l)" );&lt;br /&gt;registerColumnType( Types.NUMERIC, "NUMERIC" );&lt;br /&gt;&lt;br /&gt;getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE,NO_BATCH);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public String getIdentityColumnString() {&lt;br /&gt;//return " counter ";&lt;br /&gt;return "not null auto_number";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public String getIdentitySelectString() {&lt;br /&gt;return "select @@IDENTITY";&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here is a test xml file which works :-&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#3333ff;"&gt;&amp;lt;hibernate-mapping&amp;gt;&lt;br /&gt;       &amp;lt;class name="com.suchak.hibernatetest.domainobjects.Person" table="Person"&amp;gt;&lt;br /&gt;              &amp;lt;id name="ID" column="ID" &amp;gt;&lt;br /&gt;                   &amp;lt;generator class="identity"/&amp;gt;&lt;br /&gt;              &amp;lt;/id&amp;gt;&lt;br /&gt;              &amp;lt;property name="firstName"&amp;gt;&lt;br /&gt;                    &amp;lt;column name="FirstName"/&amp;gt;&lt;br /&gt;              &amp;lt;/property&amp;gt;&lt;br /&gt;                    &amp;lt;property name="lastName"&amp;gt;&lt;br /&gt;              &amp;lt;column name="LastName"/&amp;gt;&lt;br /&gt;                    &amp;lt;/property&amp;gt;&lt;br /&gt;        &amp;lt;/class&amp;gt;&lt;br /&gt;&amp;lt;/hibernate-mapping&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#3333ff;"&gt;The above ID is an Interger in java and Autonumber in Microsoft ms access &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;color:#3333ff;"&gt;&lt;/span&gt;&lt;br /&gt;Also it goes without saying that there is a person object. You can create it looking at the xml above.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Note:-&lt;/strong&gt; There are problems of still not being able to use Long with the above but that is due to issues of the ms odbc driver. It has nothing to do with Hibernate.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-111530363640428734?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/111530363640428734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=111530363640428734&amp;isPopup=true' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/111530363640428734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/111530363640428734'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2005/05/hibernate-3-with-microsoft-ms-access.html' title='Hibernate 3 with Microsoft ms access 2000 odbc'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9699730.post-110483628738188058</id><published>2005-01-04T02:41:00.000-08:00</published><updated>2005-01-04T03:20:17.680-08:00</updated><title type='text'>Struts mapping recap</title><content type='html'>Here is a sample stuts action mapping:-&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;span style="font-family: courier new;"&gt;&amp;lt;form-beans&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;	&amp;lt;form-bean name="TestForm" type="com.test.form.TestForm"&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;&amp;lt;/form-bean&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;&amp;lt;action-mappings&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;&amp;lt;action path="/Test" parameter="action" type="com.test.action.TestAction" scope="request" validate="false" name="TestForm"&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;		&amp;lt;forward name="list" path="/web/jsp/test.jsp" redirect="false"&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;	&amp;lt;/forward&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;&amp;lt;/action&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The name parameter is what tells what is the form.&lt;br /&gt;In the above the parameter action is what defines where the execution of the struts dispatch action will go to.&lt;br /&gt;For example /Test?list will go a method called list in the Test Dispatch action.&lt;br /&gt;There is only one forward above with the same name list, so mapping.findforward("list"), will forward to "&lt;web&gt;/web/jsp/test.jsp". The redirect false will make sure that it is not redirected.&lt;br /&gt;&lt;br /&gt;If it were to be redirect=true, the conatiner would forward the "&lt;web&gt;/web/jsp/test.jsp" to the browser and then again asks the bowser to submit the same back to the server. Whatever test,jsp renders on screen after the submit of that test.jsp(which might have some form) would be visible. after that.&lt;br /&gt;&lt;br /&gt;In short instead of just a forward to test.jsp , it forwards to test.jsp and then forces the browser to submit test.jsp again.&lt;br /&gt;&lt;br /&gt;Internally this is done using two diffetent serlet api methods.&lt;br /&gt;&lt;br /&gt;The forward is done using the requestdispatcher forward method&lt;br /&gt;&lt;a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/RequestDispatcher.html#forward%28javax.servlet.ServletRequest,%20javax.servlet.ServletResponse%29"&gt;http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/RequestDispatcher.html#forward&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The redirect is done using the sendRedirect method of the http response object.&lt;br /&gt;&lt;a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletResponse.html#sendRedirect%28java.lang.String%29"&gt;http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletResponse.html#sendRedirect&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Needless to say whatever was there in the first request scope will be lost.One way to not loose pervious request data is the use of hidden variables back and forth but this can be very cumbersome.&lt;/web&gt;&lt;/web&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110483628738188058?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110483628738188058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110483628738188058&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110483628738188058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110483628738188058'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2005/01/struts-mapping-recap.html' title='Struts mapping recap'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110473681678707542</id><published>2005-01-02T22:59:00.000-08:00</published><updated>2005-01-03T02:34:24.996-08:00</updated><title type='text'>Understanding EJB transactions</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Transaction isolation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is a property related to the database.&lt;br /&gt;&lt;br /&gt;TRANSACTION_SERIALIZABLE—Simultaneously executing this transaction multiple times has the same effect as executing the transaction multiple times in a serial fashion. This is the most restrictive and should be avoided is most cases.This solves the problems of phantom reads by never letting any other transaction even read or update this data.&lt;br /&gt;TRANSACTION_REPEATABLE_READ—Once the transaction reads a subset of data, repeated reads of the same data return the same values, even if other transactions have subsequently modified the data. This is the also restrictive but less than TRANSACTION_SERIALIZABLE and also should be avoided is most cases. This solves the problem of non repreatable reads.&lt;br /&gt;TRANSACTION_READ_COMMITTED—The transaction can view only committed updates from other transactions. This is the default in servers like weblogic. This solves the problem of dirty reads.&lt;br /&gt;TRANSACTION_READ_UNCOMMITTED—The transaction can view uncommitted updates from other transactions. This is least restrictive, but it is also makes dirty reads possible.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;How does a transaction apply itslef to an EJB ?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;How to declare what transaction scheme to use ?trans-attribute in ejb-jar.xml&lt;br /&gt;&lt;br /&gt;Specifies how the container manages the transaction boundaries when delegating a method invocation to an enterprise bean's business method. Allowable value include:&lt;br /&gt; * NotSupported&lt;br /&gt; * Supports&lt;br /&gt; * Required&lt;br /&gt; * RequiresNew&lt;br /&gt; * Mandatory&lt;br /&gt; * Never&lt;br /&gt;&lt;br /&gt;Note: Because clients do not provide a transaction context for calls to an MDB, MDBs that use container-managed transactions must have trans-attribute of Required.&lt;br /&gt;&lt;br /&gt;If not specified, the EJB container issues a warning, and uses NotSupported for MDBs and Supports for other types of EJBs.&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;In a stateless session bean as well as an entity bean the transaction does not span method calls. In statefull session bean since there is a user session invloved the transaction can span various method call.&lt;br /&gt;&lt;br /&gt;There is an interface called javax.ejb.SessionSynchronization which provides call back methods to the statefull session bean so as to know what is happening with the transaction:-&lt;br /&gt;&lt;a href="http://java.sun.com/products/ejb/javadoc-1.0/javax.ejb-javadoc/javax.ejb.SessionSynchronization.html"&gt;&lt;span style="font-style: italic;"&gt;http://java.sun.com/products/ejb/javadoc-1.0/javax.ejb-javadoc/javax.ejb.SessionSynchronization.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="afterBegin"&gt;&lt;b&gt;afterBegin&lt;/b&gt;&lt;/a&gt; &lt;pre&gt; public abstract void afterBegin() throws RemoteException&lt;br /&gt;&lt;/pre&gt;  &lt;dl&gt; &lt;dd&gt; The afterBegin method notifies a session Bean instance that a new transaction has started, and that the subsequent business methods on the instance will be invoked in the context of the transaction.&lt;/dd&gt;&lt;dd&gt;The instance can use this method, for example, to read data  from a database and cache the data in the instance fields.&lt;/dd&gt;   &lt;dd&gt;This method executes in the proper transaction context.&lt;/dd&gt; &lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;b&gt;Throws:&lt;/b&gt; RemoteException     &lt;/dt&gt;&lt;dd&gt; Thrown if the instance could not perform the     function requested by the container because of a system-level error.   &lt;/dd&gt;&lt;/dl&gt;&lt;/dd&gt; &lt;/dl&gt;  &lt;a name="beforeCompletion()"&gt;&lt;img src="http://java.sun.com/products/ejb/javadoc-1.0/javax.ejb-javadoc/images/red-ball.gif" alt=" o " height="12" width="12" /&gt;&lt;/a&gt; &lt;a name="beforeCompletion"&gt;&lt;b&gt;beforeCompletion&lt;/b&gt;&lt;/a&gt; &lt;pre&gt; public abstract void beforeCompletion() throws RemoteException&lt;br /&gt;&lt;/pre&gt;  &lt;dl&gt; &lt;dd&gt; The beforeCompletion method notifies a session Bean instance that a transaction is about to be committed. The instance can use this method, for example, to write any cached data to a database.&lt;/dd&gt;&lt;dd&gt;This method executes in the proper transaction context.&lt;/dd&gt;   &lt;dd&gt;&lt;b&gt;Note:&lt;/b&gt; The instance may still cause the container to rollback the transaction by invoking the setRollbackOnly() method on the instance context, or by throwing an exception.&lt;/dd&gt; &lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;b&gt;Throws:&lt;/b&gt; RemoteException     &lt;/dt&gt;&lt;dd&gt; Thrown if the instance could not perform the     function requested by the container because of a system-level error.   &lt;/dd&gt;&lt;/dl&gt;&lt;/dd&gt; &lt;/dl&gt;  &lt;a name="afterCompletion(boolean)"&gt;&lt;img src="http://java.sun.com/products/ejb/javadoc-1.0/javax.ejb-javadoc/images/red-ball.gif" alt=" o " height="12" width="12" /&gt;&lt;/a&gt; &lt;a name="afterCompletion"&gt;&lt;b&gt;afterCompletion&lt;/b&gt;&lt;/a&gt; &lt;pre&gt; public abstract void afterCompletion(boolean committed) throws RemoteException&lt;br /&gt;&lt;/pre&gt;  &lt;dl&gt; &lt;dd&gt; The afterCompletion method notifies a session Bean instance that a transaction commit protocol has completed, and tells the instance whether the transaction has been committed or rolled back.&lt;/dd&gt;&lt;dd&gt;This method executes with no transaction context.&lt;/dd&gt;   &lt;dd&gt;This method executes with no transaction context.&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/dd&gt; &lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;b&gt;Parameters:&lt;/b&gt;     &lt;/dt&gt;&lt;dd&gt; committed - True if the transaction has been committed, false     if is has been rolled back.     &lt;/dd&gt;&lt;dt&gt; &lt;b&gt;Throws:&lt;/b&gt; RemoteException     &lt;/dt&gt;&lt;dd&gt; Thrown if the instance could not perform the     function requested by the container because of a system-level error.   &lt;/dd&gt;&lt;/dl&gt;&lt;/dd&gt; &lt;/dl&gt; However you can start a transaction in a method of a session bean and then call other some other bean's methods. This way you can propogate transactions.&lt;br /&gt;&lt;br /&gt;Lets say you have a parent EJB and a child EJB.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;All parent and child EJB methods have transaction as RequriesNew.&lt;/span&gt;&lt;br /&gt;In this case it is suprising but true, that all unchecked and runtime exceptions in child mthods will cause the parent to roll back too. Checked application exceptions will have no effect on the parent. However here if the parent fails after the child has finished executing, the results of the child will not have any effect.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;All parent and child EJB methods have transaction as Requries.&lt;/span&gt;&lt;br /&gt;In this case too all unchecked and runtime exceptions in child methods will cause the parent to roll back too. Also they both have the same Transaction context as the parent here propogates the transaction to the child. Here if the parent fails after the child has finished executing, the results of the child will also roll back.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Nested transactions:&lt;/span&gt;&lt;br /&gt;By default EJB's do not support nested transactions.&lt;br /&gt;However one can simulate nested transactions by using a combination of the &lt;span style="font-style: italic;"&gt;"parent and child EJB methods have transaction as Requries. "  &lt;/span&gt;and  "&lt;/span&gt;&lt;span style="font-style: italic;"&gt;parent and child EJB methods have transaction as RequriesNew&lt;/span&gt;" or a combination of the above, type of architechture.&lt;/span&gt; You can not let parent rollback by using requiresNew on the child EJB and then you have two seperate transactions independent of each other.&lt;/span&gt;Also You can force a parent rollback by having all child EJB's that are called throw up an excpetion like " ForceRollbackParentException and make sure that the parent has not caught it. &lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110473681678707542?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110473681678707542/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110473681678707542&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110473681678707542'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110473681678707542'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2005/01/understanding-ejb-transactions.html' title='Understanding EJB transactions'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110439567149387817</id><published>2004-12-29T23:25:00.000-08:00</published><updated>2004-12-30T02:49:17.490-08:00</updated><title type='text'> Patterns 3 : Behavioral patterns</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Chain of Responsibility&lt;/span&gt;&lt;br /&gt;The Chain of Responsibility pattern allows a number of classes to attempt to handle a request, without any of them knowing about the capabilities of the other classes. It provides a loose coupling between these classes; the only common link is the request that is passed between them. The request is passed along until one of the classes can handle it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Applicability&lt;/span&gt;&lt;br /&gt;We use the Chain of Responsibility when&lt;br /&gt;· You have more than one handler that can handle a request and there is no way to know which handler to use. The handler must be determined automatically by the chain.&lt;br /&gt;· You want to issue a request to one of several objects without specifying which one explicitly.&lt;br /&gt;· You want to be able to modify the set of objects dynamically that can handle requests.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;A Chain or a Tree?&lt;/span&gt;&lt;br /&gt;Of course, a Chain of Responsibility does not have to be linear. The Smalltalk Companion suggests that it is more generally a tree structure with a number of specific entry points all pointing upward to the most general node.&lt;br /&gt;&lt;br /&gt;Another way of handling a tree-like structure is to have a single entry point that branches to the specific button, menu or other widget types, and then “un-branches” as above to more general help cases. There is little reason for that complexity -- you could align the classes into a single chain, starting at the bottom, and going left to right and up a row at a time until the entire system had been traversed.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Consequences of the Chain of Responsibility&lt;/span&gt;&lt;br /&gt;1. The main purpose for this pattern, like a number of others, is to reduce coupling between objects. An object only needs to know how to forward the request to other objects.&lt;br /&gt;2. This approach also gives you added flexibility in distributing responsibilities between objects. Any object can satisfy some or all of the requests, and you can change both the chain and the responsibilities at run time.&lt;br /&gt;3. An advantage is that there may not be any object that can handle the request, however, the last object in the chain may simply discard any requests it can’t handle.&lt;br /&gt;4. Finally, since Java can not provide multiple inheritance, the basic Chain class needs to be an interface rather than an abstract class, so that the individual objects can inherit from another useful hierarchy, as we did here by deriving them all from JPanel. This disadvantage of this approach is that you often have to implement the linking, sending and forwarding code in each module separately.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Command pattern&lt;/span&gt;&lt;br /&gt;The Chain of Responsibility forwards requests along a chain of classes, but the Command pattern forwards a request only to a specific module. It encloses a request for a specific action inside an object and gives it a known public interface. It lets you give the client the ability to make requests without knowing anything about the actual action that will be performed, and allows you to change that action without affecting the client program in any way.&lt;br /&gt;&lt;br /&gt;One important purpose of the Command pattern is to keep the program and user interface objects completely separate from the actions that they initiate. In other words, these program objects should be completely separate from each other and should not have to know how other objects work. The user interface receives a command and tells a Command object to carry out whatever duties it has been instructed to do. The UI does not and should not need to know what tasks will be executed.&lt;br /&gt;&lt;br /&gt;The Command object can also be used when you need to tell the program to execute the command when the resources are available rather than immediately. In such cases, you are queuing commands to be executed later. Finally, you can use Command objects to remember operations so that you can support Undo requests.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Consequences of the Command Pattern&lt;br /&gt;&lt;/span&gt;The main disadvantage of the Command pattern is a proliferation of little classes that either clutters up the main class if they are inner or clutters up the program namespace if they are outer classes.&lt;br /&gt;Now even in the case where we put all of our actionPerformed events in a single basket, we usually call little private methods to carry out the actual function. It turns out that these private methods are just about as long as our little inner classes, so there is frequently little difference in complexity between inner and outer class approaches.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Anonymous Inner Classes&lt;/span&gt;&lt;br /&gt;We can reduce the clutter of our name space by creating unnamed inner classes by declaring an instance of a class on the spot where we need it. For example, we could create our Red button and the class for manipulating the background all at once&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;btnRed.addActionListener(new ActionListener() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public void actionPerformed(ActionEvent e) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;p.setBackground(Color.red);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;} );&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This is not very readable, however, and does not really improve the number of run-time classes since the compiler generates a class file even for these unnamed classes.&lt;br /&gt;&lt;br /&gt;In fact, there is very little difference in the compiled code size among these various methods, once you create classes in any form at all.&lt;br /&gt;&lt;br /&gt;Byte code size of Command class implementations&lt;br /&gt;Program type                                     Byte code size&lt;br /&gt;No command classes                         1719&lt;br /&gt;Named inner classes                         4450&lt;br /&gt;Unnamed inner classes                     3683&lt;br /&gt;External classes                                 3838&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Providing Undo&lt;/span&gt;&lt;br /&gt;Another of the main reasons for using Command design patterns is that they provide a convenient way to store and execute an Undo function. Each command object can remember what it just did and restore that state when requested to do so if the computational and memory requirements are not too overwhelming.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Interpreter pattern&lt;br /&gt;&lt;/span&gt;Some programs benefit from having a language to describe operations they can perform. The Interpreter pattern generally describes defining a grammar for that language and using that grammar to interpret statements in that language.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Motivation&lt;br /&gt;&lt;/span&gt;When a program presents a number of different, but somewhat similar cases it can deal with, it can be advantageous to use a simple language to describe these cases and then have the program interpret that language. Such cases can be as simple as the sort of Macro language recording facilities a number of office suite programs provide, or as complex as Visual Basic for&lt;br /&gt;Applications (VBA). VBA is not only included in Microsoft Office products, but can be embedded in any number of third party products quite simply.&lt;br /&gt;&lt;br /&gt;One of the problems we must deal with is how to recognize when a language can be helpful. The Macro language recorder simply records menu and keystroke operations for later playback and just barely qualifies as a language; it may not actually have a written form or grammar. Languages such as VBA, on the other hand, are quite complex, but are far beyond the&lt;br /&gt;capabilities of the individual application developer. Further, embedding commercial languages such as VBA, Java or SmallTalk usually require substantial licensing fees, which make them less attractive to all but the largest developers.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Applicability&lt;/span&gt;&lt;br /&gt;As the SmallTalk Companion notes, recognizing cases where an Interpreter can be helpful is much of the problem, and programmers without formal language/compiler training frequently overlook this approach. There are not large numbers of such cases, but there are two general places where languages are applicable:&lt;br /&gt;&lt;br /&gt;1. When the program must parse an algebraic string. This case is fairly obvious. The program is asked to carry out its operations based on a computation where the user enters an equation of some sort. This frequently occurs in mathematical-graphics programs, where the program renders a curve or surface based on any equation it can evaluate.&lt;br /&gt;Programs like Mathematica and graph drawing packages such as Origin work in this way.&lt;br /&gt;&lt;br /&gt;2. When the program must produce varying kinds of output. This case is a little less obvious, but far more useful. Consider a program that can display columns of data in any order and sort them in various ways. These programs are frequently referred to as Report Generators, and&lt;br /&gt;while the underlying data may be stored in a relational database, the user interface to the report program is usually much simpler then the SQL language which the database uses. In fact, in some cases, the simple report language may be interpreted by the report program and translated into SQL.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Consequences of the Interpreter Pattern&lt;/span&gt;&lt;br /&gt;Whenever you introduce an interpreter into a program, you need to provide a simple way for the program user to enter commands in that language. It can be as simple as the Macro record button we noted earlier, or it can be an editable text field like the one in the program above.&lt;br /&gt;&lt;br /&gt;However, introducing a language and its accompanying grammar also requires fairly extensive error checking for misspelled terms or misplaced grammatical elements. This can easily consume a great deal of programming effort unless some template code is available for implementing this checking. Further, effective methods for notifying the users of these errors are not easy to design and implement.&lt;br /&gt;&lt;br /&gt;In the Interpreter example above, the only error handling is that keywords that are not recognized are not converted to ParseObjects and pushed onto the stack. Thus, nothing will happen, because the resulting stack sequence probably cannot be parsed successfully, or if it can, the item represented by the misspelled keyword will not be included.&lt;br /&gt;&lt;br /&gt;You can also consider generating a language automatically from a user interface of radio and command buttons and list boxes. While it may seem that having such an interface obviates the necessity for a language at all, the same requirements of sequence and computation still apply. When you have to have a way to specify the order of sequential operations, a language is a good way to do so, even if the language is generated from the user interface.&lt;br /&gt;&lt;br /&gt;The Interpreter pattern has the advantage that you can extend or revise the grammar fairly easily one you have built the general parsing and reduction tools. You can also add new verbs or variables quite easily once the foundation is constructed.&lt;br /&gt;&lt;br /&gt;In the simple parsing scheme we show in the Parser class above, there are only 6 cases to consider, and they are shown as a series of simple if statements. If you have many more than that, Design Patterns suggests that you create a class for each one of them. This again makes language extension easier, but has the disadvantage of proliferating lots of similar little classes. Finally, as the syntax of the grammar becomes more complex, you run the risk of creating a hard to maintain program. While interpreters are not all that common in solving general programming problems, the Iterator pattern we take up next is one of the most common ones you’ll be using.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Iterator pattern&lt;/span&gt;&lt;br /&gt;The Iterator is one of the simplest and most frequently used of the design patterns. The Iterator pattern allows you to move through a list or collection of data using a standard interface without having to know the details of the internal representations of that data. In addition you can also define special iterators that perform some special processing and return only specified elements of the data collection.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Mediator pattern&lt;/span&gt;&lt;br /&gt;When a program is made up of a number of classes, the logic and computation is divided logically among these classes. However, as more of these isolated classes are developed in a program, the problem of communication between these classes become more complex. The more each class needs to know about the methods of another class, the more tangled the class structure can become. This makes the program harder to read and harder to maintain. Further, it can become difficult to change the program, since any change may affect code in several other classes. The Mediator pattern addresses this problem by promoting looser coupling between these classes. Mediators accomplish this by being the only class that has detailed knowledge of the methods of other classes. Classes send inform the mediator when changes occur and the Mediator passes them on to any other classes that need to be informed.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Consequences of the Mediator Pattern&lt;/span&gt;&lt;br /&gt;1. The Mediator makes loose coupling possible between objects in a program. It also localizes the behavior that otherwise would be distributed among several objects.&lt;br /&gt;2. You can change the behavior of the program by simply changing or subclassing the Mediator.&lt;br /&gt;3. The Mediator approach makes it possible to add new Colleagues to a system without having to change any other part of the program.&lt;br /&gt;4. The Mediator solves the problem of each Command object needing to know too much about the objects and methods in the rest of a user interface.&lt;br /&gt;5. The Mediator can become monolithic in complexity, making it hard to change and maintain. Sometimes you can improve this situation by revising the responsibilities you have given the Mediator. Each object should carry out it’s own tasks and the Mediator should only manage the&lt;br /&gt;interaction between objects.&lt;br /&gt;6. Each Mediator is a custom-written class that has methods for each Colleague to call and knows what methods each Colleague has available. This makes it difficult to reuse Mediator code in different projects. On the other hand, most Mediators are quite simple and writing this code is far easier than managing the complex object interactions any other way.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Implementation Issues&lt;/span&gt;&lt;br /&gt;The Mediator pattern we have described above acts as a kind of Observer pattern, observing changes in the Colleague elements. Another approach is to have a single interface to your Mediator, and pass that method various constants or objects which tell the Mediator which operations to perform. In the same fashion, you could have a single Colleague interface that each Colleague would implement, and each Colleague would then decide what operation it was to carry out.&lt;br /&gt;Mediators are not limited to use in visual interface programs, however, it is their most common application. You can use them whenever you are faced with the problem of complex intercommunication between a number of objects.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Memento pattern&lt;/span&gt;&lt;br /&gt;Suppose you would like to save the internal state of an object so you can restore it later. Ideally, it should be possible to save and restore this state without making the object itself take care of this task, and without violating encapsulation. This is the purpose of the Memento pattern.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Motivation&lt;/span&gt;&lt;br /&gt;Objects frequently expose only some of their internal state using public methods, but you would still like to be able to save the entire state of an object because you might need to restore it later. In some cases, you could obtain enough information from the public interfaces (such as the drawing position of graphical objects) to save and restore that data. In other cases, the color, shading, angle and connection relationship to other graphical objects need to be saved and this information is not readily available. This sort of information saving and restoration is common in systems that need to support&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Undo commands.&lt;/span&gt;&lt;br /&gt;If all of the information describing an object is available in public variables, it is not that difficult to save them in some external store. However, making these data public makes the entire system vulnerable to change by external program code, when we usually expect data inside an object to be private and encapsulated from the outside world.&lt;br /&gt;&lt;br /&gt;The Memento pattern attempts to solve this problem by having privileged access to the state of the object you want to save. Other objects have only a more restricted access to the object, thus preserving their encapsulation. This pattern defines three roles for objects:&lt;br /&gt;1. The Originator is the object whose state we want to save.&lt;br /&gt;2. The Memento is another object that saves the state of the Originator.&lt;br /&gt;3. The Caretaker manages the timing of the saving of the state, saves the Memento and, if needed, uses the Memento to restore the state of the Originator.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Consequences of the Memento&lt;/span&gt;&lt;br /&gt;The Memento provides a way to preserve the state of an object while preserving encapsulation, in languages where this is possible. Thus, data that only the Originator class should have access to effectively remains private. It also preserves the simplicity of the Originator class by delegating the saving and restoring of information to the Memento class. On the other hand, the amount of information that a Memento has to save might be quite large, thus taking up fair amounts of storage. This further has an effect on the Caretaker class (here the Mediator) which may have to design strategies to limit the number of objects for which it saves state. In our simple example, we impose no such limits. In cases where objects change in a predictable manner, each Memento may be able to get by with saving only incremental changes of an object’s state.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Other Kinds of Mementos&lt;/span&gt;&lt;br /&gt;While supporting undo/redo operations in graphical interfaces is one significant use of the Memento pattern, you will also see Mementos used in database transactions. Here they save the state of data in a transaction where it is necessary to restore the data if the transaction fails or is incomplete.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Observer pattern&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Consequences of the Observer Pattern&lt;/span&gt;&lt;br /&gt;Observers promote abstract coupling to Subjects. A subject doesn’t know the details of any of its observers. However, this has the potential disadvantage of successive or repeated updates to the Observers when there are a series of incremental changes to the data. If the cost of these updates is high, it may be necessary to introduce some sort of change management, so that the Observers are not notified too soon or too frequently. When one client makes a change in the underlying data, you need to decide which object will initiate the notification of the change to the other observers. If the Subject notifies all the observers when it is changed, each client is not responsible for remembering to initiate the notification. On the other hand, this can result in a number of small successive updates being triggered. If the clients tell the Subject when to notify the other clients, this cascading notification can be avoided, but the clients are left with the responsibility of telling the Subject when to send the notifications. If one client “forgets,” the program simply won’t work properly. Finally, you can specify the kind of notification you choose to send by defining a number of update methods for the Observers to receive depending on the type or scope of change. In some cases, the clients will thus be able to ignore some of these notifications&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;State pattern&lt;/span&gt;&lt;br /&gt;The State pattern is used when you want to have an enclosing class switch between a number of related contained classes, and pass method calls on to the current contained class. Design Patterns suggests that the State pattern switches between internal classes in such a way that the enclosing object appears to change its class. In Java, at least, this is a bit of an exaggeration, but the actual purpose to which the classes are put can change significantly.&lt;br /&gt;&lt;br /&gt;Many programmers have had the experience of creating a class which performs slightly different computations or displays different information based on the arguments passed into the class. This frequently leads to some sort of switch or if-else statements inside the class that determine which behavior to carry out. It is this inelegance that the State pattern seeks to replace.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Consequences of the State Pattern&lt;/span&gt;&lt;br /&gt;1. The State pattern localizes state-specific behavior in an individual class for each state, and puts all the behavior for that state in a single object.&lt;br /&gt;2. It eliminates the necessity for a set of long, look-alike conditional statements scattered through the program’s code.&lt;br /&gt;3. It makes transition explicit. Rather than having a constant that specifies which state the program is in, and that may not always be checked correctly, this makes the change explicit by copying one of the states to the state variable.&lt;br /&gt;4. State objects can be shared if they have no instance variables. Here only the Fill object has instance variables, and that color could easily be made an argument instead.&lt;br /&gt;5. This approach generates a number of small class objects, but in the process, simplifies and clarifies the program.&lt;br /&gt;6. In Java, all of the States must inherit from a common base class, and they must all have common methods, although some of those methods can be empty. In other languages, the states can be implemented by function pointers with much less type checking, and, of course, greater chance of error.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Strategy pattern&lt;/span&gt;&lt;br /&gt;The Strategy pattern is much like the State pattern in outline, but a little different in intent. The Strategy pattern consists of a number of related algorithms encapsulated in a driver class called the Context. Your client program can select one of these differing algorithms or in some cases the Context might select the best one for you. The intent, like the State pattern, is to switch easily between algorithms without any monolithic conditional statements. The difference between State and Strategy is that the user generally chooses which of several strategies to apply and that only one strategy at a time is likely to be instantiated and active within the Context class. By contrast, as we have seen, it is likely that all of the different States will be active at once and switching may occur frequently between them. In addition, Strategy encapsulates several algorithms that do more or less the same thing, while State encapsulates related classes that each do something somewhat different. Finally, the concept of transition between different states is completely missing in the Strategy pattern.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Motivation&lt;/span&gt;&lt;br /&gt;A program which requires a particular service or function and which has several ways of carrying out that function is a candidate for the Strategy pattern. Programs choose between these algorithms based on computational efficiency or user choice. There can be any number of strategies and more can be added and any of them can be changed at any time.&lt;br /&gt;&lt;br /&gt;There are a number of cases in programs where we’d like to do the same thing in several different ways. Some of these are listed in the Smalltalk Companion:&lt;br /&gt;· Save files in different formats.&lt;br /&gt;· Compress files using different algorithms&lt;br /&gt;· Capture video data using different compression schemes&lt;br /&gt;· Use different line-breaking strategies to display text data.&lt;br /&gt;· Plot the same data in different formats: line graph, bar chart or pie chart.&lt;br /&gt;&lt;br /&gt;In each case we could imagine the client program telling a driver module (Context) which of these strategies to use and then asking it to carry out the operation.&lt;br /&gt;The idea behind Strategy is to encapsulate the various strategies in a single module and provide a simple interface to allow choice between these strategies. Each of them should have the same programming interface, although they need not all be members of the same class hierarchy. However, they do have to implement the same programming interface.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Consequences of the Strategy Pattern&lt;/span&gt;&lt;br /&gt;Strategy allows you to select one of several algorithms dynamically. These algorithms can be related in an inheritance hierarchy or they can be unrelated as long as they implement a common interface. Since the Context switches between strategies at your request, you have more flexibility than if you simply called the desired derived class. This approach also avoids the sort of condition statements than can make code hard to read ad maintain. On the other hand, strategies don’t hide everything. The client code must be aware that there are a number of alternative strategies and have some criteria for choosing among them. This shifts an algorithmic decision to the client programmer or the user.&lt;br /&gt;Since there are a number of different parameters that you might pass to different algorithms, you have to develop a Context interface and strategy methods that are broad enough to allow for passing in parameters that are not used by that particular algorithm.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Template pattern&lt;/span&gt;&lt;br /&gt;Whenever you write a parent class where you leave one or more of the methods to be implemented by derived classes, you are in essence using the Template pattern. The Template pattern formalizes the idea of defining an algorithm in a class, but leaving some of the details to be implemented in subclasses. In other words, if your base class is an abstract class, as often happens in these design patterns, you are using a simple form of the Template pattern.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Motivation&lt;/span&gt;&lt;br /&gt;Templates are so fundamental, you have probably used them dozens of times without even thinking about it. The idea behind the Template pattern is that some parts of an algorithm are well defined and can be implemented in the base class, while other parts may have several implementations and are best left to derived classes. Another main theme is recognizing that there are some basic parts of a class that can be factored out and put in a base class so that they do not need to be repeated in several subclasses.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Kinds of Methods in a Template Class&lt;/span&gt;&lt;br /&gt;A Template has four kinds of methods that you can make use of in derive classes:&lt;br /&gt;1. Complete methods that carry out some basic function that all the subclasses will want to use, such as calcx and calcy in the above example. These are called Concrete methods.&lt;br /&gt;2. Methods that are not filled in at all and must be implemented in derived classes. In Java , you would declare these as abstract methods, and that is how they are referred to in the pattern description.&lt;br /&gt;3. Methods that contain a default implementation of some operations, but which may be overridden in derived classes. These are called Hook methods. Of course this is somewhat&lt;br /&gt;arbitrary, because in Java you can override any public or protected method in the derived class, but Hook methods are intended to be overridden, while Concrete methods are not.&lt;br /&gt;4. Finally, a Template class may contain methods which themselves call any combination of abstract, hook and concrete methods. These methods are not intended to be overridden, but describe an algorithm without actually implementing its details. Design Patterns refers to these as Template methods.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Summary and Consequences&lt;/span&gt;&lt;br /&gt;Template patterns occur all the time in OO software and are neither complex nor obscure in intent. They are normal part of OO programming and you shouldn’t try to make them more abstract than they actually are.&lt;br /&gt;The first significant point is that your base class may only define some of the methods it will be using, leaving the rest to be implemented in the derived classes. The second major point is that there may be methods in the base class which call a sequence of methods, some implemented in the base class and some implemented in the derived class. This Template method defines a general algorithm, although the details may not be worked out completely in the base class.&lt;br /&gt;Template classes will frequently have some abstract methods that you must override in the derived classes, and may also have some classes with a simple “place-holder” implementation that you are free to override where this is appropriate. If these place-holder classes are called from another method in the base class, then we refer to these overridable methods are “Hook” methods.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Visitor pattern&lt;/span&gt;&lt;br /&gt;The Visitor pattern turns the tables on our object-oriented model and creates an external class to act on data in other classes. This is useful if there are a fair number of instances of a small number of classes and you want to perform some operation that involves all or most of them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Motivation&lt;/span&gt;&lt;br /&gt;While at first it may seem “unclean” to put operations that should be inside a class in another class instead, there are good reasons for doing it. Suppose each of a number of drawing object classes has similar code for drawing itself. The drawing methods may be different, but they probably all use underlying utility functions that we might have to duplicate in each class. Further, a set of closely related functions is scattered throughout a number of different classes&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;When to Use the Visitor Pattern&lt;/span&gt;&lt;br /&gt;You should consider using a Visitor pattern when you want to perform an operation on the data contained in a number of objects that have different interfaces. Visitors are also valuable if you have to perform a number of unrelated operations on these classes. On the other hand, as we will see below, Visitors are a good choice only when you do not expect many new classes to be added to your program.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Sample Code&lt;/span&gt;&lt;br /&gt;We have a simple Employee object which maintains a record of the employee’s name, salary, vacation taken and number of sick days taken. A simple version of this class is:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;font-size:85%;" &gt;&lt;span style="color: rgb(0, 0, 153);"&gt;public class Employee&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;int sickDays, vacDays;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;float Salary;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;String Name;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;public Employee(String name, float salary,&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;int vacdays, int sickdays)&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;vacDays = vacdays; sickDays = sickdays;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;Salary = salary; Name = name;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;public String getName() { return Name; }&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;public int getSickdays() { return sickDays; }&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;public int getVacDays() { return vacDays; }&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;public float getSalary() { return Salary; }&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;public void accept(Visitor v) { v.visit(this); }&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Note that we have included the accept method in this class. Now let’s suppose that we want to prepare a report of the number of vacation days that all employees have taken so far this year. We could just write some code in the client to sum the results of calls to each Employee’s getVacDays function, or we could put this function into a Visitor.&lt;br /&gt;Since Java is a strongly typed language, your base Visitor class needs to have a suitable abstract visit method for each kind of class in your program. In this first simple example, we only have Employees, so our basic abstract Visitor class is just&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;span style="font-family: courier new;"&gt;public abstract class Visitor&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;public abstract void visit(Employee emp);&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;}&lt;/span&gt;&lt;br /&gt; &lt;/span&gt;&lt;br /&gt;Notice that there is no indication what the Visitor does with each  class in either the client classes or the abstract Visitor class. We can in fact write a whole lot of visitors that do different things to the classes in our program. The Visitor we are going to write first just sums the vacation data&lt;br /&gt;for all our employees:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new; color: rgb(0, 0, 153);font-size:85%;" &gt;public class VacationVisitor extends Visitor&lt;br /&gt;{&lt;br /&gt;protected int total_days;&lt;br /&gt;public VacationVisitor() { total_days = 0; }&lt;br /&gt;//-----------------------------&lt;br /&gt;public void visit(Employee emp)&lt;br /&gt;{&lt;br /&gt;total_days += emp.getVacDays();&lt;br /&gt;}&lt;br /&gt;//-----------------------------&lt;br /&gt;public int getTotalDays()&lt;br /&gt;{&lt;br /&gt;return total_days;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Visiting the Classes&lt;/span&gt;&lt;br /&gt;Now, all we have to do to compute the total vacation taken is to go through a list of the employees and visit each of them, and then ask the Visitor for the total.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new; color: rgb(0, 0, 153);font-size:85%;" &gt;VacationVisitor vac = new VacationVisitor();&lt;br /&gt;for (int i = 0; i &lt; employees.length; i++)&lt;br /&gt;{&lt;br /&gt;employees[i].accept(vac);&lt;br /&gt;}&lt;br /&gt;System.out.println(vac.getTotalDays());&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Let’s reiterate what happens for each visit:&lt;br /&gt;&lt;br /&gt;1. We move through a loop of all the Employees.&lt;br /&gt;2. The Visitor calls each Employee’s accept method.&lt;br /&gt;3. That instance of Employee calls the Visitor’s visit method.&lt;br /&gt;4. The Visitor fetches the vacation days and adds them into the total.&lt;br /&gt;5. The main program prints out the total when the loop is complete.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Double Dispatching&lt;/span&gt;&lt;br /&gt;No article on the Visitor pattern is complete without mentioning that you are really dispatching a method twice for the Visitor to work. The Visitor calls the polymorphic accept method of a given object, and the accept method calls the polymorphic visit method of the Visitor. It this bidirectional calling that allows you to add more operations on any class that has an accept method, since each new Visitor class we write can carry out whatever operations we might think of using the data available in these classes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Traversing a Series of Classes&lt;/span&gt;&lt;br /&gt;The calling program that passes the class instances to the Visitor must know about all the existing instances of classes to be visited and must keep them in a simple structure such as an array or Vector. Another possibility would be to create an Enumeration of these classes and pass it to the Visitor. Finally, the Visitor itself could keep the list of objects that it is to visit. In our simple example program, we used an array of objects, but any of the other methods would work equally well.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Consequence of the Visitor Pattern&lt;/span&gt;&lt;br /&gt;The Visitor pattern is useful when you want to encapsulate fetching  data from a number of instances of several classes. Design Patterns suggests that the Visitor can provide additional functionality to a class without changing it. We prefer to say that a Visitor can add functionality to a collection of classes and encapsulate the methods it uses. The Visitor is not magic, however, and cannot obtain private data from classes: it is limited to the data available from public methods. This might force you to provide public methods that you would otherwise not have provided. However, it can obtain data from a disparate collection of unrelated classes and utilize it to present the results of a global calculation to the user program.&lt;br /&gt;&lt;br /&gt;It is easy to add new operations to a program using Visitors, since the Visitor contains the code instead of each of the individual classes. Further, Visitors can gather related operations into a single class rather than forcing you to change or derive classes to add these operations. This can make the program simpler to write and maintain.&lt;br /&gt;&lt;br /&gt;Visitors are less helpful during a program’s growth stage, since each time you add new classes which must be visited, you have to add an abstract visit operation to the abstract Visitor class, and you must add an implementation for that class to each concrete Visitor you have written. Visitors can be powerful additions when the program reaches the point where many new classes are unlikely. Visitors can be used very effectively in Composite systems&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110439567149387817?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110439567149387817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110439567149387817&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110439567149387817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110439567149387817'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/patterns-3-behavioral-patterns.html' title=' Patterns 3 : Behavioral patterns'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110422978977617357</id><published>2004-12-27T23:18:00.000-08:00</published><updated>2004-12-29T23:20:38.193-08:00</updated><title type='text'> Patterns 2 : Structural patterns</title><content type='html'>&lt;span style="font-style: italic;"&gt;Some of this material is from the java patterns book by James cooper.*&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Adapter pattern&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;The Adapter pattern is used to convert the programming interface of one class into that of another. We use adapters whenever we want unrelated classes to work together in a single program. The concept of an adapter is thus pretty simple; we write a class that has the desired interface and then make it communicate with the class that has a different interface.&lt;br /&gt;&lt;br /&gt;There are two ways to do this: by inheritance, and by object composition. In the first case, we derive a new class from the nonconforming one and add the methods we need to make the new derived class match the desired interface. The other way is to include the original class inside the new one and create the methods to translate calls within the new class. These two approaches, termed class adapters and object adapters are both fairly easy to implement in Java.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Bridge pattern&lt;br /&gt;&lt;/span&gt;The Bridge pattern is used to separate the interface of class from its implementation, so that either can be varied separately. At first sight, the bridge pattern looks much like the Adapter pattern, in that a class is used to convert one kind of interface to another. However, the intent of the Adapter pattern is to make one or more classes’ interfaces look the same as that of a particular class. The Bridge pattern is designed to separate a class’s interface from its implementation, so that you can vary or replace the implementation without changing the client code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Consequences of the Bridge Pattern&lt;/span&gt;&lt;br /&gt;1. The Bridge pattern is intended to keep the interface to your client program constant while allowing you to change the actual kind of class you display or use. This can prevent you from recompiling a complicated set of user interface modules, and only require that you recompile the bridge itself and the actual end display class.&lt;br /&gt;&lt;br /&gt;2. You can extend the implementation class and the bridge class separately, and usually without much interaction with each other.&lt;br /&gt;&lt;br /&gt;3. You can hide implementation details from the client program much more easily.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Composite pattern.&lt;/span&gt;&lt;br /&gt;Frequently programmers develop systems in which a component may be an individual object or it may represent a collection of objects. The Composite pattern is designed to accommodate both cases. You can use the Composite to build part-whole hierarchies or to construct data representations of trees. In summary, a composite is a collection of objects, any one of which may be either a composite, or just a primitive object. In tree nomenclature, some objects may be nodes with additional branches and some may be leaves.&lt;br /&gt;&lt;br /&gt;The problem that develops is the dichotomy between having a single, simple interface to access all the objects in a composite, and the ability to distinguish between nodes and leaves. Nodes have children and can have children added to them, while leaves do not at the moment have children, and in some implementations may be prevented from having children added to them.&lt;br /&gt;&lt;br /&gt;Some authors have suggested creating a separate interface for nodes&lt;br /&gt;and leaves, where a leaf could have the methods&lt;br /&gt;&lt;br /&gt;public String getName();&lt;br /&gt;public String getValue();&lt;br /&gt;&lt;br /&gt;and a node could have the additional methods:&lt;br /&gt;&lt;br /&gt;public Enumeration elements();&lt;br /&gt;public Node getChild(String nodeName);&lt;br /&gt;public void add(Object obj);&lt;br /&gt;public void remove(Object obj);&lt;br /&gt;&lt;br /&gt;This then leaves us with the programming problem of deciding which elements will be which when we construct the composite.&lt;br /&gt;&lt;br /&gt;However, Design Patterns suggests that each element should have the same interface, whether&lt;br /&gt;it is a composite or a primitive element. This is easier to accomplish, but we are left with the question of what the getChild() operation should accomplish when the object is actually a leaf.&lt;br /&gt;&lt;br /&gt;Java makes this quite easy for us, since every node or leaf can return an Enumeration of the contents of the Vector where the children are stored. If there are no children, the hasMoreElements() method returns false at once. Thus, if we simply obtain the Enumeration from each element, we can quickly determine whether it has any children by checking the&lt;br /&gt;hasMoreElements() method.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Decorator Pattern&lt;br /&gt;&lt;/span&gt;The Decorator pattern provides us with a way to modify the behavior of individual objects without having to create a new derived class. Suppose we have a program that uses eight objects, but three of them need an additional feature. You could create a derived class for each of these objects, and in many cases this would be a perfectly acceptable solution. However, if each of these three objects require different modifications, this would mean creating three derived classes. Further, if one of the classes has features of both of the other classes, you begin to create a complexity that is both confusing and unnecessary.&lt;br /&gt;&lt;br /&gt;For example, suppose we wanted to draw a special border around some of the buttons in a toolbar. If we created a new derived button class, this means that all of the buttons in this new class would always have this same new border, when this might not be our intent. Instead, we create a Decorator class that decorates the buttons. Then we derive any number of specific Decorators from the main Decorator class, each of which performs a specific kind of decoration.&lt;br /&gt;&lt;br /&gt;In order to decorate a button, the Decorator has to be an object derived from the visual environment, so it can receive paint method calls and forward calls to other useful graphic methods to the object that it is decorating. This is another case where object containment is favored over object inheritance. The decorator is a graphical object, but it contains the object it is decorating. It may intercept some graphical method calls, perform some additional computation and may pass them on to the underlying object it is decorating.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Non-Visual Decorators&lt;/span&gt;&lt;br /&gt;Decorators, of course, are not limited to objects that enhance visual classes. You can add or modify the methods of any object in a similar fashion. In fact, non-visual objects are usually easier to decorate, because there are usually fewer methods to intercept and forward.&lt;br /&gt;&lt;br /&gt;While coming up with a simple example is difficult, a series of Decorators do occur naturally in the java.io classes. Note the following in the Java documentation:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;The class FilterInputStream itself simply overrides all methods of InputStream with versions that pass all requests to the underlying input stream. Subclasses of FilterInputStream may further override some of these methods as well as provide additional methods and fields.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The FilterInputStream class is thus a Decorator that can be wrapped around any input stream class. It is essentially an abstract class that doesn’t do any processing, but provides a layer where the relevant methods have been duplicated. It normally forwards these method calls to the enclosed parent stream class.&lt;br /&gt;&lt;br /&gt;The interesting classes derived from FilterInputStream include:-&lt;br /&gt;&lt;br /&gt;BufferedInputStream: Adds buffering to stream so that every call does not cause I/O to occur.&lt;br /&gt;&lt;br /&gt;CheckedInputStream: Maintains a checksum of bytes as they are read&lt;br /&gt;&lt;br /&gt;DataInputStream: Reads primitive types (Long, Boolean, Float, etc.) from the input stream.&lt;br /&gt;&lt;br /&gt;DigestInputStream: Computes a MessageDigest of any input stream.&lt;br /&gt;&lt;br /&gt;InflaterInputStream: Implements methods for uncompressing data.&lt;br /&gt;&lt;br /&gt;PushbackInputStream: Provides a buffer where data can be “unread,” if during parsing you discover you need to back up.&lt;br /&gt;&lt;br /&gt;These decorators can be nested, so that a pushback, buffered input stream is quite possible.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Decorators, Adapters and Composites&lt;/span&gt;&lt;br /&gt;There is an essential similarity among these classes that you may have recognized.&lt;br /&gt;&lt;br /&gt;Adapters also seem to “decorate” an existing class. However, their function is to change the interface of one or more classes to one that is more convenient for a particular program.&lt;br /&gt;&lt;br /&gt;Decorators add methods to particular instances of classes, rather than to all of them. You could also imagine that a composite consisting of a single item is essentially a decorator.&lt;br /&gt;Once again, however, the intent is different&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Consequences of the Decorator Pattern&lt;/span&gt;&lt;br /&gt;The Decorator pattern provides a more flexible way to add responsibilities to a class than by using inheritance, since it can add these responsibilities to selected instances of the class. It also allows you to customize a class without creating subclasses high in the inheritance hierarchy. Design Patterns points out two disadvantages of the Decorator pattern One is that a Decorator and its enclosed component are not identical. Thus tests for object type will fail. The second is that Decorators can lead to a system with “lots of little objects” that all look alike to the programmer trying to maintain the code. This can be a maintenance headache.&lt;br /&gt;&lt;br /&gt;Decorator and Façade evoke similar images in building architecture,but in design pattern terminology, the Façade is a way of hiding a complex system inside a simpler interface, while Decorator adds function by wrapping a class.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Facade Pattern&lt;/span&gt;&lt;br /&gt;The Façade pattern allows you to simplify complexity by providing a simplified interface to subsystems. This simplification may in some cases reduce the flexibility of the underlying classes, but usually provides all the function needed for all but the most sophisticated users. These users can still, of course, access the underlying classes and methods.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;FlyWeight Pattern&lt;/span&gt;&lt;br /&gt;There are cases in programming where it seems that you need to generate a very large number of small class instances to represent data. Sometimes you can greatly reduce the number of different classes that you need to instantiate if you can recognize that the instances are fundamentally the same except for a few parameters. If you can move those variables outside the class instance and pass them in as part of a method call, the number of separate instances can be greatly reduced.&lt;br /&gt;&lt;br /&gt;The Flyweight design pattern provides an approach for handling such classes. It refers to the instance’s intrinsic data that makes the instance unique, and the extrinsic data which is passed in as arguments. The Flyweight is appropriate for small, fine-grained classes like individual characters or icons on the screen. For example, if you are drawing a series of icons on the screen in a folder window, where each represents a person or data file, it does not make sense to have an individual class instance for each of them that remembers the person’s name and the icon’s screen position. Typically these icons are one of a few similar images and the position where they are drawn is calculated dynamically based on the window’s size in any case.&lt;br /&gt;&lt;br /&gt;In another example in Design Patterns, each character in a font is represented as a single instance of a character class, but the positions where the characters are drawn on the screen are kept as external data so that there needs to be only one instance of each character, rather than one for each appearance of that character.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Sharable Objects&lt;/span&gt;&lt;br /&gt;The Smalltalk Companion points out that sharable objects are much like Flyweights, although the purpose is somewhat different. When you have a very large object containing a lot of complex data, such as tables or bitmaps, you would want to minimize the number of instances of that object. Instead, in such cases, you’d return one instance to every part of the program that asked for it and avoid creating other instances.&lt;br /&gt;&lt;br /&gt;A problem with such sharable objects occurs when one part of a program wants to change some data in a shared object. You then must decide whether to change the object for all users, prevent any change, or create a new instance with the changed data. If you change the object for every instance, you may have to notify them that the object has changed.&lt;br /&gt;&lt;br /&gt;Sharable objects are also useful when you are referring to large data systems outside of Java, such as databases.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Proxy Pattern&lt;/span&gt;&lt;br /&gt;The Proxy pattern is used when you need to represent a complex object by a simpler one. If creating an object is expensive in time or computer resources, Proxy allows you to postpone this creation until you need the actual object. A Proxy usually has the same methods as the object it&lt;br /&gt;represents, and once the object is loaded, it passes on the method calls from the Proxy to the actual object.&lt;br /&gt;&lt;br /&gt;There are several cases where a Proxy can be useful:&lt;br /&gt;1. If an object, such as a large image, takes a long time to load.&lt;br /&gt;2. If the object is on a remote machine and loading it over the network may be slow, especially during peak network load periods.&lt;br /&gt;3. If the object has limited access rights, the proxy can validate the access permissions for that user.&lt;br /&gt;&lt;br /&gt;Proxies can also be used to distinguish between requesting an instance of an object and the actual need to access it. For example, program initialization may set up a number of objects which may not all be used right away. In that case, the proxy can load the real object only when it is needed.&lt;br /&gt;&lt;br /&gt;Let’s consider the case of a large image that a program needs to load and display. When the program starts, there must be some indication that an image is to be displayed so that the screen lays out correctly, but the actual image display can be postponed until the image is completely loaded. This is particularly important in programs such as word processors and web browsers that lay out text around the images even before the images are available.&lt;br /&gt;&lt;br /&gt;An image proxy can note the image and begin loading it in the background, while drawing a simple rectangle or other symbol to represent the image’s extent on the screen before it appears. The proxy can even delay loading the image at all until it receives a paint request, and only then begin the process.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Comparison with Related Patterns&lt;/span&gt;&lt;br /&gt;Both the Adapter and the Proxy constitute a thin layer around an object. However, the Adapter provides a different interface for an object, while the Proxy provides the same interface for the object, but interposes itself where it can save processing effort.&lt;br /&gt;&lt;br /&gt;A Decorator also has the same interface as the object it surrounds, but its purpose is to add additional (usually visual) function to the original object. A proxy, by contrast, controls access to the contained class.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110422978977617357?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110422978977617357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110422978977617357&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110422978977617357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110422978977617357'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/patterns-2-structural-patterns.html' title=' Patterns 2 : Structural patterns'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110413328638501759</id><published>2004-12-26T23:04:00.000-08:00</published><updated>2004-12-29T22:35:38.786-08:00</updated><title type='text'>Patterns 1 : Creational patterns</title><content type='html'>&lt;span style="font-style: italic;"&gt;Some of this material is from the java patterns book by James cooper.*&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Factory Pattern&lt;/span&gt;&lt;br /&gt;Factory patterns helps localizing the generation of certain obects to one place in code. That way we have control over how and what object is created.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Factory Method &lt;/span&gt;&lt;br /&gt;It provides a simple decision making class that returns one of several possible subclasses of an abstract base class depending on the data that are provided.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;When to Use a Factory Pattern&lt;/span&gt;&lt;br /&gt;You should consider using a Factory pattern when&lt;br /&gt;· A class can’t anticipate which kind of class of objects it must create.&lt;br /&gt;· A class uses its subclasses to specify which objects it creates.&lt;br /&gt;· You want to localize the knowledge of which class gets created.&lt;br /&gt;&lt;br /&gt;There are several similar variations on the factory pattern to recognize.&lt;br /&gt;1. The base class is abstract and the pattern must return a complete working class.&lt;br /&gt;2. The base class contains default methods and is only subclassed for cases where the default methods are insufficient.&lt;br /&gt;3. Parameters are passed to the factory telling it which of several class types to return. In this case the classes may share the same method names but may do something quite different.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Abstract Factory Method &lt;/span&gt;&lt;br /&gt;It provides an interface to create and return one of several families of related objects.&lt;br /&gt;&lt;br /&gt;The Abstract Factory pattern is one level of abstraction higher than the factory pattern. You can use this pattern when you want to return one of several related classes of objects, each of which can return several different objects on request. In other words, the Abstract Factory is a factory object that returns one of several factories.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Consequences of Abstract Factory&lt;/span&gt;&lt;br /&gt;One of the main purposes of the Abstract Factory is that it isolates the concrete classes that are generated. The actual class names of these classes are hidden in the factory and need not be known at the client level at all. Because of the isolation of classes, you can change or interchange these product class families freely. Further, since you generate only one kind of concrete class, this system keeps you for inadvertently using classes from different families of products. However, it is some effort to add new class families, since you need to define new, unambiguous conditions that cause such a new family of classes to be returned.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Builder Pattern&lt;/span&gt;&lt;br /&gt;It separates the construction of a complex object from its representation, so that several different representations can be created depending on the needs of the program.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Prototype Pattern &lt;/span&gt;&lt;br /&gt;It starts with an initialized and instantiated class and copies or clones it to make new instances rather than creating new instances.&lt;br /&gt;The Protoype pattern is used when creating an instance of a class is very time-consuming or complex in some way. Then, rather than creating more instances, you make copies of the original instance, modifying them as appropriate.&lt;br /&gt;&lt;br /&gt;Noramlly in java you use clone method to shallwo copy an object.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 153);font-family:courier new;" &gt;MyObject mNew = (MyObject)mOld.clone();&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But to do a deepcopy you do this. Remember that the Object &lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;tobeDeepCloned&lt;/span&gt;&lt;/span&gt;  has to have all of its child objects as serializable.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;public Object deepClone(Object tobeDeepCloned)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    try{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            ByteArrayOutputStream b = new ByteArrayOutputStream();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            ObjectOutputStream out = new ObjectOutputStream(b);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            out.writeObject(&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);font-family:courier new;font-size:85%;"  &gt;&lt;br /&gt;tobeDeepCloned&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            ByteArrayInputStream bIn = new ByteArrayInputStream(b.toByteArray());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            ObjectInputStream oi = new ObjectInputStream(bIn);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            return (oi.readObject());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    catch (Exception e)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        { &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            System.out.println("exception:"+e.getMessage());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            return null;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Singleton Pattern &lt;/span&gt;&lt;br /&gt;It is a class of which there can be no more than one instance. It provides a single global point of access to that instance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110413328638501759?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110413328638501759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110413328638501759&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110413328638501759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110413328638501759'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/patterns-1-creational-patterns.html' title='Patterns 1 : Creational patterns'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110363574706443568</id><published>2004-12-21T05:28:00.000-08:00</published><updated>2004-12-21T22:19:00.523-08:00</updated><title type='text'>Aspect oriented programming with CGLIB</title><content type='html'>&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;&lt;br /&gt;1 Introduction and background&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;2 Purpose of this article&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;3 Prerequisites&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;4 Topic 1: Measure the time taken by method calls&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;4.1 SimpleClass class&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;4.2 TimeInterceptor class 4&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;4.3 MethodTimeGenerator class 4&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;4.4 Main class 5&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;4.5 Topic Conclusion 6&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;5 Topic 2: Dynamic connection allocation 6&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;5.1 DaoTagInterface 6&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;5.2 DAO class 6&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;5.3 DaoInterceptor class 7&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;5.4 DaoGenerator class 9&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;5.5 DaoFactory class 9&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;5.6 Main class 9&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;5.7 Topic Conclusion 10&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;6 Conclusion. 11&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-family:courier new;" &gt;7 Drawbacks 11&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;1 Introduction and background&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Aspect oriented programming has been talked about greatly recently. There are developers who think that it is a great idea and also an equal number who think that it is not as it breaks the principles of Object oriented programming.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;2 Purpose of this article&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;During the last few years I faced some issues that were present across the entire code base.&lt;br /&gt;I thought must have a clean/fast way of solving but I did not have an answer until I read what aspect oriented programming was.&lt;br /&gt;I will present two such problems and their solutions.&lt;br /&gt;I investigated CGLIB after reading this article http://www.onjava.com/lpt/a/5250 by Eugene Kuleshov at Onjava.com.&lt;br /&gt;This paper is a result of that investigation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;3 Prerequisites&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Cglib 2 jar file in the class path. It can be downloaded from here: http://sourceforge.net/project/showfiles.php?group_id=56933&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;4 Topic 1: Measure the time taken by method calls&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One of the issues was measuring the exact time taken by each of my method calls, so as to better solve performance issues.&lt;br /&gt;I wanted to do this in a way, so as to be able to switch it on/off as and when required.&lt;br /&gt;&lt;br /&gt;Here are the classes&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;4.1 SimpleClass class&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;package com.test.methodtimetest;&lt;br /&gt;/**&lt;br /&gt;* @author suchakj&lt;br /&gt;*/&lt;br /&gt;public class SimpleClass {&lt;br /&gt;public void simpleMethod() {&lt;br /&gt;System.out.println("Hello In Simple Method");&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;This is just a class with a single method that prints hello.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;4.2 TimeInterceptor class&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;package com.test.methodtimetest;&lt;br /&gt;import java.lang.reflect.Method;&lt;br /&gt;import java.sql.Timestamp;&lt;br /&gt;import net.sf.cglib.proxy.MethodInterceptor;&lt;br /&gt;import net.sf.cglib.proxy.MethodProxy;&lt;br /&gt;/**&lt;br /&gt;* @author suchakj&lt;br /&gt;*/&lt;br /&gt;public class TimeInterceptor implements MethodInterceptor {&lt;br /&gt;/* This is the method that intecepts a method, it automatically adds the start and end time&lt;br /&gt;* for a method.&lt;br /&gt;* @see net.sf.cglib.proxy.MethodInterceptor#intercept&lt;br /&gt;* (java.lang.Object, java.lang.reflect.Method, java.lang.Object[],&lt;br /&gt;* net.sf.cglib.proxy.MethodProxy)&lt;br /&gt;*/&lt;br /&gt;public Object intercept(&lt;br /&gt;Object obj,&lt;br /&gt;Method method,&lt;br /&gt;Object[] args,&lt;br /&gt;MethodProxy proxy)&lt;br /&gt;throws Throwable {&lt;br /&gt;System.out.println("Before method : " + method + " Time : " + new Timestamp(System.currentTimeMillis()));&lt;br /&gt;Object o = proxy.invokeSuper(obj,args);&lt;br /&gt;System.out.println("After method : " + method + " Time : " + new Timestamp(System.currentTimeMillis()));&lt;br /&gt;return o;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;This is a class that implements the Cglib MethodInterceptor interface. The MethodInterceptor interface implements a single method called intercept(). The cglib framework calls this method when a particular Object method is intercepted.&lt;br /&gt;As we can see that the intercept method , adds a Timestamp, before and after the method call. The method is called using proxy.invokeSuper(obj,args); . This takes care of the method timing in one central place.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;4.3 MethodTimeGenerator class&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;package com.test.methodtimetest;&lt;br /&gt;import net.sf.cglib.proxy.Enhancer;&lt;br /&gt;/**&lt;br /&gt;* @author suchakj&lt;br /&gt;*/&lt;br /&gt;public class MethodTimeGenerator {&lt;br /&gt;public static Object getTimeEnhancedObject(Class clazz){&lt;br /&gt;Enhancer e = new Enhancer();&lt;br /&gt;e.setSuperclass(clazz);&lt;br /&gt;e.setCallback(new TimeInterceptor());&lt;br /&gt;return e.create();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;This is the main generator. This class uses the cglib Enhancer class to join the method interceptor class with the any class(in our case it is SimpleClass).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;4.4 Main class&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;package com.test;&lt;br /&gt;import com.test.daoconntest.DAO;&lt;br /&gt;import com.test.daoconntest.DaoFactory;&lt;br /&gt;import com.test.daoconntest.DaoInterceptor;&lt;br /&gt;import com.test.methodtimetest.MethodTimeGenerator;&lt;br /&gt;import com.test.methodtimetest.SimpleClass;&lt;br /&gt;/**&lt;br /&gt;* @author suchakj&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;public class Main {&lt;br /&gt;&lt;br /&gt;public static void testMethodTimeTest(){&lt;br /&gt;//this could come from a factory.&lt;br /&gt;SimpleClass s = (SimpleClass)MethodTimeGenerator.getTimeEnhancedObject(SimpleClass.class);&lt;br /&gt;s.simpleMethod();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt;testMethodTimeTest();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;This the test class. This class is testing our implementation.&lt;br /&gt;&lt;br /&gt;Here is the output.&lt;br /&gt;---------------------------------------------------------------------------------------------------------------&lt;br /&gt;Before method : public void com.test.methodtimetest.SimpleClass.simpleMethod() Time : 2004-12-17 14:20:36.046&lt;br /&gt;Hello In Simple Method&lt;br /&gt;After method : public void com.test.methodtimetest.SimpleClass.simpleMethod() Time : 2004-12-17 14:20:36.14&lt;br /&gt;---------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;4.5 Topic Conclusion&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The above code shows how simple it is to add time delay interceptor to a class. It is not at all intrusive on the class that is being intercepted for recording the time delay.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;5 Topic 2: Dynamic connection allocation&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The importance of connection pools cannot be underestimated.&lt;br /&gt;The main issue I faced in an environment was whether a method returned the connection back to the pool after it had finished using the same.&lt;br /&gt;I wanted to do this in a way, so as to do this in a central place also.&lt;br /&gt;This example will also modify the arguments passed to the method.&lt;br /&gt;&lt;br /&gt;Here are the classes&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;5.1 DaoTagInterface&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;package com.test.daoconntest;&lt;br /&gt;/**&lt;br /&gt;* @author suchakj&lt;br /&gt;*&lt;br /&gt;* This is just a tag inteface&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;public interface DaoTagInterface {&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;This is just a tagging interface for DAO classes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;5.2 DAO class&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;package com.test.daoconntest;&lt;br /&gt;import java.sql.Connection;&lt;br /&gt;import java.sql.ResultSet;&lt;br /&gt;import java.sql.SQLException;&lt;br /&gt;import java.sql.Statement;&lt;br /&gt;/**&lt;br /&gt;* @author suchakj&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;public class DAO implements DaoTagInterface{&lt;br /&gt;&lt;br /&gt;public void daoMethod(String someParam,Object connection){&lt;br /&gt;System.out.println("In Dao Method");&lt;br /&gt;if(connection!=null){&lt;br /&gt;System.out.println("Got a Valid connection that i can use");&lt;br /&gt;}else{&lt;br /&gt;System.out.println("No connection");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/* try {&lt;br /&gt;Statement s = ((Connection)connection).createStatement();&lt;br /&gt;ResultSet r = s.executeQuery("Select * from SomeTable");&lt;br /&gt;} catch (SQLException e) {&lt;br /&gt;// TODO Auto-generated catch block&lt;br /&gt;e.printStackTrace();&lt;br /&gt;}*/&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;This is the Data access class. It does the call to the database.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;5.3 DaoInterceptor class&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;package com.test.daoconntest;&lt;br /&gt;import java.lang.reflect.Method;&lt;br /&gt;import java.sql.Connection;&lt;br /&gt;import net.sf.cglib.proxy.MethodInterceptor;&lt;br /&gt;import net.sf.cglib.proxy.MethodProxy;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* @author suchakj&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;public class DaoInterceptor implements MethodInterceptor {&lt;br /&gt;&lt;br /&gt;/* This is the method that intecepts dao methods, it automatically adds connection objects,&lt;br /&gt;* to the method from a pool and also returns them back to the pool&lt;br /&gt;* @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], net.sf.cglib.proxy.MethodProxy)&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;public Object intercept(Object obj, Method method, Object[] args,&lt;br /&gt;&lt;br /&gt;MethodProxy proxy) throws Throwable {&lt;br /&gt;&lt;br /&gt;// Connection connection = getConnection();&lt;br /&gt;Object connection = getConnection();&lt;br /&gt;args[args.length -1] = connection;&lt;br /&gt;proxy.invokeSuper(obj,args);&lt;br /&gt;returnConnection(connection);&lt;br /&gt;return null;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* @return Connection&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;private Object getConnection() {&lt;br /&gt;// get the connection from some Connection pool&lt;br /&gt;System.out.println("Getting connection from pool ...");&lt;br /&gt;return new Object();// this is just for testing this should be a java.sql.connection object&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* @param Connection&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;private void returnConnection(Object c) {&lt;br /&gt;System.out.println("returning connection to pool ...");&lt;br /&gt;// Return the connection back to the pool..&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;This is a class that implements the Cglib MethodInterceptor interface. The MethodInterceptor interface implements a single method called intercept(). The cglib framework calls this method when a particular Object method is intercepted.&lt;br /&gt;The getConnection() and returnConnection() methods can get and return connections from a pool.&lt;br /&gt;As we can see this class changes the arguments passed to the method as&lt;br /&gt;“Object connection = getConnection();”&lt;br /&gt;“args[args.length -1] = connection;”&lt;br /&gt;“proxy.invokeSuper(obj,args);”&lt;br /&gt;Thus a “connection object” should be passed to the method daoMethod(String someParam,Object connection). We shall see this in the test.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;5.4 DaoGenerator class&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;package com.test.daoconntest;&lt;br /&gt;import net.sf.cglib.proxy.Enhancer;&lt;br /&gt;/**&lt;br /&gt;* @author suchakj&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;public class DaoGenerator {&lt;br /&gt;public static Object getTimeEnhancedObject(Class clazz){&lt;br /&gt;Enhancer e = new Enhancer();&lt;br /&gt;e.setSuperclass(clazz);&lt;br /&gt;e.setCallback(new DaoInterceptor());&lt;br /&gt;return e.create();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;This is the main generator for the DAO interceptor. This class uses the cglib Enhancer class to join the interceptor class DaoInterceptor with the any dao class(in our case it is DAO class).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;5.5 DaoFactory clas&lt;/span&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;s&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;package com.test.daoconntest;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* @author suchakj&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;public class DaoFactory {&lt;br /&gt;public static DaoTagInterface getDao(Class clazz) throws InstantiationException, IllegalAccessException {&lt;br /&gt;return (DaoTagInterface) DaoGenerator.getTimeEnhancedObject(clazz);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;This is a factory for generating DAO classes. It uses the DaoGenerator for generating Dao classes.&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;5.6 Main class&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This the same test class as in the previous topic. This class is testing our implementation.&lt;br /&gt;&lt;br /&gt;package com.test;&lt;br /&gt;import com.test.daoconntest.DAO;&lt;br /&gt;import com.test.daoconntest.DaoFactory;&lt;br /&gt;import com.test.daoconntest.DaoInterceptor;&lt;br /&gt;import com.test.methodtimetest.MethodTimeGenerator;&lt;br /&gt;import com.test.methodtimetest.SimpleClass;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* @author suchakj&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;public class Main {&lt;br /&gt;&lt;br /&gt;public static void testMethodTimeTest(){&lt;br /&gt;//this could come from a factory.&lt;br /&gt;SimpleClass s = (SimpleClass)MethodTimeGenerator.getTimeEnhancedObject(SimpleClass.class);&lt;br /&gt;s.simpleMethod();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static void testDaoConn(){&lt;br /&gt;DAO d;&lt;br /&gt;try {&lt;br /&gt;d = (DAO)DaoFactory.getDao(DAO.class);&lt;br /&gt;d.daoMethod("test",null);&lt;br /&gt;} catch (InstantiationException e) {&lt;br /&gt;// TODO Auto-generated catch block&lt;br /&gt;e.printStackTrace();&lt;br /&gt;} catch (IllegalAccessException e) {&lt;br /&gt;// TODO Auto-generated catch block&lt;br /&gt;e.printStackTrace();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt;//testMethodTimeTest();&lt;br /&gt;testDaoConn();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Here is the output.&lt;br /&gt;---------------------------------------------------------------------------------------------------------------&lt;br /&gt;Getting connection from pool ...&lt;br /&gt;In Dao Method&lt;br /&gt;Got a Valid connection that I can use&lt;br /&gt;Returning connection to pool ...&lt;br /&gt;---------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;5.7 Topic Conclusion&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The above code shows how simple it is for a dao to give and return a connection from/to the connection pool, without writing such code in all the dao methods.Also the code for this is in a central place and can be modified as needed.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;6 Conclusion.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Aspects of a code base , a framework can be cleanly coded using Aspect oriented programming. It can be coded in a non intrusive way using Cglib. Thus the result is Aspect code of a similar type in one central place and still applied to the objects that need the Aspect. The two aspects we talked about were getting connection and returning them to a connection pool, and timing methods for querying performance.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;7 Drawbacks&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Some of the drawbacks of what is explained above are.&lt;br /&gt;&lt;br /&gt;1) There could be two or more dao method calls that want to use the same connection object for the reason of transactions. For this the solution could be that we check if the user has sent a connection and if he has then do not apply the interception&lt;br /&gt;&lt;br /&gt;2) For both the topics a new Enhancer is created at each method call, it would be better to have a cache of a Hashmap or a WeakHashMap so that the impact of new Enhancer creation at every method call is reduced.&lt;br /&gt;&lt;br /&gt;3) The daointerceptor assumes that the method will have a Connection param, which will be the last param, and also which will be ignored even if sent by the user.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110363574706443568?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110363574706443568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110363574706443568&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110363574706443568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110363574706443568'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/aspect-oriented-programming-with-cglib.html' title='Aspect oriented programming with CGLIB'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110363020223314283</id><published>2004-12-21T03:40:00.000-08:00</published><updated>2006-07-07T08:55:24.130-07:00</updated><title type='text'>Implementing a Frequency date time generator in java</title><content type='html'>The java calendar class does a lot of good things. As far as adding days to a date is concerened it has three methods.&lt;br /&gt;&lt;br /&gt;set(f, value) : sets the field f which could be weekdday, month, year,etc. to the value specified.&lt;br /&gt;&lt;br /&gt;add(f, delta) : adds detla to the field f which could be weekdday, month, year,etc.&lt;br /&gt;&lt;br /&gt;roll(f, delta) : adds detla to the field f which could be weekdday, month, year,etc whichout changing the larger fields. For exmaple using roll to add 10 to the month value of Dec 31 2004 will roll to OCt 31 2004 as year being the larger will be the same.&lt;br /&gt;&lt;br /&gt;For more details on these methods look at &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html"&gt;http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The objective of this post to to reconcile the calendar class with the computation of custom frequencies like daily, weekly,monthing, biweekly etc..&lt;br /&gt;&lt;br /&gt;I have written a class that uses the calendar to compute custom frequencies in a manner that helps the user get the next date, if he just supplies his current date and the frequency.&lt;br /&gt;&lt;br /&gt;Beware ! Reading this class is not easy at all, however it can be very usefull.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;import java.sql.Timestamp;&lt;br /&gt;import java.util.Calendar;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; *  This class generates a date/time based on a frequency. &lt;br /&gt; *  It accepts a range of frequencies, like Hourly, Monthy, Weekly,&lt;br /&gt; *  Yearly,BiWeekly, SemiMonthy,Quarterly and LastDayOfMonth and &lt;br /&gt; *  based on the frequency generates the next run date.&lt;br /&gt; * &lt;br /&gt; * @author suchakj&lt;br /&gt; */&lt;br /&gt;public class RunFreqGenerator {&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  *  This interface holds the string values for all frequencies. &lt;br /&gt;  *  The frequnecies are Hourly, Monthy, Weekly, Yearly,BiWeekly, SemiMonthy,&lt;br /&gt;  *  Quarterly and LastDayOfMonth.&lt;br /&gt;  *     &lt;br /&gt;  */ &lt;br /&gt; public interface RunFreqInterface {&lt;br /&gt;  public static final String RUN_FREQ_HOURLY = "H";&lt;br /&gt;&lt;br /&gt;  public static final String RUN_FREQ_DAILY = "D";&lt;br /&gt;&lt;br /&gt;  public static final String RUN_FREQ_MONTHLY = "M";&lt;br /&gt;&lt;br /&gt;  public static final String RUN_FREQ_WEEKLY = "W";&lt;br /&gt;&lt;br /&gt;  public static final String RUN_FREQ_YEARLY = "Y";&lt;br /&gt;&lt;br /&gt;  public static final String RUN_FREQ_BIWEEKLY = "B";&lt;br /&gt;&lt;br /&gt;  public static final String RUN_FREQ_SEMIMONTHLY = "S";&lt;br /&gt;&lt;br /&gt;  public static final String RUN_FREQ_QUARTERLY = "Q";&lt;br /&gt;&lt;br /&gt;  public static final String RUN_FREQ_HALFYEARLY = "L";&lt;br /&gt;&lt;br /&gt;  public static final String LAST_DAY_OF_MONTH = "LD";&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  *  Every frequency needs a certain set of parameters to determine the next &lt;br /&gt;  *  run date.&lt;br /&gt;  *  &lt;br /&gt;  *  This class holds the frequency related parameters based on the frequency&lt;br /&gt;  *  type.     &lt;br /&gt;  *     &lt;br /&gt;  */&lt;br /&gt; public class DateFreqHolder {&lt;br /&gt;  &lt;br /&gt;  // The date for the next run.&lt;br /&gt;  private Timestamp nextDate;&lt;br /&gt;  &lt;br /&gt;  // A frequency based on the RunFreqInterface attributes.&lt;br /&gt;  private String freq;&lt;br /&gt;&lt;br /&gt;  /* &lt;br /&gt;   * The day of the run i.e Monday, Wednesday etc. It is eighter the full &lt;br /&gt;   * name or the first three letters of the day name.&lt;br /&gt;   */&lt;br /&gt;  private String run_day;&lt;br /&gt;&lt;br /&gt;  /* &lt;br /&gt;   * The numerical day of the month on which the the task is run for the&lt;br /&gt;   * first time.&lt;br /&gt;   */&lt;br /&gt;  private String first_run_date;&lt;br /&gt;&lt;br /&gt;  /* &lt;br /&gt;   * The month of the run i.e January,February etc. It is eighter the full &lt;br /&gt;   * name or the first three letters of the month name.&lt;br /&gt;   */&lt;br /&gt;  private String run_month;&lt;br /&gt;&lt;br /&gt;  /* &lt;br /&gt;   * The numerical day of the month on which the task is run for a &lt;br /&gt;   * second time. &lt;br /&gt;   */&lt;br /&gt;  private String second_run_date;&lt;br /&gt;&lt;br /&gt;  public String getFirst_run_date() {&lt;br /&gt;   return first_run_date;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setFirst_run_date(String first_run_date) {&lt;br /&gt;   this.first_run_date = first_run_date;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public String getRun_month() {&lt;br /&gt;   return run_month;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setRun_month(String run_month) {&lt;br /&gt;   this.run_month = run_month;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public String getRun_day() {&lt;br /&gt;   return run_day;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setRun_day(String run_day) {&lt;br /&gt;   this.run_day = run_day;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public String getSecond_run_date() {&lt;br /&gt;   return second_run_date;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setSecond_run_date(String second_run_date) {&lt;br /&gt;   this.second_run_date = second_run_date;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public String getFreq() {&lt;br /&gt;   return freq;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public Timestamp getNextDate() {&lt;br /&gt;   return nextDate;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setFreq(String freq) {&lt;br /&gt;   this.freq = freq;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setNextDate(Timestamp nextDate) {&lt;br /&gt;   this.nextDate = nextDate;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* &lt;br /&gt;  * Gets the next date based on the data in the DateFreqHolder&lt;br /&gt;  *  &lt;br /&gt;  */&lt;br /&gt; public static Timestamp getNextDate(DateFreqHolder holder) throws Exception {&lt;br /&gt;&lt;br /&gt;  Timestamp previousRunDate = holder.getNextDate();&lt;br /&gt;  if (previousRunDate == null) {&lt;br /&gt;   throwNullVarException("nextRundate");&lt;br /&gt;  }&lt;br /&gt;  String runFreq = holder.getFreq();&lt;br /&gt;  if (runFreq == null) {&lt;br /&gt;   throwNullVarException("run freq");&lt;br /&gt;  }&lt;br /&gt;  Calendar cal = Calendar.getInstance();&lt;br /&gt;  cal.setTime(previousRunDate);&lt;br /&gt;&lt;br /&gt;  if (RunFreqInterface.RUN_FREQ_HOURLY.equals(runFreq)) {&lt;br /&gt;   return addHours(cal, 1);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if (RunFreqInterface.RUN_FREQ_DAILY.equals(runFreq)) {&lt;br /&gt;   return addHours(cal, 24);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if (RunFreqInterface.RUN_FREQ_WEEKLY.equals(runFreq)) {&lt;br /&gt;   String runDay = holder.getRun_day();&lt;br /&gt;   if (runDay == null) {&lt;br /&gt;    throwNullVarForFreqException("run day", RunFreqInterface.RUN_FREQ_WEEKLY);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return addWeeks(cal, cal.get(Calendar.DAY_OF_WEEK),&lt;br /&gt;     getWeekday(runDay), 1);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if (RunFreqInterface.RUN_FREQ_MONTHLY.equals(runFreq)) {&lt;br /&gt;   String runDate = holder.getFirst_run_date();&lt;br /&gt;   if (runDate == null) {&lt;br /&gt;    throwNullVarForFreqException("run date", RunFreqInterface.RUN_FREQ_MONTHLY);&lt;br /&gt;   }&lt;br /&gt;   return addMonth(cal, runDate);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if (RunFreqInterface.RUN_FREQ_QUARTERLY.equals(runFreq)) {&lt;br /&gt;   String runDate = holder.getFirst_run_date();&lt;br /&gt;   if (runDate == null) {&lt;br /&gt;    throwNullVarForFreqException("run date", RunFreqInterface.RUN_FREQ_QUARTERLY);&lt;br /&gt;   }&lt;br /&gt;   return addQuarter(cal, cal.get(Calendar.MONTH), runDate);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if (RunFreqInterface.RUN_FREQ_YEARLY.equals(runFreq)) {&lt;br /&gt;   String runDate = holder.getFirst_run_date();&lt;br /&gt;   String runMonth = holder.getRun_month();&lt;br /&gt;   if (runDate == null) {&lt;br /&gt;    throwNullVarForFreqException("run date", RunFreqInterface.RUN_FREQ_YEARLY);&lt;br /&gt;   }&lt;br /&gt;   if (runMonth == null) {&lt;br /&gt;    throwNullVarForFreqException("run month", RunFreqInterface.RUN_FREQ_YEARLY);&lt;br /&gt;   }&lt;br /&gt;   return addMonths(cal, cal.get(Calendar.MONTH), getMonth(runMonth),&lt;br /&gt;     runDate, 12);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if (RunFreqInterface.RUN_FREQ_BIWEEKLY.equals(runFreq)) {&lt;br /&gt;   String runDay = holder.getRun_day();&lt;br /&gt;   if (runDay == null) {&lt;br /&gt;    throwNullVarForFreqException("run day", RunFreqInterface.RUN_FREQ_BIWEEKLY);&lt;br /&gt;   }&lt;br /&gt;   return addWeeks(cal, cal.get(Calendar.DAY_OF_WEEK),&lt;br /&gt;     getWeekday(runDay), 2);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if (RunFreqInterface.RUN_FREQ_SEMIMONTHLY.equals(runFreq)) {&lt;br /&gt;   String runDateString = holder.getFirst_run_date();&lt;br /&gt;   String secondRunDateString = holder.getSecond_run_date();&lt;br /&gt;   if (runDateString == null) {&lt;br /&gt;    throwNullVarForFreqException("run date",&lt;br /&gt;      RunFreqInterface.RUN_FREQ_SEMIMONTHLY);&lt;br /&gt;   }&lt;br /&gt;   if (secondRunDateString == null) {&lt;br /&gt;    throwNullVarForFreqException("second run date",&lt;br /&gt;      RunFreqInterface.RUN_FREQ_SEMIMONTHLY);&lt;br /&gt;   }&lt;br /&gt;   if (RunFreqInterface.LAST_DAY_OF_MONTH.equals(runDateString)) {&lt;br /&gt;    throw new Exception("DateFreqHolder cannot have "&lt;br /&gt;      + "first rundate as last day of the month ::"&lt;br /&gt;      + RunFreqInterface.RUN_FREQ_SEMIMONTHLY);&lt;br /&gt;   }&lt;br /&gt;   int runDate = (new Integer(runDateString)).intValue();&lt;br /&gt;   int secondRunDate = 0;&lt;br /&gt;&lt;br /&gt;   if (RunFreqInterface.LAST_DAY_OF_MONTH.equals(secondRunDateString)) {&lt;br /&gt;    secondRunDate = 31;&lt;br /&gt;   } else {&lt;br /&gt;    secondRunDate = (new Integer(secondRunDateString)).intValue();&lt;br /&gt;   }&lt;br /&gt;   if (secondRunDate &gt; runDate) {&lt;br /&gt;    throw new Exception("DateFreqHolder cannot have "&lt;br /&gt;      + "first rundate less than the second run date "&lt;br /&gt;      + "for task type ::: "&lt;br /&gt;      + RunFreqInterface.RUN_FREQ_SEMIMONTHLY);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   int previousRunDateInt = cal.get(Calendar.DAY_OF_MONTH);&lt;br /&gt;&lt;br /&gt;   if (previousRunDateInt &lt; runDate) {&lt;br /&gt;    cal.set(Calendar.DAY_OF_MONTH, runDate);&lt;br /&gt;    return new Timestamp(cal.getTime().getTime());&lt;br /&gt;   } else if ((previousRunDateInt &gt;= runDate)&lt;br /&gt;     &amp; (previousRunDateInt &gt; secondRunDate)) {&lt;br /&gt;    cal.set(Calendar.DAY_OF_MONTH, secondRunDate);&lt;br /&gt;    return new Timestamp(cal.getTime().getTime());&lt;br /&gt;   } else if (previousRunDateInt &gt;= secondRunDate) {&lt;br /&gt;    return addMonth(cal, runDateString);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  throw new Exception("DateFreqHolder does not have a proper fequency ::");&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /*&lt;br /&gt;  * This method returns the int value of the month based on the string &lt;br /&gt;  * supplied. Please note valid month strings are the full month name or the &lt;br /&gt;  * first three letters of the month name. For example January, February or &lt;br /&gt;  * Jan, Feb. &lt;br /&gt;  * &lt;br /&gt;  * This method is not case sensitive.&lt;br /&gt;  * &lt;br /&gt;  */&lt;br /&gt; private static int getMonth(String month) throws Exception {&lt;br /&gt;  if ("JAN".equalsIgnoreCase(month) || "JANUARY".equalsIgnoreCase(month)) {&lt;br /&gt;   return Calendar.JANUARY;&lt;br /&gt;  }&lt;br /&gt;  if ("FEB".equalsIgnoreCase(month) || "FEBRUARY".equalsIgnoreCase(month)) {&lt;br /&gt;   return Calendar.FEBRUARY;&lt;br /&gt;  }&lt;br /&gt;  if ("MAR".equalsIgnoreCase(month) || "MARCH".equalsIgnoreCase(month)) {&lt;br /&gt;   return Calendar.MARCH;&lt;br /&gt;  }&lt;br /&gt;  if ("APR".equalsIgnoreCase(month) || "APRIL".equalsIgnoreCase(month)) {&lt;br /&gt;   return Calendar.APRIL;&lt;br /&gt;  }&lt;br /&gt;  if ("MAY".equalsIgnoreCase(month)) {&lt;br /&gt;   return Calendar.MAY;&lt;br /&gt;  }&lt;br /&gt;  if ("JUN".equalsIgnoreCase(month) || "JUNE".equalsIgnoreCase(month)) {&lt;br /&gt;   return Calendar.JUNE;&lt;br /&gt;  }&lt;br /&gt;  if ("JUL".equalsIgnoreCase(month) || "JULY".equalsIgnoreCase(month)) {&lt;br /&gt;   return Calendar.JULY;&lt;br /&gt;  }&lt;br /&gt;  if ("AUG".equalsIgnoreCase(month) || "AUGUST".equalsIgnoreCase(month)) {&lt;br /&gt;   return Calendar.AUGUST;&lt;br /&gt;  }&lt;br /&gt;  if ("SEP".equalsIgnoreCase(month)&lt;br /&gt;    || "SEPTEMBER".equalsIgnoreCase(month)) {&lt;br /&gt;   return Calendar.SEPTEMBER;&lt;br /&gt;  }&lt;br /&gt;  if ("OCT".equalsIgnoreCase(month) || "OCTOBER".equalsIgnoreCase(month)) {&lt;br /&gt;   return Calendar.OCTOBER;&lt;br /&gt;  }&lt;br /&gt;  if ("NOV".equalsIgnoreCase(month) || "NOVEMBER".equalsIgnoreCase(month)) {&lt;br /&gt;   return Calendar.NOVEMBER;&lt;br /&gt;  }&lt;br /&gt;  if ("DEC".equalsIgnoreCase(month) || "DECEMBER".equalsIgnoreCase(month)) {&lt;br /&gt;   return Calendar.DECEMBER;&lt;br /&gt;  }&lt;br /&gt;  throw new Exception("Month cannot be :: " + month);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /*&lt;br /&gt;  * This method returns the int value of the week day based on the string &lt;br /&gt;  * supplied. Please note valid week day strings are the full week day name &lt;br /&gt;  * or the first three letters of the week day name. For example Mondya, &lt;br /&gt;  * Tuesday or Mon, Tue. &lt;br /&gt;  * &lt;br /&gt;  * This method is not case sensitive.&lt;br /&gt;  * &lt;br /&gt;  */&lt;br /&gt; private static int getWeekday(String weekday) throws Exception {&lt;br /&gt;  if ("SUN".equalsIgnoreCase(weekday)&lt;br /&gt;    || "SUNDAY".equalsIgnoreCase(weekday)) {&lt;br /&gt;   return Calendar.SUNDAY;&lt;br /&gt;  }&lt;br /&gt;  if ("MON".equalsIgnoreCase(weekday)&lt;br /&gt;    || "MONDAY".equalsIgnoreCase(weekday)) {&lt;br /&gt;   return Calendar.MONDAY;&lt;br /&gt;  }&lt;br /&gt;  if ("TUE".equalsIgnoreCase(weekday)&lt;br /&gt;    || "TUESDAY".equalsIgnoreCase(weekday)) {&lt;br /&gt;   return Calendar.TUESDAY;&lt;br /&gt;  }&lt;br /&gt;  if ("WED".equalsIgnoreCase(weekday)&lt;br /&gt;    || "WEDNESDAY".equalsIgnoreCase(weekday)) {&lt;br /&gt;   return Calendar.WEDNESDAY;&lt;br /&gt;  }&lt;br /&gt;  if ("THU".equalsIgnoreCase(weekday)&lt;br /&gt;    || "THURSDAY".equalsIgnoreCase(weekday)) {&lt;br /&gt;   return Calendar.THURSDAY;&lt;br /&gt;  }&lt;br /&gt;  if ("FRI".equalsIgnoreCase(weekday)&lt;br /&gt;    || "FRIDAY".equalsIgnoreCase(weekday)) {&lt;br /&gt;   return Calendar.FRIDAY;&lt;br /&gt;  }&lt;br /&gt;  if ("SAT".equalsIgnoreCase(weekday)&lt;br /&gt;    || "SATURDAY".equalsIgnoreCase(weekday)) {&lt;br /&gt;   return Calendar.SATURDAY;&lt;br /&gt;  }&lt;br /&gt;  throw new Exception("Day of the week cannot be :: " + weekday);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* &lt;br /&gt;  * Throws exception stating that a particular DateFreqHolder variable cannot&lt;br /&gt;  * be null for a particular frequency&lt;br /&gt;  * &lt;br /&gt;  */ &lt;br /&gt; private static void throwNullVarForFreqException(String var, String freq)&lt;br /&gt;   throws Exception {&lt;br /&gt;  throw new Exception("DateFreqHolder cannot have a null :: " + var&lt;br /&gt;    + " when freq is :: " + freq);&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* &lt;br /&gt;  * Throws exception stating that a particular variable cannot be null.&lt;br /&gt;  * &lt;br /&gt;  */ &lt;br /&gt; private static void throwNullVarException(String var) throws Exception {&lt;br /&gt;  throw new Exception("DateFreqHolder cannot have a null :: " + var);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* &lt;br /&gt;  * Add a month to the supplied calender. After that set the date to the &lt;br /&gt;  * runDate(day of the month) supplied. &lt;br /&gt;  * &lt;br /&gt;  */ &lt;br /&gt; private static Timestamp addMonth(Calendar cal, String runDate)&lt;br /&gt;   throws Exception {&lt;br /&gt;  return addMonths(cal, 1, runDate);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* &lt;br /&gt;  * Add months to the supplied calender as per noOfMonths. After that set &lt;br /&gt;  * the date to the runDate(day of the month) supplied. &lt;br /&gt;  * &lt;br /&gt;  */  &lt;br /&gt; private static Timestamp addMonths(Calendar cal, int noOfMonths,&lt;br /&gt;   String runDate) {&lt;br /&gt;  cal.add(Calendar.MONTH, noOfMonths);&lt;br /&gt;  if (RunFreqInterface.LAST_DAY_OF_MONTH.equals(runDate)&lt;br /&gt;    || ((new Integer(runDate)).intValue() &gt; cal&lt;br /&gt;      .getActualMaximum(Calendar.DAY_OF_MONTH))) {&lt;br /&gt;   cal.set(Calendar.DAY_OF_MONTH, cal&lt;br /&gt;     .getActualMaximum(Calendar.DAY_OF_MONTH));&lt;br /&gt;  } else {&lt;br /&gt;   cal.set(Calendar.DAY_OF_MONTH, (new Integer(runDate)).intValue());&lt;br /&gt;  }&lt;br /&gt;  return new Timestamp(cal.getTime().getTime());&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; /* &lt;br /&gt;  * This method is used for yearly tasks.&lt;br /&gt;  * &lt;br /&gt;  * It add months to the supplied calender as per noOfMonths which will be 12 &lt;br /&gt;  * for a yearly task. After that it sets the month to the runMonth(month of &lt;br /&gt;  * the year) supplied and the runDate(day of the month) to the supplied &lt;br /&gt;  * runDate.&lt;br /&gt;  *  &lt;br /&gt;  */ &lt;br /&gt; private static Timestamp addMonths(Calendar cal, int previousRunMonth,&lt;br /&gt;   int runMonth, String runDate, int noOfMonths) throws Exception {&lt;br /&gt;  if (previousRunMonth == runMonth) {&lt;br /&gt;   cal.add(Calendar.MONTH, noOfMonths);&lt;br /&gt;   return new Timestamp(cal.getTime().getTime());&lt;br /&gt;  } else {&lt;br /&gt;   if (runMonth &gt; previousRunMonth) {&lt;br /&gt;    return addMonths(cal, runMonth - previousRunMonth, runDate);&lt;br /&gt;   } else {&lt;br /&gt;    return addMonths(cal, noOfMonths&lt;br /&gt;      - (previousRunMonth - runMonth), runDate);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; /* &lt;br /&gt;  * This method is used for quarterly tasks.&lt;br /&gt;  * &lt;br /&gt;  * It add 3 months to the supplied calender. After that it sets the &lt;br /&gt;  * the runDate(day of the month) to the supplied runDate.&lt;br /&gt;  *  &lt;br /&gt;  */ &lt;br /&gt; private static Timestamp addQuarter(Calendar cal, int previousRunMonth,&lt;br /&gt;   String runDate) throws Exception {&lt;br /&gt;  if (isQuarterMonth(previousRunMonth)) {&lt;br /&gt;   return addMonths(cal, 3, runDate);&lt;br /&gt;  } else {&lt;br /&gt;   return addMonths(cal,&lt;br /&gt;     getNoOFMonthsToNextQuarterMonth(previousRunMonth), runDate);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* &lt;br /&gt;  * This method is used for quarterly tasks.&lt;br /&gt;  * &lt;br /&gt;  * It returns an int value that is used to add up the months &lt;br /&gt;  * for a quarter. &lt;br /&gt;  * &lt;br /&gt;  * The reason this method is needed is that all quarters are&lt;br /&gt;  * fixed i.e. March, June, September and December&lt;br /&gt;  *  &lt;br /&gt;  * For example a date is in october, so the number of months for it &lt;br /&gt;  * to reach the next quarter is 2 months. How ever if a date is in november &lt;br /&gt;  * the number of months for it to reach the next quarter is 1 month.  &lt;br /&gt;  *   &lt;br /&gt;  */ &lt;br /&gt; private static int getNoOFMonthsToNextQuarterMonth(int previousRunMonth)&lt;br /&gt;   throws Exception {&lt;br /&gt;  if (previousRunMonth &gt; 12) {&lt;br /&gt;   throw new Exception("Month cannot be :: " + previousRunMonth);&lt;br /&gt;  }&lt;br /&gt;  if (Calendar.MARCH &gt;= previousRunMonth) {&lt;br /&gt;   return Calendar.MARCH - previousRunMonth;&lt;br /&gt;  } else if (Calendar.JUNE &gt;= previousRunMonth) {&lt;br /&gt;   return Calendar.JUNE - previousRunMonth;&lt;br /&gt;  } else if (Calendar.SEPTEMBER &gt;= previousRunMonth) {&lt;br /&gt;   return Calendar.SEPTEMBER - previousRunMonth;&lt;br /&gt;  } else if (Calendar.DECEMBER &gt;= previousRunMonth) {&lt;br /&gt;   return Calendar.DECEMBER - previousRunMonth;&lt;br /&gt;  }&lt;br /&gt;  return 0;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /*&lt;br /&gt;  * This method checks wether the previousRunMonth supplied is a quarter &lt;br /&gt;  * month.&lt;br /&gt;  */&lt;br /&gt; private static boolean isQuarterMonth(int previousRunMonth) {&lt;br /&gt;  if (Calendar.MARCH == previousRunMonth&lt;br /&gt;    || Calendar.JUNE == previousRunMonth&lt;br /&gt;    || Calendar.SEPTEMBER == previousRunMonth&lt;br /&gt;    || Calendar.DECEMBER == previousRunMonth) {&lt;br /&gt;   return true;&lt;br /&gt;  }&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /*&lt;br /&gt;  * This method adds weeks to a given calendar. Also it sets the run &lt;br /&gt;  * day(day of the month) as per the supplied run day.&lt;br /&gt;  * &lt;br /&gt;  */&lt;br /&gt; private static Timestamp addWeeks(Calendar cal,&lt;br /&gt;   int previousRunDateDayOfTheWeek, int runDay, int noOfWeeks) {&lt;br /&gt;  if (previousRunDateDayOfTheWeek == runDay) {&lt;br /&gt;   cal.add(Calendar.WEEK_OF_YEAR, noOfWeeks);&lt;br /&gt;  } else {&lt;br /&gt;   if (runDay &gt; previousRunDateDayOfTheWeek) {&lt;br /&gt;    cal.add(Calendar.DAY_OF_WEEK, runDay&lt;br /&gt;      - previousRunDateDayOfTheWeek);&lt;br /&gt;   } else {&lt;br /&gt;    cal.add(Calendar.DAY_OF_WEEK,&lt;br /&gt;      7 - (previousRunDateDayOfTheWeek - runDay));&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  return new Timestamp(cal.getTime().getTime());&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /*&lt;br /&gt;  * This method adds hours to a given calendar based on the integer value &lt;br /&gt;  * supplied.&lt;br /&gt;  * &lt;br /&gt;  */&lt;br /&gt; private static Timestamp addHours(Calendar cal, int i) {&lt;br /&gt;  cal.add(Calendar.HOUR_OF_DAY, 1);&lt;br /&gt;  return new Timestamp(cal.getTime().getTime());&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /*&lt;br /&gt;  * This is the main test controller method&lt;br /&gt;  */ &lt;br /&gt; public static void main(String[] s) {&lt;br /&gt;  try {&lt;br /&gt;   RunFreqGenerator.DateFreqHolder holder = (new RunFreqGenerator()).new DateFreqHolder();&lt;br /&gt;   holder.setNextDate(new Timestamp(System.currentTimeMillis()));&lt;br /&gt;   testHourAdd(holder);&lt;br /&gt;   testDayAdd(holder);&lt;br /&gt;   testWeekAdd(holder);&lt;br /&gt;   holder.setFirst_run_date("28");&lt;br /&gt;   holder.setSecond_run_date("29");&lt;br /&gt;   testMonthAdd(holder);&lt;br /&gt;   testSemiMonthlyAdd(holder);&lt;br /&gt;   testQuarterAdd(holder);&lt;br /&gt;   testYearAdd(holder);&lt;br /&gt;&lt;br /&gt;   // test for the last day of the month.&lt;br /&gt;   Calendar c = Calendar.getInstance();&lt;br /&gt;   c.set(Calendar.MONTH, Calendar.JANUARY);&lt;br /&gt;   c.set(Calendar.DAY_OF_MONTH, 31);&lt;br /&gt;   holder.setFirst_run_date("1");&lt;br /&gt;   holder.setNextDate(new Timestamp(c.getTime().getTime()));&lt;br /&gt;&lt;br /&gt;   testMonthAdd(holder);&lt;br /&gt;   testSemiMonthlyAdd(holder);&lt;br /&gt;   testQuarterAdd(holder);&lt;br /&gt;   testYearAdd(holder);&lt;br /&gt;&lt;br /&gt;   Calendar c1 = Calendar.getInstance();&lt;br /&gt;   c1.set(Calendar.MONTH, Calendar.FEBRUARY);&lt;br /&gt;   c1.set(Calendar.DAY_OF_MONTH, 29);&lt;br /&gt;   holder.setFirst_run_date("31");&lt;br /&gt;   holder.setNextDate(new Timestamp(c1.getTime().getTime()));&lt;br /&gt;&lt;br /&gt;   testMonthAdd(holder);&lt;br /&gt;   testSemiMonthlyAdd(holder);&lt;br /&gt;   testQuarterAdd(holder);&lt;br /&gt;   testYearAdd(holder);&lt;br /&gt;&lt;br /&gt;   Calendar c3 = Calendar.getInstance();&lt;br /&gt;   c3.set(Calendar.MONTH, Calendar.APRIL);&lt;br /&gt;   c3.set(Calendar.DAY_OF_MONTH, 30);&lt;br /&gt;   holder.setFirst_run_date("LD");&lt;br /&gt;   holder.setNextDate(new Timestamp(c3.getTime().getTime()));&lt;br /&gt;&lt;br /&gt;   testMonthAdd(holder);&lt;br /&gt;   testSemiMonthlyAdd(holder);&lt;br /&gt;   testQuarterAdd(holder);&lt;br /&gt;   testYearAdd(holder);&lt;br /&gt;&lt;br /&gt;   Calendar c4 = Calendar.getInstance();&lt;br /&gt;   c4.set(Calendar.MONTH, Calendar.FEBRUARY);&lt;br /&gt;   c4.set(Calendar.DAY_OF_MONTH, 29);&lt;br /&gt;   holder.setFirst_run_date("29");&lt;br /&gt;   holder.setNextDate(new Timestamp(c4.getTime().getTime()));&lt;br /&gt;   testMonthAdd(holder);&lt;br /&gt;   testSemiMonthlyAdd(holder);&lt;br /&gt;   testQuarterAdd(holder);&lt;br /&gt;   testYearAdd(holder);&lt;br /&gt;  } catch (Exception e) {&lt;br /&gt;   e.printStackTrace();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; // the mothod names below are are self explanatory.&lt;br /&gt; private static void testYear(DateFreqHolder holder, String month)&lt;br /&gt;   throws Exception {&lt;br /&gt;  System.out.println("testing Year add ::::: month :: " + month&lt;br /&gt;    + " runday :: " + holder.getFirst_run_date());&lt;br /&gt;  holder.setFreq(RunFreqInterface.RUN_FREQ_YEARLY);&lt;br /&gt;  holder.setRun_month(month);&lt;br /&gt;  System.out.println("Previous Run date :: " + holder.getNextDate());&lt;br /&gt;  System.out.println("Next Run date " + month + " :: "&lt;br /&gt;    + getNextDate(holder));&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static void testHourAdd(DateFreqHolder holder) throws Exception {&lt;br /&gt;  System.out.println("Testing hour add");&lt;br /&gt;  holder.setFreq(RunFreqInterface.RUN_FREQ_HOURLY);&lt;br /&gt;  System.out.println("Previous Run date :: " + holder.getNextDate());&lt;br /&gt;  System.out.println("Next Run date :: " + getNextDate(holder));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static void testDayAdd(DateFreqHolder holder) throws Exception {&lt;br /&gt;  System.out.println("Testing Day add");&lt;br /&gt;  holder.setFreq(RunFreqInterface.RUN_FREQ_DAILY);&lt;br /&gt;  System.out.println("Previous Run date :: " + holder.getNextDate());&lt;br /&gt;  System.out.println("Next Run date :: " + getNextDate(holder));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static void testWeekAdd(DateFreqHolder holder) throws Exception {&lt;br /&gt;&lt;br /&gt;  testWeekDay(holder, "SUN");&lt;br /&gt;  testWeekDay(holder, "MON");&lt;br /&gt;  testWeekDay(holder, "TUE");&lt;br /&gt;  testWeekDay(holder, "WED");&lt;br /&gt;  testWeekDay(holder, "THU");&lt;br /&gt;  testWeekDay(holder, "FRI");&lt;br /&gt;  testWeekDay(holder, "SAT");&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static void testWeekDay(DateFreqHolder holder, String weekDay)&lt;br /&gt;   throws Exception {&lt;br /&gt;  System.out.println("Testing Week add ::::: " + weekDay);&lt;br /&gt;  holder.setFreq(RunFreqInterface.RUN_FREQ_WEEKLY);&lt;br /&gt;  holder.setRun_day(weekDay);&lt;br /&gt;  System.out.println("Previous Run date :: " + holder.getNextDate());&lt;br /&gt;  System.out.println("Next Run date " + weekDay + " :: "&lt;br /&gt;    + getNextDate(holder));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static void testMonthAdd(DateFreqHolder holder) throws Exception {&lt;br /&gt;  System.out.println("testing month add ::::: month :: " + " runday :: "&lt;br /&gt;    + holder.getFirst_run_date());&lt;br /&gt;  holder.setFreq(RunFreqInterface.RUN_FREQ_MONTHLY);&lt;br /&gt;  // holder.setRun_month(month);&lt;br /&gt;  System.out.println("Previous Run date :: " + holder.getNextDate());&lt;br /&gt;  System.out.println("Next Run date " + " :: " + getNextDate(holder));&lt;br /&gt;&lt;br /&gt;  System.out.println();&lt;br /&gt;  System.out.println();&lt;br /&gt;  System.out.println();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static void testQuarterAdd(DateFreqHolder holder) throws Exception {&lt;br /&gt;  System.out.println("testing Quarter add ::::: " + " runday :: "&lt;br /&gt;    + holder.getFirst_run_date());&lt;br /&gt;  holder.setFreq(RunFreqInterface.RUN_FREQ_QUARTERLY);&lt;br /&gt;  // holder.setRun_month(month);&lt;br /&gt;  System.out.println("Previous Run date :: " + holder.getNextDate());&lt;br /&gt;  System.out.println("Next Run date " + " :: " + getNextDate(holder));&lt;br /&gt;&lt;br /&gt;  System.out.println();&lt;br /&gt;  System.out.println();&lt;br /&gt;  System.out.println();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static void testSemiMonthlyAdd(DateFreqHolder holder)&lt;br /&gt;   throws Exception {&lt;br /&gt;  System.out.println("testing Semi Monthly add ::::: "&lt;br /&gt;    + " first runday :: " + holder.getFirst_run_date());&lt;br /&gt;  System.out.println("testing Semi Monthly add ::::: "&lt;br /&gt;    + " second runday :: " + holder.getSecond_run_date());&lt;br /&gt;  holder.setFreq(RunFreqInterface.RUN_FREQ_SEMIMONTHLY);&lt;br /&gt;  // holder.setRun_month(month);&lt;br /&gt;  System.out.println("Previous Run date :: " + holder.getNextDate());&lt;br /&gt;  System.out.println("Next Run date " + " :: " + getNextDate(holder));&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static void testYearAdd(DateFreqHolder holder) throws Exception {&lt;br /&gt;  testYear(holder, "JAN");&lt;br /&gt;  testYear(holder, "FEB");&lt;br /&gt;  testYear(holder, "MAR");&lt;br /&gt;  testYear(holder, "APR");&lt;br /&gt;  testYear(holder, "MAY");&lt;br /&gt;  testYear(holder, "JUN");&lt;br /&gt;  testYear(holder, "JUL");&lt;br /&gt;  testYear(holder, "AUG");&lt;br /&gt;  testYear(holder, "SEP");&lt;br /&gt;  testYear(holder, "OCT");&lt;br /&gt;  testYear(holder, "NOV");&lt;br /&gt;  testYear(holder, "DEC");&lt;br /&gt;  System.out.println();&lt;br /&gt;  System.out.println();&lt;br /&gt;  System.out.println();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110363020223314283?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110363020223314283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110363020223314283&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110363020223314283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110363020223314283'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/implementing-frequency-date-time.html' title='Implementing a Frequency date time generator in java'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110362763288465150</id><published>2004-12-21T02:42:00.000-08:00</published><updated>2004-12-21T03:40:05.006-08:00</updated><title type='text'>PDF template creation using iText</title><content type='html'>This will sound exiting to those who know that , one can use the Adobe Arcobat writer toll to create templates. These templates can use used to fill up data programatically using iText api.&lt;br /&gt;&lt;br /&gt;How would you do so ?.&lt;br /&gt;&lt;br /&gt;Lets assume that you already have the itext.jar in class path and let's say you have create a template using adobe acrobat.&lt;br /&gt;&lt;br /&gt;Then you call that template in your code like this :-&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;   File template = new File(templatePDFFile);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    byte[]  templateByteArray = getBytesFromFile(template); // somehow get the bytes out of the file.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    Document document - new Document();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    FileOutputStream fos = new FileOutputStream(outputFileName);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    PdfWriter writer = PdfWriter.getInstance(document, fos);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    document.open();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    PdfContentByte cb = writer.getDirectContent();    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    PDFReader = new PdfReader(templateByteArray);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    HashMap fieldBoxes = getFieldBoxes(reader);// get all the fields of the template and then use them via stamper.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;    // now we use the stamper to do the template majic&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    stamp = new PdfStamper(reader, outputStream);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    cbStamper = stamp.getOverContent(1);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    form = stamp.getAcroFields();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    rect = (Rectangle) fieldBoxes.get("mytestimage");&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    addSpecialImage(&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        cbStamper,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        testImage,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        rect.left(),&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        rect.bottom(),&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        rect.right(),&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        rect.top()&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    );&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;font-size:100%;" &gt;Here is what the addspecial image method in our code does&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;private void addSpecialImage(&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        PdfContentByte cb,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        Image img,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        float x1,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        float y1,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        float x2,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        float y2)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        float h = y2 - y1;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        float w = x2 - x1;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    try{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        img.scaleToFit(x2 - x1, y2 - y1);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        img.setAbsolutePosition(x1, y1);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        cb.addImage(img);                            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        catch (Exception e)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            log(e.getMessage());&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            timeLog(e.getMessage());&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            e.printStackTrace();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;However now you can create the template we used above also programatically on the fly using iText.&lt;br /&gt;&lt;br /&gt;Here is some random code that does this:-&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;    //    llx - lower left x&lt;br /&gt;   //    lly - lower left y&lt;br /&gt;   PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(somepdfname));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            document.open();            &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                BaseFont helv = BaseFont.createFont("Helvetica", "winansi", false);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                PdfContentByte cb = writer.getDirectContent();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                cb.moveTo(0, 0);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                float fontSize = DEFAULT_FONT_SIZE;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                Color textColor = new GrayColor(0f);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                PdfFormField field = PdfFormField.createTextField(writer, false, false, 0);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; field.setWidget(new Rectangle(llx, lly, llx + DEFAULT_UPPER_X_DIFFERENCE, lly + DEFAULT_UPPER_Y_DIFFERENCE), PdfAnnotation.HIGHLIGHT_INVERT);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                field.setFlags(PdfAnnotation.FLAGS_PRINT);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                field.setFieldName(DEFAULT_FIELDNAME_STARTSTRING + j + "_" + i);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                field.setBorderStyle(new PdfBorderDictionary(2,        PdfBorderDictionary.STYLE_SOLID));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                field.setPage();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                PdfAppearance tp = cb.createAppearance(170, 30);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                PdfAppearance da = (PdfAppearance)tp.getDuplicate();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                da.setFontAndSize(helv, fontSize);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                da.setColorFill(textColor);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                field.setDefaultAppearanceString(da);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                writer.addAnnotation(field);&lt;br /&gt;               document.close();&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;So  this is the power of iText, it does so many nice things with PDF, some of them are undocumented.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110362763288465150?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110362763288465150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110362763288465150&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110362763288465150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110362763288465150'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/pdf-template-creation-using-itext.html' title='PDF template creation using iText'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110362335118898799</id><published>2004-12-21T01:30:00.000-08:00</published><updated>2004-12-21T02:05:23.776-08:00</updated><title type='text'>Modify poolit FixedPooler class to not give null objects on resize</title><content type='html'>Pool it from acent phase &lt;a href="http://www.ascent-phase.org/projects/poolit/"&gt;http://www.ascent-phase.org/projects/poolit/&lt;/a&gt; had a good object pooling library. I wanted to use the library for on of my projects, specifically i wanted to use the FixedPooler class &lt;a href="http://www.ascent-phase.org/projects/poolit/api/org/ascentphase/poolit/poolers/FixedPooler.html"&gt;http://www.ascent-phase.org/projects/poolit/api/org/ascentphase/poolit/poolers/FixedPooler.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;FixedPooler  has a  resize method that i desired to use.&lt;br /&gt;&lt;h3&gt; resize&lt;/h3&gt;  &lt;pre&gt;public void &lt;b&gt;resize&lt;/b&gt;(int newsize)&lt;/pre&gt;  &lt;dl&gt; &lt;dd&gt;Changes the size of the pool. If the new size is smaller than the current, the number of objects exceeding the new size will be discarded. If the new size is greater than the current, the objects currently pooled will be moved over to the new pool, but no new objects will be created to fill in the new space. &lt;p&gt; &lt;/p&gt;&lt;/dd&gt;&lt;dd&gt;&lt;br /&gt;&lt;/dd&gt;&lt;dd&gt;&lt;dl&gt;&lt;dt&gt;&lt;b&gt;Parameters:&lt;/b&gt;&lt;/dt&gt;&lt;dd&gt;&lt;code&gt;newsize&lt;/code&gt; - the new size of the poo&lt;/dd&gt;&lt;/dl&gt;&lt;/dd&gt; &lt;/dl&gt; So as seen above it does resize the pool as i wanted. But it did not add any new objects to the resized pool.&lt;br /&gt;&lt;br /&gt;It uses an array to store objects internally and also there is a pointer called availablepos which is an int, that keeps track of which is the next object to fetch.&lt;br /&gt;&lt;br /&gt;Please keep in mind that an array of size one, means that there can be a value at position 0. In other words Array positions start at 0.&lt;br /&gt;&lt;br /&gt;For example. consider this pool(Array intenally)&lt;br /&gt;Lets say the pool consists of string values of "A"&lt;br /&gt;{"A","A","A"}&lt;br /&gt;So here the pool size is 3 and the availablepos is 2.&lt;br /&gt;&lt;br /&gt;A call to the fetch method will do this.&lt;br /&gt;{"A","A",null}&lt;br /&gt;So now the pool size is 2 and  the availablepos is 1.&lt;br /&gt;&lt;br /&gt;one more call to fetch will do this&lt;br /&gt;{"A",null,null}&lt;br /&gt;So now the pool size is 1 and  the availablepos is 0.&lt;br /&gt;&lt;br /&gt;one more call to fetch will do this&lt;br /&gt;{null,null,null}&lt;br /&gt;So now the pool size is 0 and  the availablepos is -1.&lt;br /&gt;&lt;br /&gt;How does this affect resize.&lt;br /&gt;&lt;br /&gt;Lets say we are in this position:&lt;br /&gt;{"A",null,null}&lt;br /&gt;The pool size is 1 and  the availablepos is 0.&lt;br /&gt;&lt;br /&gt;Now someone issues a resize to be 6 by calling pool.resize(6)&lt;br /&gt;So what will happen is&lt;br /&gt;{"A",null,null, null,null,null}&lt;br /&gt;&lt;br /&gt;The logical uestion is why can it not be&lt;br /&gt;{"A",null,null, "A","A","A"}, that is the new Array gets the default objects in the pool ?&lt;br /&gt;&lt;br /&gt;Look at the value of availablepos, it is 0, how ill that move to the new values as still at position 0 there is a value. Also the way to copy arrays in java is System.arraycopy(), and that does the copy exactly as descibed above, copies the values from the old array to the new array.&lt;br /&gt;&lt;br /&gt;How do we solve this ?&lt;br /&gt;&lt;br /&gt;I wrote a class that i called ModifiedFixedPooler which operates just like the Fixed pooler by pool it. But it handles the availablepos pointer differently.&lt;br /&gt;&lt;br /&gt;Let's consider the same example&lt;br /&gt;Lets say the pool consists of string values of "A"&lt;br /&gt;{"A","A","A"}&lt;br /&gt;So now here the pool size is 3 and the availablepos is O.&lt;br /&gt;&lt;br /&gt;A call to the fetch method will do this.&lt;br /&gt;{null,"A","A"}&lt;br /&gt;So now the pool size is 2 and  the availablepos is 1.&lt;br /&gt;&lt;br /&gt;one more call to fetch will do this&lt;br /&gt;{null,null,"A"}&lt;br /&gt;So now the pool size is 1 and  the availablepos is 2.&lt;br /&gt;&lt;br /&gt;one more call to fetch will do this&lt;br /&gt;{null,null,null}&lt;br /&gt; So now the pool size is 0 and  the availablepos is 3.&lt;br /&gt;&lt;br /&gt;How does help the resize.&lt;br /&gt;&lt;br /&gt;Lets say we are in this position:&lt;br /&gt;{null,null,"A"}&lt;br /&gt; So now the pool size is 1 and  the availablepos is 2.&lt;br /&gt;&lt;br /&gt;Now someone issues a resize to be 6 by calling pool.resize(6)&lt;br /&gt;So what will in my method is this&lt;br /&gt;{null,null,"A", "A","A","A"}&lt;br /&gt; So now the pool size is 4 and  the availablepos is still 2 which is right and does not need to change.&lt;br /&gt;&lt;br /&gt;You can get the source code for fixed pooler at&lt;a href="http://www.ascent-phase.org/downloads.php"&gt; http://www.ascent-phase.org/downloads.ph&lt;/a&gt;&lt;a href="http://www.ascent-phase.org/downloads.php"&gt;p&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I am typing in the source code for the modified fixed pooler here.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;/*&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; * Created on March 21, 2004&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;package com.test.poolit;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;/*&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; *    @author suchakj&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    import org.ascentphase.poolit.CreateException;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    import org.ascentphase.poolit.FetchException;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    import org.ascentphase.poolit.PoolHandler;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    import org.ascentphase.poolit.Pooler;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;import org.ascentphase.poolit.handlers.NoArgHandler;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;import org.ascentphase.poolit.poolers.FixedPooler;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    public class ModifiedFixedPooler implements Pooler {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        protected Object pool[];&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        protected PoolHandler handler;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        /**&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * Points to the index in the pool array where the next available object&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * can be retrieved from.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        protected int availPos;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        /**&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * Creates a pool with the specified class and size.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         *&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * @param name  class to be pooled&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * @param size  size of pool to be created&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        public ModifiedFixedPooler(Class name, int size) throws CreateException {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            this(new NoArgHandler(name), size);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        /**&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * Creates a pool using the specified handler and size.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         *&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * @param handler  PoolHandler to be used by this pool&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * @param size  size of pool to be created&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        public ModifiedFixedPooler(PoolHandler handler, int size) throws CreateException {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            this.handler = handler;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            this.pool = new Object[size];&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            this.availPos = size;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            fillPool();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        public synchronized Object fetch() throws FetchException {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            Object objret = null;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            do {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                if (availPos &lt;&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    objret = pool[availPos];&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    // remove reference in case object is not returned to pool&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    // so it can be garbage collected&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    pool[availPos++] = null;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    if (!handler.verify(objret)) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                        handler.destroy(objret);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                        objret = null;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                } else { // no more objects available in pool&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    try {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                        objret = handler.create();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    } catch (CreateException e) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                        throw new FetchException(e.toString());&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            } while (objret == null);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            //logx.info("availPos :: " + availPos);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            return objret;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        public synchronized void release(Object o) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            if (o == null) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                throw new NullPointerException();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            } else if (availPos!=0 &amp;&amp;amp; availPos &lt;= pool.length) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                pool[--availPos] = o;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            } else { // pool full, so prepare object to be garbage collected&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                handler.destroy(o);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        /**&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * Reports the number of objects currently in the pool.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         *&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * @return the number of objects in the pool&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        public int size() {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            return pool.length - availPos;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        /**&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * Reports the maximum number of objects this pool can contain.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         *&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * @return the capacity of the pool&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        public int capacity() {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            return pool.length;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        /**&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * Changes the size of the pool.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * If the new size is smaller than the current, the number of objects&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * exceeding the new size will be discarded.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * If the new size is greater than the current, the objects currently&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * pooled will be moved over to the new pool, and new objects will be&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * created to fill in the new space.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         *&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * @param newsize  the new size of the pool&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        public synchronized void resize(int newsize) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            if (newsize != capacity()) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                Object newpool[] = new Object[newsize];&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                // if newsize is smaller than # of current available objects, then&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                // copy upto newsize&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                int tempsize = pool.length;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                if (newsize &lt;&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    System.arraycopy(pool, 0, newpool, 0, newsize);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    // any objects not moved over to new pool are to be destroyed&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    // Which is ok as the size has to be shrunk or reduced&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    while (tempsize!=newsize){&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                        handler.destroy(pool[--tempsize]);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    // set next available object to first element in array&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    //availPos = newsize - 1;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                } else { // copy up to available # of objects&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    int filllength=newpool.length-pool.length;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    int currentfillpos = pool.length;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    System.arraycopy(pool, 0, newpool, 0, currentfillpos);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    // no need to change availPos value&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    for (int i=0; i&lt;filllength&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                        try {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                            newpool[currentfillpos] = handler.create();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                        } catch (CreateException e) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                            e.printStackTrace();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                        ++currentfillpos;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                    }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                pool = newpool;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        /**&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * Called by constructor to fill up the pool.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        protected void fillPool() throws CreateException {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            for (int i=0; i&lt;pool.length&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                availPos--;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                pool[availPos] = handler.create();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                //--availPos;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        /**&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * Destroys all objects in the pool.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * Implicitly, the next call to the fetch() will force a call to the&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * handler's create() method.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         * @see org.ascentphase.poolit.Pooler#close() &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;         */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        public synchronized void close() {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            while (availPos &lt;&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                handler.destroy(pool[availPos]);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                pool[availPos] = null;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                ++availPos;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    public static void main(String[] args) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        try {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            ModifiedFixedPooler this_ = new ModifiedFixedPooler(String.class, 10);    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            this_.fetch();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            this_.resize(20);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            FixedPooler this_original = new FixedPooler(String.class,10);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            this_original.fetch();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            this_original.resize(20);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        } catch (CreateException e) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            // TODO Auto-generated catch block&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            e.printStackTrace();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        } catch (FetchException e) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            // TODO Auto-generated catch block&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;            e.printStackTrace();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pool.length&gt;&lt;/span&gt;&lt;/filllength&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110362335118898799?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110362335118898799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110362335118898799&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110362335118898799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110362335118898799'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/modify-poolit-fixedpooler-class-to-not.html' title='Modify poolit FixedPooler class to not give null objects on resize'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110354998113705060</id><published>2004-12-20T05:24:00.000-08:00</published><updated>2004-12-20T05:40:37.243-08:00</updated><title type='text'>New struts actionform ,creation and reset() method</title><content type='html'>This is an issue that i faced while using struts.&lt;br /&gt;&lt;br /&gt;Struts has ActionForm classes, and they have a defined scope in the mapping file. Scope could be page, request or  session.&lt;br /&gt;&lt;br /&gt;Now , there are two issues.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1) &lt;span style="font-weight: bold;"&gt;Do not rely on the constructor of the from bean&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;The reason is that struts is implemented such that it first checks in the appropriate scope for the form bean, and if it finds the bean it uses the same bean after calling reset(). This means that there could be times when your form bean constructor is not even called!!!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://struts.apache.org/userGuide/building_model.html#actionform"&gt;http://struts.apache.org/userGuide/building_model.html#actionform&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2) Be aware of how the reset() method works.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;If you have form beans stored in session scope make sure that you implement the reset() method. The reason is the that reset() method is called when the continer takes the bean from that scope and uses it after it calls the reset() method to clean up the bean. The default implementation is to do nothing in the Actionform superclass's reset() method.&lt;br /&gt;&lt;br /&gt;Also since you cannot thus rely on the constructor, you might as well have a reset() method to initialize code.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://struts.apache.org/userGuide/building_controller.html#action_form_classes"&gt;http://struts.apache.org/userGuide/building_controller.html#action_form_classes&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110354998113705060?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110354998113705060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110354998113705060&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110354998113705060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110354998113705060'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/new-struts-actionform-creation-and.html' title='New struts actionform ,creation and reset() method'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110354723542972527</id><published>2004-12-20T04:46:00.000-08:00</published><updated>2004-12-20T05:57:25.183-08:00</updated><title type='text'>Java Generics collection add performance</title><content type='html'>I wanted to test the raw performance of using java generics with collections. So i wrote up the following code to add a similar nomber of objects to a collection.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;public class Test {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    private void testGenericsAddPerformance(){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        long startTime = System.currentTimeMillis();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        long endTime = 0;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.out.println("STARTTime without generics ::: " + startTime);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        ArrayList l = new ArrayList();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        for(long i = 0;i&lt;4000001&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            l.add("SSSSSSSSSSSSSSSSSSSSSSSSSsss");            &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        endTime = System.currentTimeMillis();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.out.println("ENDTime without generics ::: " + endTime);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.out.println("Diff without generics ::: " + (endTime-startTime) + " milliseconds");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        l=null;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.gc();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        &lt;/span&gt;&lt;span style="font-family:courier new;"&gt;startTime = System.currentTimeMillis();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        endTime = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.out.println("STARTTime with generics ::: " + startTime);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        ArrayList&lt;string&gt; l1 = new ArrayList&lt;string&gt;();&lt;/string&gt;&lt;/string&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        for(long i = 0;i&lt;4000001&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            l1.add("SSSSSSSSSSSSSSSSSSSSSSSSSsss");            &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        endTime = System.currentTimeMillis();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.out.println("ENDTime with generics :::" + endTime);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.out.println("Diffith generics ::: " + (endTime-startTime) + " milliseconds");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        l=null;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        System.gc();        &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public static void main(String[] args) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        Test this_ = new Test();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        this_.testGenericsAddPerformance();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here are the results.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;STARTTime without generics ::: 1103546585484&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ENDTime without generics ::: 1103546586921&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Diff without generics ::: &lt;span style="font-weight: bold;"&gt;1437 milliseconds&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;STARTTime with generics ::: 1103546586953&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ENDTime with generics :::1103546587468&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Diffith generics ::: &lt;span style="font-weight: bold;"&gt;515 milliseconds&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;font-size:100%;" &gt;&lt;span style="color: rgb(0, 0, 0);"&gt;At least the initial raw performance seems to be better using Generics.&lt;/span&gt;&lt;br /&gt; &lt;br /&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;I have used JDK 1.5 version &lt;/span&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-family: arial;font-size:100%;" &gt;&lt;span style="color: rgb(0, 0, 0);"&gt;1.5.0-beta2&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110354723542972527?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110354723542972527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110354723542972527&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110354723542972527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110354723542972527'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/java-generics-collection-add.html' title='Java Generics collection add performance'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110354551529315909</id><published>2004-12-20T03:42:00.000-08:00</published><updated>2004-12-20T05:58:21.363-08:00</updated><title type='text'>Hibernate Mapping issue !</title><content type='html'>I led a team of developers implementing Hibernate for a project. There was this developer who always managed to get stuck in something very silly.&lt;br /&gt;&lt;br /&gt;So one day he comes to me declaring , "Hibernate does not work at all", i have doen everthing as per the spec and still it does notw work.&lt;br /&gt;&lt;br /&gt;I saw his code and mapping and it seemed very fine! , i spent 4 hours debugging what he had done. In the process i opened up the hibernate source code (release 1.4) .&lt;br /&gt;&lt;br /&gt;What i found was indeed silly.&lt;br /&gt;&lt;br /&gt;This developer had done the following Hibernate mapping:-&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; ..... &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  &lt;property name="corporationId" type="java.lang.Integer" column="CORPORATION_ID "&gt; ....&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;Looks innocent does it not ? Well look again, there is a space &lt;/span&gt;&lt;/property&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;column="CORPORATION_ID " , &lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;and this is what hibernate did not like and gave the error &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="postbody"&gt;will get the error that "JDBC error , column name not found...".&lt;br /&gt;&lt;br /&gt;Here is the code for the Integer value Type from hibernate.&lt;br /&gt;&lt;/span&gt; &lt;table align="center" border="0" cellpadding="3" cellspacing="1" width="100%"&gt; 	&lt;tbody&gt;&lt;tr&gt;	  &lt;td class="code"&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; public class IntegerType extends PrimitiveType implements DiscriminatorType, VersionType {       &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;           &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    private static final Integer ZERO = new Integer(0);       &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;           &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    public Object get(ResultSet rs, String name) throws SQLException {       &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;       return new Integer(rs.getInt(name));       &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    }       &lt;/span&gt;&lt;br /&gt;.... &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt; &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt; The error would not exist if the method was returning like this:-&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; return new Integer(rs.getInt(name.trim()));&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;I did post this some time ago on the hibernate forum :-&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forum.hibernate.org/viewtopic.php?t=926430"&gt;http://forum.hibernate.org/viewtopic.php?t=926430&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I got a resonse that trim is not needed. I sort of agree that a developer should not be stupid to put spaces in the hibernate mapping files, but also i think having a trim(), does no harm.&lt;br /&gt;At least that way i could have saved some time debugging.&lt;br /&gt;&lt;br /&gt;Lastly i love open source code, as that way i know exactly what the issue is, rather than having to imagine what the problem maybe, or waiting for technical support.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110354551529315909?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110354551529315909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110354551529315909&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110354551529315909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110354551529315909'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/hibernate-mapping-issue.html' title='Hibernate Mapping issue !'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110354086191630597</id><published>2004-12-20T03:01:00.000-08:00</published><updated>2005-01-03T02:18:53.043-08:00</updated><title type='text'>Understanding Hibernate Transaction rollbacks.</title><content type='html'>Hibernate does not have object level rollbacks. This means that the rollbacks and commits are always at the sql level.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);font-size:85%;" &gt;&lt;span style="font-family: courier new;"&gt;method{&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;do{t = session.transaction;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;try{&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;t.begintransaction&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;----code----&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;VO p = new VO();&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;session.save(p); // db insert not yet called&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;---code---&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;t.comit;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;}catch{&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;t.rollback;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;}//method end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Assume that an ID is generated by a custom class that i have built which basically reads a database table for id and updates the same at the same time.&lt;br /&gt;Lets say there is an exception before the commit is called, then the above does not work as the t.rollback does not rollback the saved object in memory. There is no way to rollback that saved object in memory. I repeat roll back is always SQL level roll back, meaning that any sql fired between a transaction will be rolled back.&lt;br /&gt;&lt;br /&gt;Moreover the next call to session.flush() still inserts the Object as the tx.rollback is just a sql level rollback and not object level.&lt;br /&gt;&lt;br /&gt;To correct that i did this.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);font-size:85%;" &gt;&lt;span style="font-family: courier new;"&gt;method{&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;do{t = session.transaction;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;try{&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;t.begintransaction&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;----code----&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;VO p = new VO();&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;session.save(p); // db insert not yet called&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;session.flush(); // db insert forced, Hence sql query fired.&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;---code---&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;t.comit;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;}catch{&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;t.rollback;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;}//method end&lt;/span&gt;&lt;br /&gt; &lt;br /&gt; &lt;/span&gt;Here the object was not inserted when session.flush was called next time at some other place in the code. The above code did the real rollback as needed.&lt;br /&gt;&lt;br /&gt;Conclusion from Hibernate team in the forum.&lt;br /&gt;&lt;br /&gt;The Hibernate Session is a unit of work. After you have committed or rolled back, you should close the session and get a new one for the next unit of work.&lt;br /&gt;Sherman&lt;br /&gt;&lt;br /&gt;In short there must be a new session (session.close()), after every commit or rollback and the old session must be discarded.&lt;br /&gt;&lt;br /&gt;Please refer here :&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forum.hibernate.org/viewtopic.php?t=932970"&gt;http://forum.hibernate.org/viewtopic.php?t=932970&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110354086191630597?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110354086191630597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110354086191630597&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110354086191630597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110354086191630597'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/understanding-hibernate-transaction.html' title='Understanding Hibernate Transaction rollbacks.'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110354000196817688</id><published>2004-12-20T02:52:00.000-08:00</published><updated>2005-01-03T02:14:43.516-08:00</updated><title type='text'>Ant default debug level</title><content type='html'>&lt;o:p&gt;&lt;/o:p&gt;&lt;span style="font-size:100%;"&gt;The javac compiler generates the line numbers while compiling so that in case of an exception the stack trace can tell what line number the error happened.&lt;/span&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Example&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;      &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;java.lang.NullPointerException&lt;br /&gt;at ThreadCallB.run(ThreadCallB.java:7)&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;      &lt;p class="MsoNormal"&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;java.lang.NullPointerException&lt;br /&gt;at ThreadCallA.run(ThreadCallA.java:7)&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;So I know I should look at line 7 of ThreadCallA.java and ThreadCallB.java .&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;However if I say "javac –g:none" while compiling then I will not get the above line numbers. Not so helpful, right ?&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;But that is what ant defaults to. Look at this doc: &lt;a href="http://ant.apache.org/manual/CoreTasks/javac.html"&gt;http://ant.apache.org/manual/CoreTasks/javac.html&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;i&gt;&lt;span style=""&gt;“Debug: Indicates whether source should be compiled with debug information; defaults to &lt;/span&gt;&lt;/i&gt;&lt;code&gt;&lt;i&gt;&lt;span style=""&gt;off&lt;/span&gt;&lt;/i&gt;&lt;/code&gt;&lt;i&gt;&lt;span style=""&gt;. If set to &lt;/span&gt;&lt;/i&gt;&lt;code&gt;&lt;i&gt;&lt;span style=""&gt;off&lt;/span&gt;&lt;/i&gt;&lt;/code&gt;&lt;i&gt;&lt;span style=""&gt;, &lt;/span&gt;&lt;/i&gt;&lt;code&gt;&lt;i&gt;&lt;span style=""&gt;-g:none&lt;/span&gt;&lt;/i&gt;&lt;/code&gt;&lt;i&gt;&lt;span style=""&gt; will be passed on the command line for compilers that support it (for other compilers, no command line argument will be used). If set to &lt;/span&gt;&lt;/i&gt;&lt;code&gt;&lt;i&gt;&lt;span style=""&gt;true&lt;/span&gt;&lt;/i&gt;&lt;/code&gt;&lt;i&gt;&lt;span style=""&gt;, the value of the &lt;/span&gt;&lt;/i&gt;&lt;code&gt;&lt;i&gt;&lt;span style=""&gt;debuglevel&lt;/span&gt;&lt;/i&gt;&lt;/code&gt;&lt;i&gt;&lt;span style=""&gt; attribute determines the command line argument.”&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;i&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;   &lt;span style=""&gt;Maybe there is solid reason for this, but it sure beats me if there is one!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110354000196817688?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110354000196817688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110354000196817688&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110354000196817688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110354000196817688'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/ant-default-debug-level.html' title='Ant default debug level'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110353895554650051</id><published>2004-12-20T02:32:00.000-08:00</published><updated>2005-01-03T02:11:22.933-08:00</updated><title type='text'>Understanding what is locked when using the synchronized keyword.</title><content type='html'>&lt;span style="font-size:100%;"&gt;I wanted to put on paper, the exact meaning of what is locked when the synchronized keyword is used.&lt;/span&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;What I had read and heard discussed was that the Object is locked when a thread enters a synchronized method in a class. Now that will lead one to believe that the entire Object is locked. &lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Let us see.&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Here is a class with a synchronized method “a”and a non synchronized method “b”.&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;table style="border: medium none ; background: silver none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-left: 5.4pt; border-collapse: collapse; width: 600px; height: 463px; color: rgb(0, 0, 153);" bg="" border="1" cellpadding="0" cellspacing="0"&gt;   &lt;tbody&gt;&lt;tr style="height: 134.5pt;"&gt;   &lt;td style="border: 0.5pt solid windowtext; padding: 0in 5.4pt; width: 6in; height: 134.5pt;" valign="top" width="576"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;public   class Methods {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;public   synchronized void a(){&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;while(true){&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;System.err.println("a");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;System.out.println("Thread.currentThread()"   +&lt;span style=""&gt;     &lt;/span&gt;Thread.currentThread());&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;public   void b(){&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;while(true){&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;System.err.println("b");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;System.out.println("Thread.currentThread()"   + Thread.currentThread());&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;}&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Here is class that gives singletons of the above class&lt;/span&gt;&lt;/p&gt;   &lt;table style="border: medium none ; background: silver none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-left: 5.4pt; border-collapse: collapse; color: rgb(0, 0, 153);" bg="" border="1" cellpadding="0" cellspacing="0"&gt;   &lt;tbody&gt;&lt;tr style="height: 134.5pt;"&gt;   &lt;td style="border: 0.5pt solid windowtext; padding: 0in 5.4pt; width: 6in; height: 134.5pt;" valign="top" width="576"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;public   class MethodsFactory {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;public   static Methods m = null; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;public   static synchronized Methods getMethodsInstance(){&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;if(m == null){&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;            &lt;/span&gt;m = new Methods();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;return m;&lt;span style=""&gt;   &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;   &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;}&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Here are two Threads classes A and B that call the above factory and get the same instance of the Methods class, but call method a and b respectively. remember a is synchronized and b is not.&lt;/span&gt;&lt;/p&gt;   &lt;table style="border: medium none ; background: silver none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-left: 5.4pt; border-collapse: collapse; color: rgb(0, 0, 153);" bg="" border="1" cellpadding="0" cellspacing="0"&gt;   &lt;tbody&gt;&lt;tr style="height: 134.5pt;"&gt;   &lt;td style="border: 0.5pt solid windowtext; padding: 0in 5.4pt; width: 6in; height: 134.5pt;" valign="top" width="576"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;import   java.util.List;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;public   class ThreadCallA extends Thread&lt;span style=""&gt;  &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;public void run() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;            &lt;/span&gt;Methods m =   MethodsFactory.getMethodsInstance();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;            &lt;/span&gt;m.a();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;}&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;table style="border: medium none ; background: silver none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-left: 5.4pt; border-collapse: collapse; color: rgb(0, 0, 153);" bg="" border="1" cellpadding="0" cellspacing="0"&gt;   &lt;tbody&gt;&lt;tr style="height: 134.5pt;"&gt;   &lt;td style="border: 0.5pt solid windowtext; padding: 0in 5.4pt; width: 6in; height: 134.5pt;" valign="top" width="576"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;import   java.util.List;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;public   class ThreadCallB extends Thread&lt;span style=""&gt;  &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;public void run() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;            &lt;/span&gt;Methods m =   MethodsFactory.getMethodsInstance();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;            &lt;/span&gt;m.b();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;}&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Now here is the main Test class.&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;table style="border: medium none ; background: silver none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-left: 5.4pt; border-collapse: collapse; color: rgb(0, 0, 153);" bg="" border="1" cellpadding="0" cellspacing="0"&gt;   &lt;tbody&gt;&lt;tr style="height: 134.5pt;"&gt;   &lt;td style="border: 0.5pt solid windowtext; padding: 0in 5.4pt; width: 6in; height: 134.5pt;" valign="top" width="576"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;public   class Threadtest {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;public static void main(String[] args) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;            &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;            &lt;/span&gt;Thread TA = new ThreadCallA();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;            &lt;/span&gt;TA.setName("TA");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;            &lt;/span&gt;TA.start(); &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;            &lt;/span&gt;Thread TB =&lt;span style=""&gt;  &lt;/span&gt;new ThreadCallB();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;            &lt;/span&gt;TB.setName("TB");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;            &lt;/span&gt;TB.start();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;            &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;&lt;span style=""&gt;      &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style=""&gt;}&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;   &lt;p style="color: rgb(0, 0, 153);" class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Here is the result.&lt;/span&gt;&lt;/p&gt;   &lt;table  style="border: medium none ; background: silver none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-left: 5.4pt; border-collapse: collapse; color: rgb(0, 0, 0);" bg="" border="1" cellpadding="0" cellspacing="0"&gt;   &lt;tbody&gt;&lt;tr style="height: 152.5pt;"&gt;   &lt;td style="border: 0.5pt solid windowtext; padding: 0in 5.4pt; width: 6in; height: 152.5pt;" valign="top" width="576"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;a&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;Thread.currentThread()Thread[TA,5,main]&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;a&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;Thread.currentThread()Thread[TA,5,main]&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;a&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;Thread.currentThread()Thread[TA,5,main]&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;a&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;Thread.currentThread()Thread[TA,5,main]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;b&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;Thread.currentThread()Thread[TB,5,main]&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;b&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;Thread.currentThread()Thread[TB,5,main]&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;b&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;Thread.currentThread()Thread[TB,5,main]&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;b&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;Thread.currentThread()Thread[TB,5,main]&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;a&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;Thread.currentThread()Thread[TA,5,main]&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;b&lt;/span&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="background: white none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;Thread.currentThread()Thread[TA,5,main]&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;So even though method a() locks the object another thread can call method b() !.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;This is because b() is not synchronized.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;So what is a lock ? The lock just locks all &lt;/span&gt;&lt;span style="font-size:100%;"&gt;synchronized code in an Object. On the static side any class is an instance of "Class", so the same applies there too.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Now if you synchronize b(), then b() will also be locked when a() is called. &lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;And in our case due to us having “while(true)”, whichever thread gets to one of the methods first will be the only thread executing and the other thread will never get to the other synchronized method. Try it !,&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;span style="font-family:arial;"&gt;Now if you have a static method, that method can still be called when there is a lock due to an instance method&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110353895554650051?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110353895554650051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110353895554650051&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110353895554650051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110353895554650051'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/understanding-what-is-locked-when.html' title='Understanding what is locked when using the synchronized keyword.'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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-9699730.post-110352603438600315</id><published>2004-12-19T22:58:00.000-08:00</published><updated>2005-01-03T02:09:59.176-08:00</updated><title type='text'>Java Tiger and Me !</title><content type='html'>&lt;o:p&gt;&lt;/o:p&gt;I had come to java from a smalltalk background. I found a few things very strange.    &lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;And now I can see that the there are solutions to what I found strange, back in mar-apr of 2000, in the new Java Tiger release.&lt;/p&gt;   &lt;h3&gt;Need to cast classes in and out of collections.&lt;/h3&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;I had posted on the java newsgroup. The heading was &lt;a href="http://groups-beta.google.com/group/comp.lang.java.programmer/browse_frm/thread/1d442ca53ab5dae/4e9512089e83df63?tvc=1&amp;q=suchak&amp;amp;_done=%2Fgroup%2Fcomp.lang.java.programmer%2Fsearch%3Fgroup%3Dcomp.lang.java.programmer%26q%3Dsuchak%26qt_g%3D1%26searchnow%3DSearch+this+group%26&amp;_doneTitle=Back+to+Search&amp;amp;scrollSave=&amp;&amp;amp;d#4e9512089e83df63"&gt;&lt;u&gt;Casting Classes&lt;/u&gt;&lt;/a&gt; . Of course the credit for this goes to smalltalk. It is such a superb language.&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;All that I was saying there is that objects should know who they are when are put in or taken out of collections. &lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;Using Generics for java collections does this very nicely.&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;But of course my complaint and another aspect , that that was that in totality “Objects should know who they are” . But that issue is one of language itself, being type safe or not, and I have learned to live with java being type safe. &lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;   &lt;h3&gt;Need to have to use two different artifacts for the same type of thing&lt;span style="font-size:18;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h3&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;Why should there be an int and an Integer at all. I had posted about this as &lt;a href="http://groups-beta.google.com/group/ibm.software.vajava.language/browse_frm/thread/833fa965202893bb/578760310ac69cd7?tvc=1&amp;q=suchak+java&amp;amp;_done=%2Fgroups%3Fq%3Dsuchak+java%26start%3D20%26&amp;_doneTitle=Back+to+Search&amp;amp;scrollSave=&amp;&amp;amp;d#578760310ac69cd7"&gt;&lt;u&gt;&lt;span style=""&gt;Why the difference between Integer and int ??&lt;/span&gt;&lt;/u&gt;&lt;/a&gt;&lt;span style=""&gt; in the java newsgroups.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;u&gt;&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;   &lt;p class="MsoBodyText"&gt;It still seems so illogical to me. Why have primitives at all in an object oriented language. Again this had come from knowing smalltalk.&lt;span style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;Now we have something called&lt;span style="font-weight: bold;"&gt; &lt;span style="color: rgb(255, 102, 102);"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;autoboxing&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;in both java and C#, which helps with just that.&lt;br /&gt;&lt;/p&gt;&lt;o:p&gt;&lt;/o:p&gt;   &lt;p class="MsoNormal"&gt;A good article for new features in java is at &lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;a href="http://www.javaworld.com/javaworld/jw-04-2004/jw-0426-tiger1.html"&gt;http://www.javaworld.com/javaworld/jw-04-2004/jw-0426-tiger1.html&lt;/a&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;a href="http://www.javaworld.com/javaworld/jw-06-2004/jw-0607-tiger2.html"&gt;http://www.javaworld.com/javaworld/jw-06-2004/jw-0607-tiger2.html&lt;/a&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;   &lt;span style=";font-family:verdana;font-size:100%;"  &gt;I will try and post some performance metrics, which will show whether collections are faster with or without generics.&lt;/span&gt;&lt;span style=""&gt;&lt;a href="http://groups-beta.google.com/group/comp.lang.java.programmer/browse_frm/thread/1d442ca53ab5dae/4e9512089e83df63?tvc=1&amp;q=suchak&amp;amp;_done=%2Fgroup%2Fcomp.lang.java.programmer%2Fsearch%3Fgroup%3Dcomp.lang.java.programmer%26q%3Dsuchak%26qt_g%3D1%26searchnow%3DSearch+this+group%26&amp;_doneTitle=Back+to+Search&amp;amp;scrollSave=&amp;&amp;amp;d#4e9512089e83df63"&gt;&lt;u&gt;&lt;/u&gt;&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9699730-110352603438600315?l=objectissues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://objectissues.blogspot.com/feeds/110352603438600315/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9699730&amp;postID=110352603438600315&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110352603438600315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9699730/posts/default/110352603438600315'/><link rel='alternate' type='text/html' href='http://objectissues.blogspot.com/2004/12/java-tiger-and-me.html' title='Java Tiger and Me !'/><author><name>Suchak Jani</name><uri>http://www.blogger.com/profile/05719835138712160495</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>
