[ 
https://issues.apache.org/jira/browse/TOMEE-4449?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Richard Zowalla updated TOMEE-4449:
-----------------------------------
    Fix Version/s: 10.1.4
                       (was: 10.1.3)

> Invalid jakarta.validation.ConstraintDeclarationException thrown
> ----------------------------------------------------------------
>
>                 Key: TOMEE-4449
>                 URL: https://issues.apache.org/jira/browse/TOMEE-4449
>             Project: TomEE
>          Issue Type: Bug
>          Components: TomEE Core Server
>    Affects Versions: 10.0.0
>            Reporter: Ricardo Herrera
>            Assignee: Markus Jung
>            Priority: Major
>             Fix For: 10.1.4
>
>
> jakarta.validation spec says overridden methods cannot be constrained 
> (annotated with @Valid annotation, for example), in such case the constraint 
> must be applied to the parent class/method. If I follow this rule, the 
> validation is *NOT* performed in TomEE. For example, In my project, I have 
> the following classes (please ignore the "Unknown macro:" labels, those were 
> added by Jira and I don't know how to make them go away in the code style) 
>  
> {quote}public interface HelloManager
>  \{     public Message getGreeting();     public void setGreeting(@Valid 
> Message message); }
>  
>  
> @ApplicationScoped
> public class JpaHelloManager implements HelloManager
> Unknown macro: \{     @Override     public Message getGreeting() Unknown 
> macro}
>     @Override
>     @Transactional
>     public void setGreeting(Message message)
> Unknown macro: \{       // some logic     }
> }
>  
> @Path("/hello")
> public class HelloResource
> Unknown macro: \{     @Inject     private HelloManager manager;       @GET    
>  @Produces(MediaType.APPLICATION_JSON)     public Message getGreeting() 
> Unknown macro}
>     @POST
>     @Produces(MediaType.APPLICATION_JSON)
>     @Consumes(MediaType.APPLICATION_JSON)
>     public Response getGreeting(Message message)
> Unknown macro: \{     manager.setGreeting(message);          return 
> Response.ok().build();     }
> }
>  
> public class Message
> Unknown macro: \{      private String type;     @NotBlank(message = "Greeting 
> cannot be empty")     @Size(max = 50, message="Greeting cannot be longer than 
> 50 characters")     private String title;     // setters and getters }
> {quote}
>  
> but NONE of the validations are performed when I POST a request with invalid 
> data and If I change the JpaHelloManager.setGreeting() method to be
> {quote}    public void setGreeting(@Value Message message)  
> Unknown macro: \{     }
> {quote}
> Then I got the following exception when I hit whatever endpoint:
> {quote}jakarta.validation.ConstraintDeclarationException: Illegal 
> strengthening: overridden [cascades] in inheritance hierarchy: [arg0 of 
> public void mx.com.hexam.JpaHelloManager.setGreeting(mx.com.hexam.Message), 
> arg0 of public abstract void 
> mx.com.hexam.HelloManager.setGreeting(mx.com.hexam.Message)]
>     at 
> org.apache.bval.jsr.metadata.Liskov$StrengtheningIssue.check(Liskov.java:128)
>     at 
> org.apache.bval.jsr.metadata.Liskov.noStrengtheningOfPreconditions(Liskov.java:212)
>     at 
> org.apache.bval.jsr.metadata.Liskov.validateContainerHierarchy(Liskov.java:155)
>     at 
> org.apache.bval.jsr.metadata.HierarchyBuilder$ForContainer.<init>(HierarchyBuilder.java:302)
>     at 
> org.apache.bval.jsr.metadata.HierarchyBuilder.forContainer(HierarchyBuilder.java:374)
>     at 
> org.apache.bval.jsr.metadata.CompositeBuilder$ForExecutable.lambda$getParameters$3(CompositeBuilder.java:220)
>     at java.base/java.util.stream.IntPipeline$1$1.accept(IntPipeline.java:180)
>     at 
> java.base/java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Streams.java:104)
>     at 
> java.base/java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:711)
>     at 
> java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
>     at 
> java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
>     at 
> java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
>     at 
> java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
>     at 
> java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
>     at 
> org.apache.bval.jsr.metadata.CompositeBuilder$ForExecutable.getParameters(CompositeBuilder.java:222)
>     at 
> org.apache.bval.jsr.descriptor.MetadataReader$ForExecutable.getParameterDescriptors(MetadataReader.java:350)
>     at org.apache.bval.jsr.descriptor.ExecutableD.<init>(ExecutableD.java:46)
>     at org.apache.bval.jsr.descriptor.MethodD.<init>(MethodD.java:32)
>     at 
> org.apache.bval.jsr.descriptor.MetadataReader$ForBean.lambda$getMethods$6(MetadataReader.java:190)
>     at java.base/java.util.HashMap.forEach(HashMap.java:1421)
>     at 
> org.apache.bval.jsr.descriptor.MetadataReader$ForBean.getMethods(MetadataReader.java:186)
>     at org.apache.bval.jsr.descriptor.BeanD.<init>(BeanD.java:63)
>     at 
> org.apache.bval.jsr.descriptor.DescriptorManager.getBeanDescriptor(DescriptorManager.java:79)
>     at 
> org.apache.bval.jsr.ValidatorImpl.getConstraintsForClass(ValidatorImpl.java:48)
>     at 
> org.apache.webbeans.custom.Validator$$OwbNormalScopeProxy14428537300.getConstraintsForClass(jakarta/validation/Validator.java)
>     at org.apache.bval.cdi.BValInterceptor.construct(BValInterceptor.java:109)
>     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
> Method)
>     at 
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
>     at 
> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>     at java.base/java.lang.reflect.Method.invoke(Method.java:569)
>     at 
> org.apache.webbeans.component.InterceptorBean.intercept(InterceptorBean.java:152)
>     at 
> org.apache.webbeans.intercept.InterceptorInvocationContext.proceed(InterceptorInvocationContext.java:65)
>     at 
> org.apache.webbeans.portable.InjectionTargetImpl.produce(InjectionTargetImpl.java:171)
>     at 
> org.apache.webbeans.portable.AbstractProducer.produce(AbstractProducer.java:140)
>     at 
> org.apache.webbeans.component.AbstractOwbBean.create(AbstractOwbBean.java:124)
>     at org.apache.webbeans.component.ManagedBean.create(ManagedBean.java:66)
>     at 
> org.apache.webbeans.context.creational.BeanInstanceBag.create(BeanInstanceBag.java:76)
>     at 
> org.apache.webbeans.context.AbstractContext.getInstance(AbstractContext.java:159)
>     at 
> org.apache.webbeans.context.AbstractContext.get(AbstractContext.java:125)
>     at 
> org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:101)
>     at 
> org.apache.webbeans.intercept.ApplicationScopedBeanInterceptorHandler.getContextualInstance(ApplicationScopedBeanInterceptorHandler.java:65)
>     at 
> org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.get(NormalScopedBeanInterceptorHandler.java:71)
>     at 
> mx.com.hexam.JpaHelloManager$$OwbNormalScopeProxy0.getGreeting(mx/com/hexam/JpaHelloManager.java)
>     at mx.com.hexam.web.HelloResource.getGreeting(HelloResource.java:28)
>     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
> Method)
>     at 
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
>     at 
> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>     at java.base/java.lang.reflect.Method.invoke(Method.java:569)
>     at 
> org.apache.openejb.server.cxf.rs.PojoInvoker.performInvocation(PojoInvoker.java:37)
>     at 
> org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
>     at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:200)
>     at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:103)
>     at 
> org.apache.openejb.server.cxf.rs.AutoJAXRSInvoker.invoke(AutoJAXRSInvoker.java:68)
>     at 
> org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)
>     at 
> org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)
>     at 
> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
>     at 
> org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
>     at 
> org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265)
>     at 
> org.apache.openejb.server.cxf.rs.CxfRsHttpListener.doInvoke(CxfRsHttpListener.java:266)
>     at 
> org.apache.tomee.webservices.CXFJAXRSFilter.doFilter(CXFJAXRSFilter.java:80)
>     at 
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
>     at 
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
>     at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
>     at 
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
>     at 
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
>     at org.apache.openejb.server.httpd.EEFilter.doFilter(EEFilter.java:67)
>     at 
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
>     at 
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
>     at 
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
>     at 
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
>     at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)
>     at 
> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
>     at 
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
>     at 
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
>     at 
> org.apache.tomee.catalina.OpenEJBSecurityListener$RequestCapturer.invoke(OpenEJBSecurityListener.java:97)
>     at 
> org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:663)
>     at 
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
>     at 
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
>     at 
> org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397)
>     at 
> org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
>     at 
> org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905)
>     at 
> org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741)
>     at 
> org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
>     at 
> org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
>     at 
> org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
>     at 
> org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
>     at java.base/java.lang.Thread.run(Thread.java:840)
> {quote}
> I played with other servers (Glassfish and Wildfly) and they don't perform 
> the validation either if I omit the Valid annotation on the 
> JpaHelloManager.setGreeting() method. That is consistent with TomEE, but if I 
> add it, then the validation is performed as expected with no exception. TomEE 
> must provide a way to perform the validation in this hierarchy case.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to