You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级至Java 11后Apache Shiro无法找到默认Ehcache配置

Java 11升级后Shiro无法自动加载默认Ehcache配置的问题

问题背景

将使用Apache Shiro的Web应用从Java 8升级到Java 11(仅Java版本变更,所有依赖包无变动)后,启动服务器时出现Shiro无法找到默认ehcache.xml配置的错误,Java 8环境下运行完全正常。

报错信息

[main] INFO org.apache.shiro.web.env.EnvironmentLoader - Starting Shiro environment initialization.
[main] ERROR org.apache.shiro.web.env.EnvironmentLoader - Shiro environment initialization failed
java.lang.NullPointerException: The url can not be null
    at org.ehcache.xml.XmlConfiguration.<init>(XmlConfiguration.java:151)
    at org.ehcache.xml.XmlConfiguration.<init>(XmlConfiguration.java:131)
    at org.ehcache.xml.XmlConfiguration.<init>(XmlConfiguration.java:115)
    at org.ehcache.integrations.shiro.EhcacheShiroManager.getConfiguration(EhcacheShiroManager.java:176)
    at org.ehcache.integrations.shiro.EhcacheShiroManager.ensureCacheManager(EhcacheShiroManager.java:149)
    at org.ehcache.integrations.shiro.EhcacheShiroManager.init(EhcacheShiroManager.java:205)
    at org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:45)
    at org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:40)
    at org.apache.shiro.config.ReflectionBuilder$BeanConfigurationProcessor.execute(ReflectionBuilder.java:831)
    at org.apache.shiro.config.ReflectionBuilder.buildObjects(ReflectionBuilder.java:290)
    at org.apache.shiro.config.IniSecurityManagerFactory.buildInstances(IniSecurityManagerFactory.java:181)
    at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:139)
    at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:107)
    at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:98)
    at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:47)
    at org.apache.shiro.config.IniFactorySupport.createInstance(IniFactorySupport.java:150)
    at org.apache.shiro.util.AbstractFactory.getInstance(AbstractFactory.java:47)
    at org.apache.shiro.web.env.IniWebEnvironment.createWebSecurityManager(IniWebEnvironment.java:296)
    at org.apache.shiro.web.env.IniWebEnvironment.configure(IniWebEnvironment.java:121)
    at org.apache.shiro.web.env.IniWebEnvironment.init(IniWebEnvironment.java:73)
    at org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:45)
    at org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:40)
    at org.apache.shiro.web.env.EnvironmentLoader.createEnvironment(EnvironmentLoader.java:313)
    at org.apache.shiro.web.env.EnvironmentLoader.initEnvironment(EnvironmentLoader.java:139)
    at org.apache.shiro.web.env.EnvironmentLoaderListener.contextInitialized(EnvironmentLoaderListener.java:58)

现有配置

web.xml配置

<listener>
        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>

该配置自动加载WEB-INF/shiro.ini,其中缓存管理器配置如下:

shiro.ini核心配置

[main]
...
cacheManager = org.ehcache.integrations.shiro.EhcacheShiroManager
securityManager.cacheManager = $cacheManager

依赖信息(无变动)

  • shiro-all-1.12.0.jar
  • shiro-ehcache3-1.0.0.jar
  • 其他依赖:commons-beanutils、commons-logging、log4j、slf4j、ehcache

Java 8下的正常启动日志

[main] INFO org.apache.shiro.web.env.EnvironmentLoader - Starting Shiro environment initialization.
[main] INFO org.ehcache.xml.XmlConfiguration - Loading Ehcache XML configuration from file:/path/to/my/app/lib/shiro-ehcache3-1.0.0.jar!/org/ehcache/integrations/shiro/ehcache.xml.

已尝试的无效方案

  1. 在shiro.ini中添加cacheManager.cacheManagerConfigFile = /path/to/custom/configuration.xml(使用从shiro-ehcache3 jar中提取的默认配置),报错:
    org.apache.shiro.ShiroException: java.net.MalformedURLException: no protocol: /path/to/my/app/ehcache.xml
    
  2. 在代码中手动设置cacheManagerConfigFile路径,尝试过/path/to/my/app/ehcache.xml、file:///path/to/...、classpath:ehcache.xml,均触发相同的MalformedURLException。

最小复现示例

Java测试代码

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.util.Factory;

public class Test {
    
    public static void main(String[] args) {
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
    }

}

配套shiro.ini(放置于类路径根目录)

[main]
cacheManager = org.ehcache.integrations.shiro.EhcacheShiroManager
securityManager.cacheManager = $cacheManager

该示例在Java 8下运行正常,Java 11(Amazon Corretto 11.0.16-amzn、Temurin 11.0.20-tem)及Java 17(17.0.8-amzn)均报相同的"URL can not be null"错误。


解决方案

问题根源

Java 9+ 对JDK内部API的访问限制及类加载机制变化,导致shiro-ehcache3-1.0.0.jar中EhcacheShiroManager类获取默认配置文件的方式失效——该类使用的ClassLoader.getResource()方法在模块化环境下无法正确定位Jar内的默认ehcache.xml,返回null进而触发NPE。

修复步骤

  1. 优先升级shiro-ehcache3依赖版本:shiro-ehcache3 1.0.0版本存在Java 9+兼容性问题,升级到1.0.1及以上稳定版,该版本已修复类加载相关的兼容性问题,升级后无需额外配置即可自动加载默认配置。
  2. 若无法升级依赖,手动指定带协议的配置文件路径:
    在shiro.ini中配置时必须使用带协议前缀的路径,例如:
    # 使用Jar内的默认配置
    cacheManager.cacheManagerConfigFile = classpath:org/ehcache/integrations/shiro/ehcache.xml
    # 或使用自定义配置文件(需放置在类路径下)
    cacheManager.cacheManagerConfigFile = classpath:ehcache.xml
    
    注意:必须加上classpath:或file:协议前缀,直接使用文件路径会触发MalformedURLException。

验证

升级依赖或配置正确路径后,Java 11下启动应用,日志将恢复类似Java 8的正常输出,自动加载指定的ehcache.xml配置。


内容的提问来源于stack exchange,提问作者RTF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 06:26:02