vaadin / spring

Spring integration for Vaadin
https://vaadin.com/start
175 stars 101 forks source link

Autowiring UI scoped beans fail if they are autowired between UI instance creation and browser details request #174

Open peterl1084 opened 7 years ago

peterl1084 commented 7 years ago

When Vaadin Spring UI is initialized in SpringUIProvider.createInstance the UIID is set to CurrentInstance that provides a way to autowire @UIScope beans to UI bean still in creation. After the UI instance is created the SpringUIProvider.createInstance removes the UIID from CurrentInstance.

Now, Vaadin will initialize the created UI instance by invoking it's init method. Before this browser details are requested and during browser details setup the UI is attached to session. While attaching to session all the components are attached to connector hierarchy and during this operation also @UIScoped instances are looked into. When attaching @UIScoped components the bean store is looked up by first checking if the UI.getCurrent is set and if not then by looking if CurrentInstance.get(UIID.class) is set. That this stage between lines (196 - 212) in Vaadin's UIInitHandler (Vaadin 8.0.0.beta1) there is a point in login where neither, UIID nor UI.getCurrent are set.

This will result in assertation error in bean store lookup with Spring's UI bean store giving following exception:

java.lang.IllegalArgumentException: Found no valid com.vaadin.spring.internal.UIID instance! at org.springframework.util.Assert.notNull(Assert.java:115) ~[spring-core-4.3.5.RELEASE.jar:4.3.5.RELEASE] at com.vaadin.spring.internal.UIScopeImpl$VaadinSessionBeanStoreRetrievalStrategy.getUIID(UIScopeImpl.java:158) ~[vaadin-spring-2.0.0.beta1.jar:2.0.0.beta1] at com.vaadin.spring.internal.UIScopeImpl$VaadinSessionBeanStoreRetrievalStrategy.getBeanStore(UIScopeImpl.java:168) ~[vaadin-spring-2.0.0.beta1.jar:2.0.0.beta1]

I think this problem could be fixed simply by moving

UI.setCurrent(ui);

from line 212 to 192 before the UI's session is set.

peterl1084 commented 7 years ago

The problem cannot be fixed as proposed as moving the setting current UI higher simply doesn't work as UI is not yet initialized at that stage.

Also, the above described problem only occurs when the bean is in proxied mode (with TARGET_CLASS). Otherwise the first description is still accurate.

vaadin-miki commented 4 years ago

this happens also when using karibu testing for v8 when the main UI class is a UI-scoped bean; fetching it from ApplicationContext to pass to MockVaadin.setup() raises exactly the same error message

not that it matters ;)