Archive for March, 2007

Unchecked warnings and type erasure with Java Generics

Wednesday, March 14th, 2007

I am currently cleaning a whole code base from all its warnings and I kept stumbling upon a few warnings related to the use of generics. And all I can find on Google is people telling each other to use @SuppressWarnings(”unchecked”)…

For a start, I am not a big fan of annotation (I will probably post some day on that), but this is more like sidestepping the problem and acquiring bad practices for dealing with warnings.

2 different warnings

Consider the following example encountered while using Apache Log4J:

Enumeration<Appender> e = log.getAllAppenders();

This will generate the following warning: “Type safety: The expression of type Enumeration needs unchecked conversion to conform to Enumeration”

OK, fine! so let’s cast it to the proper type:

Enumeration<Appender> e = (Enumeration<Appender>)log.getAllAppenders();

Well, the result is not quite what we expected in that it’s still generating a warning: “Type safety: The cast from Enumeration to Enumeration is actually checking against the erased type Enumeration”.

Even though we are pretty sure this should never generate any ClassCastException, these warnings are just plain annoying for code quality…

More on erased types

The implementation of Generics in Java 1.5 came with a nice advantage: you could code in fancy spanking-new 1.5 generics and still generate classes that were compatible with previous versions of Java!

They did that by enforcing the type safety with generics only at compilation time, but otherwise generate code compatible with Java 1.2+ by removing any parameterised type from the compiled class.

In effect, using generics it is now easier to code type-safe classes, but the checking is not done at runtime. If you find a way to feed your application with instances that do not comply with the intended generics behaviour (in our example, having an Enumeration of, say, String instead of Appender), this will certainly result in a nice ClassCastException!

And that’s the way it is implemented in Java, full stop! No discussion possible (until they decide to cut with previous versions of Java). So why have a warning at all?

The solution

Actually, there is a very simple answer to this (apart from the fact that future versions might not provide backward compatibility)…

It is obvious we are trying to get an Enumeration of Appender instances in order to apply some process on each of them; …but wait!

Appender is an interface… (that’s what got me on the tracks for the solution!)

What you are actually getting is an Enumeration on implementations of Appender; that is, any implementation possible!!!

So really, the code logically needs to be written as follows:

Enumeration<? extends Appender> e = (Enumeration<? extends Appender>)log.getAllAppenders();

That’s right! we want to be able to deal generically with any subtype of Appender… seems soooo easy now with hindsight, isn’t it?

Sphere: Related Content

mod_rewrite and url parameters

Monday, March 12th, 2007

Apache’s mod_rewrite module is very potent for manipulating urls on the server-side; it allows you to:

  • hide the technology used to dynamically generate the pages
  • hide the construction of the URL, rendering it more difficult to modify some parameters in order to get the application in an non-desired state, thus limiting the risk of an exploit to be discovered by a hacker or a script-kiddie
  • improve human legibility of URLs
  • improve search engines crawl and indexation

The problem, though, is that you have to understand what is happenning under the hood to be able to produce effective rewriting that will not be worse than the original URL scheme!
A problem I have been looking to resolve for quite some time, is how to pass on the parameters from the exposed URL to the rewritten one…

For instance, if I have the URL myserver/book_15645854.html, I can simply rewrite it to call the myserver/book_details.php?bookid=15645854 url by using the following rule with a regular expression:

RewriteRule ^book_([0-9]+)\.html$ book_details.php?bookid=$1

But now, what if I want to rewrite the following URL

myserver/contact_form.html?email=eg@example.com

so that it populates the source email field by default with the email passed as a parameter to the dynamic contact page like myserver/contact.php?email=eg@example.com ?

Bad news is that you can’t use a regular expression in the RewriteRule. It just won’t work! And you can’t seem to find anything in the documentation that tells you why…

Good news is, it’s actually quite simple but, coming back to what I said about looking under the hood, you have to understand that the rule you define in the RewriteRule clause is working on the resource part of your URL and not on the overall request URL with all it’s parameter!

The actual parameters are contained in a variable called QUERY_STRING that you can use as follows:

RewriteRule ^contact_form\.html$ contact.php?%{QUERY_STRING}

…now I will try to find how to collect only one of the parameters - ideas welcome!

Finally, you might to have a look at this more complete article: Mod_rewrite Introduction and Cheat Sheet, it has everything you want to forget about mod_rewrite!

Sphere: Related Content