-
I have a a custom validator which looks like: @Dependent
public class GreetingListValidator implements ConstraintValidator<GreetingList, String> {
@ConfigProperty(name = "greeting.list", defaultValue = "hello")
String greetingList;
private Set<String> greetings = Collections.emptySet();
@Override
public void initialize(GreetingList constraintAnnotation) {
System.out.println("Greeting List is " + greetingList+" in GreetingListValidator");
greetings = Arrays.stream(greetingList.split(","))
.map(String::trim).map(String::toLowerCase)
.collect(Collectors.toSet());
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return greetings.contains(value.trim().toLowerCase());
}
} I compile (with native compilation) and deploy my app.
The effective greeting list is the default one: hello . It does not contain bonjour. The external configuration is not taken. :'( Now, as a workaround, I moved my validation code into a CDI bean: @ApplicationScoped
public class GreetingListService {
@ConfigProperty(name = "greeting.list", defaultValue = "hello")
String greetingList;
private Set<String> greetings = Collections.emptySet();
@PostConstruct
public void initialize() {
System.out.println("Greeting List is " + greetingList+" in GreetingListValidator");
greetings = Arrays.stream(greetingList.split(","))
.map(String::trim).map(String::toLowerCase)
.collect(Collectors.toSet());
}
public boolean isValid(String value) {
return greetings.contains(value.trim().toLowerCase());
}
}
@Dependent
public class GreetingListValidator implements ConstraintValidator<GreetingList, String> {
@Inject
String greetingListService;
@Override
public void initialize(GreetingList constraintAnnotation) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return greetingListService.isValid(value);
}
} And this works! The environment variable is taken. :-) My question is about Validator lifecycle. Are they created as CDI beans? What is the difference between a Validator initialization and a CDI bean inialization regarding @ConfigProperty injection |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 16 replies
-
Answering to myself, I have just noticed during native compilation:
The |
Beta Was this translation helpful? Give feedback.
-
Well, not exactly at build time. The CDI container is started during the |
Beta Was this translation helpful? Give feedback.
-
@mkouba Thanks for explaining, I am not sure to grasp everything though, it seems a bit complicated. Lesson learned, I tried several alternatives. @Dependent
public class GreetingListValidator implements ConstraintValidator<GreetingList, String> {
@ConfigProperty(name = "greeting.list", defaultValue = "hello")
Provider<String> greetingList;
private Set<String> greetings;
@Override
public void initialize(GreetingList constraintAnnotation) {
String s = greetingList.get();
System.out.println("Greeting List is " + s + " in GreetingListValidator");
greetings = Arrays.stream(s.split(","))
.map(String::trim).map(String::toLowerCase)
.collect(Collectors.toSet());
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return greetings.contains(value.trim().toLowerCase());
}
} Yet this is not enough. The @Dependent
public class GreetingListValidator implements ConstraintValidator<GreetingList, String> {
@ConfigProperty(name = "greeting.list", defaultValue = "hello")
Provider<String> greetingList;
private Set<String> greetings;
@Override
public void initialize(GreetingList constraintAnnotation) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (greetings == null) {
String s = greetingList.get();
System.out.println("Greeting List is " + s + " in GreetingListValidator");
greetings = Arrays.stream(s.split(","))
.map(String::trim).map(String::toLowerCase)
.collect(Collectors.toSet());
}
return greetings.contains(value.trim().toLowerCase());
}
} This another possible workaround. |
Beta Was this translation helpful? Give feedback.
-
I am still puzzled by the fact that validator init doesn't behave like normal CDI bean init. |
Beta Was this translation helpful? Give feedback.
Well, not exactly at build time. The CDI container is started during the
STATIC_INIT
bootstrap phase. For a native executable build, however, theSTATIC_INIT
bootstrap phase runs as part of the native build process. I.e. if a CDI bean is initialized duringSTATIC_INIT
of a native executable build then the@ConfigProperty
injection points cannot reflect the runtime values (configured with system properteis and ENV variables). And it seems thatConstraintValidator
s are initialized during theSTATIC_INIT
phase.