Friday, April 9, 2010

Data Validation - using the Hibernate Validator

Hi, Recently I've started to fiddle with a Data Validation problem.
Given a data model represented as an object graph of POJO-s, we should validate it.
The data model should contain some declarative validation rules and the validation infrastructure should get the object graph as an input, traverse it and produce the series of validation errors (if any)

I've figured out that the data validation problem has been addressed by JSR 303
The project Hibernate Validator 4.x is a reference implementation of this spec. So I've decided to investigate ;)

This project contains a fairly good tutorial here
So I've started to use this framework in my project. One thing that I've noticed is that the default message resolution wasn't flexible enough for my needs. Obviously after reading the tutorial, I've come to conclusion that I should define a custom "message interpolator". In this article I want to provide an example of how to use it.

My requirements are:

- I would like to override the default message bundle

- I would like define different messages for the same validated entity. For instance, if I have 2 (or more) different usages for the same data model, then theoretically I would like to show the different messages when validating the same data.

I've created the new project by running maven as the tutorial suggests:

mvn archetype:generate -DarchetypeCatalog=http://repository.jboss.com/maven2/archetype-catalog.xml -DgroupId=mark.test -DartifactId=beanvalidation-test -Dversion=1.0-SNAPSHOT -Dpackage=mark.test

This command generated the project with the following list of dependencies:



Now I'm ready to start my tests.
We will need six classes:

Class DataObject will represent our domain data and this class will have the validation annotation defined on it's getters:



Just pay attention to the annotations. The field 'foo' can't be null and The field 'bar' can't be less than 10

Another class we will need is the ResourceBundle storage.
This class is a message bundle container it contains a matrix of strings. There are two columns in this matrix: the column 0 is a key, the column 1 is a message itself.
In this example I've implemented the resouce bundle that can be created from the given stream (in our case it could be a properties file). One can think about the better design, but its just a simple examlpe...



The loaded bundles should be stored in a library and supplied with the unique identifier that will be accessible from the application. This can be done by the class that represents the bundle library and the enum that represents a unique ID:





And now the most interesting parts - The message interpolator itself and the code that actually makes a validation.




The Main class looks like this:


In the main method I:
- build the resource bundles library
- create the validator (see the 'Bootstraping' chapter of the aforementioned tutorial for addition information)
- create a data object
- validate the data object
- reconfigure the message interpolator so that it will take the messages from another source
- validate the data object again
- once more reconfigure the message interpolator
- validate the data object again

Note that I supplied two property files during the library creation.
Each property file contains the various messages that can be used in the framework.
The keys are predefined and can be found in the hibernate-validator-4.0.2.GA.jar
in the file named ValidationMessages.properties

I've redefined the message I need (obviously for the NotNull and for the Size).
If the message is not found in the message bundle, automatically the default bundle will be used...
So, for example, my main_app_bundle.properties file contains the single line:


javax.validation.constraints.NotNull.message=In my application this value may not be null


(I intentionally don't touch the Size message to keep it default here, In real application I would probably redefine them all)
My my_custom_bundle.properties files contains two lines (again to handle NotNull error in my own way):


javax.validation.constraints.NotNull.message=Yet another 'not null' message example


Now the output:

may not be null
must be greater than or equal to 10
=====================
In my application this value may not be null
must be greater than or equal to 10
=====================
Yet another 'not null' message example
In my application this value must be greater than or equal to 10
=====================

The first section as expected shows message that can be found in the default bundle supplied with the framework.

The second section is produced by the second validation invocation on the same object.
This time you can see that the 'not-null' error has been changed to one found in my properties file but the second message remained unchanged

The third section is the result of the third validation call. Here you can see that both of the messages have been redefined

Since the messages appear in the set, we can't do any assumptions about their order.

I would also like to provide the full list of the available keys and default values (in english):
=====================================================================================
javax.validation.constraints.AssertFalse.message=must be false
javax.validation.constraints.AssertTrue.message=must be true
javax.validation.constraints.DecimalMax.message=must be less than or equal to {value}
javax.validation.constraints.DecimalMin.message=must be greater than or equal to {value}
javax.validation.constraints.Digits.message=numeric value out of bounds (<{integer} digits>.<{fraction} digits> expected)
javax.validation.constraints.Future.message=must be in the future
javax.validation.constraints.Max.message=must be less than or equal to {value}
javax.validation.constraints.Min.message=must be greater than or equal to {value}
javax.validation.constraints.NotNull.message=may not be null
javax.validation.constraints.Null.message=must be null
javax.validation.constraints.Past.message=must be in the past
javax.validation.constraints.Pattern.message=must match "{regexp}"
javax.validation.constraints.Size.message=size must be between {min} and {max}
org.hibernate.validator.constraints.Email.message=not a well-formed email address
org.hibernate.validator.constraints.Length.message=length must be between {min} and {max}
org.hibernate.validator.constraints.NotEmpty.message=may not be empty
org.hibernate.validator.constraints.Range.message=must be between {min} and {max}
=====================================================================================

I hope this post was helpful, feel free to comment

Best regards, Mark Bramnik

Friday, April 2, 2010

Some tricks with reflection

Hi, everyone!

Today I would like to talk a little about reflection api and some interesting tricks we can do with it.
Basically, reflection allows us to introspect the object's structure during the runtime.
With the help of reflection we can:
- obtain the information about the methods/fields of the object
- obtain the information about superclass/interfaces that the object implements
- obtain the value of the data fields
- invoke the methods of the object dynamically

While in general I believe that the reflection shouldn't be vastly used in a properly designed Object Oriented program, sometimes we just can't live without this very powerful feature. From my experience the reflection based APIs are extensively used in different frameworks when we just don't have any information about the classes that will be used...

In this post I'll try to show some less known usages of the reflection API.
So, here we go :)

1. Instanceof with reflection

We will mimic the well known instanceof operator's behavior with the help of reflection:

The Class java.lang.Number is the common ancestor for Integer, Float, Double and other so-called wrapper classes
So we expect that the following code will produce 'true' twice:


Ok, but we knew that i is castable to Number, so it's not a big deal...
Now how about checking the String:


One could expect that this code would print 'false'. But in fact we can't even compile this code. The error is :

Inconvertible types; can't cast java.lang.String to java.lang.Number

So we can't fool the java compile with obviously false expression.
We can however upcast our String to Object and this code will run as expected.

The output is 'false'

Now lets see how the things can be done with the help of reflection:
Class "java.lang.Class" contains meta information about the object, this is our key to reflection APIs.
We will use its "isAssignableFrom" method that behaves exactly like 'instanceof' operator but makes it regardless the called classes. The method called on the class A will return true iff the parameter (which is also a java.lang.Class) is a successor of class A (or class A itself).

Example:

>>true - because Integer is a subclass of Number



>>false - because String is not a subclass of Number



>>true - because Number can be assigned to Number (upcasted).



>> false - because String is not a subclass of Number



As we see we the same result could be achieved with 'instanceof'.
But this time we don't need the casting (!); and since any object has a getClass() method, we don't need any information about the object we're going to check. This is impossible if we would chose the 'instanceof' approach:

Example:




2. Accessing the private data of the object.

OK, this sounds like a dirty trick, since it seems to break the encapsulation. But sometimes we need to know what is an internal structure of the class.
So how we can do that?
Imagine we have a fairly simple class A defined like this:


Using the traditional object oriented approach we just don't have a way to modify or even read the value of the field foo outside the class A!
So what should we do?
Let's use reflection :)



The problem is that the field is private therefore the program produces an exception during the runtime:
java.lang.IllegalAccessException: Class Test can not access a member of class A with modifiers "private"
So we have to slightly modify the program. We will say to the java runtime environment: "Its ok, I know that I can access this variable"
The program will look like this:


Now the program will run perfectly and print out the value of "foo" field as expected.
Of course its possible to modify the property:

Now the output would be:
5
10

Thats all, hope you found this short article interesting!

Thursday, April 1, 2010

CGLIB introduction

Today I would like to briefly discuss the bytecode generation framework, CGLIB.

There are a lot of these frameworks, each one works at the different level of abstraction.
Recently I was looking for a high-level framework that would let me to dynamically change my classes providing its proxy and substituting the functionality of some methods.

While the most obvious jdk proxies can do the job (java.lang.reflect.Proxy), I've figured out, that when I don't have both an interface and implementation of my to-be-proxified class, it just doesn't work. So I've found another solution, a library called CGLIB

The only significant drawback for me was a lack of comprehensive documentation, in fact I've found only one decent tutorial here (It could be great if someone could point me on more tutorials about this tool).
Anyway, I think that a beginner's level introduction can't harm so I fill the gap and share the experience :)

So CGLIB is a bytecode generation library, that relies on low-level
ASM framework.
So in order to create a working example we'll need to open a regular java project and add two jars as a dependency (the latest versions available at the moment):

- cglib-2.2.jar
- asm-all-3.2.jar

We will 'proxify' the mock Algorithm class which is supposed to implement some long-running algorithm. We would like to measure its execution time.

So we create our algorithm like this:



Now the most interesting part of the program:
We'll create a class that adds the 'measurements'. This class will be used by CGLIB to proxify our algorithm, so it should implement net.sf.cglib.proxy.MethodInterceptor

The class looks like this:



The last class is the main class. Here we will actually create the proxy so here we'll see some CGLIB related code:



The output of this program is predictable :)

Before
running the algorithm
After
Took: 500 ms

Thats all, thanks for your attention
Mark Bramnik