Close
Back

Vaadin Framework 8 comes with Java 8 native APIs

For a web framework whose history spans back 15 years, Vaadin Framework contains an insane number of modern web technologies. It has been an SPA (single-page application) before the term was coined, it uses WebSockets for a constantly open communication channel, Sass for enhanced theme building and you can easily wrap a WebComponent based JS widgets with a clean Java API for use in Vaadin applications.

We have been really active taking in all the new stuff that has become possible regarding web as an application platform, but we have been rather conservative in taking full advantage of JVM and Java, which has also developed with leaps. In Vaadin 8, we focus the core of the product, the Java API that you use to build your awesome UIs, and make that faster and easier to use.

Most of the API in Vaadin is still valid and perfectly functional. You can even use e.g. lambdas with certain features, but it has been designed in an era with no generics, lambda expressions, method references and even without a proper java.util.collections package.

Getting rid of millstones around our neck

Oracle has dropped their support for Java 7 and IBM has a modern Java 8 support, so nobody on Earth should be using Java 7 or 6. But we know there still are people who are using them. To make big leaps forward we need to let something go. Vaadin 7 will still be supported for the minority of Java developers who are still bound to old Java versions, for one reason or another.

Also, we will be dropping support for some old browsers, most notably IE 8-10. If Microsoft thinks nobody should use them, so should you. We know this is rough for some users, but we just need to go forward. This will make us much more agile to develop our components in upcoming versions.

Backwards compatibility, in terms of API compatibility, is another thing that might make you a bit afraid of the upgrade as well. We won’t promise a 100% backwards compatibility as we want to clean some old methods from our components, but we’re making a special backwards compatibility module which will make upgrading to Vaadin 8 much simpler than the previous Vaadin 6 to Vaadin 7 upgrade.

Data binding renewed - less and simpler code

Most of the renewals in Vaadin 8 will be related to “data binding”: how to connect data to tabular components, how to populate options in select components and how to bind business objects to field components in forms.

Previously Vaadin developers used a lot of proprietary interfaces called Containers, Items and Properties to do the databinding. In the early days of JVM this was a good idea, but in the modern era of Java, most Vaadin developers just wrap their lists of beans using a helper class called BeanItemContainer, and give that container to e.g. Vaadin ComboBox component. In Vaadin 8, we just pass the beans directly to the component.

Also, with previous versions, if there was some customization needed for the presentation, either a custom DTO or tricky work with the Container-Item-Property stuff was needed. Now, you can often change the presentation with a single lambda expression.

The following common use case, implemented with both Vaadin 7 and a pre-release of Vaadin 8 emphasises how dramatic a difference the “containerless” modern API can make:

Before:

ComboBox comboBox = new ComboBox();
List<Contact> contacts = service.findAll();
BeanItemContainer<Contact> beanItemContainer = new BeanItemContainer<>(Contact.class);
GeneratedPropertyContainer gpc = new GeneratedPropertyContainer(beanItemContainer);
gpc.addGeneratedProperty("name_combined", new PropertyValueGenerator() {
   @Override
   public Object getValue(Item item, Object itemId, Object propertyId) {
       String firstName = (String) item.getItemProperty("firstName").getValue();
       String lastName = (String) item.getItemProperty("lastName").getValue();
       return firstName + " " + lastName;
   }

   @Override
   public Class getType() {
       return String.class;
   }

   @Override
   public Container.Filter modifyFilter(final Container.Filter filter) throws UnsupportedFilterException {
       final SimpleStringFilter ssf = (SimpleStringFilter) filter;
 
       return new Container.Filter() {
           @Override
           public boolean passesFilter(Object itemId, Item item) throws UnsupportedOperationException {
               final It/nem generatedItem = gpc.getItem(itemId);
               String fullname = generatedItem.getItemProperty("name_combined").getValue().toString();
               // Ignore case as ComboBox
               return fullname.toLowerCase().startsWith(ssf.getFilterString());
           }
 
           @Override
           public boolean appliesToProperty(Object propertyId) {
               return "name_combined".equals(propertyId);
           }
       };
   }
 
});
comboBox.setContainerDataSource(gpc);
comboBox.setItemCaptionPropertyId("name_combined");

After:

ComboBox<Contact> comboBox = new ComboBox<>();
comboBox.setItems(service.findAll());
comboBox.setItemCaptionProvider(c-> c.getFirstName() + " " + c.getLastName());

Simpler, faster and more readable, that is the code you write with Vaadin 8.

When building forms, in the future you’ll use a concept called BeanBinder, which directly accepts your domain objects. The BeanBinder also contains a lot of cool improvements regarding form validation and makes it much easier to create top notch UX for your end users. The new BeanBinder also gives you much more control to customize how your form works, like where and how to present validation errors. The validation can be executed dynamically, as the user is still typing in, and enabling the primary action only when it can actually be executed. The BeanBinder has full support for cross field validation using JSR 303 validators and you can define your validation rules as a single lambda expression.

The code example below shows how to bind a phone number and email TextField to a Contact bean, with slightly different methods and custom validators.

final Contact contact = new Contact();
 
final TextField phone = new TextField();
final TextField email = new TextField();
Button save = new Button("Save");
 
final Predicate<String> requirePhoneOrEmail = v -> !phone.getValue()
       .trim().isEmpty() || !email.getValue().trim().isEmpty();
 
final BeanBinder<Contact> binder = new BeanBinder<>(Contact.class);
binder.forField(email)
       // cross field validation, both programmatic Vaadin specific
       // style and JSR 303 validators are supported
       .withValidator(requirePhoneOrEmail,
               "Both phone and email cannot be empty")
       // express simple validators using on line lambda expressions
       .withValidator(value -> value.length() > 3,
               "Email must be longer than 3 letters.")
       // or use some of the built in validators, like before
       .withValidator(new EmailValidator("Incorrect email address"))
       // bind to email property in Contact bean
       .bind("email");
 
binder.forField(phone)
       .withValidator(requirePhoneOrEmail,
               "Both phone and email cannot be empty")
       // bind with explicitly set getter and setter lambdas
       .bind(Contact::getPhone, Contact::setPhone);
 
// Trigger cross-field validation when the other field is changed,
// not needed with JSR 303
email.addValueChangeListener(event -> binder.validate());
phone.addValueChangeListener(event -> binder.validate());
 
binder.setStatusHandler(new BinderStatusHandler() {
   @Override
   public void accept(BinderValidationStatus<?> t) {
       // react to validity changes
       save.setEnabled(t.isOk());
   }
});

This is just the tip of the iceberg. There are many other exciting enhancements coming up. For example, a super easy way of connecting lazy loading components to data without a need to build a custom Container. We believe that Vaadin Framework 8 will make your life as a Java developer much easier.

Developer preview released at JavaOne

We have been working a lot on these changes and we are confident that we are on the right track. But at the same time, we also know we have been looking at these changes from a short distance - probably missing some important details about our API. Thus, we want your help! Even though a lot of things are still in flux, you can try out the next generation of Vaadin API today with 8.0.0.alpha2 and help us make web development easier than ever.

As usual, quite a few people from our team are at JavaOne. Come meet with some of the core developers who can answer even the trickiest questions related to the new versions. Visit our booth and the Vaadin Meetup at JavaOne to give us new ideas and get more insights of Vaadin 8!

See the in progress documentation for data model in version 8

 
Comments
Trackback URL:

Add Comment
Posted on 9/19/16 9:22 AM.
Started some days ago exploring Vaadin 8. Great work guys. Thank you
Posted on 9/19/16 9:50 AM.
This is really awesome! Keep going this way guys!!!
Posted on 9/20/16 9:38 AM.
> nobody on Earth should be using Java 7 or 6
Except embedded devices. Try to run Vaadin on RaspberryPi. Vaadin itself is small, but JRE is the problem. To solve this issue, Java8 introduced compact profiles. Compact3 uses 24MB, full JRE 140MB. Unfortunately, Vaadin needs full Java stack due to java.beans dependency. In fact, there are not many full JRE references in Vaadin code. We replaced java.beans with our introspection library, removed AWT (!?) dependencies in ColorPicker, removed some client code references from server code (and so eliminated installation of huge client jars on the server) and voila - Vaadin runs with compact3 profile on embedded platform with 256 MB RAM emoticon
But I am afraid, Vaadin 8 means out for Vaadin on IoT.
Posted on 9/20/16 9:50 AM.
Can't wait. Just got onto Java 8 and Tomcat 8 in my last sprint. Bring it on!
Posted on 9/28/16 8:52 PM.
I checked the new data binding. Really great job! However, the Tree component is not (yet) included. What is the planning for this component?
Posted on 9/30/16 6:50 AM.
"Oracle has dropped their support for Java 7 and IBM has a modern Java 8 support, so nobody on Earth should be using Java 7 or 6"

Oracle HAS NOT dropped Java 7 support.
Oracle has only dropped FREE Java 7 support.
Also companies like Red Hat still supports Java 7 and 6 (via OpenJDK)
Check your facts before writing stupid statements!
---
Google App Engine Java 8 support is still in BETA stage.
---
"If Microsoft thinks nobody should use them, so should you." - one more stupid statement (who is author of this article?!)
Only client/customer can say, if we must support old IE!
We must do, what paying customer asks (even if it means supporting old IE) and Vaadin must do, what their paying customer asks - even if it means supporting old IE (in Vaadin7 at least).
---
Professional level of article's author is terrible - it is like as he thinks of Vaadin's users are children.
Posted on 10/3/16 12:09 PM.
You could at least be somewhat respectful with your comments.
Posted on 10/3/16 3:09 PM in reply to Normunds Mazurs.
How about respect for professional programmers from author in first place?!
For example:
"Ladies and gentlemen (or fellow developers), we introduce new version of Vaadin framework.
This new version of framework have new features: ....
Those features were implemented because of: ....
This new version of framework have additional limitations: .....
Those limitations are because of: ......
Any framework user can still use older version x.x.z of framework, which does not have those limitations. Older version will be supported for X time or until paying customers pays for support."

This is respectful tone and not patronizing manner in which article is written!
Posted on 10/4/16 8:51 AM in reply to Adam Brusselback.
Good work, especially the data binding improvements.

Maybe you can think about serialization and provide some guidelines in Vaadin documentation and blog posts how to use DataSource with non-serializable services:

com.vaadin.server.data.DataSources must be Serializable - and that means the two functions provided as arguments for BackEndDataSource must be serializable.
On the other hand, JPA DAOs or Repositories or other service implementations are not serializable per-se. That means forwarding methods from services and repositories as lambdas sacrifices the Vaadin API requirements (which impose an indirect requirement on serializable data-provider-functions).

If Vaadin does not want to help the developer by doing the serialization job I'd appreciate some help and guide-lines for how you think we should do it.
Posted on 10/12/16 3:01 PM.
Good stuff.
In the last code snippet, should there be another statement such as "binder.setBean(contact)" to complete the example?
Posted on 11/12/16 2:36 PM.
I sense a lot of hatred. The dark force is strong with this one.
Posted on 1/6/17 7:46 AM in reply to Normunds Mazurs.