Strange Java issue with reflection and statics

Yesterday I found myself struggling with an odd Java problem. I suspect it is a Java bug, though I have deeply, deeply ingrained resistance to blaming anything on my environment. I can hear university lecturers and early employers pointing out ‘it is always you’ when I naively suggested that possibility years ago. But this just may be the exception.

I’m using reflection to discover the data type of the first parameter on this method:

public void init(Email annotation, PropertyMetadata propertyMetadata)

in this case Email is actually an annotation rather than an ordinary class. It has a full type of

nz.co.senanque.validationengine.annotations.Email

But when I locate the init method using reflection and get the type of the first parameter like this:

Class p = (Class)method.getParameterTypes()[0];

the type I get is

java.lang.annotation.Annotation

rather than

nz.co.senanque.validationengine.annotations.Email

and this causes my validation engine to ignore validating email fields. I have other kinds of validation (eg Length) which work perfectly well, the type for Length is returned correctly no problem. So I went over the code to see what the difference was. The good news is I eventually found it, the bad news is it doesn’t really make a lot of sense.

The init method shown above lives in a class called EmailValidator. Again, I have a list of these such as LengthValidator, RegexValidator and so on. They all look the same, except that EmailValidator misbehaves. The one difference is that EmailValidator has some static Strings defined. It looks like this:

public class EmailValidator implements FieldValidator
{
    private static String ATOM = “[^x00-x1F^(^)^<^>^@^,^;^:^\^”^.^[^]^s]”;
    private static String DOMAIN = “(” + ATOM + “+(.” + ATOM + “+)*”;
    private static String IP_DOMAIN = “[[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}]”;

See? Just ordinary  static Strings. They don’t seem to have any relationship to the init method. But they do. If I make them non-static (ie remove the ‘static’ from the definition) then… it all comes right. The datatype comes as

nz.co.senanque.validationengine.annotations.Email
 
as it should. There is no downside to making the statics into ordinary fields because these classes are singletons, instantiated only once. And, of course the validation now works. 

The result, when I edit ‘@’ out of Amy’s email address and tab off the field shows the error signal and disables the ‘save’ button, which is what is supposed to happen if there is an error. When I roll the mouse over the error signal it pops up with more detail. The totally cool thing about this is that all I need to do to add validation to the field is annotate it with @Email, everything else just happens (as long as those static fields are changed).

Leave a Reply

Your email address will not be published. Required fields are marked *