Val's Blog
Lots of stuff for Web 2.0 freaks and Javaholics
Feeds RSS | Atom | RDF
 
 
Frederik Brooks: "Adding manpower to a late software project makes it later."
[ Login ]

July 2008
SunMonTueWedThuFriSat
   1  2  3  4  5 
 6  7  8  9  10  11  12 
 13  14  15  16  17  18  19 
 20  21  22  23  24  25  26 
 27  28  29  30  31   
Jun  |  Today  |  Aug
XML Feeds   Subscribe with Bloglines

Javaranch Sheriff   My LinkedIn Profile
Drop me a line or two   Bloglines Blogroll
JavaRSS   Referers
How cool are you?   My Reviews

Next trips...
SpringOne 2008 (Jun 11-12, 08)
Ajax Exp. 2008 (Sep 29-Oct 1, 08)
Top 10 entries (#hits)
(As of Nov 30, 2007)


Top 10 entries (#hits/day)
Come Back (5.032)
(As of Nov 30, 2007)
Recent Blog Entries
Recent Blog Comments
Re: Review of "Marketing Management 12th"
i know marketing management by kotler is good book but the problem is that the management part of this book is totally missing as fare as i know managemet is complete different subject and it should not be mixed i am student of MBA i was looking at ass...

Re: Review of "Pro Spring"
Using simple POJOs + factories without Spring for "echo" and "counter" would be a lot more easier. No need to write those XML files... So, in this case using Spring makes me write a lot more code... (OK, you can generate everything with the help of And...

pls urgent
Hi I am trying to generate the word doc but i m not understanding wats happening any one pls figure it out /* * WordAPI.java * * Created on May 30, 2006, 10:50 AM * * To change this template, choose Tools | Template Manager * and open the te...
Archives (# entries)
Links
Other Blogs
Other Blogs

Reviewing
Reading
Locations of visitors to this page
What they once said...
 

It is commonly admitted that dynamic languages are usually more flexible and permissible than static ones. On the other hand, another recognized fact about dynamic languages is that they provide more ways for you to write buggy software if you don't pay enough attention and don't play by the rules.

For instance, I recently came across a nice bug in a web application making heavy use of Spring 2.0.2, JSP 2.0 and JSTL. Here is a piece of code that closely resembles the original code.

...

<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core' %>
<%@ taglib prefix='spring' uri='http://www.springframework.org/tags' %>

...

<ul>
<c:forEach items="${someValues}" var="value" varStatus="status">
	<li>${status.index}. ${value}</li>
</c:forEach>
</ul>

...

<spring:bind path="address.zip">
	<c:if test="status.error">
		<c:out value="The ZIP code is not properly formatted." />
	</c:if>
</spring:bind>

...

Can you spot it? Ok, it might not be immediately clear what the problem is, but remember that the JSP Expression Language is a dynamic language, and thus, variables are weakly typed. The problem lies around is the status variables and here is why. In the JSTL forEach loop, we are defining a page-scoped variable named status that will keep track of the loop iterations and provide some useful information about each iteration, such as the iteration index, whether it is the first or last iteration, etc. At the bottom, we are using the bind tag of the Spring tag library, which allows to detect whether the value of the property identified by the path attribute (i.e., address.zip) could not be validated properly.

Now the thing is that the bind tag implicitely defines a new page-scoped variable, named... status, too, which provides some information about the validation of the property, such as whether the validation failed for instance (using the status.error property, etc). The error that we were seeing in the browser was along the lines of:

javax.servlet.jsp.JspException: javax.servlet.jsp.jstl.core.LoopTagSupport$1Status

Very explicit as anyone can judge. In the end, the problem was that the first status variable is of type javax.servlet.jsp.jstl.core.LoopTagSupport$1Status, while the second is of type org.springframework.web.servlet.support.BindStatus and those two types share nothing in common. After careful debugging, we could see that the cause of that JSPException was a ClassCastException, which is a typical exception raised when a weakly typed language (i.e., the JSP expression language) is being transformed into a strongly typed language (i.e., Java). So one solution here consists of renaming the first status variable using another identifier, because there is no way to override the name of the second status variable provided by spring:bind, probably one of the few thing you cannot customize in Spring ;)

For the record, the Spring 1.2.2 codebase used to explicitly cast the status variable to the org.springframework.web.servlet.support.BindStatus type, which would cause unavoidable ClassCastExceptions being raised (see SPR-1140 for more info). This has been fixed in Spring 1.2.3 and starting from release 2.0.4, any status variable available in the page or request scope is saved and re-exposed after the tag body has been evaluated (more info)

I hope this post will help other people not fall into the same nasty trap.

A very common mistake that might seem obvious (or so I hope), yet that I've seen in many places is the one where we need to read characters from any kind of input streams and we cast an int read from that input stream to a char a little bit too early.

The usual code goes like this:

InputStream in = ...;
char c = 0;
while ((c = (char) in.read()) > -1) {
   //do something with c
}

The while loop will never break and depending on what you do within the loop probably end up in an OutOfMemoryError being raised, for instance if you keep appending the read character to a StringBuffer or something similar.

The reason for this is that the type char is the only unsigned primitive type in Java, and thus, the range of allowed values for a variable having the type char starts at 0. It's obvious then that the local variable c will never get assigned the value -1 but in case i is -1 (i.e., end of stream reached), c will get the value Character.MAX_VALUE (or 0xFFFF). Thus the solution consists of applying the type cast within the while loop only after the value check is successful, as shown below:

InputStream in = ...;
int i = 0;
while ((i = in.read()) > -1) {
   char c = (char) i;
   //do something with c
}
//EOF reached

That way the loop will always break at some point and you'll be safe.

I'm going to start a new weekly series of postings called "Spot the bug". The idea of this series goes along the lines of The Daily WTF, yet the goal is not to point fingers at anyone, but more to help people write better code, learn from others' mistakes and sensibilize them to bad practices and bugs present in existing codebases.

The first "Spot the bug" entry will be posted tomorrow, so make sure you stay tuned. Thanks to you all for your ongoing support!!

 
About this Blog