Home > JavaEE > Vaadin Spring integration

Vaadin Spring integration

I lately became interested in Vaadin, another web framework but where everything is done on the server side: no need for developers to learn HTML, CSS nor JavaScript. Since Vaadin adress my remarks about web applications being to expensive because of a constant need of well-rounded developers, I dug a little deeper: it will probably be the subject of another post.

Anyway, i became a little disappointed when I wanted to use my favourite Dependency Injection framework, namely Spring, in Vaadin. After a little Google research, I found the Vaadin Wiki and more precisely the page talking about Vaadin Spring Integration. It exposes two ways to integrate Spring in Vaadin.

The first one uses the Helper “pattern”, a class with static method that has access to the Spring application context. IMHO, those Helper classes should be forgotten now we have DI since they completely defeat its purpose. If you need to explicitly call the Helper static method in order to get the bean, where’s the Inversion of Control?

The second solution uses Spring proprietary annotation @Autowired in order to use DI. Since IoC is all about decoupling, I’m vehemently opposed to coupling my code to the Spring framework.

Since neither option seemed viable to me, let me present you the one I imagined: it is very simple and consists of subclassing the Vaadin’s AbstractApplicationServlet and using it instead of the classical ApplicationServlet.

public class SpringVaadinServlet extends AbstractApplicationServlet {

  /** Class serial version unique identifier. */
  private static final long serialVersionUID = 1L;

  private Class clazz;

  @Override
  public void init(ServletConfig config) throws ServletException {

    super.init(config);

    WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(
      config.getServletContext());

    Application application = (Application) wac.getBean("application", Application.class);

    clazz = application.getClass();
 }

  /**
  * Gets the application from the Spring context.
  *
  * @return The Spring bean named 'application'
  */
  @Override
  protected Application getNewApplication(HttpServletRequest request)
    throws ServletException {

    WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(
      request.getSession().getServletContext());

    return (Application) wac.getBean("application", Application.class);
  }

  /**
  * @see com.vaadin.terminal.gwt.server.AbstractApplicationServlet#getApplicationClass()
  */
  @Override
  protected Class getApplicationClass()
  throws ClassNotFoundException {

    return clazz;
  }
}

This solution is concise and elegant (according to me). Its only drawback is that it couples the servlet to Spring. But a class-localized coupling is of no consequesence and perfectly acceptable. Morevoer, this lets you use Spring autowiring mechanism, JSR 250 autowiring or plain old XML explicit wiring.

email
Send to Kindle
Categories: JavaEE Tags: ,
  1. gthomas
    April 9th, 2010 at 09:42 | #1

    Hi there,

    Thank you for your post, it sounds interesting. But I’m such a newbie on these technologies and I have some problem to imagine your solution in a project.

    Do you have somewhere a simple example which could easily show us how it is working ?

    Thank you again !!!

    Regards,

    Guillaume

  2. April 9th, 2010 at 23:09 | #2

    Just replace Vaadin servlet declaration in your web.xml deployment descriptor by the following snippet:

    
    
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app...>
    ...
      <servlet>
          <servlet-name>Vaadin servlet</servlet-name>
          <servlet-class>ch.frankel.blog.vaadin.SpringVaadinServlet </servlet-class>
          <init-param>
           <param-name>application</param-name>
          <param-value>ch.frankel.blog.vaadin.Application</param-value>
          </init-param>
      </servlet>
      <servlet-mapping>
          <servlet-name>Vaadin servlet</servlet-name>
          <url-pattern>/*</url-pattern>
      </servlet-mapping>
    </web-app>
  3. Brian
    April 11th, 2010 at 04:37 | #3

    “Its only drawback is that it couples the servlet to Spring”. That’s kinda the point :) You gotta tie the know somewhere.

  4. Brian
    April 11th, 2010 at 04:37 | #4

    @Brian
    know=knot

  5. Matt
    August 22nd, 2010 at 07:55 | #5

    Hi Nicolas,

    Is the … section above required at all?
    Should the “application” bean be defined in a/the spring applicationcontext.xml file?

    Thanks,
    Matt

  6. Matt
    August 22nd, 2010 at 07:57 | #6

    Sorry, there’s a problem with my last post, it should be:

    Is the init-param section above required at all?
    Should the “application” bean be defined in a/the spring applicationcontext.xml file?

    Thanks,
    Matt

  7. kunal
    September 7th, 2010 at 02:40 | #7

    I have the exact same questions as asked by Matt just above. Plus, are your UI components like form, window, textbox… so on are also managed by spring? for example, my forms need a service bean set to them so that they can persist when the form is populated.

  8. September 7th, 2010 at 20:55 | #8

    @Matt
    Matt, the init-param is not used per se but could be so that the Application bean could be named differently. Good remark.

  9. September 7th, 2010 at 20:56 | #9

    @kunal
    All my components are managed by Spring so that I can inject them services, like you need them to.

  10. Tom
    January 30th, 2011 at 11:19 | #10

    Surely, the Vaadin components (including the application) would have to be be scoped on “prototype” in order not to share state across sessions?!

  11. Zak
    June 21st, 2011 at 22:06 | #11

    Please more updates , examples and files to download

  12. July 8th, 2011 at 14:31 | #12

    HI I m using Vaadin frame work assume that i have table inside the panel . I m getting spring Service from BackSide .(Server) which is best way to populate the data for the gride if you give me example it would be great

  13. Zakos
    July 16th, 2011 at 18:31 | #13

    Hi,
    I use 13.5.2. Setup from http://www.blackbeltfactory.com/ui#CoursePage/15593452/EN
    to allow @Autowire and others Spring tools because @Autowire and others things worked only on the class that extends Application.

    Don’t know why it’s happen , but it’s working , its using AspectJ , could be a ‘fix’ for not using it?

  14. July 16th, 2011 at 18:58 | #14

    Hi,
    BlackBelt Factory’s solution is on a whole different integration level than what I propose.
    According to me, AOP is a kind of heavy artillery that’s very powerful: so, I’m very wary about it. In Vaadin’s case, it’s not my first choice because I can do without it easily. Choose your libraries carefully, since with luck you will have to maintain your software on a long period.

  15. Zakos
    July 18th, 2011 at 12:36 | #15

    I cant avoid use AspectJ as I mentioned . I would if it was possible. ( other classes get nulls when trying autowired )

    You wrote :
    “Spring Integration is an add-on for Vaadin that let you use Spring and its dependency injection mechanism in Vaadin painlessly.”

    but it doesn’t work , except on the class which extends Application , any solution?

    Thanks

  16. July 18th, 2011 at 12:50 | #16

    @Zakos
    I would suggest you use their method and not the Vaadin add-on I provide. I can’t imagine them being compatible.

  17. Guodang Zuo
    July 23rd, 2011 at 07:33 | #17

    i’m chinese,my english is not good.
    I had downloaded Spring Integration is an add-on for Vaadin,but is doesn’t work.
    the readme.txt of zip file have some errors and less than description for applicationContext.xml of spring.
    my configuration is
    web.xml

    Vaadin servlet
    cn.zuoguodang.vaadin.SpringVaadinServlet

    application
    cn.zuoguuodang.vaadin.DemoApplication

    Vaadin servlet
    /*

    applicationContext.xml

    it works ordinary.if you have question then send email to zuoguodang@163.com,Look forward to learning together.
    thx.

  18. Sebastian
    March 23rd, 2012 at 14:02 | #18

    I’m afraid I’m not getting it. Can you explain why it is a good idea to use Spring with the Vaadin UI Code?

  19. March 23rd, 2012 at 19:54 | #19

    Hello Sebastian,

    I didn’t state it was a good idea to use Spring to glue together your UI components, just that it was possible. Anyway, you’ll probably need to inject your components with services to load the data to display and this article tells you how to integrate Spring and Vaadin.

  20. Sebastian
    March 23rd, 2012 at 21:50 | #20

    Don’t understand me wrong, I really like your article and I appreciate your Vaadin tutorials in general but from your point of view what would be the way to go? Would it be worth the effort to integrate Spring with Vaadin (I don’t know much about the benefits you get from Spring besides DI) or wouldn’t it be the easier and better documented way to go straight on without an DI framework for the view?

  21. March 24th, 2012 at 01:10 | #21

    My answer cannot be as black-and-white as you want it to be: it depends on your context, including (and surely not limited to) your enterprise, your skills, your co-workers skills, your willingness to unit test, and so on.

  22. June 27th, 2012 at 19:47 | #22

    Hi Nicolas,

    I’m just beginning with learning Vaadin and I’m also very sad about the worse Spring integration. Your solution is currently the best I’ve found, but I have found a problem with your solution.

    If you use @Transactional in your application class, Spring wraps it with a proxy object and your solution fails (object is of type Proxy$xy instead of Application). I could fix the problem by using seperate DAO classes but currently I have no need for that overhead.

    Another solution could be to use “AspectJ proxy mode” (not tested yet) but I don’t want to depend on AspectJ.

    Do you have a simple solution for that problem?

  23. June 27th, 2012 at 21:56 | #23

    Hi Patrick,
    Thanks for your kind comment. Like you said, my solution has a couple of problems: the one you mention, but also the fact that it doesn’t handle deserialization from one cluster node to another.

    Considering your case, since Application is not an interface, you won’t be able to cast the proxy without AOP. Event if you don’t want to depend on AspectJ, I do not see other solutions.

    If you’re interested to explore an entirely different path, that also solves serialization issues, I invite you to read this article.

    For more Vaadin-related stuff, you can also check regularly More Vaadin.com.

  24. June 27th, 2012 at 23:03 | #24

    @Nicolas Frankel
    Hmm… doesn’t really look comfortable :)

    I think I will give AspectJ another chance. I don’t wanted to use AspectJ because I recently ran into strange code completition problems in Eclipse while using AspectJ + AspectJ Maven integration.

    But as Eclipse 4.2 was released today I have to setup my IDE anyway. Maybe it was only a configuration problem…

    What method would you use to integrate Spring and Vaadin if you had to build such a solution for a customer? Helper class, AspectJ or the method described above?

  25. June 27th, 2012 at 23:10 | #25

    I’m sorry but there are many contextual informations I do not have access to to make such a decision: for example, helpers are bad from a design point of view, but are quite good when your team is consituted by junior developers only.

    I would suggest you draw a table and for each option, you list its pros and cons in your environment. Then you could either decide, or let the customer do it.

  26. Jerome
    September 10th, 2012 at 21:04 | #26

    I learnt a lot about Vaadin these days and I must admit I still have a question: why is there deer on the book cover ?

  27. September 10th, 2012 at 21:12 | #27

    Had you bought my book, you would have known the answer: it stands on the first page :-)

  28. ravi teja
    February 27th, 2013 at 08:50 | #28

    When i use above example i am facing a problem with singleton pattern i.e., when i login to the application in one browser it is going to home page correctly, again when i login in another browser it is directly going to home page.
    plz help me how to resolve this problem.
    Thanks,
    Ravi teja.

  1. No trackbacks yet.