-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prefer accessing UI through attached elements over UI.getCurrent() #6757
Comments
Similar issue for LitRenderer specifically: #4963 (also caused by UI.getCurrent) |
In our internal discussion, it was suggested that we could improve the DX for existing @mshabarov What do you think? Would it be possible to add this API? |
Store the UI reference (and expose it) in ComponentEvent. I think I would never use a method like UI.getCurrentOrThrow (would prefer to make a null check for UI.getCurrent()). The best option would be that Component.getUI would be thread safe. The current situation is quite odd (that it is not) and it is not even documented 🤔 |
An But not sure the one with throwing an exception is a good solution long-term, I’d avoid it. Better to make a helper and disclaim that it’s an internal API. |
Describe your motivation
Components sometimes need access to the UI instance, but there isn't a single standard way how to get that instance. One of the approaches widely used across the codebase is
UI.getCurrent()
. However, it's often neglected that this API isn't thread-safe and may returnnull
in some contexts. One such example is when the component instance is created in a background thread without a UI lock:Then, in ComponentRenderer, a variable is set to an empty string if
UI.getCurrent()
isnull
. This prevents null pointer exceptions but still eventually causes the app to break elsewhere, which isn't the best solution:flow-components/vaadin-renderer-flow-parent/vaadin-renderer-flow/src/main/java/com/vaadin/flow/data/renderer/ComponentRenderer.java
Lines 146 to 149 in 7249a90
Here are similar examples from other modules:
flow-components/vaadin-renderer-flow-parent/vaadin-renderer-flow/src/main/java/com/vaadin/flow/data/renderer/LitRenderer.java
Lines 83 to 90 in 7249a90
flow-components/vaadin-spreadsheet-flow-parent/vaadin-spreadsheet-flow/src/main/java/com/vaadin/flow/component/spreadsheet/Spreadsheet.java
Lines 1181 to 1184 in 7249a90
flow-components/vaadin-charts-flow-parent/vaadin-charts-flow/src/main/java/com/vaadin/flow/component/charts/ChartOptions.java
Lines 48 to 57 in 7249a90
flow-components/vaadin-dialog-flow-parent/vaadin-dialog-flow/src/main/java/com/vaadin/flow/component/dialog/Dialog.java
Lines 1052 to 1056 in 7249a90
Describe the solution you'd like
Instead of using
UI.getCurrent()
, methods should access UI through an attached component or element that is available in the current context. This is a thread-safe approach. Here are some ways to do this:However, if no attached element is available and hence the use of
UI.getCurrent()
is unavoidable, the method documentation should state this requirement and the null case should be handled properly with a clear exception like here:flow-components/vaadin-dialog-flow-parent/vaadin-dialog-flow/src/main/java/com/vaadin/flow/component/dialog/Dialog.java
Lines 762 to 772 in 7249a90
Additional context
Originally discovered by @archiecobbs in vaadin/flow#20240 (comment)
Related #6751
The text was updated successfully, but these errors were encountered: