Open PeterTeunissen opened 2 years ago
Hello The validations are thread safe - this particular approach of unloading validation libraries within a threaded environment was not a requirement - I will look into the issues and see about adding
Can you be more specific on how you are reproducing the issue ? Are you using the UI or the service
Thanks
Sean
On Aug 2, 2022, at 11:01 AM, Peter Teunissen @.***> wrote:
We have build the ccd-validator and are calling the code with different document which need different validationObjectives.
We see the below ConcurrentModificationException in the code. Looking at the code the unload/reload methods on the Mu2consolePackage.eINSTANCE look like a static operation. That makes me wonder if the ccd validator is thread safe?
java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.remove(HashMap.java:1483) at org.hl7.security.ds4p.contentprofile.impl.CONTENTPROFILEPackageImpl.unload(CONTENTPROFILEPackageImpl.java:435) at org.sitenv.referenceccda.validators.schema.ReferenceCCDAValidator.validateDocumentByTypeUsingMDHTApi(ReferenceCCDAValidator.java:160) at org.sitenv.referenceccda.validators.schema.ReferenceCCDAValidator.validateFile(ReferenceCCDAValidator.java:108) at org.sitenv.referenceccda.validators.schema.ReferenceCCDAValidator$$FastClassBySpringCGLIB$$fb042745.invoke(
) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136) at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) at org.sitenv.referenceccda.validators.schema.ReferenceCCDAValidator$$EnhancerBySpringCGLIB$$c5ebceb.validateFile( ) at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.doMDHTValidation(ReferenceCCDAValidationService.java:202) at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.runValidators(ReferenceCCDAValidationService.java:127) at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.validateCCDAImplementation(ReferenceCCDAValidationService.java:79) at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.validateCCDA(ReferenceCCDAValidationService.java:69) < > — Reply to this email directly, view it on GitHub https://github.com/onc-healthit/reference-ccda-validator/issues/155, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABIZ4F7QQOXDEC6NFI5UVWDVXEZ6HANCNFSM55LP47GQ. You are receiving this because you are subscribed to this thread.
It is sporadic (but persistent). I will try to recreate and update here. We have this integrated with another process, so the call is direct to the Rest endpoint (not through the UI). We will try some jmeter setup.
There are two more flavors of these errors:
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.remove(HashMap.java:1483)
at org.openhealthtools.mdht.uml.cda.mu2consol.impl.Mu2consolPackageImpl.unload(Mu2consolPackageImpl.java:303)
at org.sitenv.referenceccda.validators.schema.ReferenceCCDAValidator.validateDocumentByTypeUsingMDHTApi(ReferenceCCDAValidator.java:159)
at org.sitenv.referenceccda.validators.schema.ReferenceCCDAValidator.validateFile(ReferenceCCDAValidator.java:108)
at org.sitenv.referenceccda.validators.schema.ReferenceCCDAValidator$$FastClassBySpringCGLIB$$fb042745.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at org.sitenv.referenceccda.validators.schema.ReferenceCCDAValidator$$EnhancerBySpringCGLIB$$c5ebceb.validateFile(<generated>)
at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.doMDHTValidation(ReferenceCCDAValidationService.java:202)
at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.runValidators(ReferenceCCDAValidationService.java:127)
at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.validateCCDAImplementation(ReferenceCCDAValidationService.java:79)
at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.validateCCDA(ReferenceCCDAValidationService.java:69)
at com.cerner.ccdavalidator.service.CCDAValidationService.validateCCDA(CCDAValidationService.java:117)
at com.cerner.ccdavalidator.rest.CCDAValidationController.doValidationWithDomainNameAndLogicalDomainId(CCDAValidationController.java:106)
and
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)
at java.util.ArrayList$Itr.remove(ArrayList.java:875)
at org.sitenv.vocabularies.validation.services.VocabularyValidationService.limitConfiguredExpressionsBySeverity(VocabularyValidationService.java:174)
at org.sitenv.vocabularies.validation.services.VocabularyValidationService.validate(VocabularyValidationService.java:219)
at org.sitenv.vocabularies.validation.services.VocabularyValidationService.validate(VocabularyValidationService.java:136)
at org.sitenv.vocabularies.validation.services.VocabularyValidationService.validate(VocabularyValidationService.java:105)
at org.sitenv.referenceccda.validators.vocabulary.VocabularyCCDAValidator.doValidation(VocabularyCCDAValidator.java:78)
at org.sitenv.referenceccda.validators.vocabulary.VocabularyCCDAValidator.validateFileImplementation(VocabularyCCDAValidator.java:66)
at org.sitenv.referenceccda.validators.vocabulary.VocabularyCCDAValidator.validateFile(VocabularyCCDAValidator.java:54)
at org.sitenv.referenceccda.validators.vocabulary.VocabularyCCDAValidator$$FastClassBySpringCGLIB$$b32d0b9.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at org.sitenv.referenceccda.validators.vocabulary.VocabularyCCDAValidator$$EnhancerBySpringCGLIB$$2d929969.validateFile(<generated>)
at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.doVocabularyValidation(ReferenceCCDAValidationService.java:210)
at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.runValidators(ReferenceCCDAValidationService.java:143)
at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.validateCCDAImplementation(ReferenceCCDAValidationService.java:79)
at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.validateCCDA(ReferenceCCDAValidationService.java:69)
Not surprised but the MU2 - as they have the same code snippet
The VocabularyValidationService is in a different area - will reach out to those resources
Sean
On Aug 2, 2022, at 3:48 PM, Peter Teunissen @.***> wrote:
There are two more flavors of these errors:
java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.remove(HashMap.java:1483) at org.openhealthtools.mdht.uml.cda.mu2consol.impl.Mu2consolPackageImpl.unload(Mu2consolPackageImpl.java:303) at org.sitenv.referenceccda.validators.schema.ReferenceCCDAValidator.validateDocumentByTypeUsingMDHTApi(ReferenceCCDAValidator.java:159) at org.sitenv.referenceccda.validators.schema.ReferenceCCDAValidator.validateFile(ReferenceCCDAValidator.java:108) at org.sitenv.referenceccda.validators.schema.ReferenceCCDAValidator$$FastClassBySpringCGLIB$$fb042745.invoke(
) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136) at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) at org.sitenv.referenceccda.validators.schema.ReferenceCCDAValidator$$EnhancerBySpringCGLIB$$c5ebceb.validateFile( ) at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.doMDHTValidation(ReferenceCCDAValidationService.java:202) at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.runValidators(ReferenceCCDAValidationService.java:127) at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.validateCCDAImplementation(ReferenceCCDAValidationService.java:79) at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.validateCCDA(ReferenceCCDAValidationService.java:69) at com.cerner.ccdavalidator.service.CCDAValidationService.validateCCDA(CCDAValidationService.java:117) at com.cerner.ccdavalidator.rest.CCDAValidationController.doValidationWithDomainNameAndLogicalDomainId(CCDAValidationController.java:106) and java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911) at java.util.ArrayList$Itr.remove(ArrayList.java:875) at org.sitenv.vocabularies.validation.services.VocabularyValidationService.limitConfiguredExpressionsBySeverity(VocabularyValidationService.java:174) at org.sitenv.vocabularies.validation.services.VocabularyValidationService.validate(VocabularyValidationService.java:219) at org.sitenv.vocabularies.validation.services.VocabularyValidationService.validate(VocabularyValidationService.java:136) at org.sitenv.vocabularies.validation.services.VocabularyValidationService.validate(VocabularyValidationService.java:105) at org.sitenv.referenceccda.validators.vocabulary.VocabularyCCDAValidator.doValidation(VocabularyCCDAValidator.java:78) at org.sitenv.referenceccda.validators.vocabulary.VocabularyCCDAValidator.validateFileImplementation(VocabularyCCDAValidator.java:66) at org.sitenv.referenceccda.validators.vocabulary.VocabularyCCDAValidator.validateFile(VocabularyCCDAValidator.java:54) at org.sitenv.referenceccda.validators.vocabulary.VocabularyCCDAValidator$$FastClassBySpringCGLIB$$b32d0b9.invoke(
) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136) at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) at org.sitenv.referenceccda.validators.vocabulary.VocabularyCCDAValidator$$EnhancerBySpringCGLIB$$2d929969.validateFile( ) at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.doVocabularyValidation(ReferenceCCDAValidationService.java:210) at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.runValidators(ReferenceCCDAValidationService.java:143) at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.validateCCDAImplementation(ReferenceCCDAValidationService.java:79) at org.sitenv.referenceccda.services.ReferenceCCDAValidationService.validateCCDA(ReferenceCCDAValidationService.java:69) — Reply to this email directly, view it on GitHub https://github.com/onc-healthit/reference-ccda-validator/issues/155#issuecomment-1203147124, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABIZ4F2VLTMQ5GFI2Q6EEJLVXF3QZANCNFSM55LP47GQ. You are receiving this because you commented.
We have setup jmeter, with 4 different thread groups, each with an HTTP Request with a different XML document. Each thread group makes 10 concurrent requests. So we hit the validators with 40 requests at the same time. We have 2 instances of the validator running behind a load balancer, so each instance would be hit with roughly 20 requests concurrently.
Give it enough time and we get the ConcurrentModificationException.
@swmuir We could try to help fix this, but would need some pointers. You mentioned something in the first comment about maybe not unloading validation libraries?
In order to work as one WAR, we had to add a load/unload procedure to switch between MU2 and non-MU2 validation. If you make a separate WAR for MU2, or, you have no use for MU2 validation and never run it (2014 is pretty old at this point), then it should be a non-issue. We could certainly look into fixing this (or removing it). We recently had a discussion where we agreed to sunset MU2 in general. So, I'm not sure we will have the resources to change the operation. It would be interesting to know if you are using MU2.
We have build the ccd-validator and are calling the rest endpoint with different documents (with different validationObjectives) concurrently under pretty high volume.
We see the below ConcurrentModificationException in the code. Looking at the code the unload/reload methods on the Mu2consolePackage.eINSTANCE look like a static operation. That makes me wonder if the ccd validator is thread safe?