How To Fix Error 'Unable to make field transient'
Problem
Текст ошибки:
Suppressed: java.lang.reflect.InaccessibleObjectException: Unable to make field transient java.lang.Object[] java.util.ArrayList.elementData accessible: module java.base does not "opens java.util" to unnamed module @6adbc9d
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
at net.sf.ehcache.pool.sizeof.ObjectGraphWalker.getAllFields(ObjectGraphWalker.java:271)
at net.sf.ehcache.pool.sizeof.ObjectGraphWalker.getFilteredFields(ObjectGraphWalker.java:229)
at net.sf.ehcache.pool.sizeof.ObjectGraphWalker.walk(ObjectGraphWalker.java:160)
at net.sf.ehcache.pool.sizeof.SizeOf.deepSizeOf(SizeOf.java:72)
at net.sf.ehcache.pool.impl.DefaultSizeOfEngine.sizeOf(DefaultSizeOfEngine.java:190)
at net.sf.ehcache.pool.impl.AbstractPoolAccessor.add(AbstractPoolAccessor.java:63)
at net.sf.ehcache.store.MemoryStore.put(MemoryStore.java:281)
at net.sf.ehcache.Cache.putInternal(Cache.java:1620)
at net.sf.ehcache.Cache.put(Cache.java:1546)
at net.sf.ehcache.Cache.put(Cache.java:1511)
at org.springframework.cache.ehcache.EhCacheCache.put(EhCacheCache.java:128)
... 118 common frames omitted
How to reproduce it
Если в конфигурации Ehcache установить лимит для размера определенного кэша или всех кэшей, то Java будет выбрасывать исключения при попытках вставки в кэш, как приведены выше, потому что Ehcache попытается подсчитать размеры объект и не сможет из-за ограничений доступа на вызовы методов рефлексии у объектов из других пакетов.
How to solve it
Мне помог ответ на StackOverflow.
В нем написано, что необходимо добавить VM опции во время запуска приложения:
--add-opens java.base/java.util=ALL-UNNAMED
Также может работать и для других пакетов. Пример:
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.nio=ALL-UNNAMED
--add-opens java.base/sun.nio.ch=ALL-UNNAMED
Пример запуска java приложения с опциями:
java --add-opens java.base/java.lang=ALL-UNNAMED -jar ./app.jar