The Problem
Recently, one of my co-workers had an issue with a website written in JSP. Every time he went to a page, a Servlet Filter was failing with an error that the Java class “StringBuilder
” was not found. I’ve added this Servlet Filter in the application recently and this worked fine on other machines and in our Test Servers, but failed on this one machine. Also, we use Java 1.4 and there is no way we could be using Stringbuilder which was only introduced in Java 1.5. (Java 1.4 has only StringBuffer. See here for a discussion on the two).
(I know we are using older technology – we use Sybase EA Server 5.5, which forces us to stick with Java 1.4, but go with me on this.)
Java Strings and Java Compiler
I set to find out why it was complaining about something we don’t use. I looked at the class file generated. It had “StringBuilder
”. Then it hit me. We use a lot of String
Concatenation in our code and we use String
concatenation using plus sign (+). This seemingly innocuous usage caused it and the error has to do with Compiler Optimization.
Java String
s are immutable, meaning they cannot be changed at run time. Each time we concatenate String
s, we are essentially creating newer and newer String
s.
So, str1 + str2 + str3
is essentially equivalent to:
res1 = str1 + str2
res2 = res1 + str3
But Compiler may take a different approach to optimize concatenation using StringBuffer
or StringBuilder
(See here). So the above concatenation can be rewritten (by compiler) as:
StringBuilder(str1).append(str2).append(str3);
So this is what happened in our case. Some concatenation got turned into StringBuilder
by the Compiler and hence the error. Wasn’t that supposed to read StringBuffer
(because it’s supposed to be Java 1.4)? Well that was because of another mistake. When he set up Eclipse, our friend used a newer version than the one I recommended which defaulted to Java 1.6 compiler which caused the optimizer to produce > 1.5 code!! Hence the error on StringBuilder
. But the error showed up in the first place because of the Compiler Optimization! If the compiler used the String.Concatenate
in the first place, we would not have seen this error!!.
And Compiler may sometimes choose to do just that, use String.Concatenate
as shown in preciseJava.com. Also, such Compiler optimization may not always be good. See this interesting blog about various possibilities of concatenations.
Oh yeah, we overrode the workspace settings in Eclipse to use 1.4 compiler for the project and all is well now.
Reference Links
- http://chaoticjava.com/posts/stringbuilder-vs-string/
- http://javamoods.blogspot.com/2010/02/optimization-dont-do-it-compiler-will.html
- http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=5&ved=0CF4QFjAE&url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.122.5641%26rep%3Drep1%26type%3Dpdf&ei=LIK6UMCwBMWUjAK4_4HIBw&usg=AFQjCNFo6trLwU4wlxgrTNFBa1tGb1p9Cg&sig2=qHQIg8S0qI-CXdJ6EOaa8w
- http://www.precisejava.com/javaperf/j2se/StringAndStringBuffer.htm
- http://code-thrill.blogspot.com/2012/08/stringbuilder-optimizations-demystified.html
Filed under: CodeProject, Java
Tagged: Java