First Alpha of Bean Validation 2.0 Reference Implementation Available

by Gunnar Morling on 16 Feb 2017 release

A few days after the release of the Bean Validation 2.0 Early Draft 1 there is now also a first version of the reference implementation available.

If you are using Apache Maven, add the following dependency to your pom.xml to give it a test ride:

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.0.Alpha1</version>
</dependency>

The 6.0.0.Alpha1 release provides all the functionality of the Early Draft 1. In addition there is support for

  • nested type argument constraints, e.g. Map<String, Size(min=1) List<@NotNull Item>> itemsByCategory; this addresses open question #1 from the proposal for the validation of container elements

  • definition of constraints using Lambda expressions and method references

  • validation of java.time.Duration via two new constraints, @DurationMin and @DurationMax

If you think those things should be added to the spec, please let us know. Your feedback on these features as well as all the other Early Draft 1 additions will be much appreciated!

Check out the original Hibernate Validator release announcement for all the details.

Comments

Bean Validation 2.0 Early Draft 1 is Out

by Gunnar Morling on 14 Feb 2017 release

I’m very happy to announce the first Early Draft Review of JSR 380, Bean Validation 2.0!

This Early Draft comprises all the spec changes done so far and it’s a great opportunity for us to get feedback from the community at large. You can read the spec draft either directly on this website or download it from jcp.org. A GitHub diff showing all the changes to the spec’s AsciiDoc document done so far (sans some typo and style fixes) is available here.

The updated API can be downloaded from from jcp.org or fetched from Maven Central using the coordinates javax.validation:validation-api:2.0.0.Alpha1.

What’s New?

The main theme of Bean Validation 2.0 is support for and taking advantage of Java 8. This concerns new language features such as type use annotations as well as library additions.

An example of the latter is the support for the new Java 8 date and time API (JSR 310). You can now use @Past and @Future on javax.time types such as Instant, LocalDate etc.:

@Future
private LocalDate deliveryDate;

For types that don’t represent a specific instant but rather an interval of time, you can configure that the current month, year etc. should be considered valid, too, using the new attribute orPresent():

@Past(orPresent=true)
private final Year inceptionYear = Year.of( 2017 );

An example where Bean Validation benefits from new language features in Java 8 is the new mechanism for validating the elements of Collection, Optional and other container types. By annotating type arguments of generic types you can now put constraints to the container elements (as opposed to the container itself):

List<@NotNull @Email String> emails;

Also cascaded validation (@Valid) gets more powerful with that. E.g. you can now perform a cascaded validation of map keys and map values (only values were supported before):

Map<@Valid Customer, @Valid Address> primaryAddressByCustomer;

Another use case for this is validation of values wrapped in a java.util.Optional:

Optional<@Past LocalDate> getRegistrationDate();

We’ve baked in support for type argument constraints on types such as Iterable, Map, Optional and some more, but this isn’t a fixed list. You can plug in custom implementations of the ValueExtractor contract which will allow you to put type argument constraints to other collection types (e.g. Google Guava’s Multimap) or even collection classes from other JVM languages such as Ceylon.

What else?

Support for JSR 310 and type argument constraints are just two of the new features. Some other changes are:

  • All constraints and a few other Bean Validation annotations are repeatable

  • Method parameter names to be shown in error messages are obtained using reflection (if enabled)

  • ConstraintValidator#initialize() is a default method, simplifying the implementation of constraint validators which don’t need to access the annotation state

  • ValidatorFactory extends AutoCloseable, allowing to use it in try-with-resources blocks

To learn more about the changes we’ve done so far, either check out our progress report from a few weeks ago or the specification document itself.

What’s next?

The next step will be to bring the Bean Validation reference implementation, Hibernate Validator, up to par with the Early Draft 1. Most of the work for this has been done already, so you can expect the first Alpha release of Hibernate Validator 6 later this week. This will allow you to play around with all the new features and explore them in more depth.

This release will add some features on top of what is in spec so far, e.g. support for defining constraints using Lambda expressions. We felt it’d be good to gain some experience with this and some other features by putting an implementation into the hands of users before adding them to the spec. More details on that once the reference implementation is out.

In terms of spec changes, some of the next features we are planning to work on are:

  • Adding some new constraints as per our recent survey, e.g. @Email, @NotEmpty, @NotBlank

  • Ability to validate an object and a list of changes (BVAL-214) which would be useful for validating class-level constraints in UI use cases

  • Separating the message interpolation algorithm from the retrieval of messages from resource bundles (BVAL-217)

What can you do to help?

Glad you asked :)

As in its previous versions, Bean Validation 2.0 is developed fully in the open. So we count on your feedback on the Early Draft as well as any other ideas or suggestions you may have around Bean Validation. One area where we are looking for feedback specifically is the proposal for container value validation. There is a list of open questions towards the end of that section. If you have thoughts on any of those, please let us know.

To get a discussion started, just post a comment below, send a message to our mailing list or post in the Bean Validation forum. If you find a bug or have a specific feature request, please raise them in the issue tracker.

And as Bean Validation is a true open source project, contributing e.g. in form of patches is easy, too. Check out the contribution guide to learn more.

Finally, let me say a big thank you to everyone involved with making the Early Draft happen; your work is much appreciated!

Comments

Apache BVal certified as Bean Validation 1.1 implementation

by Gunnar Morling on 07 Feb 2017 news certification

While the work on Bean Validation 2.0 is well underway, I’ve some good news to share on Bean Validation 1.1 today: Apache BVal has been certified as a compliant implementation of the Bean Validation 1.1 spec!

Thanks to the great work of the friendly folks working on Apache BVal and TomEE, it has passed the TCK quite a while ago, so this announcement is long overdue. The tested version is Apache BVal 1.1.2, using the Bean Validation API signatures from org.apache.tomee:javaee-api:7.0-1 and version 1.1.4.Final of the Bean Validation TCK.

The list of certified implementations has been updated accordingly.

Congrats to the BVal team!

Comments

Bean Validation 2.0 Progress Report

by Gunnar Morling on 19 Jan 2017 news progress-report

It has been a few months since we’ve kicked off the work on Bean Validation 2.0 (JSR 380). We have made some good progress, so I’d like to give you a quick update on what has been achieved so far and what the next steps will be. This is planned to be the first post of a regular blog series with JSR 380 status updates.

Expert group formation

It all started with the review ballot of the JCP executive committee on the new JSR. The ballot was approved with a huge majority, allowing the JSR to proceed and create its expert group.

In a short time, individuals and representatives from multiple companies joined the EG, providing input and experiences from different angles and perspectives. This also gives us very good connections to the EGs of other specs such as JAX-RS or java.time (JSR 310) which will be beneficial for creating new (or improving existing) integrations with those.

First changes

With the first EG members on board, we didn’t lose time and began with the work on the new spec revision. One of the initial actions was to convert the spec document from DocBook into the fabulous AsciiDoc format. Using AsciiDoc comes with many advantages which make working on the spec a much more enjoyable experience:

  • It can be written using any text editor

  • Changes are easier to track, e.g. when reviewing pull requests on GitHub

  • We can include actual source files from the API instead of copying them

While that’s primarily a technicality interesting to those working on the spec, it also is beneficial for Bean Validation users, as you for instance can easily track all the changes done so far by examining a simple diff on GitHub.

Support for new date and time API

The primary theme in Bean Validation is the embrace of Java 8. Java 8 comes with a variety of improvements to the language (e.g. Lambda expressions and default methods) but also many useful additions to the class library.

One prominent example of the latter is the new date and time API (JSR 310). Types such as Instant, LocalDate or ZonedDateTime are now supported by the @Past and @Future constraints (BVAL-496):

@Future
private LocalDate deliveryDate;

@Past and @Future now also have a new attribute orPresent():

@Past(orPresent=true)
private final Year inceptionYear = Year.of( 2017 );

That’s useful for types such as Year or LocalDate which don’t represent a specific instant but rather an interval of time and you want to consider the entire current year, day etc. as valid.

Another improvement related to the validation of dates and times is the new ClockProvider extension point. It allows you to specify what is "now" when validating @Past and @Future. That comes in handy for instance if you want to work with the time and time zone of the currently logged in user in a multi-user, multi-timezone application.

But it’s also useful for (re-)running batch jobs with a different logical date than the current one or for testing with a fixed point in time considered as "now":

Validator validator = Validation.byDefaultProvider()
    .configure()
    .clockProvider( () -> Clock.fixed(
        Instant.parse("2017-01-19T11:00:00.00Z" ),  ZoneId.systemDefault() )
    )
    .buildValidatorFactory()
    .getValidator();

Validation of Collection, Optional and other containers

Looking at language changes in Java 8, the newly allowed locations for annotations (type annotations) prove themselves a very useful feature for Bean Validation. By putting constraints to type arguments of parameterized types, it finally gets possible to apply constraints to the elements of collections in a concise and intuitive way (BVAL-508):

List<@NotNull @Email String> emails;

Putting the constraints to the String type argument makes it apparent that they should not be applied to the list object itself, but rather to each contained element.

Similarly, it’s possible to apply constraints to the elements of an array:

String @NotNull @Email[] emails;

Also cascaded validation gets more flexible with that. It’s now possible to mandate that the keys and values of maps should be validated (so far, only values were validated) by using @Valid like this:

Map<@Valid Customer, @Valid Address> primaryAddressByCustomer;

But it doesn’t end there. The spec also defines support for java.util.Optional:

Optional<@Past LocalDate> getRegistrationDate();

As well as for the hierarchy of property types in JavaFX:

Property<@Min(1) Integer> revenue;

Acknowledging that JavaFX provides dedicated non-generic sub-types of Property for specific data types (e.g. StringProperty or IntegerProperty), it is also supported to put constraints on the element itself in this case:

@Min(1)
IntegerProperty revenue;

This becomes possible by defining means of "automatic value unwrapping" for specific types such as the JavaFX ones. Check out the latest spec draft to learn more about how this is handled.

While the spec mandates support for type argument constraints on types such as Iterable, Map, Optional and some more, this can be easily extended via the ValueExtractor contract. This interface is used when the Bean Validation engine needs to obtain the elements of a constrained container.

Custom extractor implementations can be plugged in when bootstrapping a validator, allowing to use type argument constraints with custom collection types such as the ones defined by Google’s Guava library (e.g. Multimap or Table):

ListMultimap<@Valid Customer, @Email String> emailsByCustomer;

We are considering to detect custom extractors using the service loader mechanism, allowing providers of container types to bundle corresponding extractors with their library and making them automatically available to you.

Validation of container elements is by far the most complex feature and we’d like to gather some more feedback on it before committing to it. Hence its current proposal is added as an appendix to the spec draft. We are eager to learn about your thoughts and feedback in general, but it’s especially important for this issue due to its complexity.

We’ve compiled a list of open questions around this proposal. If you have thoughts on any of those, please make sure to let us know, e.g. by commenting below. The snapshot builds of the reference implementation (Maven GAV org.hibernate:hibernate-validator:6.0.0-SNAPSHOT) already implement the current proposal, so you can get it from the JBoss Maven repo in order to play with that feature.

Other improvements

While support for JSR 310 and validation of container elements have been the largest features we’ve been working on so far, there are some more smaller, yet very useful improvements.

E.g. all the built-in constraints are repeatable annotations now, allowing to define them several times without requiring the explicit @List annotation ([BVAL-497]):

@ZipCode(countryCode = "fr", groups = Default.class, message = "zip code is not valid")
@ZipCode(
    countryCode = "fr",
    groups = SuperUser.class,
    message = "zip code invalid. Requires overriding before saving."
)
private String zipCode;

ConstraintValidator#initialize() has an empty default implementation now (BVAL-555), simplifying the implementation of constraint validators that don’t need to access any constraint attributes. You can simply omit the initialize() method:

public class AssertTrueValidator implements ConstraintValidator<AssertTrue, Boolean> {

    @Override
    public boolean isValid(Boolean bool, ConstraintValidatorContext constraintValidatorContext) {
        return bool == null || bool;
    }
}

Another nice improvement is the usage of actual parameter names when reporting constraint violations for constraints on method or constructor parameters (BVAL-498). Provided you have enabled reflective parameter name access during compilation (using -parameters javac option), Path.Node#getName() will return the actual parameter name instead of "arg0", "arg1" for parameter nodes.

Next steps

With all these things in place, we feel it is the right time to put out an Alpha1 release of Bean Validation 2.0 and will post it for Early Draft Review to the JCP within the next days. This should get the discussed changes into the hands of more people out there and will let us improve and hone the features added so far.

In parallel we’ll continue with some other features from the backlog. Issues high on our priority list are:

  • Adding some new constraints as per our recent survey, e.g. @NotEmpty, @NotBlank

  • Separating the notions of message resolver and message interpolator (BVAL-217)

  • Ability to validate an object and a list of changes (BVAL-214)

We also contemplate the idea of using Java 8 Lambda expressions and method references for defining constraints without an explicit ConstraintValidator implementation class. This is already supported in the reference implementation:

ConstraintMapping mapping = ...
mapping.constraintDefinition( Directory.class ) // @Directory is a constraint annotation
    .validateType( File.class ).with( File::exists );

We haven’t decided yet whether to put this into the spec or not. So we recommend you give it a try in the reference implementation and let us know about your thoughts. The feedback when sharing the idea on Twitter was very encouraging.

We are also working with the expert group for JAX-RS 2.1 (JSR 370) to further improve integration of the two specs, e.g. in the field of I18N.

This list of issues is not cast in stone, so if there is anything close to your heart, please speak up and let us know about your ideas.

Outreach

To get more closely in touch with the Bean Validation users out there, we’ve also submitted talks on Bean Validation 2.0 to several conferences. I will be presenting on it at JavaLand 2017 and have plans for some JUGs. You also can expect a new edition of the Asylum Podcast discussing Bean Validation 2.0 and working on a JSR in general in the next weeks. And you can find an interview with me on Bean Validation 2.0 on heise Developer (in German).

Raise your feedback

Bean Validation is a true community effort, so we are eager to learn about your suggestions and proposals. Don’t be shy, get a discussion started by dropping a comment below, posting to the feedback forum or sending a message to the Bean Validation mailing list.

Comments

Survey - Where do you use constraints on parameterized type?

by Emmanuel Bernard on 23 Nov 2016 feedback

For Bean Validation 2, we are working on the support for Collection<@Email String>, Optional<@Min(3) Integer> etc. This has been a very common request and with Java 8 type use support, we can how achieve this. However, we need your feedback on how you would use such feature.

Some context

We have support not only for collections, Optional, Java FX properties but also for what we call custom parameterized containers. We are wondering a few things about custom parameterized containers, namely how common they are. This will affect the trade-offs we want to make on the design of that feature.

What is a container?

A container is a type that wraps and exposes one or several values. The values is what you want to apply your constraints on. And the container is parameterized because at use site, you can declare what type it actually contains. For a Set<@Email String>, we want to make sure every string in the set is an email.

Another less obvious example is a tuple class.

public class Pair<V1,V2> {
    V1 getV1() { ... }
    V2 getV2(); { ... }
}

public class Address {
    // street1 is mandatory, street2 is optional
    // represented via a Pair object
    Pair<@NotNull @Size(max=250) String, @Size(max=250) String> streetFields;
}

Other examples are:

  • a tree structure containing specific object types

  • Guava’s Multimap (or any multimap for that matter)

Questions

We are wondering which type of parameterized containers you have in your code base and how likely you are going to apply constrains on their contained value. The form is a list of short questions that will help us get a better picture.

Here is the link to the form in a separate page or use it directly embedded below.

Many thanks!

Comments