i18n provider with OSGi

When implementing a translation provider following the description here: https://vaadin.com/docs/v14/flow/advanced/tutorial-i18n-localization.html, one has to take care that the translation provider is available in the classpath of the flow server bundle. When running the UI in an OSGi environment, this can e.g. be reached by placing it in a fragment bundle which attaches to com.vaadin.flow.server as host.

In general, translation works. However, when calling getTranslation(“some_key”) from a thread - which e.g. opens a pop-up window with an error message after some timeout - I receive following exception - not knowing whether that is a general issue or related to the specifics of OSGi:

java.lang.NullPointerException
        at com.vaadin.flow.component.Component.getI18NProvider(Component.java:600)
        at com.vaadin.flow.component.Component.getLocale(Component.java:617)
        at com.vaadin.flow.component.Component.getTranslation(Component.java:574)
		...

Here the code which leads to this issue (it is called from a class derived from VerticalLayout) :

		TimerTask timerTask = new TimerTask() {

			@Override
			public void run() {
				showDialog(getTranslation("timeoutErrorText"));
			}
		};

		final Timer timer = new Timer("TimeoutTimer");
		timer.schedule(timerTask, TIMEOUT);

Line 600 of the Component class in the flow-server contains the following:

VaadinService.getCurrent().getInstantiator().getI18NProvider();

Does anybody have an idea how to solve this?

Thanks,
Jochen

Hi. I’ve created https://github.com/vaadin/flow/issues/6932 for tracking this issue, there is a workaround described in the issue (not invented by me :))

In general, you may not do any UI related things in a separate thread directly.
So:

  • you may not call showDialog (I don’t know actually how it’s implemented though, but I assume it calls only UI related methods).
  • you may not call getI18NProvider since it’s a method in Component class.

And you have already identified a reason why: VaadinService.getCurrent() returns null since it’s not for your thread.

Every time when you need a call on any UI object it should be done inside UI::access or VaadinSession::access.
This way your runnable will be executed with a proper lock which protect UI resources being used from multiple threads and also sets thread locals for the runnable.

Looking at my old threads …

Please note that the VaadinService.getCurrent is not in my code - it is in the Component class in the flow-server.

So: waiting for the next step of OSGi update, according to the latest roadmap coming with Vaadin 18 later this year, hopefully also resolving all the things mentioned in issue 6932 :).

Regards
Jochen