堆缓存大小配置为 MB 时 Ehcache 的非法反射访问警告
Illegal reflective access warning for Ehcache when heap cache size is configured in MB
我使用Ehcache作为hibernate的查询缓存,以下是我的Ehcache配置。
<cache alias="default-query-results-region">
<key-type>org.hibernate.cache.spi.QueryKey</key-type>
<value-type>java.lang.Object</value-type>
<expiry>
<ttl unit="seconds">30</ttl>
</expiry>
<resources>
<heap unit="MB">1</heap>
<offheap unit="MB">2</offheap>
</resources>
</cache>
当我执行我的应用程序时,控制台记录了以下警告。
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.ehcache.sizeof.ObjectGraphWalker (file:/C:/Users/<my_username>/.m2/repository/org/ehcache/ehcache/3.9.4/ehcache-3.9.4.jar) to field java.util.ArrayList.elementData
WARNING: Please consider reporting this to the maintainers of org.ehcache.sizeof.ObjectGraphWalker
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
但是如果我将堆单元指定为 entries
,我不会收到警告。
<heap unit="entries">2</heap>
以下是我使用的Ehcache版本
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.9.4</version>
</dependency>
下面是我的休眠配置,我在其中指定了 Ehcache 作为缓存提供程序。
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.jcache.JCacheRegionFactory</property>
<property name="hibernate.javax.cache.provider">org.ehcache.jsr107.EhcacheCachingProvider</property>
<property name="hibernate.javax.cache.uri">ehcache.xml</property>
我正在使用 OpenJDK 11
。
出现此警告的原因是什么?有什么办法可以解决吗?
如果您通过物理大小(即 MB)限制缓存,EHCache 必须以某种方式探测所有数据结构以确定它们的实际大小(以字节为单位)。为此,它必须反射性地“闯入”所有 类 以确定大小。您可以使用以下 java 命令行标志来允许 EHCache(但不幸的是所有其他代码)执行此操作:--add-opens=java.base/java.util=ALL-UNNAMED
请注意,您可能还需要打开 java.base
模块的其他包,具体取决于您在缓存条目中使用的数据结构类型。此解决方案附带的一个特殊“安全问题”是,您的 运行 的任何其他代码现在也可以执行各种操作,Java 9 开始封装这些代码以提高安全性。要仅将此“权限”限制为 EHCache,您必须 运行 在模块模式下,但我不确定您想要做什么。
总的来说,我建议您不要使用具有物理大小的堆配置。仅使用堆外或基于一些平均条目大小假设的条目配置。
我使用Ehcache作为hibernate的查询缓存,以下是我的Ehcache配置。
<cache alias="default-query-results-region">
<key-type>org.hibernate.cache.spi.QueryKey</key-type>
<value-type>java.lang.Object</value-type>
<expiry>
<ttl unit="seconds">30</ttl>
</expiry>
<resources>
<heap unit="MB">1</heap>
<offheap unit="MB">2</offheap>
</resources>
</cache>
当我执行我的应用程序时,控制台记录了以下警告。
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.ehcache.sizeof.ObjectGraphWalker (file:/C:/Users/<my_username>/.m2/repository/org/ehcache/ehcache/3.9.4/ehcache-3.9.4.jar) to field java.util.ArrayList.elementData
WARNING: Please consider reporting this to the maintainers of org.ehcache.sizeof.ObjectGraphWalker
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
但是如果我将堆单元指定为 entries
,我不会收到警告。
<heap unit="entries">2</heap>
以下是我使用的Ehcache版本
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.9.4</version>
</dependency>
下面是我的休眠配置,我在其中指定了 Ehcache 作为缓存提供程序。
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.jcache.JCacheRegionFactory</property>
<property name="hibernate.javax.cache.provider">org.ehcache.jsr107.EhcacheCachingProvider</property>
<property name="hibernate.javax.cache.uri">ehcache.xml</property>
我正在使用 OpenJDK 11
。
出现此警告的原因是什么?有什么办法可以解决吗?
如果您通过物理大小(即 MB)限制缓存,EHCache 必须以某种方式探测所有数据结构以确定它们的实际大小(以字节为单位)。为此,它必须反射性地“闯入”所有 类 以确定大小。您可以使用以下 java 命令行标志来允许 EHCache(但不幸的是所有其他代码)执行此操作:--add-opens=java.base/java.util=ALL-UNNAMED
请注意,您可能还需要打开 java.base
模块的其他包,具体取决于您在缓存条目中使用的数据结构类型。此解决方案附带的一个特殊“安全问题”是,您的 运行 的任何其他代码现在也可以执行各种操作,Java 9 开始封装这些代码以提高安全性。要仅将此“权限”限制为 EHCache,您必须 运行 在模块模式下,但我不确定您想要做什么。
总的来说,我建议您不要使用具有物理大小的堆配置。仅使用堆外或基于一些平均条目大小假设的条目配置。