Nicolas Frankel is an IT consultant with 10 years experience in Java / JEE environments. He likes his job so much he writes technical articles on his blog and reviews technical books in his spare time. He also tries to find other geeks like him in universities, as a part-time lecturer. Nicolas is a DZone MVB and is not an employee of DZone and has posted 224 posts at DZone. You can read more from them at their website. View Full User Profile

Chicken and Egg Problem With Spring and Vaadin

05.03.2010
| 9541 views |
  • submit to reddit

The more I dive into Vaadin, the more I love it: isolation from dirty plumbing, rich components, integration with portlets, Vaadin has it all.

Anyway, the more you explore a technology, the bigger the chances you fall down the proverbial rabbit hole. I found one just yesterday and came up with a solution. The problem is the following: in Vaadin, application objects are tied to the session. Since I’m a Spring fanboy, it does make sense to use Spring to wire all my dependencies. As such, I scoped all application-related beans (application, windows, buttons, resources, …) with session like so:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/aop

    http://www.springframework.org/schema/aop/spring-aop.xsd">

  <context:annotation-config />

  <bean id="application" scope="session">
  <aop:scoped-proxy />
...
</beans>

This works nicely, until you happen to use DI to wire further. By wire further, I mean wiring windows into application, button into windows and then resources (icons) into buttons. It is the last  step that cause a circular dependency. Icon resources are implemented in Vaadin by com.vaadin.terminal.ClassResource. This class has two constructors that both needs an application instance.

The dependency cycle is thus: application -> window -> button -> resource -> application. Spring don’t like it and protests energically to it by throwing an exception which is labeled like so Requested bean is currently in creation: Is there an unresolvable circular reference?

. I think, in this case, that the design of the ClassResource is not adapted. That’s whyI designed a class aligned with Spring deferred instantiation: since the application is session-scoped, Spring uses a proxy that defers instantation from application start (Spring normal behaviour) to session use. The point is to implement the ApplicationResource interface, which needs an interface, but to set application only when needed:

public class DeferredClassResource implements ApplicationResource {

private static final long serialVersionUID = 1L;
private int bufferSize = 0;
private long cacheTime = DEFAULT_CACHETIME;
private Class<?> associatedClass;
private final String resourceName;
private Application application;

public DeferredClassResource(String resourceName) {

if (resourceName == null) {

throw new IllegalArgumentException("Resource name cannot be null");
}

this.resourceName = resourceName;
}

public DeferredClassResource(Class<?> associatedClass, String resourceName) {

this(resourceName);

if (associatedClass == null) {

throw new IllegalArgumentException("Associated class cannot be null");
}

this.associatedClass = associatedClass;
}

... // standard getters

@Override
public String getFilename() {

int index = 0;

int next = 0;

while ((next = resourceName.indexOf('/', index)) > 0
&& next + 1 < resourceName.length()) {
index = next + 1;
}

return resourceName.substring(index);
}

@Override
public DownloadStream getStream() {

final DownloadStream ds = new DownloadStream(associatedClass
.getResourceAsStream(resourceName), getMIMEType(),
getFilename());

ds.setBufferSize(getBufferSize());

ds.setCacheTime(cacheTime);

return ds;
}

@Override
public String getMIMEType() {

return FileTypeResolver.getMIMEType(resourceName);
}

public void setApplication(Application application) {

if (this.application == application) {

return;
}

if (this.application != null) {

throw new IllegalStateException("Application is already set for this resource");
}

this.application = application;

associatedClass = application.getClass();

application.addResource(this);
}
}

DeferredClassResource is just a copy of ClassResource, but with adaptations that let the application be set later, not only in constructors. My problem is solved, I just need to let application know my resources so it can call setApplication(this) in a @PostConstruct annotated method.

From http://blog.frankel.ch/chicken-and-egg-problem-with-spring-and-vaadin

Published at DZone with permission of Nicolas Frankel, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Ivan Lazarte replied on Tue, 2010/05/04 - 10:33am

My mind rejects this kind of stuff from the outset. How can scoping ui classes to session be a good thing? The server will end up being the limitation. It seems to me it would completely defeat the purpose of html.

David Lee replied on Tue, 2010/05/04 - 12:49pm

Hence why I try to avoid spring like the plague.

Here you have this fabulous framework that should be making you more productive,  but you don't achieve that productivity because you're wrestling with Spring to do you can probably do without Spring.

I just don't get the Spring lovefest.

But I do agree that Vaadin is awesome.

Mark Unknown replied on Tue, 2010/05/04 - 4:12pm

I get why you don't get the "Spring lovefest". But i don't get why you avoid spring all together. What are you doing or using instead?   I do RCP and thus a lot of remoting. I had to code that by hand till Spring appeared.  On the other hand, of the little i have used Spring MVC, I don't care for it much. Of couse, I don't care much for Struts or ....

Travis Calder replied on Wed, 2010/05/05 - 2:09pm

The "Spring lovefest" has little to do with Spring and everything to do with Dependency Injection.

The idea is that you write a bunch of loosely coupled highly-reusable components, then wire them together at run-time.

With something like Vaadin, this is a really cool concept. I can tools and widgets, then reuse those tools and widgets to create forms and windows for the user. The widgets can be tested directly, providing trust in the windows.

Finally, session-scoping the components ensures that each user gets his own "version" of the application. Everything just kind of works out.

I think the author found a real issue with Spring/Vaadin interactions, and provided a solid solution to that issue. A+

Travis Calder replied on Sun, 2010/05/09 - 5:35pm

Looking a little closer, have you considered just using a ThemeResource?

Nicolas Frankel replied on Mon, 2010/05/10 - 5:58am in response to: Travis Calder

ThemeResource is well, used by a theme. My proposal isn't limited to graphic resource. But yours is a good question...

Michael Eric replied on Wed, 2012/09/26 - 3:53pm

Nice to see someone working so closely with Vaadin and Spring. I’m just getting started with Vaadin and so far I’m very pleased and enthused. Building a little recipe book app with Vaadin and db4o, let’s see how it all goes. Nice post!

redhat 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.