Localization Vaadin 24.3.x

According to the documentation, starting with Vaadin 24.3 localization should be quite easy. As far as I understand, Vaadin provides a DefaultI18NProvider and the only thing I need to do is to create a file called src/main/resources/vaadin-i18n/translations.properties.

I created the property file and added one property to it. I modified the source file of my view to call getTranslation("myproperty"). No compile errors so far. but when I start my application I get an exception:

NullPointerException:
Cannot invoke "com.vaadin.flow.server.VaadinService.getInstantiator()"
because the return value of "com.vaadin.flow.server.VaadinService.getCurrent()" is null

I must admit, that I tried to call getTranslation from within the constructor of my view. As a test, I implemented the LocaleChangeObserver and tried to call the method from within the localeChange method. That worked!

Is it correct that I can’t get translations from within the contructor or am I missing something? Isn’t it a good practice to build the UI in the constructor of the view?

Happy easter to everybody!

1 Like

Service should have been available… So that NPE is kinda weird tbh… but you can also inject I18NProvider directly in the view that needs it, if you wanna stay with constructor view building…

Well that’s a long debate, probably 10 people have 20 opinion on :grimacing: I normally build layouts in the constructor or @PostConstruct and anything on top within my after navigation method so that I don’t waste previous CPU circles with code that is never needed if e.g. the before enter observer rejects the user to access the view because the constructor is always called.

3 Likes

Wild guess: is your view perhaps implenting AppShellConfigurator?

No, my Application class (generated by start.vaadin.com) implements it. My view with the @Route annotation (I have only one view) extends Div and uses constructor injection to inject instances of other components for my application.

I can’t reproduce your NPE

1 Like

Steps to reproduce:

  1. git clone https://github.com/McPringle/apus.git
  2. cd apus
  3. git checkout git checkout translation-npe
  4. ./mvnw

It looks like I might have an issue with the task scheduler which might cause that problem. But it has no priority, I changed the way I build the UI of the initial view and it works for now. I have more important tasks to do to make this app work for the conference… :face_with_peeking_eye:

Thanks for trying out!

I’ll look into it. Just a remark. getTranslation uses ResourceBundles and you can pass parameters as a vararg to the method and don’t need to String.format

1 Like

The problem is that ConferenceView and SocialView are Spring Beans and instantiate before the Vaadin Service is ready.

To make it work you must move the code in @PostConstruct method:

   public ConferenceView(@NotNull final ConferenceService conferenceService,
                          @NotNull final TaskScheduler taskScheduler) {
        this.conferenceService = conferenceService;
        this.taskScheduler = taskScheduler;
    }

    @PostConstruct
    void setup() {
        setId("conference-view");
        add(new H2(String.format(getTranslation("conference.heading"),
                LocalDate.now().getDayOfWeek().getDisplayName(TextStyle.FULL, UI.getCurrent().getLocale()))));
        add(createLegend());
        add(sessionContainer);
        updateConferenceSessions();
        final ScheduledFuture<?> updateScheduler = taskScheduler.scheduleAtFixedRate(this::updateScheduler, UPDATE_FREQUENCY);
        addDetachListener(event -> updateScheduler.cancel(true));
    }

Personally I avoid to have Vaadin components that are Spring Beans other than the Routes.

2 Likes

That’s what I did now on the main branch! :-)

I changed it, thanks for the hint!

You can study this demo application for how to implement localization in Vaadin 23/24 application. This specific app is Java EE stack, but it is almost the same with Spring Boot as well. Especially see the CustomI18NProvider and then use of getTranslation and LocaleChange events.