Apache Shiro cannot find ehcache default config with Java 11

94 Views Asked by At

I have a web application that uses Apache Shiro. I'm upgrading from Java 8 to 11. That is the only change, but when I try to launch my server, it looks like shiro can't find the default ehcache.xml config. I get the following error:

[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)

In my web.xml I have:

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

...which automatically picks up my shiro.ini config in my WEB-INF directory, which contains (among other things):

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

When I compile and run using java 8, there's no problems finding the ehcache config and the server starts up normally:

[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.

As I mentioned, the only change is that I'm compiling and running with java 11. All of the same jars are available to both builds, and those shiro specific jars are:

  • shiro-all-1.12.0.jar
  • shiro-ehcache3-1.0.0.jar

I've also tried adding cacheManager.cacheManagerConfigFile = /path/to/custom/configuration.xml to my shiro.ini as suggested by the docs here by extracting the default ehcache.xml config file from the ehcache jar, but no matter what path I use in the ini file, the server startup always fails with org.apache.shiro.ShiroException: java.net.MalformedURLException: no protocol: /path/to/my/app/ehcache.xml.

I've also tried setting the cacheManagerConfigFile path to the ehcache xml config programmatically in my application entry point, but I get a MalformedURLException for any string that I provide e.g. "/path/to/my/app/ehcache.xml", "file:///path/to..." or "classpath:ehcache.xml".

The default ehcache.xml config extraction was really just a workaround though (that I can't get working), so ideally I would like to understand and fix why shiro isn't finding the default config itself with java 11.

I've reproduced this problem with a minimal example by initialising the ini file programatically like below and putting the ini file into the root of the classpath:

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);
    }

}

The shiro.ini in this case only contains:

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

Java 8 is fine, Java 11 fails with the "URL can not be null" error. For the example to work, you'll also need:

  • commons-beanutils
  • commons-logging
  • log4j
  • slf4j
  • ehcache

...as well as the 2 shiro jars I mentioned previously. The specific java 11 builds I've tried using that fail are Amazon Coretto (11.0.16-amzn) and Temeric (11.0.20-tem), and the java 8 builds that are working for me are 8.0.332-tem and 8.0.382-amzn.

I've also tried compiling and running with Java 17 (17.0.8-amzn), which fails with the same error.

1

There are 1 best solutions below

0
RTF On

My problem was that I was using the pre-built maven artifact for the shiro-ehcache package, so I've managed to sort this out by building the package from source with Java 11. Since jaxb was dropped from java 11, I also needed the following packages:

  • jaxb-impl
  • jaxb-core
  • jaxb-api
  • jakarta.xml.bind-api
  • jakarta.activation
  • javax.activation-api