3

Currently I try to create a sample implementation utilizing Spring Boot and Vaadin. I tried to initialize the vaadin navigator in a spring managed bean, but therefore I need access to the UI object.

I implemented the MVP pattern which needs a lot of classes and interfaces but the problem boils down to the following sample code:

@SpringUI
public class MyVaadinUI extends UI
{
    @Autowired
    private MainPresenter mainPresenter;

    protected void init(VaadinRequest request)
    {
       setContent(mainPresenter.getView());
    }
}

@UIScope
@SpringComponent
public class MainPresenterImpl implements MainPresenter
{
    @Autowired
    public MainPresenterImpl(MainModel model, MainView view)
    {
        super(model, view);
    }

    @PostConstruct
    public void init()
    {
       UI ui = UI.getCurrent();
       Assert.isNull(ui); // ui is always null
    }
}

I've already read that the UI instance is kept in a ThreadLocal variable. I could verify that by debugging. I don't understand why the wired bean MainPresenter is in a different thread. It also shouldn't be a matter of scopes.

So far the application runs fine until I try to access the UI instance in the Presenter.

The VAADIN wiki did not help and I couldn't find a helpful answer in this forum.

Patrick T
  • 294
  • 3
  • 11
  • Have you gone through this list ? http://stackoverflow.com/search?q=vaadin+spring+autowire+null – André Schild May 20 '16 at 09:49
  • Most of these search results I saw earlier. 90% complain about autowired fields that are null due to misconfiguration or using @Autowire in objects that were not instantiated by spring. The last 10% do not match my problem either. – Patrick T May 20 '16 at 10:02

1 Answers1

2

After several hours I can answer this myself.

The solution to this problem is keeping the order of initialization in mind: When the @PostConstruct of MainPresenterImpl is called there is no UI yet and the UI is not yet registered in the ThreadLocal instance. I fixed the problem like this:

@SpringUI
public class MyVaadinUI extends UI
{
    @Autowired
    private MainPresenter mainPresenter;

    protected void init(VaadinRequest request)
    {
       mainPresenter.initAfterBeanCreation()
       setContent(mainPresenter.getView());
    }
}

@UIScope
@SpringComponent
public class MainPresenterImpl implements MainPresenter
{
    @Autowired
    public MainPresenterImpl(MainModel model, MainView view)
    {
        super(model, view);
    }

    @PostConstruct
    public void init()
    {
       UI ui = UI.getCurrent(); // ui is always null
    }

    public void initAfterBeanCreation()
    {
        UI ui = UI.getCurrent(); // now ui is not null
    }
}
Patrick T
  • 294
  • 3
  • 11