Широ Эх Кэш ConcurrenctModificationException

Недавно я добавил Shiro с EH Cache в свое веб-приложение, и с тех пор я вижу несколько исключений ConcurrentModificationException:

[shiro-active%0053ession%0043ache.data] ERROR net.sf.ehcache.store.disk.DiskStorageFactory - Disk Write of 3ae3f634-cd97-4614-bd04-517d81623971 failed: 
net.sf.ehcache.CacheException: Failed to serialize element due to ConcurrentModificationException. This is frequently the result of inappropriately sharing thread unsafe object (eg. ArrayList, HashMap, etc) between threads
at net.sf.ehcache.store.disk.DiskStorageFactory.serializeElement(DiskStorageFactory.java:401)
at net.sf.ehcache.store.disk.DiskStorageFactory.write(DiskStorageFactory.java:381)
at net.sf.ehcache.store.disk.DiskStorageFactory$DiskWriteTask.call(DiskStorageFactory.java:473)
at net.sf.ehcache.store.disk.DiskStorageFactory$PersistentDiskWriteTask.call(DiskStorageFactory.java:1067)
at net.sf.ehcache.store.disk.DiskStorageFactory$PersistentDiskWriteTask.call(DiskStorageFactory.java:1051)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)

У меня проблема в том, что трассировка стека не дает много информации о том, где проблема в коде, и поскольку веб-приложение довольно большое.

Любые советы о том, как найти и исправить ошибку, будут высоко оценены.

РЕДАКТИРОВАТЬ: проблема возникает, когда пользователь переходит из модуля ROOT «www.my-site.com/» в модуль приложения «www.my-site.com/app/». Оба модуля используют Shiro в другом кеше/сеансе (т. е. пока без SSO). Единственное, что они разделяют, — это 3 файла cookie: locale/currency/cookie-consent. Я не думаю, что это происходит из файлов cookie, поскольку доступ к ним осуществляется в начале запроса (т.е. при выходе из ROOT для доступа к приложению только приложение получает доступ к файлам cookie и сохраняет локаль в сеансе).

Любая идея о том, что может быть причиной проблемы?

--------------- РЕДАКТИРОВАТЬ -------- Вот более подробная трассировка стека. Простой сеанс Широ, кажется, играет свою роль:

Caused by: java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:806)
at java.util.HashMap$EntryIterator.next(HashMap.java:847)
at java.util.HashMap$EntryIterator.next(HashMap.java:845)
at java.util.HashMap.writeObject(HashMap.java:1012)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at org.apache.shiro.session.mgt.SimpleSession.writeObject(SimpleSession.java:461)

---------------------------- РЕДАКТИРОВАТЬ 2 ------------------

Я думаю, что нашел источник проблемы. У меня есть метод, который хранит несколько атрибутов String в сеансе. Приложение отлично работает без него, и проблема возвращается, как только я раскомментирую ее. Чего я не понимаю, так это того, почему это вызывает исключение одновременной модификации: этот метод только сохраняет строки в сеансе, и к сеансу обращается только один поток. Любые подсказки?

----------- РЕДАКТИРОВАТЬ 3 -------------------

Я заменил строки на 4 POJO. Теперь исключение возникает только один раз, когда пользователь впервые попадает на страницу (прямо перед началом выполнения кода doGet(...).

Похоже, это не создает никаких рабочих проблем, поэтому я, вероятно, просто проигнорирую это сейчас. Если кто-нибудь понимает, что происходит, пожалуйста, дайте мне крик.


person user2177336    schedule 23.07.2013    source источник
comment
Какие объекты вы пытаетесь поместить в сеанс широ? Есть ли вероятность, что вы могли бы поместить массив или хэш-карту или добавить значения к этим конструкциям данных в рамках сеанса в течение всего срока действия этого сеанса? Как говорится в сообщении стека, я видел, как это происходит при сохранении в кеше ArrayList и его дальнейшем изменении после сохранения... Если это так, попробуйте изменить тип этой структуры данных на потокобезопасный тип (т.е. concurrentHashMap) ...   -  person lanimall    schedule 23.07.2013
comment
Я согласен с Ianimall - похоже, что кто-то/что-то хранит в сеансе не потокобезопасную коллекцию. Попробуйте использовать аналог Concurrent* и посмотрите, работает ли он.   -  person Les Hazlewood    schedule 23.07.2013
comment
Нет, я храню только String и int на основе pojo. Странно то, что сеанс в ROOT не используется совместно с сеансом в приложении. Следовательно, я не понимаю исключения в первую очередь. Знаете ли вы, как я могу получить более подробную информацию (например, трассировку стека, показывающую объект, вызывающий исключение)?   -  person user2177336    schedule 23.07.2013
comment
У меня только что появилась идея... кажется, что запись на диск происходит именно в тот момент, когда возникает ошибка. Используете ли вы какой-то антивирус, который может заблокировать (из-за сканирования) файл, в который ehcache пытается записать? или что-нибудь еще, что может возиться с файлами? Это может быть так ... Чтобы быть уверенным, я бы удалил остановку этих процессов и посмотрел, произойдет ли это снова. Вы также можете удалить переполнение на диск для ehcache... и посмотреть, произойдет ли это снова. Наконец, я бы включил уровень DEBUG в используемой вами структуре ведения журнала (log4j?), чтобы получить больше информации о том, что происходит вокруг ошибки...   -  person lanimall    schedule 24.07.2013
comment
Я попытался внедрить SSO для своих двух модулей, и проблема немного прояснилась. Мне кажется, что 2 менеджера безопасности пытаются одновременно получить доступ к одной и той же хэш-карте в кеше. Следовательно, решением может быть реализация пользовательского кеша с ConcurrentHashMap. Я также рассмотрю возможность включения DEBUG в log4j. Держать вас в курсе.   -  person user2177336    schedule 24.07.2013
comment
Глядя на этот пост stackoverflow.com /questions/15245813/ кажется, что проблема явно связана с одновременным доступом к одному и тому же дисковому хранилищу.   -  person user2177336    schedule 24.07.2013
comment
Я не уверен в том, что происходит. Я попытался создать тестовый проект с двумя веб-приложениями, использующими один и тот же кеш, и он работал нормально. Затем я попытался запустить только модуль ROOT моего проекта, и ошибка снова появилась. Следовательно, это похоже на проблему параллелизма в одном веб-приложении. Я подробно изучил журналы, но не смог определить точный источник ошибки. Кажется, это происходит до запуска моего кода: Apache Shiro ищет файл cookie сеанса, а затем повторно попадает в кеш, сохраняя и получая некоторые значения из сеансов.   -  person user2177336    schedule 24.07.2013
comment
Отредактирует вопрос, чтобы поставить более подробную трассировку стека   -  person user2177336    schedule 24.07.2013