This repository was archived by the owner on May 28, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
This repository was archived by the owner on May 28, 2018. It is now read-only.
Cannot inject CDI bean into custom validator #3801
Copy link
Copy link
Open
Description
Jersey doesn't allow me to inject CDI bean into my custom Validator.
Sample code:
@ApplicationScoped
public class AllowedWeightsValidator implements ConstraintValidator<AllowedWeights, Map<String, Integer>> {
@Inject
private Localizer localizer;
@Override
public void initialize(AllowedWeights allowedWeights) {
// ...
}
@Override
public boolean isValid(Map<String, Integer> weights, ConstraintValidatorContext context) {
// ...
}
}
The exception is:
<org.glassfish.jersey.server.internal.JerseyResourceContext> <BEA-000000> <Lookup and initialization failed for a resource class: class package.AllowedWeightsValidator.
A MultiException has 1 exceptions. They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=Localizer,parent=AllowedWeightsValidator,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1451781908)
at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:75)
at org.jvnet.hk2.internal.Utilities.justInject(Utilities.java:941)
at org.jvnet.hk2.internal.ServiceLocatorImpl.inject(ServiceLocatorImpl.java:980)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:1055)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:1046)
at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:173)
at org.glassfish.jersey.server.internal.JerseyResourceContext.getResource(JerseyResourceContext.java:102)
at org.glassfish.jersey.server.validation.internal.InjectingConstraintValidatorFactory.getInstance(InjectingConstraintValidatorFactory.java:61)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.createAndInitializeValidator(ConstraintValidatorManager.java:141)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.getInitializedValidator(ConstraintValidatorManager.java:101)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:125)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:91)
at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:83)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:547)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:487)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:451)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:403)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateCascadedConstraint(ValidatorImpl.java:723)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateCascadedConstraints(ValidatorImpl.java:601)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:412)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateCascadedConstraint(ValidatorImpl.java:723)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateCascadedConstraints(ValidatorImpl.java:601)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateParametersInContext(ValidatorImpl.java:992)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateParameters(ValidatorImpl.java:300)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateParameters(ValidatorImpl.java:254)
at org.glassfish.jersey.server.validation.internal.DefaultConfiguredValidator.onValidate(DefaultConfiguredValidator.java:175)
at org.glassfish.jersey.server.validation.internal.ValidationInterceptorExecutor.proceed(ValidationInterceptorExecutor.java:113)
at org.glassfish.jersey.server.validation.internal.DefaultConfiguredValidator.validateResourceAndInputParams(DefaultConfiguredValidator.java:146)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:134)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
Such injection should be according to Beans Validation spec (1.1, section 10.3.2) supported:
If no custom ConstraintValidatorFactory is requested by the user, the ValidatorFactory must be configured with a custom ConstraintValidatorFactory instance that returns CDI managed beans representing the requested ConstraintValidator types
When I inject (via @javax.inject.Inject
) the Validator manually, everything works as expected. The problem occurs when I have a JAX-RS @POST
method accepting POJO with my custom validation annotation.
This problem can be workarounded by registering the following ContextResolver:
public class ValidationConfigResolver implements ContextResolver<ValidationConfig> {
@Context
private ResourceContext resourceContext;
@Override
public ValidationConfig getContext(Class<?> aClass) {
return new ValidationConfig().constraintValidatorFactory(new CDIConstraintValidatorFactory(resourceContext));
}
private static class CDIConstraintValidatorFactory implements ConstraintValidatorFactory {
private final ResourceContext resourceContext;
public CDIConstraintValidatorFactory(ResourceContext resourceContext) {
this.resourceContext = resourceContext;
}
@Override
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> clazz) {
Instance<T> cdiInstance = CDI.current().select(clazz);
return cdiInstance.isUnsatisfied() ? resourceContext.getResource(clazz) : cdiInstance.get();
}
@Override
public void releaseInstance(ConstraintValidator<?, ?> constraintValidator) {
try {
CDI.current().destroy(constraintValidator);
} catch (UnsupportedOperationException ignored) {
// If CDI cannot destroy the validator, that's perfectly fine.
// It could have been created by HK2 (ResourceContext).
}
}
}
}
Metadata
Metadata
Assignees
Labels
No labels