Red Hat

In Relation To Bean Validation

In Relation To Bean Validation

So it's official Bean Validation 1.1 has started. It has been voted yes by the JCP expert committee yesterday.

I must admit I'm quite furious about Mark Little, the Red Hat representative and my boss, for forgetting to vote on the ballot. But provided he went on vacations last Friday and has a lot on his plate, I forgive him. You owe me though :)

More seriously, Red Hat is committed to make Bean Validation 1.1 a success and I will spend the next couple of days gathering the expert group members to get started as quickly as possible.

In the mean time and to celebrate, have a look at the official beanvalidation.org website. The idea behind the website are simple:

  • execute on the promise to run the spec in an open fashion
  • offer regular updates on the work in progress (see the news section)
  • a one time shop for everything Bean Validation related

There are several ways for you to participate in the process. From joining the development mailing list to joining the expert group full blown. Check out the contribution page.

Hibernate Validator 4.2.0.CR1

Posted by    |       |    Tagged as Bean Validation Hibernate Validator

Hibernate Validator 4.2.0.CR1 is finally ready for download via the JBoss Maven Repository or SourceForge. We promise you won't have to wait so long for 4.2.0.Final. In total we addressed 28 issues. Most of the issues where minor bug fixes, documentation and code refactorings. Thanks you everyone providing bug reports and helping us to make Validator even better :-)

The biggest change is the ability to now also configure method level validation programmatically. To implement this in an unambiguous way we had to make yet some more changes to the programmatic API. Remember how the programmatic API looked like in Beta2? Here is an example:

ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
    .property( "manufacturer", FIELD )
        .constraint( NotNullDef.class )
    .property( "licensePlate", FIELD )
        .constraint( NotNullDef.class )
        .constraint( SizeDef.class )
            .min( 2 )
            .max( 14 )
    .property( "seatCount", FIELD )
        .constraint( MinDef.class )
            .value ( 2 )
.type( RentalCar.class )
    .property( "rentalStation", METHOD)
        .constraint( NotNullDef.class ); 

With the CR1 API the same example looks like:

ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
    .property( "manufacturer", FIELD )
        .constraint( new NotNullDef() )
    .property( "licensePlate", FIELD )
        .constraint( new NotNullDef() )
        .constraint( new SizeDef()
            .min( 2 )
            .max( 14 ) )
    .property( "seatCount", FIELD )
        .constraint( new MinDef()
            .value ( 2 ) )
.type( RentalCar.class )
    .property( "rentalStation", METHOD )
        .constraint( new NotNullDef() ); 

As you can see the difference is that you now have to instantiate the definition classes. That's all. Not too bad, right? Programmatic method level validation looks like this:

ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
    .method( "drive", String.class, Integer.class )
        .parameter( 0 )
            .constraint( new NotNullDef() )
            .constraint( new MinDef().value ( 1 ) )
        .parameter( 1 )
            .constraint( new NotNullDef() )
        .returnValue()
            .constraint( new NotNullDef() )
    .method( "check" )
        .returnValue()
            .constraint( new NotNullDef() );   

You find the full change log for this release here. Please provide feedback via the Validator Forum and the Jira issue tracker.

Thanks to Gunnar and Kevin to once more were driving most of the work.

Enjoy!

P.S. If you have any opinion what should go into Bean Validation 1.1 let us know!

Seam Module Spotlight - Seam Validation

Posted by    |       |    Tagged as Bean Validation CDI Seam

I'm pleased to be able to present this week's module spotlight which was written by Gunnar Morling, the module lead for Seam Validation. - Shane.

by Gunnar Morling

Welcome back to the Seam Module Spotlight series. In this installment we're going to discuss a relatively new Seam module, Seam Validation.

This module provides an integration between Hibernate Validator which is the reference implementation of the Bean Validation standard (JSR 303) and CDI. The module's functionality falls into two areas:

  • Enhanced dependency injection services for validators, validator factories and constraint validators
  • Automatic validation of method parameters and return values based on Hibernate Validator's method validation API

Let's take a closer look at these features in the following sections.

Dependency injection services

The Bean Validation API is an integral part of the Java EE platform. So when running on a Java EE 6 compatible application server such as JBoss AS 6 you can easily retrieve Validator and ValidatorFactory instances via dependency injection.

Unfortunately this is not working out of the box when running in non-EE environments such as plain servlet containers. But don't worry, Seam Validation comes to the rescue. By adding the module as dependency to your project, validators and validator factories can be obtained using @Inject:

public class Foo {

   @Inject
   private Validator validator;

   public void doSomething() {

      Bar bar = new Bar();
		
      Set<ConstraintViolation<Bar>> constraintViolations = validator.validate(bar);
      //examine the violations ...
   }
}

But Seam Validation goes one step further and enables dependency injection also within constraint validator implementations. For instance we might have a custom constraint @ValidLicensePlate which is used to ensure that a car has a license plate which is properly registered, still valid etc.:

public class Car {

   @ValidLicensePlate
   private String licensePlate;
	
   //constructor, getter, setter etc.
}

In order to perform the required checks the constraint's validator invokes some sort of registration service (note: accessing external services can potentially be an expensive operation, so it may be a good idea to put the constraint into a separate validation group, but that's out of scope for this article). The Seam Validation module allows to inject this service into the validator as into any other CDI bean:

public class ValidLicensePlateValidator implements ConstraintValidator<ValidLicensePlate, String> {

   @Inject
   private RegistrationService registrationService;

   @Override
   public void initialize(ValidLicensePlate constraintAnnotation) {
   }

   @Override
   public boolean isValid(String value, ConstraintValidatorContext context) {

   if (value == null) {
      return true;
   }

   //delegate to registration service
   return registrationService.isValid(value);
   }
}

There is just one more step required before the @ValidLicensePlate constraint can be used: We have to register Seam Validation's constraint validator factory with the Bean Validation provider. This happens by putting a file named validation.xml with the following content into the META-INF folder of the application:

<?xml version="1.0" encoding="UTF-8"?>
<validation-config 
  xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.0.xsd">

   <constraint-validator-factory>
      org.jboss.seam.validation.InjectingConstraintValidatorFactory
   </constraint-validator-factory>
</validation-config>

Method validation

The other main feature of Seam Validation besides dependency injection is the automatic validation of method parameters and return values based on the API for method validation introduced with Hibernate Validator 4.2 (note: at the time of writing Hibernate Validator 4.2 is released as Beta version, but no major changes are expected until the final release).

This API provides an easy-to-use facility for the Programming by Contract approach to program design based on the concepts defined by the Bean Validation API. That means that any Bean Validation constraint can be used to describe

  • the preconditions that must be met before a method may be invoked (by annotating method parameters with constraints) and
  • the postconditions that are guaranteed after a method invocation returns (by annotating methods).

Things should become clearer with an example:

@AutoValidating
public class RentalStation {

   @Valid
   public Car rentCar(@NotNull CustomerPK customerPK, @NotNull @Future Date startDate, @Min(1) int durationInDays) {

      //highly complex car rental business logic ...
   }
}

Here the following pre- and postconditions are applied onto the rentCar() method:

  • The customer's primary key may not be null
  • The rental start date must not be null and must be in the future
  • The rental duration must be at least one day
  • The returned object must be valid with respect to all constraints of the Car class

By annotating the class RentalStation with @AutoValidating, all these constraints are automatically validated by a method interceptor whenever the rentCar() method is invoked. If any of the constraints can't be validated successfully, a runtime exception describing the occurred constraint violation(s) is thrown.

This approach has several advantages over traditional parameter and return value checking:

  • The checks don't have to be performed by hand. This results in less boiler-plate code to write (and to read).
  • A method's pre- and postconditions are part of its API and generated documentation. It's not necessary to add comments such as returns never null, as this information will automatically be put into the generated JavaDoc. This results in less redundancies and hence in less potential inconsistencies between implementation and documentation.

Future steps

This concludes our short tour through the Seam Validation module. If you feel like trying out the module yourself, the module home page is the right starting point. You might also be interested in the module's reference guide, and in case you found a bug or want to create a feature request the module's JIRA instance is the place to go.

Possible future developments of Seam Validation include a closer integration with other Seam 3 modules, the possibility to choose the validation groups to be used for method validation and the evaluation of standard bean constraints upon method validation.

Hibernate Validator 4.2.0.Beta2

Posted by    |       |    Tagged as Bean Validation Hibernate Validator

Hibernate Validator 4.2.0.Beta2 is bottled up and ready for consumption via the JBoss Maven Repository or SourceForge.

Since Beta1 we have been focusing on method level validation details and bug fixes. One important issue in this regard is HV-421 which defines the behavior of parameter constraint validation. Generally a logical AND is used to combine all constraints defined within a class hierarchy on a given field or method. Doing the same for method parameter constraints, however, causes ambiguities with the definition of Programming by contract where subtypes may only weaken preconditions defined by supertypes. In order to support this one would have to combine all parameter constraints within a hierarchy using an OR. A conservative alternative (the one we chose for this release) is to prohibit multiple parameter constraints on the same parameter within a class hierarchy. HV-421 discusses in more detail. We are very interested in feedback on this.

Another method level validation related feature is the extension of the meta data API (HV-440). We introduced three more interfaces TypeDescriptor, MethodDescriptor and ParameterDescriptor which you can all find in the org.hibernate.validator.method.metadata package. Here is an usage example:

 MethodValidator validator = Validation.byProvider( HibernateValidator.class )
    .configure()
    .buildValidatorFactory()
    .getValidator()
    .unwrap( MethodValidator.class );

TypeDescriptor typeDescriptor = validator.getConstraintsForType( clazz );
...
Set<MethodDescriptor> constrainedMethods = descriptor.getConstrainedMethods();
...
List<ParameterDescriptor> parameterConstraints = methodDescriptor.getParameterConstraints();
ParameterDescriptor parameterDescriptor = parameterConstraints.get( 0 );
assertTrue( parameterDescriptor.hasConstraints() );
...
Note: MethodValidator.validateParameters was renamed into MethodValidator.validateAllParameters (HV-415).

To mention at least one method level validation unrelated feature - Hibernate Validator has now a fail fast option. When enabled, validation will terminate on the first validation error. This could be interesting for large object graph validation. You can enable the fail fast flag for example via:

ValidatorFactory factory = Validation.byProvider( HibernateValidator.class )
                             .configure()
                             .failFast( true )
                             .buildValidatorFactory();
You find the full change log for this release here. Please provide feedback via the Validator Forum and the Jira issue tracker.

Enjoy!

P.S. For all the Seam people out there. Gunnar started a new Seam 3 module called SeamValidation which offers amongst other a CDI extension for method level validation. Check it out!

P.P.S. Make sure to also provide feedback on what we should include into Bean Validation 1.1

JSR - Bean Validation 1.1: what to put in?

Posted by    |       |    Tagged as Bean Validation

As you may have noticed, it's almost spring cleaning time and everyone pushes its new JSR proposal following EE 7. I wanted to share with you what I had in mind for Bean Validation. This is by no mean a definite list but more a starting point to discuss things further. In the end the EG and the community will shape the spec.

First off, I think people have been very pleased with Bean Validation (no major flaw nor big limitation). So the idea is to go for a version 1.1 rather than a 2.0.

Integration with other specs

While not part of the Bean Validation JSR, I think it is important to pursue further collaborative work with some other JSR leads on how to integrate Bean Validation into the various lifecycles of the SE/EE platforms. Certainly nobody wants each specification to invent its own validation mechanism and its own annotations. The work we did with JPA 2 and JSF 2 showed that it is possible and beneficial for the platform and developers.

  • JAX-RS: call Bean Validation upon HTTP method calls on parameters. If a parameter is not valid, JAX-RS could return the appropriate HTTP error code as well as some payload describing the error.
  • JAXB: some people have asked for integration between Bean Validation and JAXB. Basically, the Bean Validation constraints (at least the fundamental ones) could be converted into the XML schema descriptor (and vice versa) to guarantee a unified propagation between the Java land and the XML land. I have been exploring some of the needs with Martin Grebac and I hope we can converge.
  • JPA: improve the integration by letting Bean Validation constraints influence the DDL generated with the constraints declared on the entity model
  • CDI: offer a way for Bean Validation pluggable components to allow CDI style injection (in particular constraint validator implementations)
  • CDI: integrate method-level validation (see below)

Method level validation

The idea is to offer APIs to validate parameters and return values of method calls. These APIs would be used by any injection or AOP framework around method invocations. If a constraint violation is detected, an exception (eg. ConstraintViolationException) would be raised.

public class OrderManager {
  public void processOrder(@Valid Order order, @Min(0) @Max(30) int retry) {
    doProcessOrder(...)
  }
}

if Order contains constraint violations or if retry's value is not between 0 and 30, a ConstraintViolationException will be raised by the interceptor framework.

Interceptor frameworks could be:

  • CDI: some stereotyped interceptor could trigger the method validations when accessed
  • AOP style framework like Javassist or AspectJ

@Valid and group propagation

Some people have required the ability to translate a group into another group while cascading the validation. This can help reduce the number of groups and increase reuse.

public class Address {
  @NotNull String city;
  
  @Valid(from=Default.class, to=EnhancedGroup.class)
  Country country;
}

public class Country {
  @NotNull(groups=EnhancedGroup.class) 
  String name;

  @Size(min=2, max=2, groups=EnhancedGroup.class) 
  String iso2; 
}

Apply constraints on elements of collection

While we can validate constraints on the collection itself and ask to cascade validation to the elements of the collection, we cannot put constraints on the collection element itself. This is annoying for collection of native types in particular. There are several not so elegant solutions to this problem, the real solution is to wait for Annotations on Java types (JSR-308)

Collection<@NotNull String> names;

Depending on when JSR-308 finally comes out, we might want to delay this feature.

Various issues

In no particular order, here are a few issues or features we can also try to tackle.

Constraint composition

Today constraint composition is done with a logical AND (all constraints must be valid). We could also support logical OR composition.

@ConstraintComposition(OR)
@SSN
@TemporarySSN
@Constraint(validatedBy = { })
@ReportAsSingleViolation
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
public @interface ValidSSN {
	String message() default "Not a valid social security number";
	Class<?>[] groups() default { };
	Class<? extends Payload>[] payload() default { };
}

JTA and exception propagation

In EE, there are some inconsistencies on how exceptions are raised:

  • while in the process of a business method
  • raised by the declarative or explicit commit() calls

Basically when operations (like validation) are triggered within the declarative commit(), everything I believe is wrapped into a RollbackException. Which means that depending when JPA's flush() is called, ConstraintViolationException (raised by JPA) comes either untainted or comes wrapped in RollbackException. I wonder if we can fix this inconsistency.

Better rules for OSGi style containers

Some extreme modularity fanboys have complained about some fuzziness in the spec around visibility and classloaders. We should clarify that.

Exclusive flag on @BigDecimal / @BigInteger

Allow to exclude limits.

ConstraintViolationException builder

The idea is to provide a simple API to build consistent ConstraintViolationExceptions. Because Bean Validation is usually called by the lifecycle of other specifications or frameworks, it is their responsibility to raise the exception.

Your participation

That's all I have. I am sure I'm missing many improvements so please speak up. You can do it however it pleases you:

And of course, you can always go one fork ahead.

From this first wave of feedback, I plan to propose a JSR to the JCP.

Note that Hibernate Validator 4.2 has or will integrate some of these features which will provide us feedback.

Emmanuel

Vote for Pedro

Posted by    |       |    Tagged as Bean Validation Hibernate Validator

Well not really ;)

We have talked about Gunnar and Kevin that have and are still doing an awesome job on Hibernate Validator, especially for the last release and the current one in development. Please consider voting for them for the JBoss.org recognition awards.

Gunnar Morling is nominated in the:

The new method validation feature is all his for example.

And Kevin Pollet is nominated in the:

He fixed many bugs but also added some nice cool features like Joda-time support.

At JavaOne this year, I gave a more advanced presentation than usual on how to use Bean Validation. A few folks have asked me to share it and there it is.

A bit of warning though, this is a presentation that is best seen live as I talk a lot on my slides and even more during the live demo. I am not the kind of person that reads its slides and the demo part is probably about 50% of the presentation so if you can see Hardy or me doing this presentation live, by all means go.

But in the mean time, here are the slides BeanValidationBestPractices-1.0.pdf[1]. I have also put the demo code on a git repository. Simply do

//retrieve the GIT repository
git clone http://emmanuelbernard.com/various/presentations/beanvalidation-bestpractices/beanvalidation-bestpractices.git bv-bp
cd bv-bp

//checkout the demo when starting
git checkout -b demo-start-branch demo-start-state

//checkout the demo when done
git checkout -b branch-demo-done demo-done-state

//hack

I've defined two tags:

  • demo-start-state which correspond to the demo when I start working on it on stage
  • demo-done-state which correspond to the demo when I am done and leave the stage

I have left a bunch of TODOs in the start state and described what I do in a txt file at the root, you should be able to follow.

Enjoy

Bean Validation for Flex developers

Posted by    |       |    Tagged as Bean Validation

I have recently posted about the ability to use Bean Validation with various presentation technologies (here and there). Now Flex is part of the family. The good guys at GraniteDS have added support for Bean Validation into their project and hence Bean Validation is usable by all Flex users.

The work was not as straightforward as for JSF, Wicket or other Java technologies. Because they do not run on the JVM, they basically have reimplemented the full specification in Flex:

  • you can annotate your ActionScript3 objects with constraints: it supports all the standard constraints and you can write your own constraints
  • you can execute the validation logic and retrieve the error report
  • you can make use of most of the feature including advanced ones like groups, group sequence etc

And just like we did with JSF 2 and Bean Validation, the Flex forms do transparently call the constraints based on your domain model. What's also interesting for GraniteDS users keeping their Java domain model and ActionScript3 domain model in sync via Gas3, the constraints are kept in sync.

There are a couple of gotchas to be aware of. The port is not a one-to-one copy: some interfaces or design choice did not make sense due to how ActionScript3 works but overall this is a very close port

  • the constraint implementation is in the same class as the constraint declaration (not a problem in a dynamic language)
  • @Pattern has a sightly different semantic because the regexp engine in Flex is a bit different.
  • instead of the features provided by ConstraintValidatorContext, you can define a properties attribute in your constraints to make it belong to several sub-properties. not as flexible but good enough in many cases.
  • and maybe a few other things

Anyways, I won't talk to Franck until he has a 100% compliant implementation of the spec ;) Actually, I've got one real RFE: the documentation for this new validation module is part of the 'Advanced AS3 Features' chapter. I think this feature is simple enough and useful enough to warrant a better place.

To get the full documentation, check it out here. This is all part of the upcoming 2.2 version of GraniteDS.

PS: GraniteDS 2.2 also provides a full implementation of arbitrary-precision numbers, something that is surprisingly lacking from the Flex platform. So if you use Flex and are in banks or any other number crunching industry, check out their BigInteger and BigDecimal implementation.

Gunnar asked me an interesting question on Bean Validation. Instead of keeping the knowledge private, I thought it would be useful to share more wildly.

Is it possible to determine whether a given constraint is specified at field or property level using the constraint metadata API?

First off, in many case you don't need to do the distinction. Had Java support properties from the ground up, we would not have this problem (sigh).

Anyways, the answer is yes. You can fine tune what is returned from the metadata API.

PropertyDescriptor property = 
    validator.getConstraintsForClass(Address.class)
               .getConstraintsForProperty("street1");

Set<ConstraintDescriptor<?>> fieldConstraints =
    property
        .findConstraints()
            .lookingAt(Scope.LOCAL_ELEMENT)
            .declaredOn(ElementType.FIELD)
            .getConstraintDescriptors();

Set<ConstraintDescriptor<?>> propertyConstraints =
    property
        .findConstraints()
            .lookingAt(Scope.LOCAL_ELEMENT)
            .declaredOn(ElementType.METHOD)
            .getConstraintDescriptors();

The key here is the use of the findConstraints() fluent API. You have three ways to restrict the metadata retrieved:

  • declaredOn(ElementType... types): defines where to look the constraints (METHOD, FIELD etc)
  • lookingAt(Scope scope): defines whether to look for constraints hosted on superclass/interfaces (default) or not
  • unorderedAndMatchingGroups(Class<?>... groups): restrict to the constraints matching a given set of groups for this element (note that the ordering of group sequences is not respected)

That's all.

There are no functional changes between CR1 and this Final release. Some minor issues in the @Min, @Max and @EmailValidator got fixed (HV-335, HV-339) as well as some documentation typos. We also spend some time improving the parsing and validation speed by reviewing and improving some reflection based code (HV-340, HV-341, HV-342). Review the full release notes for details.

Download as usual either from the JBoss Maven repo or from SourceForge.

There are already several issues on the 4.2 roadmap, but we are welcoming ideas and suggestions for the next release on the Validator Forum. One of the major new features will most likely be method-level validation (as specified in Appendix C of the Bean Validation specification) as well.

Stay tuned!

Amendment: Gunnar did a great job summarizing the new features of Hibernate Validator 4.1 on his blog. And of course we covered already most of the new features here as well. See programmatic constraint configuration, ResourceBundleLocator and @ScriptAssert.

back to top