James Daugherty created GROOVY-11841:
----------------------------------------

             Summary: Metaclass Concurrency Problem
                 Key: GROOVY-11841
                 URL: https://issues.apache.org/jira/browse/GROOVY-11841
             Project: Groovy
          Issue Type: Bug
    Affects Versions: 4.0.0
            Reporter: James Daugherty


I'm upgrading a highly concurrent application that uses Spring Batch to 
read/write data in parallel.  After upgrading to Groovy 4, I'm seeing stack 
traces like this: 


{code:java}
java.util.ConcurrentModificationException
        at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1221)
        at groovy.lang.MetaClassImpl.getMetaProperty(MetaClassImpl.java:308)
        at 
org.grails.datastore.mapping.reflect.ClassPropertyFetcher.getStaticPropertyValuesFromInheritanceHierarchy(ClassPropertyFetcher.java:229)
        at 
org.grails.datastore.mapping.reflect.ClassPropertyFetcher.getStaticPropertyValuesFromInheritanceHierarchy(ClassPropertyFetcher.java:219)
        at 
org.grails.datastore.gorm.validation.constraints.eval.DefaultConstraintEvaluator.evaluate(DefaultConstraintEvaluator.java:116)
        at 
org.grails.datastore.gorm.validation.constraints.eval.DefaultConstraintEvaluator.evaluate(DefaultConstraintEvaluator.java:111)
        at 
org.grails.datastore.gorm.validation.constraints.eval.DefaultConstraintEvaluator.evaluate(DefaultConstraintEvaluator.java:106)
        at 
grails.gorm.validation.PersistentEntityValidator.<init>(PersistentEntityValidator.groovy:71)
        at 
org.grails.datastore.gorm.validation.constraints.registry.DefaultValidatorRegistry.getValidator(DefaultValidatorRegistry.groovy:85)
        at 
org.grails.datastore.gorm.validation.jakarta.JakartaValidatorRegistry.getValidator(JakartaValidatorRegistry.groovy:127)
        at 
org.grails.datastore.mapping.model.AbstractMappingContext.getEntityValidator(AbstractMappingContext.java:219)
        at 
org.grails.datastore.gorm.GormValidationApi.getValidator(GormValidationApi.groovy:82)
        at 
org.grails.orm.hibernate.AbstractHibernateGormValidationApi.validate(AbstractHibernateGormValidationApi.groovy:61)
        at 
org.grails.orm.hibernate.AbstractHibernateGormValidationApi.validate(AbstractHibernateGormValidationApi.groovy:55)
        at 
org.grails.datastore.gorm.GormValidateable$Trait$Helper.validate(GormValidateable.groovy:76)
        at com.triu.system.SystemDirectQuery.validate(SystemDirectQuery.groovy)
        at 
org.grails.orm.hibernate.support.ClosureEventListener.doValidate(ClosureEventListener.java:306)
        at 
org.grails.orm.hibernate.support.ClosureEventListener$7.call(ClosureEventListener.java:272)
        at 
org.grails.orm.hibernate.support.ClosureEventListener$7.call(ClosureEventListener.java:261)
        at 
org.grails.orm.hibernate.support.ClosureEventListener.doWithManualSession(ClosureEventListener.java:385)
        at 
org.grails.orm.hibernate.support.ClosureEventListener.onPreUpdate(ClosureEventListener.java:261)
        at 
org.grails.orm.hibernate.event.listener.HibernateEventListener.onPreUpdate(HibernateEventListener.java:158)
 {code}
 

 

GROOVY-9631 replaced these data structures with LinkedHashmaps.  A side effect 
of this is that code that previously executed concurrently without issue seems 
to be no longer thread safe.

[https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/LinkedHashMap.html]
 has this warning too: 


{code:java}
Note that this implementation is not synchronized.
 If multiple threads access a linked hash map concurrently, and at least
 one of the threads modifies the map structurally, it must be
 synchronized externally.  This is typically accomplished by
 synchronizing on some object that naturally encapsulates the map.

 If no such object exists, the map should be "wrapped" using the
 Collections.synchronizedMap
 method.  This is best done at creation time, to prevent accidental
 unsynchronized access to the map:{code}
It makes sense to lock down writes to maps, but since the read is non-thread 
safe it seems this could still be problematic.  

 

 

 



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

Reply via email to