Bean validation fixes

This commit is contained in:
Stuart Douglas
2018-09-20 13:27:46 +10:00
parent 61708fc7b0
commit a77564f9e6
2 changed files with 29 additions and 7 deletions

View File

@@ -41,33 +41,37 @@ class BeanValidationProcessor implements ResourceProcessor {
beanDeployment.addAdditionalBean(ValidatorProvider.class);
processorContext.addRuntimeInitializedClasses("javax.el.ELUtil");
processorContext.addResourceBundle("org.hibernate.validator.ValidationMessages");
//int constraints = new ConstraintHelperSubstitution().builtinConstraints
//TODO: this should not rely on the index and implementation being indexed, this stuff should just be hard coded
try (BytecodeRecorder recorder = processorContext.addStaticInitTask(RuntimePriority.BEAN_VALIDATION_DEPLOYMENT)) {
ValidatorTemplate template = recorder.getRecordingProxy(ValidatorTemplate.class);
template.forceInit((InjectionInstance<ValidatorProvider>) recorder.newInstanceFactory(ValidatorProvider.class.getName()));
}
processorContext.addReflectiveClass(true, false, Constraint.class.getName());
Map<DotName, Set<DotName>> seenConstraints = new HashMap<>();
Set<String> classesToBeValidated = new HashSet<>();
for (AnnotationInstance constraint : archiveContext.getCombinedIndex().getAnnotations(DotName.createSimple(Constraint.class.getName()))) {
Collection<AnnotationInstance> annotationInstances = archiveContext.getCombinedIndex().getAnnotations(constraint.target().asClass().name());
if(!annotationInstances.isEmpty()) {
processorContext.addReflectiveClass(true, false, constraint.target().asClass().name().toString());
String classToValidate = constraint.target().asClass().name().toString();
processorContext.addReflectiveClass(true, false, classToValidate);
}
for (AnnotationInstance annotation : annotationInstances) {
Set<DotName> seenTypes = seenConstraints.get(annotation.name());
if (seenTypes == null) {
seenConstraints.put(annotation.name(), seenTypes = new HashSet<>());
}
if (annotation.target().kind() == AnnotationTarget.Kind.FIELD) {
classesToBeValidated.add(annotation.target().asField().declaringClass().name().toString());
processorContext.addReflectiveField(annotation.target().asField());
seenTypes.add(annotation.target().asField().type().name());
} else if (annotation.target().kind() == AnnotationTarget.Kind.METHOD) {
classesToBeValidated.add(annotation.target().asMethod().declaringClass().name().toString());
processorContext.addReflectiveMethod(annotation.target().asMethod());
seenTypes.add(annotation.target().asMethod().returnType().name());
} else if (annotation.target().kind() == AnnotationTarget.Kind.METHOD_PARAMETER) {
classesToBeValidated.add(annotation.target().asMethodParameter().method().declaringClass().name().toString());
processorContext.addReflectiveMethod(annotation.target().asMethodParameter().method());
seenTypes.add(annotation.target().asMethodParameter().asType().asClass().name());
} else if (annotation.target().kind() == AnnotationTarget.Kind.CLASS) {
classesToBeValidated.add(annotation.target().asClass().name().toString());
seenTypes.add(annotation.target().asClass().name());
processorContext.addReflectiveClass(true, true, annotation.target().asClass().name().toString());
}
@@ -127,6 +131,16 @@ class BeanValidationProcessor implements ResourceProcessor {
}
}
}
try(BytecodeRecorder recorder = processorContext.addStaticInitTask(RuntimePriority.BEAN_VALIDATION_DEPLOYMENT)) {
ValidatorTemplate template = recorder.getRecordingProxy(ValidatorTemplate.class);
Class[] classes = new Class[classesToBeValidated.size()];
int j = 0;
for(String c : classesToBeValidated) {
classes[j++] = recorder.classProxy(c);
}
template.forceInit((InjectionInstance<ValidatorProvider>) recorder.newInstanceFactory(ValidatorProvider.class.getName()), classes);
}
}
@Override

View File

@@ -1,5 +1,9 @@
package org.jboss.shamrock.beanvalidation.runtime;
import java.lang.reflect.Proxy;
import javax.validation.Validator;
import org.jboss.shamrock.runtime.InjectionInstance;
public class ValidatorTemplate {
@@ -7,12 +11,16 @@ public class ValidatorTemplate {
/**
* Force the validation factory to be created at static init time, so it is
* bootstrapped in a JVM rather than in native-image
*
* <p>
* TODO: we really only need to run in native-image
*
* @param provider
*/
public void forceInit(InjectionInstance<ValidatorProvider> provider) {
public void forceInit(InjectionInstance<ValidatorProvider> provider, Class<?>... classesToValidate) {
provider.newInstance().forceInit();
Validator validator = provider.newInstance().factory().getValidator();
for(Class<?> i : classesToValidate) {
validator.getConstraintsForClass(i);
}
}
}