Payara: CDI injection doesn't work within of custom constraint validator

Created on 6 Jan 2018  路  3Comments  路  Source: payara/Payara

# CDI injection doesn't work within custom constraint validator #

Expected Outcome

It (probably) should work out of the box, as it works under openliberty and wildfly

Current Outcome

[2018-01-06T00:48:25.961+0200] [Payara 5..Beta1] [WARNING] [] [org.glassfish.jersey.server.internal.JerseyResourceContext] [tid: _ThreadID=38 _ThreadName=http-thread-pool::http-listener-1(4)] [timeMillis: 1515192505961] [levelValue: 900] [[
Lookup and initialization failed for a resource class: class com.afrunt.example.validation.JavaEE8BookValidator.
MultiException stack 1 of 1
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=BookService,parent=JavaEE8BookValidator,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1987912783)
at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:75)
at org.jvnet.hk2.internal.Utilities.justInject(Utilities.java:1012)
at org.jvnet.hk2.internal.ServiceLocatorImpl.inject(ServiceLocatorImpl.java:1008)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:1083)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:1074)
at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.createAndInitialize(AbstractHk2InjectionManager.java:213)
at org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager.createAndInitialize(ImmediateHk2InjectionManager.java:54)
at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:130)
at org.glassfish.jersey.server.JerseyResourceContextConfigurator.lambda$init$0(JerseyResourceContextConfigurator.java:69)
at org.glassfish.jersey.server.internal.JerseyResourceContext.getResource(JerseyResourceContext.java:107)
at org.glassfish.jersey.server.validation.internal.InjectingConstraintValidatorFactory.getInstance(InjectingConstraintValidatorFactory.java:61)
at org.hibernate.validator.internal.engine.constraintvalidation.ClassBasedValidatorDescriptor.newInstance(ClassBasedValidatorDescriptor.java:64)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.createAndInitializeValidator(ConstraintValidatorManager.java:150)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.getInitializedValidator(ConstraintValidatorManager.java:109)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getInitializedConstraintValidator(ConstraintTree.java:176)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:112)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:83)
at org.hibernate.validator.internal.metadata.core.MetaConstraint.doValidateConstraint(MetaConstraint.java:116)
at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:109)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:569)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForSingleDefaultGroupElement(ValidatorImpl.java:527)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:496)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:461)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:411)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateCascadedAnnotatedObjectForCurrentGroup(ValidatorImpl.java:641)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateCascadedConstraints(ValidatorImpl.java:604)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateParametersInContext(ValidatorImpl.java:897)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateParameters(ValidatorImpl.java:297)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateParameters(ValidatorImpl.java:254)
at org.glassfish.jersey.server.validation.internal.DefaultConfiguredValidator.onValidate(DefaultConfiguredValidator.java:178)
at org.glassfish.jersey.server.validation.internal.ValidationInterceptorExecutor.proceed(ValidationInterceptorExecutor.java:114)
at org.glassfish.jersey.server.validation.internal.DefaultConfiguredValidator.validateResourceAndInputParams(DefaultConfiguredValidator.java:146)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:138)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:243)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:103)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:493)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:415)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:104)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:277)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)
at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
at org.glassfish.jersey.internal.Errors.process(Errors.java:268)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1622)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:258)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:654)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:593)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:159)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:483)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:180)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:242)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
at java.lang.Thread.run(Thread.java:748)
]]

Steps to reproduce (Only for bug reports)

  1. Clone the example I created https://github.com/afrunt/examples/tree/master/java-ee-8-examples/bean-validation-custom-validator
  2. Build it with default profile
  3. Deploy it to payaradomain
  4. Try to send POST request to /api/book with payload {"name" : "Java ee 8"}

    Samples

    Context (Optional)

    Just wanna to be able to inject my beans to custom constraint validators to perform specific validations, that depends on DB, for example. I created the temporary workaround for this issue to continue working on my project
    https://github.com/afrunt/examples/tree/master/misc/jaxrs-bean-validation-cdi-custom-validator

    Environment

    • Payara Version: 5 Beta 1
    • Edition: Full
    • JDK Version: 8 u152 - Oracle
    • Operating System: Mac
    • Database:
Bug

Most helpful comment

Hi Andrii,

I've tested this and the issue is as you say. From what I can tell it seems to be to do with the fact that Jersey performs it's injection using HK2, so the validator can't find the Weld managed beans. The workaround you mentioned works, or alternatively you can validate the bean manually like so:

~~~
@Inject
private Validator validator;

@POST
@Produces(MediaType.APPLICATION_JSON)
public Response postCustom(Bean bean) {
validator.validate(bean);
Set> violations = validator.validate(bean);
if (violations.size() > 0) {
ConstraintViolationException ex = new ConstraintViolationException(violations);
return Response.status(422).entity(ex.getMessage()).type(MediaType.TEXT_PLAIN).build();
}
return Response.ok(bean).build();
}
~~~

I've created internal issue PAYARA-2491 to address this bug.

Kind regards,

Matt

All 3 comments

Hi Andrii,

I've tested this and the issue is as you say. From what I can tell it seems to be to do with the fact that Jersey performs it's injection using HK2, so the validator can't find the Weld managed beans. The workaround you mentioned works, or alternatively you can validate the bean manually like so:

~~~
@Inject
private Validator validator;

@POST
@Produces(MediaType.APPLICATION_JSON)
public Response postCustom(Bean bean) {
validator.validate(bean);
Set> violations = validator.validate(bean);
if (violations.size() > 0) {
ConstraintViolationException ex = new ConstraintViolationException(violations);
return Response.status(422).entity(ex.getMessage()).type(MediaType.TEXT_PLAIN).build();
}
return Response.ok(bean).build();
}
~~~

I've created internal issue PAYARA-2491 to address this bug.

Kind regards,

Matt

Payara internal issue ID PAYARA-2491

Fixed by #3021

Was this page helpful?
0 / 5 - 0 ratings