Vaadin 8 UI.getCurrent() returns null on non-request-threads

Hello community,

I´m currently testing out vaadin 8 (8.0.0) and discovered a change in behavior compared to Vaadin 7 (tested with 7.7.6).

When I call UI.getCurrent from a request-thread I get the UI attached to the current session. This works for vaadin 7 and 8 alike.

But when I call UI.getCurrent from a seperate thread that was spawned when processing a request I get the UI when using Vaadin 7 but get null when using Vaadin 8.

The following snippet visualizes the issue:

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        
        Thread t = new UiAccessor();
        t.start();
        UI ui = UI.getCurrent();
        System.out.println("UI on request-thread: " + ui);
    }
    
    class UiAccessor extends Thread {
        
        @Override
        public void run() {
            UI ui = UI.getCurrent();
            System.out.println("UI on seperate thread: " + ui);
        }
        

When running this in Vaadin 7(.7.6) it prints:

  • UI on seperate thread: com.example.myapplication.MyUI@37654c89
  • UI on request-thread: com.example.myapplication.MyUI@37654c89

But when running the same code in Vaadin 8(.0.0) it prints:

  • UI on request-thread: com.example.myapplication.MyUI@74b8567b
  • UI on seperate thread: null

Is this intended?

The UI class has a setCurrent() static method that should be used on background processing threads outside of request handling. I don’t think it was supposed to work as you demonstrated in 7.7.6, althought I don’t doubt that it did.
From the 7.7.6 javadocs
(same applies to
8.0.0
):


public static void setCurrent(UI ui)

Sets the thread local for the current UI. This method is used by the framework to set the current application whenever a new request is processed and it is cleared when the request has been processed.The application developer can also use this method to define the current UI outside the normal request handling, e.g. when initiating custom background threads.

The UI is stored using a weak reference to avoid leaking memory in case it is not explicitly cleared.


public static UI getCurrent()

Gets the currently used UI. The current UI is automatically defined when processing requests to the server.
In other cases, (e.g. from background threads), the current UI is not automatically defined.

But, in Vaadin 7 works, and in Vaadin 8 not works. If I open a window in a thread, I can’t because null pointer appears. I need to refactor all the code now.

I can confirm what is said by Alejandro

Check also the API spec of getCurrent(), it is not guaranteed to return UI from background thread.
“In other cases, (e.g. from background threads), the current UI is not automatically defined.”

https://vaadin.com/api/7.7.8/com/vaadin/ui/UI.html#getCurrent--

I agree with Anibal. In Vaadin 7 the UI was setted by the framework even for background thread. I think in Vaadin 8, to optimize memory, something has been corrected on implementation layer and now it works like design ask.

It’s not clear to me how to set UI using UI.setCurrent and from witch code point: should I set it when I create a Thread?. Maybe Vaadin team should add an example in documentation.

Stumbled across this very issue during migration to Vaadin 8.
While it appears to be a case of “works as designed” rather than a bug,
this should not go without being mentioned in the migration guide.
Especially since it, as mentioned in one of the above answers, requires quite a lot of refactoring.
Furthermore there appears to be be a similiar issue concerning
VaadinSession.getCurrent()
,
probably for the same reasons as pointed out earlier.
I will be using the following wrapper to tackle this issue:

public static void runAsync(Runnable runnable) { final UI ui = getCurrent(); final VaadinSession session = VaadinSession.getCurrent(); if (ui == null || session == null) { throw new RuntimeException("UI or Session should not be null at this point!"); } new Thread(() -> { UI.setCurrent(ui); VaadinSession.setCurrent(session); runnable.run(); }).start(); } Still I am hoping for some clarification on why this is necessary and maybe some assistance implemented into the core framework.

Within a UI.access() block, UI.getCurrent() is available even in background threads.

Outside a UI.access(), even in Vaadin 7, there were no guarantees about UI.getCurrent() pointing to anything sensible. In practice, it was inheriting the value of the context where the thread was created, which might in some cases be what is wanted for throw-away threads (which should not be used in modern application containers anyway) but is not at all correct e.g. with thread pools and other ExecutorService based solutions. This was the main reason why InheritableThreadLocal isn’t used anymore.

It should be noted that code that used UI.access() correctly in V7 should still work in V8, though UI.getCurrent() cannot be used anymore to get the UI for calling UI.access() (which only worked correctly in some situations in V7).

The
release notes for 8.0
do mention this, though not very clearly (“It is no longer possible to configure a CurrentInstance to be automatically inherited into spawned threads.”).

If you have some sort of MVP pattern in your application and you need to do UI.access() for example in Presenter class, which has methods called actually from background threads (e.g. due callbacks from Model, which has background threads, which is quite common if you have async access to DB/backend), the better pattern is to store the reference of the UI in the constructor of the Presenter class and the use that refrence for access() instead. In View class, if you inherit Vaadin component, you should be able to get the UI reference, or you alternatively you can utilize same trick as I suggested for Presenter.

feel like a noob all over again with some of the changes in 8+… what is a UI.access block that does not use the current UI instance? Simple example is sufficient - thanks.

Apparently “It is no longer possible to configure a CurrentInstance to be automatically inherited into spawned threads.” applies also to the UI access mechanism (also a thread?)… even getting past the intial UI.getCurrent() call, and accessing the UI thread, ANY session based references also return null. This breaks all sorts of code for accessing session variables (implementation instances, my current user, etc.). Even the fancy solutions only get so far and then everything breaks anyway. Only solution is to not make any session based references in any code that might get executed as part of a background trigger. Sigh… session variables used to be elegant, now they are dangerous.

Have the same problem. I used
getUI()
instead of UI.getCurrent() and it works.

Have the same problem. I used getUI() instead of UI.getCurrent() and it works.

Yes, that is what I referred previously. You can use getUI in view classes. Note, view needs to be attached, in order to be valid.

Yuyee Hr:
In your application, and you must do UI.access (), such as in the Presenter class.

That does not solve the problem. In Vaadin 8, if you are on a separate thread any of the session based values can be null - and they often are even if you start by re-setting them in the thread itself - go far enough and you will get back null for UI, Session and any of your own session variables. So this completely breaks the pattern of using session variables for sharing key values, including the pattern used in the Vaadin multi-part project starter whereby the dataservice implementation singleton is retained as a session variable - if you attempt to access that on a thread it will fail.

In most cases you instantiate the Presenter class in request thread. This means that you can do ui = UI.getCurrent() in the constructor of your presenter. Then you can use this stored “ui” for “ui.access() …”. You may need to check that ui is still attached etc. in order to avoid UIDetachedExceptions.

Yes, it’s easy to create apriori reference to UI, but that isn’t the issue… the problem is if you also on that thread attempt to access any other session data along the lines of “getCurrent()” or a session instance of any class you have saved, THOSE references will be null. The problem is not creating the thread in the UI context, it’s everything after that subject to failure. IOW, you would have to know every session-based reference you were going to make in that thread and save a local copy before running it.

Tatu Lund:
In most cases you instantiate the Presenter class in request thread. This means that you can do ui = UI.getCurrent() in the constructor of your presenter. Then you can use this stored “ui” for “ui.access() …”. You may need to check that ui is still attached etc. in order to avoid UIDetachedExceptions.

Facing the same issue as others. The above mentioned solution creates problems when there are multiple users accessing the application.