Loading...
Important Notice - Forums is archived

To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Product icon
TUTORIAL

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.

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

Benjamin Pfeffer
5 years ago Feb 28, 2017 2:07pm

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?

Alejandro C De Baca
5 years ago Feb 28, 2017 9:37pm

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.
 

Aníbal Potenza
4 years ago Apr 25, 2017 5:38pm

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.

Tatu Lund
4 years ago Apr 26, 2017 12:55pm
Luca Pertile
4 years ago Apr 28, 2017 1:27pm

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.

Lukas Wulff
4 years ago May 31, 2017 1:10pm

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.

Henri Sara
4 years ago Jul 26, 2017 12:52pm

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.").

Tatu Lund
4 years ago Jul 26, 2017 4:01pm

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.

Benjamin Huygir
4 years ago Feb 03, 2018 7:47pm
Benjamin Huygir
4 years ago Feb 03, 2018 9:29pm
Hay Chan
4 years ago Feb 12, 2018 10:18pm
Tatu Lund
4 years ago Feb 13, 2018 5:59am
Benjamin Huygir
4 years ago Feb 14, 2018 1:08pm
Tatu Lund
4 years ago Feb 14, 2018 7:52pm
Benjamin Huygir
4 years ago Feb 14, 2018 7:59pm
Shruthi Kulai
3 years ago Jun 05, 2018 8:57pm