I just had to make the rather painful (well painful for my free time) decision to re-write the project that I and a team member had written in Vaadin with the old standby’s of JQuery, JSP’s, and Spring MVC. There was a lot of frustration that went into maintaining the project over the last year and it simply became very difficult to deliver what the product team wanted in a timely manner. The point of the post is not to bash the framework, but present the difficulties I encountered that made it unusable for us. I described the reasons we picked Vaadin in a previous post Vaadin. Many of the benefits still exist, but some of our core assumptions lead to major headaches down the line.
Integration with Spring
The vast majority of what we do and where we spend our time is on the server. We’ve built large libraries of internal functions that are exposed to other aspects of our application stack through Spring. We use Spring for security, talking to the database, configuring our remoting endpoints, and almost everything else. Unfortunately, you can’t dependency inject the Vaadin
The most sensible pattern is to create a static singleton that has the beans your application needs to access. However, this is very kludgy and somewhat defeats the purpose of dependency injection. Also, since the Application is one monolithic thing, it is impossible to make use of Spring Security filters unless you write the unauthenticated portions of your application outside of Vaadin or in another Vaadin container.
Another problem is most of the advanced DataContainers in Vaadin want to interact directly with the datasource. However, we have services in the middle that abstract access to those systems. Configuring Vaadin to accomplish this was more difficult than it needed to be, leaving the developer with two real choices, hack around Vaadin’s plugins or use basic containers that you initialize yourself.
Very Inconsistent Plugins
To give a specific example, one of the bigger challenges was integrating with the Lazy Query Container. Vaadin defines interfaces to adhere to, but many of them throw
UnsupportedApplicationException, which makes it very difficult for the programmer to figure out what actually needs to be implemented for the desired behavior.
Odd Layout Behavior
When we started the project, we found layout to be very easy. Then we tried to make the look more like some of our existing products, which meant changing some of the default padding, margin, and sizes. All of this has to be done inside Vaadin or by overloading a Vaadin theme. Using normal stylesheets will often get you into trouble since it throws off Vaadin’s resize calculations.
In one concrete example, I added a
HTML content inside of a table. After making that change, there were nearly 30 empty rows at the bottom of that table. Getting rid of the
Label made it work again. It took about 60 lines of Vaadin to accomplish what I had put together in 6 lines of HTML. Also Vaadin sets every DOM element to
overflow: hidden so if one is not careful, all the elements will clip. Setting all the elements to have a different
overflow value is not trivial due to…
Thousands of HTML elements
Open Firebug on even a simple-looking page in Vaadin and you will discover elements that are nested dozens of levels deep. Therefore, even changing something simple about the box model of a specific element involves changing the elements on the tree above it. Things that are taken for granted in today’s web world, such as adjusting the size of an element in Firebug, are impossible.
The other problem is that animations don’t work. The browser can’t re-render the page and move objects out of the way smoothly so any animation looks jerky and odd. I didn’t go through the effort of installing Google Chrome to get a IE6 experience.
Long Cycle Times
In a normal java webapp, you can deploy an exploded war and fix interface issues (JS, CSS, and JSPS) with a reload of a page and firebug. Since it’s impossible to adjust on the fly with firebug and everything in a Vaadin app is written in Java, even a 1px width change requires a rebuild/container restart. What was 3 minutes of firebug fiddling has just turned into 30 minutes of cycling. This would have been less of a problem had we stuck with only Vaadin supplied look and feel, but that is not always an option.
Widgets are Opaque
I had what I thought was a trivial requirement. I need to have a start date and an end date. The dates can only cover a 90-day window and the end date can only be 30 days after the start date. I wanted the date widget to disable any dates outside of this range. This turned out to be unsupported. I almost said “impossible,” but that’s not true. I spent about a day digging through Vaadin’s source to where it interacted with GWT, back to Vaadin’s source and so on until I discovered the small change I had to make to support this feature and wrote a custom widget. However, none of this was documented wasn’t part of the official API.
Whatever success I felt at finding the solution dissipated the when we attempted to upgrade the Vaadin version and discovered the the code that my new fancy date widget depended on had been removed and no substitue was readily available. Of course product didn’t want to drop the requirement, so we stuck with the old version with the working date widget.
Weird Problems with Statefulness
A Vaadin application is stateful, which has all sorts of implications. First, unless you explicitly write a “multi-windowed” application, you cannot have different sections open in different tabs. The state of one tab will update the other tab on a refresh. Also, it is incredibly easy to screw up your error handling so that the app never recovers and the user is forced to clear their cookies before they can use the application again. We’ve even encountered this with Vaadin generated restart dialogs.
The Straw that Broke the Camel’s Back
Vaadin provides a solution to this problem with the
LoginForm widget. Vaadin generates the action for this form not through a relative path, but by reading properties from the container. However, in our case, SSL is handled by NGINX and Jetty is blissfully unaware. This works 99.9% of the time, except for Vaadin’s LoginForm, which happily attempts to send the credentials over HTTP, while the rest of the application was HTTPS giving a very unfriendly dialog in Firefox.
Much of my early time with Vaadin was spent thinking back to how I used to do it and trying to reconcile it with how I’m used to doing it now. Vaadin is clearly not meant for developers that have even moderate web experience. Going with more native web technologies will be far easier and deliver better results. Vaadin may still be an option if you need a team of Swing (or maybe Android?) developers to build web applications, but I don’t have enough experience with those frameworks to pass judgement.
If you’ve had some experience with Vaadin, I’d love to hear your thoughts as well. It’s a framework that gets mentioned frequently among teams looking to deliver web solutions. Know where it has succeeded would be just as enlightening as me sharing my issues with it.
Did you like this? Please share:
The Lost Year: A Failed Experiment to Switch Away From Mac
Fed up with the Apple Keyboard, I bought a ThinkPad, installed Linux, and promptly decided that I hated computers.
Maker's Space, Manager's Space
The Grand Remote Work Experiment: A Retrospective
The COVID-19 pandemic has lead to an unexpected experiment in remote working. What has worked and why?