堆缓存大小配置为 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,您必须 运行 在模块模式下,但我不确定您想要做什么。

总的来说,我建议您不要使用具有物理大小的堆配置。仅使用堆外或基于一些平均条目大小假设的条目配置。