Недавно я добавил 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(...).
Похоже, это не создает никаких рабочих проблем, поэтому я, вероятно, просто проигнорирую это сейчас. Если кто-нибудь понимает, что происходит, пожалуйста, дайте мне крик.