You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@bval.apache.org by "Romain Manni-Bucau (JIRA)" <ji...@apache.org> on 2019/04/21 12:14:00 UTC
[jira] [Commented] (BVAL-172) ConcurrentModificationException
during validation
[ https://issues.apache.org/jira/browse/BVAL-172?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16822674#comment-16822674 ]
Romain Manni-Bucau commented on BVAL-172:
-----------------------------------------
[~mbenson] hey Matt, seems the HashMap impl changed enough to enforce us to move to a thread safe impl, i m planning to revert my last commit and move to concurrent hashmap but before doing so, do you want to move to another lock free+thread safe structure? Boost is not super significant on my bench but would like a second opinion before doing so.
> ConcurrentModificationException during validation
> -------------------------------------------------
>
> Key: BVAL-172
> URL: https://issues.apache.org/jira/browse/BVAL-172
> Project: BVal
> Issue Type: Bug
> Affects Versions: 2.0.0, 2.x
> Environment: Java 10.0.3
>
> Reporter: John Myers
> Assignee: Romain Manni-Bucau
> Priority: Major
> Fix For: 2.0.3
>
>
> The following test case fails under Java 10.0.3:
> {code:java}
> @Test
> public void testMultipleThreads()
> throws ExecutionException, InterruptedException {
> List<CompletableFuture<Boolean>> validationResultSuppliers = new ArrayList<>();
> List<Exception> validationExceptions = new ArrayList<>();
> IntStream.range(0,5).forEach(
> i -> {
> SampleEntityForValidation sampleRequestEntity = new SampleEntityForValidation("name-" + i, "description-" + i);
> validationResultSuppliers.add(CompletableFuture.supplyAsync(() -> {
> try {
> return validator.validate(sampleRequestEntity)
> .isEmpty();
> } catch (Exception e) {
> validationExceptions.add(e);
> e.printStackTrace();
> return false;
> }
> }));
> }
> );
> CompletableFuture.allOf(validationResultSuppliers.toArray(new CompletableFuture[] {})).get();
> assertEquals(0, validationExceptions.size());
> }
> public static class SampleEntityForValidation {
> @NotNull(message = "is missing")
> @Size(min = 3, message = "must be at least 3 characters long")
> private String name;
> @NotNull(message = "is missing")
> @Size(max = 15, message = "can be at most 15 characters long")
> private String description;
> public SampleEntityForValidation (
> String name,
> String description
> ) {
> this.name = name;
> this.description = description;
> }
> }
> {code}
> throwing the following stack traces:
> {noformat}
> java.util.ConcurrentModificationException
> at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1134)
> at org.apache.bval.jsr.ConstraintCached.infos(ConstraintCached.java:133)
> at org.apache.bval.jsr.ConstraintCached.getConstraintValidatorInfo(ConstraintCached.java:128)
> at org.apache.bval.jsr.util.AnnotationsManager.supportedTargets(AnnotationsManager.java:406)
> at org.apache.bval.jsr.util.AnnotationsManager.validateConstraintDefinition(AnnotationsManager.java:337)
> at org.apache.bval.jsr.descriptor.MetadataReader$ForElement.lambda$getConstraints$1(MetadataReader.java:100)
> at java.base/java.util.stream.ReferencePipeline$11$1.accept(ReferencePipeline.java:441)
> at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
> at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
> at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
> at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
> at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
> at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
> at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
> at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:274)
> at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
> at java.base/java.util.Collections$2.tryAdvance(Collections.java:4745)
> at java.base/java.util.Collections$2.forEachRemaining(Collections.java:4753)
> at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
> at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
> at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
> at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
> at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
> at org.apache.bval.jsr.descriptor.MetadataReader$ForElement.getConstraints(MetadataReader.java:103)
> at org.apache.bval.jsr.descriptor.ElementD.<init>(ElementD.java:86)
> at org.apache.bval.jsr.descriptor.ElementD$NonRoot.<init>(ElementD.java:46)
> at org.apache.bval.jsr.descriptor.CascadableContainerD.<init>(CascadableContainerD.java:41)
> at org.apache.bval.jsr.descriptor.PropertyD.<init>(PropertyD.java:92)
> at org.apache.bval.jsr.descriptor.PropertyD$ForField.<init>(PropertyD.java:42)
> at org.apache.bval.jsr.descriptor.MetadataReader$ForBean.lambda$getProperties$2(MetadataReader.java:149)
> at java.base/java.util.HashMap.forEach(HashMap.java:1336)
> at org.apache.bval.jsr.descriptor.MetadataReader$ForBean.getProperties(MetadataReader.java:147)
> at org.apache.bval.jsr.descriptor.BeanD.<init>(BeanD.java:59)
> at org.apache.bval.jsr.descriptor.DescriptorManager.getBeanDescriptor(DescriptorManager.java:81)
> at org.apache.bval.jsr.job.ValidationJob.getBeanDescriptor(ValidationJob.java:586)
> at org.apache.bval.jsr.job.ValidationJob.access$300(ValidationJob.java:81)
> at org.apache.bval.jsr.job.ValidationJob$BeanFrame.<init>(ValidationJob.java:249)
> at org.apache.bval.jsr.job.ValidationJob$BeanFrame.<init>(ValidationJob.java:245)
> at org.apache.bval.jsr.job.ValidateBean.computeBaseFrame(ValidateBean.java:40)
> at org.apache.bval.jsr.job.ValidationJob.getResults(ValidationJob.java:558)
> at org.apache.bval.jsr.ValidatorImpl.validate(ValidatorImpl.java:53)
> at org.apache.bval.jsr.ValidationTest.lambda$testMultipleThreads$0(ValidationTest.java:748)
> at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700)
> at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1692)
> at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
> at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
> at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
> at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
> at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
> {noformat}
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)