Watch your Eclipse project encoding and Maven 2 compiler plugin encoding
I've spent last 2 hours (two hours!) trying to figure out the cause of a rather nasty bug which turned out to be a disgraceful effect of my inadvertence.
I've implemented a method that, given a number of parameters, returns an SMS object containing (among other things) the text message to be sent. In Polish language there are several diacritic letters (eg. ą, Ą, ć, Ć, ę, Ę, etc.) which should be replaced with their basic form (a, A, c, C, e, E, etc.). I prepared a following method:
private String replaceChars( String haystack, String targets, String replacements ) {
String result = haystack;
for ( int i = 0; i < targets.length(); i++ ) {
result = result.replace( targets.charAt( i ), replacements.charAt( i ) );
}
return result;
}
that is invoked like that:
sanitizedMessage = this.replaceChars( message, "ąĄćĆęĘłŁńŃóÓśŚźŹżŻ", "aAcCeElLnNoOsSzZzZ" );
As you can see, the method iterates through all characters in the targets and replaces their every occurrence in the haystack with the proper character from the replacements.
The problem was that when I launched the application from within the Eclipse it all went right. Characters got replaced and everything worked fine. But as soon as I compiled and packaged the application with Maven 2, the replacement stopped working.
It was only after several dozen iterations of running/debugging from within Eclipse and cleaning, compiling and packaging with Maven 2 that I finally checked the project encoding in Eclipse and compared it to the encoding of maven-compiler-plugin configured in pom.xml. As you surely expect at this moment, the encodings were different. Eclipse used ISO-8859-2 and the maven-compiler-plugin used UTF-8. Therefore after compiling the project with Maven, all the diacritic characters passed to replaceChars() in the targets argument became '?' so there was no way it could actually work the way I expected it to.
So finally, to recapitulate: always double check that each encoding used in each tool you use within your project matches the others. This will let you avoid tons of locale-oriented problems and unexpected gotchas during development. Oh, and don't trust the Eclipse debugger in such moment – it'll be useless.

0 comments:
Post a Comment