tag:blogger.com,1999:blog-67341682008-04-16T10:30:01.019-07:000xCAFEFEEDThoughts on Java<sup>TM</sup>/J2EE<sup>TM</sup> and related technologiesrsnoreply@blogger.comBlogger16125tag:blogger.com,1999:blog-6734168.post-15764141087733536882008-03-06T04:14:00.000-08:002008-03-08T06:31:16.571-08:00Chasing the cause for performance degradation<i>Spoiler:</i> The last three pictures speak more than the thousand odd words that preceed them
<dl>
<dt>Day before:</dt><dd>Too many issues resizing photos in Java. Takes too much memory, takes too long, runs out of mem on Mac. A quick comparison with <a href="http://www.microsoft.com/windowsxp/using/digitalphotography/learnmore/tips/eschelman2.mspx">ImageResizer PowerToy</a> shows that the Java code is taking too much memory and time. The difference is an order of magnitude higher on V's machine which is slightly older and has lesser memory.</dd>
<dt>Yesterday (and day before):</dt><dd> Implement a photo resize server using <a href="http://msdn2.microsoft.com/en-us/library/ms533798(VS.85).aspx">GDI+</a>. Go to bed happy that mem consumption is low, speed is very good and all kinks in passing around UTF-8 filenames between Java and VC++ have been ironed out.</dd>
<dt>Noon:</dt><dd> J integrates the new resizer into the code base.</dd>
<dt>2pm:</dt><dd> J verifies perf is 4 times better</dd>
<dt>6pm:</dt><dd> Code is checked in ... waiting for integration build</dd>
<dt>8pm:</dt><dd> Leave for home</dd>
<dt>10pm:</dt><dd> Receive an e-mail, integration build ready .. start downloading with the hope of gloating in the perf gains</dd>
<dt>10.30pm:</dt><dd> Installation started ... baby crying ... unplug the laptop move closer to baby ... play with the baby and complete the installation ... start the test case in background</dd>
<dt>10.35pm:</dt><dd> No sign of test completing ... should have finished 2mins ago</dd>
<dt>10.40pm:</dt><dd> Suspect some ``first time'' bug, run the test case again ... </dd>
<dt>10.46pm:</dt><dd> No luck ... still pathetic perf ... does not match what I saw in the morning</dd>
<dt>10.50pm:</dt><dd> Pissed ... shoot of a mail to J ... "dood, did you checkin the integration ... i see no diff in perf ... </dd>
<dt>10.55pm:</dt><dd> No reply ... shall I wait till morn ... </dd>
<dt>11:00pm:</dt><dd> Let me try to recreate morning's perf numbers ... run the main method on java wrapper for the resizer ... the same run which took 2mins in the morning is taking 6mins ... as bad as the java resizer ...damn ..</dd>
<dt>11:10pm:</dt><dd> WTF?!!</dd>
<dt>11:11pm:</dt><dd> Maybe I messed up the java wrapper ... run the main method on exe resizer ... </dd>
<dt>11:18pm:</dt><dd> Just as bad ... three times slower than what it was in the morn ...</dd>
<dt>11:20pm to 12:05am:</dt><dd> Make many runs trying to change some code in the exe ... nothing seems to improve perf</dd>
<dt>12:05am:</dt><dd> Low battery alert ... curse the laptop ... can't run even a few hrs without power</dd>
<dt>12:07am:</dt><dd> Make some more changes to c++ code ... build ... run ...</dd>
<dt>12:09am:</dt><dd> By Joe! Done in 2mins instead of 6!... damn thing ... why is this small change causing the whole thing to be 3 times slower ... do some googling ...</dd>
<dt>12:10am:</dt><dd> Undo the changes ... recompile and run ... see if it becomes slow again ...</dd>
<dt>12:09am:</dt><dd> Thighs are burning ... prop up the laptop</dd>
<dt>12:12am:</dt><dd> Hain?! Done in 2mins ... WTF ... it was taking 6mins just a few mins ago ...</dd>
<dt>12:15am:</dt><dd> Rollback all the changes ... recompile ... run ... </dd>
<dt>12:17am:</dt><dd> Done in two mins ... WTF ... How can this be ... Check the logs for the timining ... it was taking 6mins till a few mins ago ... and the whole thing is back to 2mins now ... no changes done ... desperate to blame it on something ... maybe anti virus was running earlier (should I check the anti virus logs?)... maybe the windows kernel has cached the files now (should I restart the laptop and see?) ... maybe it became slow when i was running on battery ...</dd>
<dt>12:18am:</dt><dd> Is that really possible ... will my CPU run slow if it is running out of power ...</dd>
<dt>12:18am:</dt><dd> Or will it be slow if it is running on battery ... to save power</dd>
<dt>12:19am:</dt><dd> Hain ... what a joke ... laptop can't be so smart ... it was just a coincidence ... I plugged in the power and it became faster ...</dd>
<dt>12:19am:</dt><dd> There are no coincidences in this business ... unplug the power ... run the test ... </dd>
<dt>12:22am:</dt><dd> No sign of ending it really is slow </dd>
<dt>12:25am:</dt><dd> Back to 6mins for the test</dd>
<dt>12:25am:</dt>
<dd> ... can't be ... really i mean ... can the laptop be so smart ... what was that thing that showed clock speed ... cpu-z ... google: cpu-z ... download ... run ... wow! It is true ... clock speed has been reduced to 598MHz instead of 1.6GHz
<br><img src="http://www.me.umn.edu/%7Eshivane/blogs/cafefeed/resources/06-mar-2008/no-power.png">
</dd>
<dt>12:25am:</dt>
<dd> OK ... now connect the power and see ... there goes my theory ... still 598MHz
<br><img src="http://www.me.umn.edu/%7Eshivane/blogs/cafefeed/resources/06-mar-2008/powered-but-idle-CPU.png">
</dd>
<dt>12:25am:</dt><dd> Hmmm ... maybe it realized though it is powered, I am not running any CPU intensive task .... could it really really that smart ... nyaaah ...</dd>
<dt>12:26am:</dt>
<dd> Start the test with power still connected ... run cpu-z ... whoa! 1.6GHz ...
<br><img src="http://www.me.umn.edu/%7Eshivane/blogs/cafefeed/resources/06-mar-2008/powered-full-steam.png">
</dd>
</dl>
<br>
<br>More googling reveals, this is Intel SpeedStep<sup>TM</sup> technology at work. It can be enabled/disabled from BIOS. A <a href="http://www.bay-wolf.com/speedstep.htm#1">quick intro</a> at Bay Wolf. <a href="http://www.intel.com/design/intarch/papers/301174.htm">Implementation details</a> at Intel.
<br>
<br>I wish I had not stopped playing games after moving to the laptop ... I suppose the newer games detect that my CPU is running below its peak capabilities and warn me to power up ... and if I had seen such a message even once in my life, it would have saved me so much time and heart-ache!
<br>
<br>Anyways ... I bow to the Gods, who implemented all this smart stuff, which I had though they would not bother to implement ...
<br><img src="http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons7/77.gif" />rsnoreply@blogger.comtag:blogger.com,1999:blog-6734168.post-35213284940787062362007-07-06T13:59:00.000-07:002008-04-11T22:30:56.661-07:00Neal Gafter's proposal for constructor type inference<p>Neal gafter has proposed that java language include <a href="http://gafter.blogspot.com/2007/07/constructor-type-inference.html">Constructor Type Inference</a> in order to reduce verbosity. So what was </p>
<pre class="jsccJAVA">
Map<String,List<Thing>> map = new HashMap<String,List<Thing>>();
</pre>
<p>looks like:</p>
<pre class="jsccJAVA">
Map<String,List<Thing>> map = new HashMap<>();
</pre>
<p>Though there is an alternate proposal to deduce the LHS type instead, like:</p>
<pre class="jsccJAVA">
map := new HashMap<String,List<Thing>>();
</pre>
<p>I find Neal's proposal more appealing and more natural to java. It feels so Java, that I have already used it thrice since morning only to be surprised by IDEA's warnings! So, if anyone is counting votes, +1 from me.</p>rsnoreply@blogger.comtag:blogger.com,1999:blog-6734168.post-89297698189257095042007-06-14T08:30:00.000-07:002007-06-14T04:03:36.511-07:00Why do catch clauses need to be ordered?<p>Looking at question #15 on JDJs <a href="http://java.sys-con.com/read/48839.htm">Secrets Of The Masters: Core Java Job Interview Questions</a> (Secrets of the masters???!! Whhoaaah!!), I was reminded of the question Vinod once asked me: "Why do catch clauses have to be ordered?"</p>
<p>It is generally known that, in Java, the order of the catch clauses is important. The more specific exceptions have to be handled first followed by the less specific exceptions. So, the following snippet of code causes a compilation error, as FileNotFoundException is more specific than IOException (FileNotFoundException extends IOException).</p>
<pre class="jsccJAVA">
try{
//Some File I/O operations here
}catch(IOException e){
//handle the I/O error
}catch(FileNotFoundException fnfe){
//handle the case when the file is not found
}
</pre>
<p>To fix it, you need to change the order in which the exceptions are handled by moving the more specific exception (FileNotFoundException) before the less specific exception (IOException), like so:</p>
<pre class="jsccJAVA">
try{
//Some File I/O operations here
}catch(FileNotFoundException fnfe){
//handle the case when the file is not found
}catch(IOException e){
//handle the I/O error
}
</pre>
<p>This change is so straight forward that, any smart IDE can do it for you</p>
<img src="http://www.me.umn.edu/~shivane/blogs/cafefeed/resources/14-jun-2007/ide-suggestions.png" alt="Screenshot of IntelliJ IDEA's suggestion to move catch clauses around"/>
<p>So Vinod's question really was: Why didn't the designers of the Java language make the compiler smart enough to sort the catch clauses automatically (instead of pushing the burden on to the IDEs/developers)?. To quote him verbatim (including the typos) from my messenger archive: ".. i mean you are asking the programmer to think like compiler than compiler think like a programmer ... from a programmer perspective... i want to catch FNFE if the exception is of that type other wise cathc IO". Interesting point .. I never thought of it before.</p>
<p>Spoiler: I don't know the answer, what follows are my thoughts or possibly my <a href="http://en.wikipedia.org/wiki/Stream_of_consciousness_writing">stream of consciousness</a>, like my article on <a href="http://www.me.umn.edu/~shivane/blogs/cafefeed/2005/09/why-is-finalize-method-protected.html">Why is finalize method protected?</a>.
<p>Having found no clues in <a href="http://java.sun.com/docs/books/jls/">The Java language specification</a> I thought the answer probably lies in the history of Java. <a href="https://duke.dev.java.net/green/">A Brief History of the Green Project</a> is a good place to start. This page gives history of Java (it was originally called Oak) and has a copy of the <a href="https://duke.dev.java.net/green/OakSpec0.2.ps">version 0.2 of the Oak language specification</a> [<a href="http://www.me.umn.edu/~shivane/blogs/cafefeed/resources/14-jun-2007/OakSpec0.2.zip">PDF</a>]. The spec gives an interesting perspective on how the Java language evolved.</p>
<h3>Side tracking: Interesting tidbits from the Oak specification</h3>
<p><ul>
<li><code>Throwable</code> was earlier called <code>GenericException</code></li>
<li>Asynchronous Exceptions: one thread can throw an exception (using Thread’s postException() instance method) to another thread</li>
<li>The protect/unprotect keywords</li>
<li>You could use <code>//* javadoc here</code> notation to write java docs apart from <code>/** javadoc here</code></li>
<li><code>print</code> and <code>println</code> were operators. <code>System.out<code> was possibly a refactoring</li>
<li>Interfaces declared constants using <code>const</code> instead of <code>public static final</code>. Like <code> const int aConstant = 42;</code></li>
<li>Supported assertions, preconditions and postconditions</li>
<li>Has no details on threads, serialization nor does it have a BNF</li>
</ul></p>
<h3>Side tracking again: Catching multiple exceptions in one catch clause</h3>
<p>Many a times people ask me: "Why can't I catch multiple exceptions in one catch clause, I generally end up pasting same error recovery code in all the catch clauses. Why isn't a catch clause <em>like a method signature</em>, where I can have a comma separated list of all the exceptions to be handled?" What they want is some thing like this:
</p>
<pre class="jsccJAVA">
try{
//Some File I/O operations here
}catch(FileNotFoundException fnfe, IOException e){
//common error handling
}
</pre>
<p>The question itself seems to have the answer. If all the exceptions were listed like method parameters, the above snippet of code would mean "Do the common error handling if BOTH FileNotFoundException and IOException are raised" instead of "Do the common error handling if EITHER FileNotFoundException or IOException is raised". The solution probably would be to use the OR operator "||" instead of commas? Some thing like:</p>
<pre class="jsccJAVA">
try{
//Some File I/O operations here
}catch(FileNotFoundException||IOException||MyNewException e){
//common error handling
}
</pre>
<p>Incidentally, the Oak specification also compares catch clauses to method definitions. From section 9.4:</p>
<q>A catch clause is like a method definition with exactly one parameter and no return type. When an exception occurs, the runtime system searches the nested try/catch clauses. *snip*</q>
<p>If you have two overloaded methods called handle, of which one takes <code>FileNotFoundException</code> as a parameter and the other takes <code>IOException</code> as a parameter, java always knows which method to call. It automatically calls the most specific method based on the runtime type of the object.</p>
<pre class="jsccJAVA">
private void handle(FileNotFoundException fnfe){
}
private void handle(IOException e){
}
</pre>
<p>Now, as suggested by the spec, each catch clause can be treated as an overloaded method which takes a subclass of Throwable as a method parameter and no return type. Now extending the method overloading analogy shouldn't java be able to detect which catch clause to invoke? Unfortunately, the complete paragraph from section 9.4 reads:</p>
<q>A catch clause is like a method definition with exactly one parameter and no return type. When an exception occurs, the runtime system searches the nested try/catch clauses. <b>The first one with a parameter type that is the same class or a superclass of the thrown object has its catch clause executed.</b> After the catch clause executes, execution resumes after the try/catch statement. It is not possible for an exception handler to resume execution at the point that the exception occurred.</q>
<p>The question now is, instead of continuing the method definition analogy and supporting overloading semantics to the catch clauses, why does the spec say the first catch clause will be chosen?</p>
<p>One possible reason could be for ease of compiler development. This seems to be an unlikely motivation.</p>
<p>Other possible reason could be for code clarity. What if the java developers start to expect that all the exception handlers that match are invoked? The problem exists with or without auto-sorting of catch clauses. A switch like construct would have been more appropriate then:</p>
<pre class="jsccJAVA">
try{
//Some File I/O operations here
}catch(Throwable t){
switchOnClass(t){ //using a hypothetical keyword switchOnClass
case FileNotFoundException:
//handle file not found error
break;
case FileNotFoundException:
case MyNewException:
//some processing for both FileNotFoundException and MyNewException
break;
}
}
</pre>
<p>Or the other possible reason is because Java's exception handling was based on C++'s (as mentioned in the foot notes of the Oak spec page 26). C++ allows multiple inheritance. So my class <code>MusicStreamingException</code> could extend both <code>MusicPlayerException</code> and <code>IOException</code>. Now assume the compiler see's this piece of code:</p>
<pre class="jsccJAVA">
try{
if(someCheckHere())
throw new MusicStreamingException();
}catch(IOException e){
}catch(MusicPlayerException e){
}
</pre>
<p>Both the catch clauses match equally and the compiler has no way of determining which one to invoke. Hence the best policy would be to choose the first catch clause. However, this would never happen in Java as it does not allow multiple inheritance, else the same problem would exist in overloaded methods. Is it possible that this requirement in the spec is only a legacy from C++? And can it be done away with without impacting the existing code?</p>rsnoreply@blogger.comtag:blogger.com,1999:blog-6734168.post-1168854543114726012007-01-15T01:43:00.000-08:002007-01-15T18:34:02.173-08:00Backward compatibility of specified, under-specified and un-specified features/API<p>Backward compatibility is a challenge for everyone from the guy writing the kernel to guy building the application. </p>
<p><a href="http://blogs.msdn.com/oldnewthing/">Raymond Chen</a> has written a lot of anecdotes on compatibility issues in windows. (See <a href="http://www.microsoft.com/technet/technetmag/issues/2006/10/WindowsConfidential/">Compatibility Constraints</a> and <a href=http://www.microsoft.com/technet/technetmag/issues/2006/11/WindowsConfidential/>Handling Compatibility Hacks</a>.) He has also authored a book with the same title as that of his blog: <a href="http://blogs.msdn.com/oldnewthing/archive/2006/12/25/1361289.aspx">The old new thing</a>, which I am sure will have even more interesting tidbits.</p>
<p>Even application developers have to worry about the API they expose and its backward compatibility. The fine people at <a href="http://viewvc.tigris.org/">viewvc</a> believed the URL scheme used by viewvc is part of their "API" and had a <a href="http://viewvc.tigris.org/servlets/ReadMsg?list=dev&msgNo=2522">thorough discussion</a> on what changes could be made to the URL scheme before and after the 1.0 release! </p>
<p>Being in the middle tier, we seem to face more than our fair share of compatibility issues. First, the product is based on the specifications which are written in English. Each vendor is free to interpret it the way they want. Eventually this leads to customer queries like: "But this works in [plug the customer's current vendor name here]!" This results in new flags in the product configuration files. Over the years we have brought up such ambiguities in the expert groups and the newer versions of the specs clarify the interpretation.</p>
<p>The other category of issues arise from ensuring compatibility with the innumerable combinations of databases, drivers, operating systems and JVMs. JV talks about <a href="http://jroller.com/trackback/jvenu/Weblog/socket_not_connected">an issue we recently faced</a> wherein upgrading the VM from 1.4.2_10 to 1.4.2_11 breaks our product. JDK 1.4 introduced a new feature of disconnected sockets. The new implementation was supposed to be backward compatible. However, the implementation had a bug (<a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=2126509">2126509 </a>). In the process of fixing this bug in 1.4.2_11, (I believe) they introduced a new bug which breaks backward compatibility.</p>
<p>Such explicit problems are easier to manage than the unwritten contracts. While debugging I rely heavily on the exceptions raised. For example when you cast an object to a type, if there is a ClassCastException, the message generally has the class name of the object. So, in your code, if you are casting to java.util.List and the exception message is java.util.String, you know you are casting a String to a List. Also if you are casting to foo.bar.Klass and the message name is also foo.bar.Klass, then it is a class loading issue. The object you have loaded is of the same class but loaded from a different classloader. Looking at the exception message I could figure out whether it was a genuinely wrong cast or a ClassLoader issue. Unfortunately in JDK 1.4 ClassCastExceptions do not have a message. For a developer this is an annoyance, but is it worth logging a bug?</p>
<p>Here is a sample output with different jdks:
<pre class="cmd">
D:\code\41>java -cp PS30\tp\classes ClassCastTest
1.5.0_06
java.lang.ClassCastException: java.lang.String
at ClassCastTest.main(ClassCastTest.java:25)
D:\code\41>java -cp PS30\tp\classes ClassCastTest
1.4.2_10
java.lang.ClassCastException
at ClassCastTest.main(ClassCastTest.java:25)
D:\code\41>java -cp PS30\tp\classes ClassCastTest
1.3.1_16
java.lang.ClassCastException: java.lang.String
at ClassCastTest.main(ClassCastTest.java:25)
</pre>
Would you write unit tests for the output messages?</p>rsnoreply@blogger.comtag:blogger.com,1999:blog-6734168.post-1168594930801114252007-01-12T01:30:00.000-08:002007-01-12T01:43:26.400-08:00Enum and other Java 5 tricks ...Deepak has finally started blogging at <a href="http://deepjava.wordpress.com/">Deep into Java</a>. He has been sharing some neat tricks like <a href="http://deepjava.wordpress.com/2006/12/08/bootstrapping-static-fields-within-enums/trackback/">Bootstrapping static fields within enums</a>.
Thanks for the tips buddy ... look forward to more of them.rsnoreply@blogger.comtag:blogger.com,1999:blog-6734168.post-1158217560081502732006-09-14T09:01:00.000-07:002006-09-14T00:18:16.380-07:00Got Phished :(<p>I booted my laptop early this morning to get my daily
dose of Google alerts. Navigating through the alerts I ended up at: <a href="http://momb.socio-kybernetics.net/">The Museum of
Modern Betas</a> and browsing through its entries I chanced upon
Google's firefox
extension for detecting phishing:
<a href="http://momb.socio-kybernetics.net/beta/google-safe-browsing-for-firefox">Safe
Browsing</a>. While I was going through their site,
I noticed the yahoo
notification window show "Deeps is now online" and I was thinking to
myself "What is this guy doing online so early in the morn?" (And may I
ask what are YOU doing online?!) Installing Google SafeBrowsing seems
to be fraught with its own problems. The SafeBrowsing home page says
that it can be installed as part of google toolbar only. Antitrust I
say! Some sites say the download is available only in US. Further
googling revealed the URL: <a href="http://dl.google.com/firefox/google-safebrowsing.xpi">http://dl.google.com/firefox/google-safebrowsing.xpi</a></p>
<p>While I
was installing the plugin (firefox waits for a couple of seconds before
enabling the install button ... i wonder why?!), I see a message from
deeps:
</p>
<q>Deeps: http://www.geocities.com/junebug585 <img src="http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons7/1.gif" alt=":)"></q>
<p>...and he logs out. I promptly clicked on the link which
showed
the page:</p>
<a href="http://www.me.umn.edu/%7Eshivane/blogs/cafefeed/resources/14-sept-2006/phishing-orig.png">
<img src="http://www.me.umn.edu/%7Eshivane/blogs/cafefeed/resources/14-sept-2006/phishing-small.png" alt="Click to enlarge"></a>
<p>"Hmmm ... password" I say. I ping deeps ..."Dood ... it's
asking for password". No response. Being a stickler for online security
(ask my wife on how i nag her into setting a different password for
each site and make sure she does not note down her passwords anywhere!)
I
think to myself... "Hey! This could be a phishing site!" (what with me
looking
at Google SafeBrowsing site just a few mins ago). "Very well", I tell
myself, "... the
url is Yahoo! Geocities, the logos and the layout looks ok ... Why
would deep try to phish my yahoo account details ... what the
hell .. let's try to login". Key in the user id pass nothing happens.
Back to Yahoo home page.
"D'oh! Have I been phished?!" with this nagging doubt go have a shower
... come back... notice deeps has replied to my message:</p>
<q>Deeps: what login?
<br>
Deeps: did u a get any message from me?
<br>
Deeps: i did not send it..
</q>
<p>"Oh God! I have been phished!! Change the password quickly."
Chirpy wifey: "Breakfast time!" "Oh God! Imagine after all my
taunts ... I've been phished ... how am I going to tell her this?! Have
I really been phished?!" So I decide to go back to the site and verify.
<a href="http://livehttpheaders.mozdev.org/">LiveHTTPHeaders</a>
shows:</p>
<pre>http://www2.fiberbit.net/form/mailto.cgi<br>POST /form/mailto.cgi HTTP/1.1<br>Host: www2.fiberbit.net<br>User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.6) Gecko/20060728 Firefox/1.5.0.6<br>Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5<br>Accept-Language: en-us,en;q=0.5<br>Accept-Encoding: gzip,deflate<br>Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7<br>Keep-Alive: 300<br>Connection: keep-alive<br>Referer: http://www.geocities.com/junebug585/?200614<br>Content-Type: application/x-www-form-urlencoded<br>Content-Length: 138<br><b>Mail_From=GOD&Mail_To=jawsy1%40gmail.com&Mail_Subject=Gift&Next_Page=http%3A%2F%2Fwww.yahoo.com<br>&.pd=fpctx_ver%253d0&<span style="color: rgb(255, 0, 0);">login=asdf&passwd=asdf</span></b><br><br>HTTP/1.x 302 Moved Temporarily<br>Date: Thu, 14 Sep 2006 04:01:30 GMT<br>Server: Apache/1.3.26 (Unix) mod_perl/1.26<br>Location: http://www.yahoo.com<br>Content-Type: text/html; charset=iso-8859-1<br>X-Cache: MISS from downloads.pramati.com<br>X-Cache-Lookup: MISS from downloads.pramati.com:3128<br>Connection: close<br></pre>
<p>"Oh no! I really have been phished! <b>Bugger has
mailed my yahoo password to himself!!</b> Change the password ...
change the password ... change the password!". Wifey, annoyed after
waiting for me at the b'fast table:
"Wot'chu doin buster?!" ... where do I hide my face now?!</p>
<p>The phisher is not Deeps... some one phished his id and sent
me the message. Maybe it is not even junebug585 whose geocities site
was used to phish for my account details ... maybe that id was also
phished and misused. Maybe it is not even jawsy1@gmail.com where my
userid/pass have been mailed ... maybe that id/pass also have been
phished?! I wonder who all will receive a message from my id now and be
phished!</p>
<p>Imagine the coincidence, I am finicky abt internet security, I
was just checking out Google's SafeBrowsing and I got phished! "I took
a
chance typing my yahoo id, surely I wouldn't have taken a chance
if the site asked for my bank account-nos/user-ids" I rationalize.
But still ... what if the phisher downloaded all my password reminder
mails from my yahoo mailbox??!!</p>
<p>All the best dad!</p>
<p> ... now the painful part of reporting abuse to yahoo and gmail
... </p>
<hr>
<p><b>Update:</b> Looks like I am not the first! ... and looks like google pages are also being used for phishing. <a href="http://www.google.com/search?q=yahoo+geocities+phishing">Google: yahoo geocities phishing</a></p>
<hr>
<p><b>Update 1:</b> Yahoo!'s soln for phishing?! (via deeps):
<br>
<br>---------- Forwarded message ----------
<br>From: Kalyan K Kumar
<br>Date: Sep 14, 2006 11:04 AM
<br>Subject: phishing
<br>To: sammelan
<br>
<br>keep an eye on those yahoo login look alike geocities links. don't enter
<br>yahoo password anywhere
<br>other than login.yahoo.com
<br>you can setup a sign in seal to protect partly.
<br>
<br><a href="http://protect.login.yahoo.com/">http://protect.login.yahoo.com/</a>
</p>rsnoreply@blogger.comtag:blogger.com,1999:blog-6734168.post-1127416103501729202005-09-22T11:30:00.000-07:002007-03-16T23:55:57.220-07:00Why is finalize method protected?<p>Rakesh sent me a mail the other day asking why the <code>finalize</code> method is <code>protected</code>.
Well, here's what I think:</p>
<p>The <code>finalize</code> method is invoked by the JVM/GarbageCollector on Objects which
are no longer referenced. So, if I were the guy who designed the <code>finalize</code> method, ideally I
would want it to be <code>private</code>. Just like why the writeObject method of the Serializable interface is
private. These methods are not meant to be called by other user objects,
these methods are invoked only by the JVM runtime classes only. So it would make
sense to make them private, and have special handling in the VM to invoke these
methods. This is ok in case of the writeObject method, however, making <code>finalize</code> method <code>private</code>
would have other implications. </p>
<p>Assume we had decided to go ahead and allow the <code>finalize</code> method to be private. Consider the following classes</p>
<pre class="jsccJAVA">public class SuperClass
{
private HeavyResource resource = new HeavyResource();
private void finalize()
throws Throwable
{
resource.shutdown();
}
}
public class SubClass
extends SuperClass
{
private AnotherResource another = new AnotherResource();
public SubClass(){
super(); //Added for clarity
}
private void finalize()
throws Throwable
{
another.shutdown();
}
}
</pre>
<p>Since SubClass extends the SuperClass, when we create an instance of SubClass,
we would also have created an instance of HeavyResource and an instance of
AnotherResource. However, when this instance of SubClass is being finalized, we
shutdown only the instance of AnotherResource. The shutdown method of
HeavyResource would not be called. </p>
<p>The recommended practice for <code>finalize</code> methods is that in the <code>finally</code> block of
the <code>finalize</code> method one should call the <code>finalize</code> method of the super class.
(That's right, in the constructor the first statement has to be the call to
super so for destructor/finalize the sequence should be reversed and super
should be called last). So
our SubClass would look something like: </p>
<pre class="jsccJAVA">public class SubClass
extends SuperClass
{
private AnotherResource another = new AnotherResource();
public SubClass(){
super(); //Added for clarity
}
private void finalize()
throws Throwable
{
try{
another.shutdown();
}finally{
super.finalize();//Compilation error here
}
}
}</pre>
<p>This would have worked, but unfortunately this won't even compile. You can
not call the private method of the super class. There are couple of ways I can
think of to solve this problem.</p>
<p>One solution of-course would be to relax our requirements and make the access modifier
of the <code>finalize</code> method protected and hope people are sensible enough not to call
it! </p>
<p>Another solution could be to allow calls to <code>super.finalize()</code>, even if the <code>finalize</code> method of
the super class has private access modifier, in the Java Language Specification
(JLS). </p>
<p>My preferred solution would be to have compilers automatically
add a try finally block and insert a call to <code>super.finalize()</code> method in the finally
block. (Modifying byte code to add a try finally block is a nightmare (as compared to adding a call to <code>super()</code>), but that's a separate discussion!)
This would be similar and consistent with the way compilers add the call to <code>super()</code> as the
first statement of a constructor if it does not already exist. (You can use
<code>javap -c ClassName</code> to look at the byte code generated by the compiler, but I
prefer to use <a href="http://http://www.ej-technologies.com/products/jclasslib/overview.html">JClasslib</a>.)</p>
<p>The <a href="http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.6">Java
language specification, (3rd ed, Section 12.6)</a> does mention that the call to <code>super.finalize</code> is not
injected automatically and provides a hint as to why:</p>
<blockquote><p>
The fact that class <code>Object</code> declares a <code>finalize</code>
method means that the <code>finalize</code> method for any class can always invoke the <code>finalize</code>
method for its superclass. This should always be done, unless it is the
programmer's intent to nullify the actions of the finalizer in the
superclass. (Unlike constructors, finalizers do not automatically
invoke the finalizer for the superclass; such an invocation must be
coded explicitly.)</p>
</blockquote>
<p>It appears this was done ``So that the programmer can nullify the actions of the finalizer in the
superclass.'' But thanks to this choice, developers today use
tools like <a href="http://pmd.sourceforge.net/rules/finalizers.html">PMD</a> which warn them about empty <code>finalize</code> methods and when the <code>finalize</code> does not call the same method of the super class.</p>
<p><b>Update (16 Jan 2007):</b> It appears that the designers of C# learnt from Java's mistakes and decided to make constructor and destructor symmetric. In C#, the destructor of the super-class is called whether the destructor of the sub-class was successfuly completed or not. From "Section 16.3: How exceptions are handled" of the <a href="http://download.microsoft.com/download/5/e/5/5e58be0a-b02b-41ac-a4a3-7a22286214ff/csharp%20language%20specification%20v1.2.doc">C# language specification 1.2</a>:</p>
<blockquote><p>
Exceptions that occur during destructor execution are worth special mention. If an exception occurs during destructor execution, and that exception is not caught, then the execution of that destructor is terminated and the destructor of the base class (if any) is called. If there is no base class (as in the case of the object type) or if there is no base class destructor, then the exception is discarded.</p></blockquote>rsnoreply@blogger.comtag:blogger.com,1999:blog-6734168.post-1098733591484791482004-10-25T12:34:00.000-07:002004-10-25T13:37:35.413-07:00Colorizing Java sources in a browser using JavaScript and CSS<h3>[or JavaScript chorma-coding]</h3>
<p>While posting Java sources on this blog, I used to wish that the browsers could
take care of chroma-coding Java sources just the way they take care of chroma-coding
XML files. It would eliminate the hassle of exporting the sources in HTML
format. All one would have to do is paste the Java source in a <code>pre</code> block and
viola! you are done with it!</p>
<img src="http://www.me.umn.edu/~shivane/blogs/cafefeed/resources/26-oct-2004/pramati-j2ee-server.png" title="Screenshot of an XML file opened in IE. IE chroma-codes the XML file and creates a live tree structure of the XML using +/- toggle buttons"/>
<p>Inspired by the "live" pages on <a href="http://www.blogger.com">Blogger</a>, <a href="http://www.feedburner.com">Feed Burner</a> and <a href="http://gmail.google.com">GMail</a>, I decided to
experiment and see if JavaScript and CSS could be used to achieve this. After
couple of hours of struggling and about 200 lines of re-factored code, I managed to
get it to work! </p>
<p>Below is the HTML colorized version of <code>ClassParser.java</code> from
the BCEL sources. Check out the curly braces ... they are live! Clicking
on them will show or hide the enclosed block! Now for the surprise ... if you
look at the HTML source for the above part, you will see only plain java source.
All the colorization and parenthesis matching has been done in <code>jscc.js</code>, <code>jsccJAVA.js</code> and <code>jscc.css</code>
referred to in the head of the HTML file. Pretty neat huh?! </p>
<pre class="jsccJAVA">
package org.apache.bcel.classfile;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache BCEL" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache BCEL", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>;.
*/
import org.apache.bcel.Constants;
import java.io.*;
import java.util.zip.*;
/***
* Wrapper class that parses a given Java .class file. The method
* <A href ="#parse">parse</A> returns a <A href ="JavaClass.html">
* JavaClass</A> object on success. When an I/O error or an
* inconsistency occurs an appropiate exception is propagated back to
* the caller.
*
* The structure and the names comply, except for a few conveniences,
* exactly with the <A href="ftp://java.sun.com/docs/specs/vmspec.ps">
* JVM specification 1.0</a>. See this paper for
* further details about the structure of a bytecode file.
*
* @version $Id: ClassParser.java,v 1.5 2002/08/09 13:09:31 mdahm Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*/
public final class ClassParser {
private DataInputStream file;
private ZipFile zip;
private String file_name;
private int class_name_index, superclass_name_index;
private int major, minor; // Compiler version
private int access_flags; // Access rights of parsed class
private int[] interfaces; // Names of implemented interfaces
private ConstantPool constant_pool; // collection of constants
private Field[] fields; // class fields, i.e., its variables
private Method[] methods; // methods defined in the class
private Attribute[] attributes; // attributes defined in the class
private boolean is_zip; // Loaded from zip file
private static final int BUFSIZE = 8192;
/***
* Parse class from the given stream.
*
* @param file Input stream
* @param file_name File name
*/
public ClassParser(InputStream file, String file_name) {
this.file_name = file_name;
String clazz = file.getClass().getName(); // Not a very clean solution ...
is_zip = clazz.startsWith("java.util.zip.") || clazz.startsWith("java.util.jar.");
if(file instanceof DataInputStream) // Is already a data stream
this.file = (DataInputStream)file;
else
this.file = new DataInputStream(new BufferedInputStream(file, BUFSIZE));
}
/*** Parse class from given .class file.
*
* @param file_name file name
* @throws IOException
*/
public ClassParser(String file_name) throws IOException
{
is_zip = false;
this.file_name = file_name;
file = new DataInputStream(new BufferedInputStream
(new FileInputStream(file_name), BUFSIZE));
}
/*** Parse class from given .class file in a ZIP-archive
*
* @param file_name file name
* @throws IOException
*/
public ClassParser(String zip_file, String file_name) throws IOException
{
is_zip = true;
zip = new ZipFile(zip_file);
ZipEntry entry = zip.getEntry(file_name);
this.file_name = file_name;
file = new DataInputStream(new BufferedInputStream(zip.getInputStream(entry),
BUFSIZE));
}
/***
* Parse the given Java class file and return an object that represents
* the contained data, i.e., constants, methods, fields and commands.
* A <em>ClassFormatException</em> is raised, if the file is not a valid
* .class file. (This does not include verification of the byte code as it
* is performed by the java interpreter).
*
* @return Class object representing the parsed class file
* @throws IOException
* @throws ClassFormatException
*/
public JavaClass parse() throws IOException, ClassFormatException
{
/******************* Read headers ********************************/
// Check magic tag of class file
readID();
// Get compiler version
readVersion();
/******************* Read constant pool and related **************/
// Read constant pool entries
readConstantPool();
// Get class information
readClassInfo();
// Get interface information, i.e., implemented interfaces
readInterfaces();
/******************* Read class fields and methods ***************/
// Read class fields, i.e., the variables of the class
readFields();
// Read class methods, i.e., the functions in the class
readMethods();
// Read class attributes
readAttributes();
// Check for unknown variables
//Unknown[] u = Unknown.getUnknownAttributes();
//for(int i=0; i < u.length; i++)
// System.err.println("WARNING: " + u[i]);
// Everything should have been read now
// if(file.available() > 0) {
// int bytes = file.available();
// byte[] buf = new byte[bytes];
// file.read(buf);
// if(!(is_zip && (buf.length == 1))) {
// System.err.println("WARNING: Trailing garbage at end of " + file_name);
// System.err.println(bytes + " extra bytes: " + Utility.toHexString(buf));
// }
// }
// Read everything of interest, so close the file
file.close();
if(zip != null)
zip.close();
// Return the information we have gathered in a new object
return new JavaClass(class_name_index, superclass_name_index,
file_name, major, minor, access_flags,
constant_pool, interfaces, fields,
methods, attributes, is_zip? JavaClass.ZIP : JavaClass.FILE);
}
/***
* Read information about the attributes of the class.
* @throws IOException
* @throws ClassFormatException
*/
private final void readAttributes() throws IOException, ClassFormatException
{
int attributes_count;
attributes_count = file.readUnsignedShort();
attributes = new Attribute[attributes_count];
for(int i=0; i < attributes_count; i++)
attributes[i] = Attribute.readAttribute(file, constant_pool);
}
/***
* Read information about the class and its super class.
* @throws IOException
* @throws ClassFormatException
*/
private final void readClassInfo() throws IOException, ClassFormatException
{
access_flags = file.readUnsignedShort();
/* Interfaces are implicitely abstract, the flag should be set
* according to the JVM specification.
*/
if((access_flags & Constants.ACC_INTERFACE) != 0)
access_flags |= Constants.ACC_ABSTRACT;
if(((access_flags & Constants.ACC_ABSTRACT) != 0) &&
((access_flags & Constants.ACC_FINAL) != 0 ))
throw new ClassFormatException("Class can't be both final and abstract");
class_name_index = file.readUnsignedShort();
superclass_name_index = file.readUnsignedShort();
}
/***
* Read constant pool entries.
* @throws IOException
* @throws ClassFormatException
*/
private final void readConstantPool() throws IOException, ClassFormatException
{
constant_pool = new ConstantPool(file);
}
/***
* Read information about the fields of the class, i.e., its variables.
* @throws IOException
* @throws ClassFormatException
*/
private final void readFields() throws IOException, ClassFormatException
{
int fields_count;
fields_count = file.readUnsignedShort();
fields = new Field[fields_count];
for(int i=0; i < fields_count; i++)
fields[i] = new Field(file, constant_pool);
}
/********************* Private utility methods **********************/
/***
* Check whether the header of the file is ok.
* Of course, this has to be the first action on successive file reads.
* @throws IOException
* @throws ClassFormatException
*/
private final void readID() throws IOException, ClassFormatException
{
int magic = 0xCAFEBABE;
if(file.readInt() != magic)
throw new ClassFormatException(file_name + " is not a Java .class file");
}
/***
* Read information about the interfaces implemented by this class.
* @throws IOException
* @throws ClassFormatException
*/
private final void readInterfaces() throws IOException, ClassFormatException
{
int interfaces_count;
interfaces_count = file.readUnsignedShort();
interfaces = new int[interfaces_count];
for(int i=0; i < interfaces_count; i++)
interfaces[i] = file.readUnsignedShort();
}
/***
* Read information about the methods of the class.
* @throws IOException
* @throws ClassFormatException
*/
private final void readMethods() throws IOException, ClassFormatException
{
int methods_count;
methods_count = file.readUnsignedShort();
methods = new Method[methods_count];
for(int i=0; i < methods_count; i++)
methods[i] = new Method(file, constant_pool);
}
/***
* Read major and minor version of compiler which created the file.
* @throws IOException
* @throws ClassFormatException
*/
private final void readVersion() throws IOException, ClassFormatException
{
minor = file.readUnsignedShort();
major = file.readUnsignedShort();
}
}
</pre>
<p>The scripts haven't been written for performance. I just wanted to keep my
effort to the minimum! I have used Regular Expressions extensively. One of the
tricky parts was to identify that <code>"mailto:markus.dahm@berlin.de"</code>
occurring in a comment as part of the comment and not to highlight it as a
String literal and at the same time identify <code>/* hello */</code> occurring
within a string literal as a part of the string literal and not highlight it as
a comment! [Did I say that right?! :)] The solution was quite straight forward though.
Instead of searching first for comments and then for string literals, I had to create
a regular expression which matched both!</p>
<p>One optimization which I haven't figured out how to implement in JavaScript
is to download only jscc.js by default and dowload jsccJAVA.js if ONLY if there is
atleast one pre element with the className as jsccJAVA. Any pointers and suggestions
in this direction are appreciated!</p>
<p>There are quite a few limitations of this implementation. Character literals
with unicode escapes are not supported. IE converts the HTML tags inside javadocs
to upper case. The HTML file is no longer XHTML compliant. Also, I have tested it
only on FireFox[0.8+] and IE [5.5+].</p>
<p>If you want to use the scripts, add the following lines to the
<code><head>...</head></code> part of your html and paste your java code between
<code><pre class="jsccJAVA"></pre></code></p>
<pre><script type="text/javascript" src="http://www.me.umn.edu/~shivane/jscc/jscc.js" />
<script type="text/javascript" src="http://www.me.umn.edu/~shivane/jscc/jsccJAVA.js" />
<link rel="stylesheet" type="text/css" href="http://www.me.umn.edu/~shivane/jscc/jscc.css" /></pre>rsnoreply@blogger.comtag:blogger.com,1999:blog-6734168.post-1090662631255243372004-07-28T01:56:00.000-07:002004-07-28T01:57:16.506-07:00Finding Srinis ...<p>There is significant difference between doing what is asked of you and doing
what is needed. Srini, our system administrator, is one of those who understands
that. It is very interesting to see him go about solving problems users
face. Installing what people want is not the end for him. He goes that extra mile
to make sure the solution suits the end-user the best.</p>
<p>Take the simple case of scanning legal documents. When
someone approached Srini to get a scanner installed, he did just that. Anyone who has tried
scanning documents or any serious number of photographs knows that it is an
extremely slow and manual process. Place the document on the bed of the
scanner, make sure the edges are aligned properly, carefully put the cover
down [to make sure the alignment does not get messed up], start the scan
[and wait forever for it to finish], view the output in the software, crop the
image, save it in the right format and then email it. A complete pain in the
*bleep*,
especially when you have to convert large number of documents. He couldn't bear to see them scan documents at that pathetically slow pace.
So his improvisation?!
You fax your document to a local extension number, which is connected to his
Linux box running the <a href="http://www.hylafax.org/">hylafax server</a>.
The server receives the fax, converts it to appropriate format and emails it
back. No fuss ... no mess ... neat huh?! </p>
<p><img
src="http://www.me.umn.edu/~shivane/blogs/cafefeed/resources/24-jul-2004/hylafax.png"
alt="Schematic diagram of the setup" /></p>
<p>A lot of people do not appreciate the difference between doing what a user wants and
doing what the user needs. Identifying such people in an interview
is a challenge. One of the things I do is to ask people to write some simple programs,
say a program to sort integers or something. If the developer
is interested in solving the user's problem I would expect her to find out more about
the problem before jumping to get to the solution. I would like to hear
questions like: <q>What kind of integers are these?</q>, <q>How many numbers are you
expecting to sort at a time?</q> This way you could eliminate those who do just what they were asked to ....
implement QuickSort.</p>
<p>I wonder what others do to identify such people.</p>rsnoreply@blogger.comtag:blogger.com,1999:blog-6734168.post-1089475862799740692004-07-10T09:09:00.000-07:002004-07-10T21:47:53.586-07:00The joy of separating style from content! <p>I have always had this fascination for CSS. Moving from hard-coding-style-in-HTML-sources
to defining-it-in-CSS is like moving from Procedural Programming to Object Oriented Programming.
Defining style classes gives a very consistent feel to the whole site [assuming you have defined
your style classes properly!] And if you want to change how some of the content looks, all you
need to touch is the CSS file. You no longer have to depend on complex search and
replace regular expressions.</p>
<p>
So, when I wrote the <a href="http://www.pramati.com/index.jsp?id=pro_pst35tools">Export to HTML plug-in</a>
for <a href="http://www.pramati.com/index.jsp?id=pro_pst35">Pramati Studio</a>, I made sure
the exported HTMLs used common CSS files to set colors and fonts. Changing the colors and
fonts in one CSS, changes the appearance of all the sources.</p>
<script type="text/javascript">
<!--
function setActiveStyleSheet(title) {
var i, a, main;
for (i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if (a.getAttribute("rel") &&
a.getAttribute("rel").indexOf("style") != -1 &&
a.getAttribute("title")) {
a.disabled = true;
if(a.getAttribute("title") == title) a.disabled = false;
}
}
}
-->
</script>
<p>
Wanna checkout the layout capabilities of CSS?! How about <a href="#" onclick="setActiveStyleSheet('Default Theme - Menu on Left'); return false;">
moving the main content to the right</a>?! Or how about choosing a more
<a href="#" onclick="setActiveStyleSheet('Tic Tac Blue'); return false;">tacky theme</a>?!
<!--For now let us <a href="#" onclick="setActiveStyleSheet('Default Theme'); return false;">get back to our simple theme!</a>-->
</p>
<p>If you are a firefox user, you can choose an alternate style sheet using it's style sheet switcher.
What's more, firefox will remember your choice the next time you visit this page!</p>
<img src="http://www.me.umn.edu/~shivane/blogs/cafefeed/resources/10-jul-2004/change-css.png" alt="Screenshot of style sheet switcher"/>
<p>And if you are one of the 30% visitors, who are still not using the firefox browser, give it a spin:</p>
<p><a href="http://getfirefox.com/"title="Get Firefox - Web browsing redefined.">
<img src="http://www.mozilla.org/products/firefox/buttons/getfirefox_large2.png" alt="Get Firefox" />
</a>
</p>
<p>Apart from the advantages you get from abstracting style into classes, better accessibility is
another key benefit of using CSS. The other day I was reading this very neat book on accessibility,
called <a href="http://diveintoaccessibility.org/">Dive Into Accessibility</a>. I loved the way
the content is presented in the context of some "real people" and how they benefit from sites using CSS.
In the chapter
<a href="http://diveintoaccessibility.org/day_10_presenting_your_main_content_first.html">
<q>Presenting your main content first</q></a>, Mark points out that screen readers read aloud
the content of the HTML source from top to bottom. However, most sites have the navigation links at the top of
the HTML source followed by the main content. So a screen reader has to read out all the navigation
links before reaching the main content. What a pain! One of the advantages
of using CSS is the ability to control the layout of HTML elements independent of their location
in the HTML source. So, using CSS we could have the main content of the page at the TOP of the
HTML source though it is visually layed out at the center of the page.</p>
<p>It hardly takes any time to read and appreciate the book ... but trust me, it takes a
whole lot longer to implement it and to get it into your blood! ... but then I have made a start!
Check out how this page would look to a <a href="#" onclick="setActiveStyleSheet('none'); return false;">
screen reader or in a text browser</a> [needs to be improved].</p>rsnoreply@blogger.comtag:blogger.com,1999:blog-6734168.post-1089081373375382762004-07-05T19:34:00.000-07:002004-07-10T21:26:46.883-07:00An update to: Memory leaks with non-static ThreadLocals ... <p>Rejeev made some interesting comments on my <a href="http://www.me.umn.edu/~shivane/blogs/cafefeed/2004/06/of-non-static-threadlocals-and-memory.html">previous post</a>
at <a href="http://www.javalobby.com/thread.jspa?forumID=61&threadID=13090">javalobby</a>.
The memory leak we had faced was with JDK 1.3_02. The java bug database has a couple of bugs reported for the same
<a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4414045">
Bug: 4414045</a> and
<a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4455134">
Bug: 4455134</a>. As per <a href="http://java.sun.com/j2se/1.4/fixedbugs/fixedbugs-all.html#Beta2">JDK 1.4 beta release notes</a> they are now fixed.
Looking at JDK 1.4 <code>ThreadLocal</code> sources it appears that they have made the <code>threadLocals</code> Map hold weak
references ... which was as <a href="http://www.me.umn.edu/~shivane/blogs/cafefeed/2004/06/of-non-static-threadlocals-and-memory.html#tl_expectations">per my expectation</a>! </p>
<blockquote>
<p>The <code>ThreadLocal</code> should have taken care of cleaning itself up when no user code is referring to it. The way to achieve this is to make the threadLocals map of the <code>Thread</code> class a <code>WeakHashMap</code>.</p></blockquote>
<p>Second, consider the case where the Object being put in the Map [in this case
a CachedObject] has overridden the <code>equals</code> and <code>hashcode</code> methods.
Say, the <code>hashcode</code> method returns a different hashcode based
on the current fields of the <code>CachedObject</code> class. Now, in the suggested
implementation, this <code>CachedObject</code> is being put in a Map.
What if the <code>hashcode</code> of the object changes
[beacause the value of some field changed], while it is in the Map. We will not be able to
remove the object from the Map. The memory leak will remain.
</p>
<p>When we decided to make the <code>ThreadLocal</code> a static field from non-static field
we changed the value of the <code>ThreadLocal</code> to a <code>Map</code> which holds the instance of
<code>CachedObject</code> vs <code>Context</code>. The assumption was that the
look up's to the Map will be based on the instance of the key. However, making
the Map an instance of a HashMap broke this assumption, as the lookup's are based on the
hashcode of key. We need a Map implementation that does instance-based lookups.
One way to achieve this would be to change the following HashMap methods: </p>
<pre class="code">260 <span class="j_kw">static int</span> hash(Object x) {
261 <span class="j_comm">/* </span>
262 <span class="j_comm">int h = x.hashCode(); </span>
263
264 <span class="j_comm">h += ~(h << 9); </span>
265 <span class="j_comm">h ^= (h >>> 14); </span>
266 <span class="j_comm">h += (h << 4); </span>
267 <span class="j_comm"> h ^= (h >>> 10); </span>
268 <span class="j_comm"> return h; </span>
269 <span class="j_comm">*/ </span>
270 <span class="j_kw">return</span> System.identityHashCode(x);
271 }
272
273 <span class="j_kw">static boolean</span> eq(Object x, Object y) {
274 <span class="j_comm">//return x == y || x.equals(y);</span>
275 <span class="j_kw">return</span> x==y;
276 } </pre>
<p>We change the <code>hash</code> method to return the <code>identityHashCode</code>
of the object. The <code>identityHashCode</code>of an Object is constant. We change the <code>eq</code> method
to do an instance check. However, since these are static methods we cannot override
them and make these changes. So to achieve this we will have to make a copy of the <code>HashMap</code>
and make the changes in it.</p>
<p>Another alternative is to wrap the key being added into the Map. This wrapper would return the <code>identityHashCode</code>
of the key as the hashcode and check instance equals of the keys in its equals.
So we write the InstanceMap and use an InstanceMap in the ThreadLocalMap instead
of a HashMap. </p>
<pre class="code">1 <span class="j_kw">import</span> java.util.HashMap;
2
3 <span class="j_kw">public class</span> InstanceMap
4 <span class="j_kw">extends</span> HashMap
5 {
6 <span class="j_kw">private</span> IdentityWrapper lookup = <span class="j_kw">new</span> IdentityWrapper();
7
8 <span class="j_kw">public</span> Object get(Object key)
9 {
10 lookup.key=key;
11 <span class="j_kw">return super</span>.get(key);
12 }
13
14 <span class="j_kw">public</span> Object put(Object key, Object value)
15 {
16 <span class="j_kw">return super</span>.put(<span class="j_kw">new</span> IdentityWrapper(key), value);
17 }
18
19 <span class="j_kw">public boolean</span> containsKey(Object key)
20 {
21 lookup.key=key;
22 <span class="j_kw">return super</span>.containsKey(lookup);
23 }
24 <span class="j_comm">//other overridden method not listed for brevity ...</span>
25 <span class="j_kw">private static class</span> IdentityWrapper
26 {
27 <span class="j_kw">private</span> Object key;
28
29 <span class="j_kw">public</span> IdentityWrapper()
30 {
31 }
32
33 <span class="j_kw">public</span> IdentityWrapper(Object key)
34 {
35 <span class="j_kw">this</span>.key = key;
36 }
37
38 <span class="j_kw">public int</span> hashCode()
39 {
40 <span class="j_kw">return</span> System.identityHashCode(key);
41 }
42
43 <span class="j_kw">public boolean</span> equals(Object obj)
44 {
45 <span class="j_kw">return</span> (obj <span class="j_kw">instanceof</span> IdentityWrapper)?((IdentityWrapper)obj).key==key:<span class="j_kw">false</span>;
46 }
47 }
48 }</pre>
<p>Since this class is being used only in our ThreadLocalMap, it will never be
accessed by two threads. We have tried to optimize the number of the wrapper
instances created by using a single wrapper [the field called lookup] for all
the lookup methods like <code>get</code> and <code>containsKey</code>. However, every call to the put
method will create a new instance and every remove call will make it GC'able. </p>rsnoreply@blogger.comtag:blogger.com,1999:blog-6734168.post-1088050672757128362004-06-23T20:36:00.000-07:002004-07-04T19:18:48.706-07:00Of non-static ThreadLocals and memory leaks ...<p>My recent experience has made me realize that the <code>ThreadLocal</code> class was never
really designed to be used as a non-static field. However, the implications of
making it non-static are not highlighted <b>enough</b> in JDK API and the many
<code>ThreadLocal</code> tutorials you find on the net. </p>
<p>If you want to know more about <code>ThreadLocals</code> I would recommend reading <a href="http://www-106.ibm.com/developerworks/library/j-threads3.html">Threading
lightly</a> by Brian Goetz. Brian talks about why and how to use ThreadLocals
along with some examples. And if you are a performance buff, you will surely
have an "Aha!" moment when you read the section on the performance
bottleneck with the JDK 1.2 implementation and how it was resolved in JDK1.3. </p>
<p>Coming back to my "Non-static ThreadLocals considered harmful" [<a href="http://www.acm.org/classics/oct95/">pun
intended</a>! ;)], couple of months ago Prasad called: </p>
<ul class="conversation">
<li><span class="who">Prasad</span>: <q>Hey I need to store some information <b>per thread per
object</b> can I do that?</q></li>
<li><span class="who">Me</span>: <q>What?!</q></li>
<li><span class="who">Prasad</span>: <q>See when we used a <code>ThreadLocal</code> for Transaction id,
it was a static singleton across the VM. In my case I need the value of my
<code>ThreadLocal</code> to be per instance of a cached object.</q></li>
<li><span class="who">Me</span>: <q>Yeah, so you can have a non static <code>ThreadLocal</code> field in your cached
object... right?!</q></li>
<li><span class="who">Prasad</span>: <q>Yeah .. that was my question. Would that work?</q></li>
</ul>
<p>What he wanted was something like: </p>
<p><img src="http://www.me.umn.edu/~shivane/blogs/cafefeed/resources/24-jun-2004/tl1.png" alt="Initial reference diagram" /> </p>
<p>So I went about stepping through the code/logic to prove how/why it would
work if you make the <code>ThreadLocal</code> non static. Well he tried the whole thing and it did work.
Only months later did we realize that
there was a memory leak in the application! Running through optimizeIt and
looking for non GC'ed instances we realized that the number of <code>Context</code> objects was
more than the cache size. Likely that there was some one referring the <code>Context</code> even after
the corresponding <code>CachedObject</code> had been removed from the <code>Cache</code>. OptimizeIt's reduced reference graph showed that the <code>ThreadLocals</code> were holding
reference to these <code>Context</code> object instances. Aha! Now there were
multiple places where the <code>CachedObjects</code> were being evicted from the <code>Cache</code>. We had to
set the <code>ThreadLocal</code> to <code>null</code> at all these places. </p>
<p>The simplest option seemed to be to set the thread local to <code>null</code> in the finalize of
the cached object. *buzzer* Well, unfortunately that wouldn't work. The finalize
method would get called in the Finalizer thread of the VM. So it would try to
set the value to <code>null</code> in the Finalizer thread ... but we wanted it to be set to
<code>null</code> in the <code>Thread</code> that accessed it! </p>
<p> So we refactored the code a bit, made sure all evictions happen in one place
and made sure to set(null) on the <code>ThreadLocal</code> of the <code>CachedObject</code> which was
going to be evicted. Unfortunately, that wasn't the end of the story. We still
had OutOfMem issues ... only that it took a little longer now. OptimizeIt's
reduced reference graph showed that the number of <code>CachedObjects</code> was same as the
<code>Cache</code> size now. So our solution did work. The memory leak was due to the number
of ThreadLocals. Logically the number of ThreadLocals has to be same as the
number of <code>CachedObjects</code>. So even after the <code>CachedObject</code> has been GC'ed, some one
was holding a reference to the ThreadLocal. Initially, while stepping through the logic we had stopped
the moment we concluded any thread would find the right value. We never went
further to analyze what happens to all the ThreadLocals we created. We just
assumed that GC would take care of it. [Which I still think was fair enough!] </p>
<p>When we invoke <code>ThreadLocal.set()</code>, the
<code>ThreadLocal</code> would add itself as the key and the <code>Context</code> as the value to the threadLocal map
of the current Thread. [This is in JDK 1.3 and above, the implementation is
slightly different in JDk1.2, but the end result is the same ... there is a
memory leak!] By setting the value of the <code>ThreadLocal</code> to <code>null</code> we have
made the value of the map entry <code>null</code> . This made the <code>Context</code> to be available for garbage collection. However, the threadLocal map of
<code>Thread</code> stills holds a reference to the key, which in our case is the <code>ThreadLocal</code>. We actually need
to remove the <code>ThreadLocal</code> and not just set its value to <code>null</code>. If you are having
trouble following this consider opening <code>ThreadLocal.java</code> and <code>Thread.java</code> from
<code><jdk_1.3++_home>/src.zip</code> and stepping through <code>ThreadLocal.set</code> and
<code>ThreadLocal.get</code> methods. The memory leak
was aggravated in this scenario because the web container reuses threads
across requests and the cache objects keep getting created and garbage
collected. However, the ThreadLocals don't get GC'ed. </p>
<a name="tl_expectations"></a>
<p>Unfortunately, it appears that till JDK1.5 came out, <code>ThreadLocal</code>'s did not
have a proper lifecycle. They were expected to be created as static singletons
or in limited numbers. For a proper life cycle I would have expected: </p>
<ol>
<li>The <code>ThreadLocal</code> should have taken care of cleaning itself up when no user
code is referring to it. The way to achieve this is to make the threadLocals
map of the <code>Thread</code> class a <code>WeakHashMap</code>. I wonder why this was not done ...
performance issues?! ... or <code>ThreadLocal</code> was just not designed for non-static usage??</li>
<li>An explicity destroy method should have been provided on <code>ThreadLocal</code>. In
JDK 1.5, a new method <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ThreadLocal.html#remove()">remove</a>
has been added to <code>ThreadLocal</code>'s API to complete its lifecycle management.
Users can call the remove method and avoid such memory leaks. </li>
</ol>
<p>But for most of us who can't make JDK 1.5 as the minimum requirement for our
application we have to find some other way out.</p>
<p>One simple option seemed to be to write a CustomThreadLocal based on the JDK 1.2
implementation of <code>ThreadLocal</code>. Basically, have a synchronized Map of <code>Thread</code> vs
threadLocalValue and expose a remove method which will remove the <code>Thread</code> from
the map. However, this has serious performance issues, which is why <code>ThreadLocal</code>
was redesigned in JDK 1.3! So the only realistic option is to make the
<code>ThreadLocal</code> a static field. </p>
<p>Currently each <code>CachedObject</code> instance has its own <code>ThreadLocal</code> instance and
each <code>ThreadLocal</code> instance holds a <code>Context</code> instance. If we make the <code>ThreadLocal</code>
static, then all the instances of <code>CachedObject</code> will refer to the same <code>ThreadLocal</code>
instance. So, in order to retain the original semantics, we will have to make
the value of the <code>ThreadLocal</code> to be a map of <code>CachedObject</code> vs <code>Context</code>. Since
multiple threads will never access this map [which is local to the thread], this
map does not need to be synchronized. So no performance bottlenecks and since
the remove method is exposed, no memory issues. The new reference graph looks
like: </p>
<p><img src="http://www.me.umn.edu/~shivane/blogs/cafefeed/resources/24-jun-2004/tl2.png" alt="New reference diagram" /> </p>
<p>and the source for the ThreadLocalMap would look like: </p>
<pre class="code">1
2 <span class="j_kw">import</span> java.util.*;
3
4 <span class="j_kw">public class</span> ThreadLocalMap
5 <span class="j_kw">implements</span> Map
6 {
7 <span class="j_kw">private</span> ThreadLocal threadLocal = <span class="j_kw">new</span> ThreadLocal();
8
9 <span class="j_kw">private</span> Map getThreadLocalMap(){
10 Map map = (Map) threadLocal.get();
11 <span class="j_kw">if</span>(map==<span class="j_kw">null</span>){
12 map = <span class="j_kw">new</span> HashMap();
13 threadLocal.set(map);
14 }
15 <span class="j_kw">return</span> map;
16 }
17
18 <span class="j_kw">public</span> Object put(Object key, Object value)
19 {
20 <span class="j_kw">return</span> getThreadLocalMap().put(key, value);
21 }
22
23 <span class="j_kw">public</span> Object get(Object key)
24 {
25 <span class="j_kw">return</span> getThreadLocalMap().get(key);
26 }
27
28 <span class="j_kw">public</span> Object remove(Object key)
29 {
30 <span class="j_kw">return</span> getThreadLocalMap().remove(key);
31 }
32
33 <span class="j_comm">//code snipped for brevity ...</span>
34
77 }</pre>rsnoreply@blogger.comtag:blogger.com,1999:blog-6734168.post-1087494429828867142004-06-17T10:45:00.000-07:002004-07-11T04:35:12.503-07:00Of Thread dumps and stack traces ...<p>Thread dumps and stack traces are probably some of the least understood features of java.
Why else would I come across developers who have no clue what do do after
looking at an Exception stack trace? </p>
<div class="linkbox" >
<a href="#ssp">Street Side Programmer?!</a>
<a href="#anatomy">Anatomy of a stack trace</a>
<a href="#innovative">Innovative usage of stack traces</a>
<a href="#td101">Thread dump 101</a>
<a href="#tdcpu">Debugging run away CPU</a>
<a href="#tdperf">Debugging performance issues</a>
<a href="#tdhang">Debugging ``hang'' problems</a>
</div>
<h3><a name="ssp">Street Side Programmer?!</a></h3>
<p>An ex-colleague of mine, Manoj ``The Anger'' Acharya, had coined the phrase
Street Side Programmer [a la Server Side Programmer] and he would dole out
this title to all those who would come to him with annoying questions.
Nothing annoyed him more than having some one come and ask him <q>I
am getting some exception when I do *blah* *blah*</q>. His typical answer
<q>*bleep*'ing Street Side Programmers ... what is some exception supposed
to mean?! Doesn't it have a name? Doesn't it have a stack trace??</q></p>
<p>I was reminded of him the other day, when a trainee learning java came
to me saying <q>My program is not running ... there seems to be
<i><b>some problem</b></i> ... can you come and take a look?</q>. The kid is
quite sweet, so instead of telling him about Anger, I just went to his seat.
The command prompt had something like this:
</p>
<pre class="cmd">C:\learn\classes>java Test
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at Test.run(Test.java:11)
at Test.<init>(Test.java:4)
at Test.main(Test.java:19)</pre>
<p>I wonder if the book he was reading had any section on reading stack traces.
[<a href="http://www.mindview.net/Books/TIJ/">Monsieur Bruce Eckel</a> ... are
you listening?!] I really think any introduction to java book should have this
as one of the earliest chapters ... right after defining a class and method!
Some one makes an error while trying out samples, or is tinkering around with
the code, which typically results in an exception ... what is one supposed to do next?!</p>
<h3><a name="anatomy">Anatomy of a Stack Trace</a></h3>
<p>Well I explained that an exception stack trace is java's way of telling you
exactly what went wrong and where it went wrong. The first line of the stack
trace gives you the exception name and the exception message and what follows is
the ``stack trace''. The stack trace is to be read from top to bottom, line by
line. Each line has the name of the class and the name of the method being
executed followed by the file name and line number in parentheses. </p>
<p>In this case a <code>java.lang.ArrayIndexOutOfBoundsException</code> with
the message ``5'' was raised. To know where it was raised, we look at the
next line. It tells us that the exception was raised while executing the
<code>run</code> method of the <code>Test</code> class at line
number 11 in <code>Test.java</code> file. The next line tells us that the run
method was called by the constructor [the stack trace shows Constructors as
<code><init></code> and static blocks in a class as <code><clinit></code>] of the Test class
at line number 4 in Test.java file. The next line tells us that the constructor
was called by the main method of Test class at line number 19 of Test.java file. </p>
<p>So the java stack trace would read in English would be like: </p>
<p>You accessed an array with an index of 5, however the array does not have 6
elements [thanks to zero based index]. This happened when I was executing the
run method of Test class which happens to be in line number 11 of Test.java
file. The run method was called by the constructor of Test class at line number
4 of Test.java file. The constructor was called by the main method of the Test
class at line number 19 of Test.java file. </p>
<p>Well... there is a wealth of information here. It tells you exactly what the
VM was doing when the exception was raised. Let us see how to debug the issue
given all this information. The Test.java file looks like this: </p>
<pre class="code">1 <span class="j_kw">public class</span> Test
2 {
3 <span class="j_kw">public</span> Test(<span class="j_kw">int</span>[] nums){
4 run(nums);
5 }
6
7 <span class="j_kw">private void</span> run(<span class="j_kw">int</span>[] nums)
8 {
9 <span class="j_kw">int</span> n = nums.length;
10 <span class="j_kw">for</span> (<span class="j_kw">int</span> i = <span class="j_lit">0</span>; i < nums.length; i++) {
11 <span class="j_kw">int</span> num = nums[n];
12 System.out.println(num);
13 }
14 }
15
16 <span class="j_kw">public static void</span> main(String argv[])
17 <span class="j_kw">throws</span> Exception
18 {
19 <span class="j_kw">new</span> Test(<span class="j_kw">new int</span>[]{<span class="j_lit">1</span>,<span class="j_lit">3</span>,<span class="j_lit">5</span>,<span class="j_lit">7</span>,<span class="j_lit">9</span>});
20 }
21 } </pre>
<p>Stepping through the code [as per the stack trace], we called the main
method, which invoked the constructor at line number 19, which in turn called
the run method at line number 4. Hey the stack trace was correct after all!
Now we look at line number 11 where the exception was raised. The exception says
that we accessed an array with incorrect index. The only array we are accessing
at line number 11 is the num array. The index being used to access the array was
<code>n</code>. So what the VM is trying to tell you is that the <code>n</code>
is larger that the size of the array nums. Which is in fact true. <code>n</code>
happens to be the length of the array. So it IS greater than the last
index of the array. What the user really wanted to do was use <code>i</code>
as the loop index and not <code>n</code>. </p>
<p>Another common exception raised is the <code>java.lang.NullPointerException</code>. The
NPE! A <code>NullPointerException</code> is Java's way of telling a user that a null
object reference was being used. Take a look at the following lines from a stack trace [snipped for brevity]: </p>
<pre class="cmd">java.lang.NullPointerException:
at foo.bar.MyServlet.doGet(MyServlet.java:36)</pre>
<p>So now we know that a null object was being referened at line number 36 of MyServlet.java. The code for the servlet looks something like:</p>
<pre class="code">35 String userNameParam = request.getParameter(<span class="j_str">"username"</span>);
36 <span class="j_kw">if</span>(userNameParam.equals(<span class="j_str">"root"</span>))
37 {
</pre>
<p>The only object reference being used in line number 36 happens to be
userNameParam. So it was null when the VM was executing that line. Now we track
down what values were assigned to the userNameParam. Line number 35 happens to
be the only assignment in this case. It assigns the value of userNameParam to
request.getParameter("username"). Since the VM told us that the
userNameParam was null, it means that the method
request.getParameter("username") returned a null value. Looking at the
documentation of the method we know that the method may return null. So the
users of the method need to code taking that into consideration. In this case we
would change the condition like so: </p>
<pre class="code">35 String userNameParam = request.getParameter(<span class="j_str">"username"</span>);
36 <span class="j_kw">if</span>(userNameParam!=null && userNameParam.equals(<span class="j_str">"root"</span>))
37 {
</pre>
<p>Thanks to stack traces some one who is not even aware of the code can pin
point the exact location of the error. In most of the cases a stack trace is
definitely starting points for debugging erroneous behavior. Who wants messy
core dumps anyways when you have readable stack traces?! </p>
<h3><a name="innovative">Innovative uses of stack traces</a></h3>
<p>Once you know what a stack trace provides, there are a lot of innovative ways
to use it. Basically answer questions like <q>how did I get here</q> or to record the
location of an event.</p>
<p>Recently a customer noticed that the VM was performing Full GC's
very frequently. This would happen even when the application is completely
idle. Looking at <code>java -verbose:gc -XX:+PrintGCTimeStamps ... </code>,
we realized that the Full GC would occur every one minute ... on the dot.
We then tried adding the <code>-XX:+DisableExplicitGC</code> option and voila
no more full GCs! So looks like some one was doing a <code>System.gc</code>
somewhere at every one minute.</p>
<p>So how do we find out who is calling it?! You would extract the
<code>System.java</code> file from <code><jdk-home>/src.zip!/java/lang/System.java</code>
and edit it like so: </p>
<pre class="code">736 <span class="j_kw">public static void</span> gc() {
737 <span class="j_kw">new</span> Exception(<span class="j_str">"Some one triggered Full GC from here"</span>).printStackTrace();
738 Runtime.getRuntime().gc();
739 }
740</pre>
<p>Compile the modified file and prepend it to your bootclasspath using the option <code>-Xbootclasspath/p:outputDir</code>. Next time we ran the application, we got the stack trace:</p>
<pre class="cmd">java.lang.Exception: Some one triggered Full GC from here
at java.lang.System.gc(System.java:737)
at sun.misc.GC$Daemon.run(GC.java:92)</pre>
<p>Adding one more stack trace to <code>GC.java</code> [You will not find sources
for the com.sun.* and sun.* packages in the src.zip that comes with
your jdk. You will have to download it from
<a href="http://wwws.sun.com/software/communitysource/j2se/java2/download.html">
Sun's Community Source site</a>.] we get to know that
<code>sun.rmi.transport.ObjectTable</code> is triggering
the full GC based on an interval specified by the system
property <code>sun.rmi.dgc.server.gcInterval</code>. The
default value for the property happens to be one minute.</p>
<p>So using the printStackTrace method we could debug
where Full GC was being triggered explicitly. You could
ofcourse do the same by setting a method break point
for the <code>System.gc</code> method. Or you could be
a smart google'er and stumble upon the ``Other
considerations'' section of the
<a href="http://java.sun.com/docs/hotspot/gc/">GC options</a>
page!</p>
<p>Instead of doing a new Exception(...).printStackTrace(),
you could alternatively do a Thread.dumpStack() which internally does the same.
The only disadvantage is that Thread,dumpStack() does take a message as its
parameter.</p>
<p>Some times it makes sense to create an exception object and hold a reference to
it until a later point in time. Suppose you have a class which looks like:</p>
<pre class="code">
1 <span class="j_kw">import</span> java.io.IOException;
2
3 <span class="j_comm">/** </span>
4 <span class="j_comm"> * A class that represents a heavy weight resource. </span>
5 <span class="j_comm"> */</span>
6 <span class="j_kw">public class</span> Resource
7 {
8 <span class="j_kw">private</span> <span class="j_kw">boolean</span> closed;
9
10 <span class="j_kw">public</span> <span class="j_kw">void</span> close() <span class="j_kw">throws</span> IOException{
11 <span class="j_kw">if</span>(closed)
12 <span class="j_kw">throw new</span> IOException(<span class="k_str">"Resource already closed."</span>);
13 <span class="j_comm">//resource cleanup</span>
14 closed=<span class="j_kw">true</span>;
15 }
16 <span class="j_comm">//code snipped for brevity ...</span></pre>
<p>The class throws an exception when a user invokes <code>close</code> on an already closed
resource. The stack trace of the <code>IOException</code> is going to tell you where
in the code you tried to close the already closed connection. For example the following output
tells you that when you called close on the Resource at line 41 of ResourceTest.java it was already closed.</p>
<pre class="cmd">
C:\learn\classes>java ResourceTest
java.io.IOException: Resource already closed.
at Resource.close(Resource.java:12)
at ResourceTest.closeResource(ResourceTest.java:37)
at ResourceTest.run(ResourceTest.java:26)
at ResourceTest.main(ResourceTest.java:50)</pre>
<p>But now what if you want to know where did you close it the first time?! You would change the code like so:</p>
<pre class="code">
1 <span class="j_kw">import</span> java.io.IOException;
2
3 <span class="j_comm">/** </span>
4 <span class="j_comm"> * A class that represents a heavy weight resource. </span>
5 <span class="j_comm"> */</span>
6 <span class="j_kw">public class</span> Resource
7 {
8 <span class="j_kw">private</span> <span class="j_kw">boolean</span> closed;
9
10 <span class="j_kw">private</span> Exception closedAt;
11
12 <span class="j_kw">public</span> <span class="j_kw">void</span> close() <span class="j_kw">throws</span> IOException{
13 <span class="j_kw">if</span>(closed) {
14 closedAt.printStackTrace();
15 <span class="j_kw">throw new</span> IOException(<span class="k_str">"Resource already closed."</span>);
16 }
17 <span class="j_comm">//resource cleanup</span>
18 closed=<span class="j_kw">true</span>;
19 closedAt=<span class="j_kw">new</span> Exception(<span class="j_str">"Resource closed here the first time."</span>);
20 }
21 <span class="j_comm">//code snipped for brevity ...</span></pre>
<p>The output would after making the changes would look like ...</p>
<pre class="cmd">C:\learn\classes>java ResourceTest
java.lang.Exception: Resource closed here the first time.
at Resource.close(Resource.java:19)
at ResourceTest.useResource(ResourceTest.java:32)
at ResourceTest.run(ResourceTest.java:25)
at ResourceTest.main(ResourceTest.java:50)
java.io.IOException: Resource already closed.
at Resource.close(Resource.java:15)
at ResourceTest.closeResource(ResourceTest.java:41)
at ResourceTest.run(ResourceTest.java:26)
at ResourceTest.main(ResourceTest.java:50)</pre>
<p>So now from the stack traces we know that a close was called first at line 32
of ResourceTest.java and later at line 41 we called a close on the same resource
for the second time.</p>
<p>There are a lot of multi threaded problems [NullPointers] which we were not
able to debug with a debugger because the whole application would become too slow
to simulate the problem scenario. However, by using Exception objects to track
threads which were setting the fields to null, we were able to resolve the
issues. A word of caution though ... creating exception objects is resource
intensive. Creating too many exception objects takes lot of CPU. And if you
are holding references to all the objects it requires memory too! </p>
<h3><a name="td101">Thread dump 101</a></h3>
<p> If the stack trace which gives the information on what a thread was doing at
that moment can help us in so many ways, just imagine the possibilites if you
could find out what every single thread in the Java VM is doing at any given
moment! A Full Thread Dump or a thread dump for short gives us exactly that
information. Consider the following source</p>
<pre class="code">1 <span class="j_kw">public class</span> Test
2 {
3 <span class="j_kw">public</span> Test(<span class="j_kw">char</span>[] chars){
4 System.out.println(<span class="j_str">"New line at "</span>+findNewLine(chars));
5 }
6
7 <span class="j_kw">private int</span> findNewLine(<span class="j_kw">char</span>[] chars)
8 {
9 <span class="j_kw">int</span> i = <span class="j_lit">0</span>;
10 <span class="j_kw">char</span> aChar;
11 <span class="j_kw">do</span>{
12 aChar = chars[i];
13 }<span class="j_kw">while</span>(aChar!=<span class="j_str">'\n'</span>);
14 <span class="j_kw">return</span> i;
15 }
16
17 <span class="j_kw">public static void</span> main(String argv[])
18 <span class="j_kw">throws</span> Exception
19 {
20 <span class="j_kw">new</span> Test(<span class="j_str">"Hello World!\nHowz goin?!"</span>>.toCharArray());
21 }
22 }</pre><p> The method <code>findNewLine</code> is supposed to return the first index of
a new line character in a given char array. [Purists please don't mail me with
the list of reasons why this approach is not right ... the idea here is not
really to write the best way to find a new line character!] Now when you
run the program it just won't print the result. One look at <code>top</code> in unix or the
task manager in windows we get to know that VM has taken the CPU for a spin....
100% CPU consumption for ever! Now wouldn't you want to know what the VM is
doing. Why is it taking all this CPU and not printing the output it is
supposed. </p>
<p> One way to do this would be rerun the program in debug mode. Use the
debugger and debug the application. However, many a times you come across such
the situation on a live system after running the app for a long duration. Since
it is a live system and we hit the issue only after running the application for
a long duration we can not leave it in debug mode for ever. The first line of defense
under such circumstances is the thread dump. </p>
<p> Run the program from the command prompt and when the CPU peaks take a thread
dump. You can get a thread dump by pressing the following at the command prompt:
<kbd>Ctrl</kbd>+<kbd>\</kbd> for unices or <kbd>Ctrl</kbd>+<kbd>Break</kbd>
for windows machines. If
you are running your application as a back ground process in unix, you could
execute <code>kill -SIGQUIT <pid></code> from another command prompt. The above signals
the VM to generate a full thread dump. Sun's VM prints the dump on the error
stream while IBM's JDK generates a new file with the thread dump every time you
send the signal. In our case the thread dump would look something like this: </p>
<pre style="font-size:14px" class="cmd">C:\learn\classes>java Test
Full thread dump Java HotSpot(TM) Client VM (1.4.2_04-b05 mixed mode):
"Signal Dispatcher" daemon prio=10 tid=0x0091db28 nid=0x744 waiting on condition [0..0]
"Finalizer" daemon prio=9 tid=0x0091ab78 nid=0x73c in Object.wait() [1816f000..1816fd88]
at java.lang.Object.wait(Native Method)
- waiting on <0x10010498> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
- locked <0x10010498> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(Unknown Source)
at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)
"Reference Handler" daemon prio=10 tid=0x009196f0 nid=0x738 in Object.wait() [1812f000..1812fd88]
at java.lang.Object.wait(Native Method)
- waiting on <0x10010388> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Unknown Source)
at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source)
- locked <0x10010388> (a java.lang.ref.Reference$Lock)
"main" prio=5 tid=0x00234998 nid=0x4c8 runnable [6f000..6fc3c]
at Test.findNewLine(Test.java:13)
at Test.<init>(Test.java:4)
at Test.main(Test.java:20)
"VM Thread" prio=5 tid=0x00959370 nid=0x6e8 runnable
"VM Periodic Task Thread" prio=10 tid=0x0023e718 nid=0x74c waiting on condition
"Suspend Checker Thread" prio=10 tid=0x0091cd58 nid=0x740 runnable
</pre>
<p> The thread dump generated here is on Sun's JDK 1.4.2. Though the output
differs from version to version and from vendor to vendor, the basic structure
is the same. The output is somewhat like going over all the threads and doing a
<code>Thread.dumpStack</code> in each of them. In this case we can see that, at the time we
took the thread dump, there were seven threads: </p>
<ol>
<li>Signal Dispatcher</li>
<li>Finalizer</li>
<li>Reference Handler</li>
<li>main</li>
<li>VM Thread</li>
<li>VM Periodic Task Thread</li>
<li>Suspend Checker Thread </li>
</ol>
<p>Each thread name is followed by whether the thread is a daemon thread or not.
Then comes <code>prio</code> the priority of the thread [ex: prio=5]. I am not sure
what the <code>tid</code> and <code>nid</code> are. My best guess is that they are the Java thread id and
the native thread id. Would love if someone could comment on that. Then what
follows the state of the thread. It is either:</p>
<ul>
<li>Runnable [marked as R in some VMs]: This state indicates that the thread
is either running currently or is ready to run the next time the OS thread
scheduler schedules it. </li>
<li>Suspended [marked as S in some VMs]: I presume this indicates that the
thread is not in a runnable state. Can some one please confirm?!</li>
<li>Object.wait() [marked as CW in some VMs]: indicates that the thread is
waiting on an object using Object.wait()</li>
<li>waiting for monitor entry [marked as MW in some VMs]: indicates that the
thread is waiting to enter a synchronized block</li>
</ul>
<p>What follows the thread description line is a regular stack trace. </p>
<h3><a name="tdcpu">Debugging run away CPU</a></h3>
<p>When we are trying to debug a run away CPU, as in this case, what we need to look at is the
set of Runnable threads in the thread dump. The question to ask is: <q>What
was the thread which was consuming CPU doing?</q> At the instant we took the above
thread dump, the thread was at line 13 of Test.java. Well ... looks like it was
checking the condition for the while loop. But eventually it should have
returned right?! So we take a few more thread dumps. Each time it shows us the
thread is within the while loop. This definitely indicates from the first time
you took a dump to the last time you took a dump, the thread never got out of
the loop. The problem is narrowed down that loop. Putting the loop under the
magnifying glass, we realize that the counter i was never being
incremented. </p>
<p>Well ... if you have a single class in your application it is no big deal!
But when you have gazillions of classes, narrowing down the problem to a single
loop within single class is a big saver! I have found this a useful tool even
when I am using a debugger. It helps me choose a good location to set my first
break point! </p>
<h3><a name="tdperf">Debugging performance issues</a></h3>
<p>Its the night before the release and your application is not performing good
enough. You really don't have enough time to run the app through a profiler.
Take heart! Like <a href="http://www.jroller.com/page/rameshl">Ramesh</a>
says ... there are always some low hanging fruits! The way a java profiler works
is, it takes snapshots of what the CPU was doing at frequent intervals and
generates a statistical report on where most of the CPU time was being spent
during the run. If your application is performing so poorly that you could take
say 10-12 thread dumps before an operation completes, you would get a rough idea
of distribution of CPU time. Some of the easy kills I can think of:</p>
<ul>
<li><i>Symptom</i>: High CPU consumption and poor response time<br/>
<i>Thread dump profile</i>: Most of the dumps show the same thread in the
same method or same class<br/>
<i>Solution</i>: The method/class is the one which is definitely taking a
lot of CPU. See if you can optimize these calls. Some of the REALLY easy
kills we have had in this category is using a Collection.remove(Object)
where the backend collection is a List. Change the backed collection to be a
HashSet. A word of caution though: There have been times when the runnable threads
are innocent and the <a href="http://www.me.umn.edu/~shivane/blogs/cafefeed/2004/05/of-perf-degradation-with-try-finallies.html">GC is the one consuming the CPU</a>.</li>
<li><i>Symptom</i>: Low CPU consumption most of which is kernel time and poor
response time<br/>
<i>Thread dump profile</i>: Most thread dumps have the runnable threads
performing some IO operations<br/>
<i>Solution</i>: Most likely your application is IO bound. If you are
reading a lot of files from the disc, see if you can implement
Producer-Consumer pattern. The Producer can perform the IO operations and
Consumers do the processing on the data which has been read by the producer.
If you notice that most IO operations are from the data base driver, see if
you can reduce the number of queries to the database or see if you can cache
the results of the query locally.</li>
<li><i>Symptom</i>: Medium/Low CPU consumption in a highly multithreaded
application<br/>
<i>Thread dump profile</i>: Most threads in most thread dumps are waiting
for a monitor on same object<br/>
<i>Solution</i>: The thread dump profile says it all. See if you can:
eliminate the need for synchronization [using ThreadLocal/Session-scope
objects] or reduce the amount of code being executed within the synchronized
block.</li>
<li><i>Symptom</i>: Medium/Low CPU consumption in a highly multithreaded
application<br/>
<i>Thread dump profile</i>: Most threads in most thread dumps are waiting
for a resource<br/>
<i>Solution</i>: If all the threads are choked for resources, say waiting on
the pool to create EJB-bean objects/DB Connection objects, see if you can
increase the pool size.</li>
</ul>
<h3><a name="tdhang">Debugging ``hang'' problems</a></h3>
<p>A textbook case of deadlock is the easiest to debug with the newer JDKs. At
the end of the thread dump you will find something like this:</p>
<pre class="cmd">Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x0091a27c (object 0x140fa790, a java.lang.Class),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x0091a25c (object 0x14026800, a java.lang.Class),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at Deadlock$2.run(Deadlock.java:48)
- waiting to lock <0x140fa790> (a java.lang.Class)
- locked <0x14026800> (a java.lang.Class)
"Thread-0":
at Deadlock$1.run(Deadlock.java:33)
- waiting to lock <0x14026800> (a java.lang.Class)
- locked <0x140fa790> (a java.lang.Class)
Found 1 deadlock.</pre>
<p>But many a times we come across hang's which are not deadlocks. One thing
that easily comes to my mind is a resource limit. For example in an EJB
container you have set the maximum bean pool size to 1000. Now say two threads
have started executing a finder each returning a collection of 1000 odd beans.
Assuming a decent CPU time slice distribution it could happen that the first
thread iterates over 500 beans and the next thread iterates over the 500 beans.
At this moment both the threads need more beans to proceed further. However the
container will not create new beans as the bean pool limit has been reached. So
both the threads wait for some beans to be release to the pool ... which is not
going to happen. We have a hung app here.... however it is not a java-level
deadlock. It is an artificial deadlock introduced due to resource limitation. </p>
<p>When your app is not responding and your CPU consumption is 0%, take a thread
dump. If it does not have a java level dead lock, then take multiple thread
dumps. If all of them show that the threads are waiting for resources [EJBs or
DBConnections] see if you can increase the pool limit or decrease the number of
resources required within a transaction. </p>
<h3>Finally</h3>
<p>Thread Dumps and stackTraces are really good tools ... they may not replace a
debugging/profiling tools but are definitely good starting points and huge time
savers. Unfortunately, I think they are undersold. Classes don't teach you about
them, Books don't talk about them and tools don't support them. I mean I can run
any class from my IDE. I has buttons to Start/Pause and Stop the app from within
the IDE. But why can't I have a button for ``Generate full Thread dump''. Every
time I need to generate a thread dump, I have to rerun the application from
command line.</p>
<p>Well ... maybe things are not so bad after all. What if the IDEs don't support
generation of a thread dump?! Most of them now open up the file and line number
if you double click on a line in the exception stack trace obtained on running
a program! And what if the books don't talk about it? People like Ashman make
sure anyone joining the support team gets their dope on thread dump from me! ;)</p>rsnoreply@blogger.comtag:blogger.com,1999:blog-6734168.post-1087305584743849812004-06-02T06:18:00.000-07:002004-06-15T06:27:41.413-07:00Surviving windoze ...<p>Over the past couple of years I have learned some tricks to survive on windows ... </p>
<h3>Keyboard shortcuts</h3>
<ul>
<li><kbd>Ctrl</kbd>+<kbd>Esc</kbd>: Same as <kbd>Win</kbd></li>
<li><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Esc</kbd>: Brings up the task manager. [It is faster than <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd> and then choosing task manager.]</li>
<li><kbd>Win</kbd>+<kbd>D</kbd>: Toggle show desktop</li>
<li><kbd>Win</kbd>+<kbd>E</kbd>: Start explorer</li>
<li><kbd>Win</kbd>+<kbd>F</kbd>: Start find in files</li>
<li><kbd>Win</kbd>+<kbd>M</kbd>: Minimize all windows</li>
<li><kbd>Win</kbd>+<kbd>shift</kbd>+<kbd>M</kbd>: Restore minimized windows</li>
<li><kbd>Win</kbd>+<kbd>R</kbd>: Run a program</li>
<li><kbd>F2</kbd>: Rename a file/dir in explorer</li>
<li><kbd>F3</kbd>: Find in the select dir of explorer</li>
</ul>
<h3>Know thy <code>cmd</code> ... </h3>
<ul>
<li>You can start one using <kbd>Win</kbd>+<kbd>R</kbd> <code>cmd</code></li>
<li><code>start <dir-name></code>: opens an explorer pointing to that directory</li>
<li><code>start <file-name></code>: opens the file with its default handler. For example <code>start <src.zip></code> will open the <code>src.zip</code> file in <a href="http://www.izsoft.dir.bg/">IZArc</a> if it is your default zip file handler</li>
<li><kbd>F7</kbd>: View command history</li>
<li><kbd>F8</kbd>: Complete the command based on history</li>
<li><kbd>Right click</kbd> on the title bar, choose properties, in the options tab switch on the ``QuickEdit Mode'' and ``Insert Mode''</li>
<li>Making a selection on the cmd [by dragging the mouse over the text in the cmd when ``QuickEdit Mode'' is on] will make the scrolling stop. The application might also stop if it cannot write any more data to its outputstream, making it look like a ``hung'' application.</li>
<li>You can enable <a href="#fcomp_in_cmd">file/dir name completion in cmd</a> on typing tab</li>
</ul>
<h3><a name="fcomp_in_cmd">File name completion in cmd</a></h3>
<p>I always missed the tab completion feature of *nix shells in
windows. Long ago <a href="http://sachinhejip.blogspot.com">Sachin</a>
told me how to acheive the same in windows. Do a <kbd>Win</kbd>+<kbd>R</kbd>
<code>regedit</code>. In the tree navigate to :
<code>HKEY_CURRENT_USER/Software/Microsoft/Comma