Monday, 7 April 2014

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).

Friday, 4 April 2014

The End of Windows XP

Microsoft have announced they will stop supporting Windows XP around now. Apparently there is still a lot of it about. It was a pretty good operating system in that it was stable and didn't use too much resource. So people hung onto it (including Mrs).
It won't suddenly stop working, of course, but there won't be any new patches to plug security holes that inevitably get found and exploited. That's really what 'support' means. And I'm listening to a discussion on the radio about your options if you are still running it.
The obvious thing to do is pay a couple of hundred dollars to MS and get a copy of Windows 8, install that (it will be a clean install, not an upgrade) and learn to use a whole new interface. Except that Windows 8 probably won't run on your old computer because W8 needs more resources (memory, disk space, CPU). Your old 3rd party software will run okay though, probably, if there is enough resource.
What they didn't mention on the radio is another option: Linux.
Here's why you should consider Linux, specifically if you are running on an older machine you want to look at Lubuntu. Here is why:
  • It will run on your existing machine, you don't need to upgrade your hardware. I'm running it just fine on a machine I bought in 2005.
  • It looks enough like XP to make you feel comfortable enough, probably more like it that Windows 8 does.
  • It will probably run your existing 3rd party software. No guarantees, but Word and Excel run just fine under a compatibility product called Wine. Setup is simple.
  • It is free. This point would be unimportant if it did not work, but it does work, so I'll say it again FREE (as in beer). You just download it. You don't need your credit card.
  • Support is not going away and there is a vibrant community of helpful people. I've never yet had to ask anything, a quick Google always finds someone else with my question, and the answer.
Yes, you will have to do a complete re-install to get there, but you were up for that anyway. Linux is seriously simple to install these days, at least as easy as Windows and it happily auto-detects your hardware and sets it up without any fuss.
Lubuntu is one of many 'packaging' options for Linux and you can find lots of others, but Lubuntu was specifically designed to look more like XP to the user and to be lighter weight, ie to run on old machines.
You can even give it a quick try out. Download the CD image from here and burn it to a CD, then boot from the CD. The CD gives you the option of running stand-alone (without touching your disk drive, it is all in memory) or installing a system on your disk. Use option one to give it a try.
When you decide you like what you see you can install it alongside your Windows system but you are better off putting in a new disk and installing onto that. The reason I recommend this is so that you absolutely know that you aren't going to press the wrong button somewhere and overwrite you existing system.
You can then put your old drive into a USB enclosure and copy your data across to the new drive.
All this is no more hassle than installing Windows 8, far less if it saved you a hardware upgrade.