Sunday, October 9, 2011

Bookmark and Share

While working on a little pet project based on OSGi I wanted to use the Pax Runner Eclipse plug-in to launch my OSGi application on the Apache Felix OSGi framework.

Unfortunately this attempt resulted in the following error:

1
2
3
4
5
6
7
8
9
10
java.lang.NoClassDefFoundError: org/eclipse/pde/internal/ui/launcher/LaunchArgumentsHelper
at org.ops4j.pax.cursor.Utils.getVMArgsOptions(Utils.java:216)
at org.ops4j.pax.cursor.LaunchConfiguration.getProgramArguments(LaunchConfiguration.java:156)
at org.eclipse.pde.launching.AbstractPDELaunchConfiguration.launch(AbstractPDELaunchConfiguration.java:72)
at org.eclipse.pde.launching.OSGiLaunchConfigurationDelegate.launch(OSGiLaunchConfigurationDelegate.java:47)
at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:853)
at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:702)
at org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(DebugUIPlugin.java:923)
at org.eclipse.debug.internal.ui.DebugUIPlugin$8.run(DebugUIPlugin.java:1126)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)

This looked pretty much like an incompatability between the Pax Runner plug-in and the Eclipse platform. And indeed the plug-in unfortunately doesn't seem to keep up with PDE-internal changes in recent Eclipse versions due to limited developer resources.

Further googling then led me to PAXRUNNER-353 at Pax Runner's issue tracker.

The ticket itself is not yet resolved, but the good news is that Christian Baranowski (whom I had the pleasure to meet during the OSGi code camp last week) created a fork on GitHub fixing the issue for now. So let's hope that this fix gets quickly merged into the main branch.

Until then Christian even has established a temporary Eclipse update site which makes upgrading the plug-in to the forked version a breeze.

So my kudos go to Christian (for fixing the plug-in) and to GitHub (for making forking easy) :-)

Monday, August 1, 2011

Bookmark and Share

Maybe you know it already: last week JSR 349 successfully passed the review ballot, meaning that the work on a new release of the Bean Validation API has officially started.

I'm really excited about this, because I've got the pleasure to be part of the JSR 349 expert group. I haven't been member of such a comitee before, so I guess this will be exciting times and I'll surely learn a whole lot of new things during the work on the specification.

What's most important right now is your feedback: what new features would you like to see included in Bean Validation 1.1, what problems did you face when working with BV 1.0 which you think should be addressed in the next release?

Your input and feedback is highly welcome at several places:

  • The Bean Validation feedback forum is a good platform for discussing ideas, requests for clarifications etc.
  • For concrete feature requests or bug reports you can open an issue at the Bean Validation issue tracker

As a starting point you might want to check out these two blog posts by Emmanuel Bernard (the Bean Validation spec. lead), where a lot of possible features are discussed.

Finally I'd like to point your attention to http://beanvalidation.org/, the JSR's official web site. There you'll find everything related, e.g. a news section, the road map and also the Bean Validation 1.0 spec. document for reference.

Now it's up to you – tell us what would YOU like to see included in Bean Validation 1.1.

Sunday, May 8, 2011

Bookmark and Share

Note: This article originally appeared on in.relation.to as part of the Seam Module Spotlight series. In order to spread the word on Seam Validation I thought it might be a good idea to post it in this blog, too.

Seam Validation is a relatively new Seam module which 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.

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
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.:

1
2
3
4
5
6
7
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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 on 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:

1
2
3
4
5
6
7
8
9
10
<?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:

1
2
3
4
5
6
7
8
9
@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 chose the validation groups to be used for method validation and the evaluation of standard bean constraints upon method validation.

Saturday, March 5, 2011

Bookmark and Share

I need your help.

To be more concise, I need your vote for the 2011 JBoss Community Recognition Awards.

These awards are an effort of JBoss/Red Hat to honor significant contributions to the JBoss community over the last year and I'm more than proud to say that I've been nominated in the "New Features" category for my contributions to Hibernate Validator.

So if you appreciate my work on Hibernate Validator – e.g. the HV annotation processor or the method validation feature I've built for HV 4.2 – or the Validation module for Seam 3 (I'll blog on this in a separate post) I've recently started, just head over to the poll and give me your vote. The voting is open until April, 2nd.

And if you really like my work, go and tell your friends that they should vote for me, too.

Just in case you feel like you need some more information to make a profound vote you might also check out my nominee description.

Another nomination I'd like to mention is the one of my fellow developer Kevin Pollet in the "Bug Fixes" category. He has done some really awesome work for HV 4.2. Besides fixing many bugs he implemented several new features like the integration with the Joda time API or the support for dynamic default group sequence definitions.

So when you (and your friends) have voted for me, don't forget to vote for Kevin, too :)

Sunday, January 16, 2011

Bookmark and Share

Earlier this week the first beta version of Hibernate Validator 4.2 was released. Hardy's announcement on in.relation.to describes in detail what's new in this release, so be sure to check it out.

One of the new features I'm really excited about is method validation, which I therefore would like to discuss in more detail in the following.

What's it about?

Up to now constraint annotations were only supported at fields or at getter methods for property constraints and at type declarations for class-level constraints.

With HV 4.2 it is now also possible to use constraint annotations for a programming style known as "Programming by Contract". More specifically this means that any Bean Validation constraints (built-in as well as custom constraints) can be used to specify

  • any preconditions that must be met before a method invocation (by annotating method parameters with constraints) and
  • any postconditions that are guaranteed after a method invocation (by annotating methods)

As example let's consider the following class from a fictitious video rental application:

1
2
3
4
5
6
7
8
9
public class MovieRepository {

    public @NotNull Set<Movie> findMoviesByTitle( 
        @NotNull @Size(min = 3) String title) {

        //search movie in database ...
    }   

}

The following pre- and postconditions will hold here (provided the method validation is triggered automatically by some integration layer, see below):

  • The title parameter is guaranteed to be not null and at least 3 characters long
  • The return set of movies is guaranteed to be not null

Compared to traditional ways of parameter or result value checking this approach has two big advantages:

  • These checks don't have to be performed manually, which results in less code to write and maintain. You'll never again have to throw IllegalArgumentExceptions or similar by hand.
  • The pre- and postconditions of a method don't have to be expressed again in the method's JavaDoc, since any of it's annotations will automatically be included in the generated JavaDoc. This means less redundancy which reduces the chance of inconsistencies between implementation and comments.

Method validation is not restricted to constraints related to parameters or to return values themselves. Using the @Valid annotation it is also possible to recursively validate parameters or return values:

1
2
3
4
5
6
7
8
public class UserRepository {

    public void persistUser(@NotNull @Valid User user) {

        //persist user in database ...
    }   

}

In this example not only the @NotNull constraint at the user parameter would be checked, but also any constraints defined at the User type. As known from standard Bean Validation the @Valid annotation could also be applied to array-, Iterable- and Map-typed parameters or return values.

The MethodValidator interface

For the purposes of method validation Hibernate Validator defines the new interface MethodValidator (any type or method names are working titles and might change until HV 4.2 is final), which provides methods for parameter and return value validation:

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface MethodValidator {

    public <T> Set<MethodConstraintViolation<T>> validateParameter(
        T object, Method method, Object parameterValue, 
        int parameterIndex, Class<?>... groups);

    public <T> Set<MethodConstraintViolation<T>> validateParameters(
        T object, Method method, Object[] parameterValues, Class<?>... groups);

    public <T> Set<MethodConstraintViolation<T>> validateReturnValue(
        T object, Method method, Object returnValue, Class<?>... groups);

}

To get hold of a method validator, unwrap an instance of HV's Validator implementation as follows:

1
2
3
4
5
MethodValidator validator = Validation.byProvider( HibernateValidator.class )
    .configure()
    .buildValidatorFactory()
    .getValidator()
    .unwrap( MethodValidator.class );

All of MethodValidator's methods return a set of MethodConstraintValidations which describe in detail any constraint violations that occurred during validation. MethodConstraintValidation extends the standard ConstraintViolation and provides additional information such as method and parameter causing a constraint violation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public interface MethodConstraintViolation<T> extends ConstraintViolation<T> {

    public static enum Kind {

        PARAMETER,

        RETURN_VALUE
    }

    Method getMethod();

    Integer getParameterIndex();

    String getParameterName();

    Kind getKind();
}

Unfortunately the byte code of a Java program normally doesn't contain any information on parameter names, therefore getParameterName() for now returns synthetic names such as arg0 etc. For a future release we are investigating approaches for parameter naming, e.g. by leveraging JSR 330's @Named annotation. I created a JIRA issue for this, so if you have any feedback on this just add a comment to the ticket.

Triggering method validation

Hibernate Validator itself only provides the engine for method validation but it does not deal with triggering such a validation.

Instead this is typically done using frameworks/APIs which provide AOP or method interception services such as AspectJ or CDI. But also plain Java dynamic proxies can basically do the trick.

Typically such a validation interceptor does the following:

  • intercept each method call to be validated,
  • validate the invocation's parameter values,
  • proceed with the method invocation and
  • finally validate the invocation's return value.

If any of the two validation steps yields one ore more constraint violations the interceptor typically throws a MethodConstraintViolationException containing the constraint violations that have occurred.

Trying it out yourself

To see whether method validation works out as intended I started a project at GitHub called methodvalidation-integration which provides validation handlers for some interception technologies popular these days.

Currently there are implementations for CDI as well as Google Guice and an InvocationHandler which can be used with JDK dynamic proxies. I also plan to add support for Spring AOP/AspectJ when time permits.

To try method validation out yourself just get the bits from GitHub and have a look at the test in each of the sub-projects. Just give it a try and let me know how everything works.

Future steps

This post introduced the new method validation feature which will be part of Hibernate Validator 4.2. The first beta release contains the basic implementations of this, so we are more than interested in you feedback on this. Please report any bugs in HV's JIRA instance, any questions or ideas for improvement are also highly welcome in HV's forum.

For HV 4.2 Beta2 we plan to add documentation on the method validation feature to HV's reference guide which will also describe some advanced topics such as using method validation with group sequences etc. We will also add support for method level constraints to the constraint meta-data API.

Two further ideas scheduled for after 4.2 are providing the ability to specify method level constraints using XML and using the programmatic constraint configuration API.