Skip to content
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

Worker Thread ClassLoader cannot load property files on Java 21 #20944

Open
MichaelPluessErni opened this issue Feb 3, 2025 · 8 comments
Open

Comments

@MichaelPluessErni
Copy link

MichaelPluessErni commented Feb 3, 2025

Description of the bug

With the upgrade from Java 17 to Java 21 we stumbled upon a bug when retrieving translations in worker threads.
We need this because we call slower services asynchronously and update the UI after receiving the responses.

Specifically, when calling getTranslation on the worker thread, the TranslationService is not able to locate/load the property file with the translations, thus returning the key of the property instead of the translated text.

Important to note: This does not occur when running the application in DEV mode! It only occurs in Production mode.

We use Vaadin 24.4.22 together with Spring Boot 3.3.8. (Error also occurs with Vaadin 24.6.4)

Expected behavior

It should be possible to call getTranslation asynchronously. (like it is possible for Java 17)

Minimal reproducible example

Template to reproduce:

// inside component code, in UI thread
Component holder = this;
CompletableFuture
    .supplyAsync(() -> {
        // expensive operation
        return "1234";
    })
    .thenAccept(orderNumber -> {
        // in worker thread
        Optional<UI> ui = holder.getUI();
        if (ui.isPresent()) {
            ui.get().access(() -> {
                // this will return "order.number.title" instead of translated text
                holder.add(new Span(getTranslation("order.number.title", orderNumber)));
            });
        }
    });

Versions

  • Vaadin / Flow version: 24.4.22 / 24.6.4
  • Java version: 21
  • Spring Boot: 3.3.8
  • OS version:
  • Browser version (if applicable):
  • Application Server (if applicable): Spring Boot: 3.3.8
  • IDE (if applicable):
@MichaelPluessErni
Copy link
Author

We ended up using this work-around in the worker thread, to still be able to build UI asynchronously:

Thread.currentThread().setContextClassLoader(component.getClass().getClassLoader());

@mcollovati
Copy link
Collaborator

I cannot reproduce using the provided code with Vaadin 24.4.22,Spring Boot: 3.3.8 and Java 21.0.6 (Temurin) and running the application for the production JAR. The translations are correctly loaded and show on the page.

Can you provide an example project that reproduces the issue?

@mcollovati
Copy link
Collaborator

BTW, 24.4 is EOL. I suggest upgrading to the latest supported version.

@mcollovati
Copy link
Collaborator

Works for me also with Vaadin 24.6.4 and Spring Boot 3.4.1

@mshabarov
Copy link
Contributor

mshabarov commented Feb 4, 2025

@MichaelPluessErni what JVM implementation/supplier do you use?

Could you also elaborate more what is the TranslationService that you refer to, is it something that Vaadin provides? I could find TranslationService in Vaadin Control Center, but not sure if it's the one you mentioned.

@MichaelPluessErni
Copy link
Author

@mcollovati @mshabarov Thank you both for taking a look at this issue.

We use Java 21.0.5 Temurin.

For getTranslation we use the default implementation of ch.coop.vaadin.i18n.TranslationService (which itself uses org.springframework.context.MessageSource).

I cannot say whether I'll be able to create a full example project to demonstrate the bug. But if I succeed, I'll be sure to post it here.

@mshabarov
Copy link
Contributor

ch.coop.vaadin.i18n.TranslationService is not a part of Vaadin framework.

Vaadin ships DefaultI18nProvider for Spring which uses ResourceBundle.
You have probably hit by a similar issue as in #18977.

Do you mind to try using Vaadin default implementation for i18n, see https://vaadin.com/docs/latest/flow/advanced/i18n-localization ?

@MichaelPluessErni
Copy link
Author

The DefaultI18NProvider is not an option for our project, because we consume translations not only from our module, but also from a parent module.
Specifically, the issue lies with ResourceBundle, because it cannot load from different classpaths. Thus we have to use ReloadableResourceBundleMessageSource in our implementation of I18NProvider.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🔎 Investigation
Development

No branches or pull requests

3 participants