Skip to content

Commit

Permalink
fix: add missing reflection hints for flow-components (#19460)
Browse files Browse the repository at this point in the history
Configures additional reflection hints required by flow-components for native image.

Fixes #19405
  • Loading branch information
mcollovati authored May 30, 2024
1 parent 04e58be commit 00dd9ef
Showing 1 changed file with 43 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
package com.vaadin.flow.spring.springnative;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import org.reflections.util.ConfigurationBuilder;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.ReflectionHints;
import org.springframework.aot.hint.RuntimeHints;
Expand Down Expand Up @@ -37,6 +46,8 @@ public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
}
registerResourceIfPresent(hints,
"com/vaadin/flow/component/login/i18n.json");
registerResourceIfPresent(hints,
"com/vaadin/flow/component/crud/i18n.json");

// Flow server resources like BootstrapHandler.js and
// RouteNotFoundError_prod.html
Expand All @@ -54,12 +65,38 @@ private void registerResourceIfPresent(RuntimeHints hints, String path) {

// These should really go into the separate components but are here for now
// to ease testing
private String[] getCommonComponentClasses() {
return new String[] { "com.vaadin.flow.component.login.LoginI18n",
"com.vaadin.flow.component.login.LoginI18n$Header",
"com.vaadin.flow.component.login.LoginI18n$Form",
"com.vaadin.flow.component.login.LoginI18n$ErrorMessage",
"com.vaadin.flow.component.messages.MessageListItem" };
private Set<String> getCommonComponentClasses() {
Set<String> classes = new HashSet<>(
List.of("com.vaadin.flow.component.messages.MessageListItem"));

// A common pattern in Flow components is to handle translations in
// classes with name ending in I18n and their potential inner classes,
// that are serialized as JSON and sent to the client.
// An exception is the Upload component whose translations class has
// capitalized N (UploadI18N)
Predicate<String> i18nClasses = className -> className
.matches(".*I18[nN]($|\\$.*$)");
// Charts and Map configurations are serialized as JSON to be sent to
// the client. All configuration classes need to be registered for
// reflection.
Predicate<String> componentsFilter = i18nClasses
.or(className -> className
.startsWith("com.vaadin.flow.component.charts.model.")
|| className.startsWith(
"com.vaadin.flow.component.map.configuration."));

classes.addAll(classesFromPackage("com.vaadin.flow.component",
componentsFilter));
return classes;
}

private static Set<String> classesFromPackage(String packageName,
Predicate<String> filter) {
return new Reflections(new ConfigurationBuilder()
.forPackage(packageName).setScanners(Scanners.SubTypes))
.getAll(Scanners.SubTypes).stream()
.filter(cl -> cl.startsWith(packageName)).filter(filter)
.collect(Collectors.toSet());
}

private String[] getClasses() {
Expand Down

0 comments on commit 00dd9ef

Please sign in to comment.