When running Tomcat with a SecurityManager, an AccessControlException is thrown during undeployment. Stack trace: Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323) at java.security.AccessController.checkPermission(AccessController.java:546) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.Class.getClassLoader(Class.java:594) at org.apache.catalina.loader.JdbcLeakPrevention.clearJdbcDriverRegistrations(JdbcLeakPrevention.java:49) I assume the default catalina.policy should be updated, to take this case into account.
Please provide the full stacktrace. The JdbcLeakPrevention class should already have the necessary permissions, so there must be something odd in the call chain. Is this issue reproducible? What steps are needed to reproduce it?
Here is the full stack trace. May 5, 2010 5:15:16 AM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc WARNING: JDBC driver de-registration failed java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.catalina.loader.WebappClassLoader.clearReferencesJdbc(WebappClassLoader.java:1820) at org.apache.catalina.loader.WebappClassLoader.clearReferences(WebappClassLoader.java:1740) at org.apache.catalina.loader.WebappClassLoader.stop(WebappClassLoader.java:1658) at org.apache.catalina.loader.WebappLoader.stop(WebappLoader.java:710) at org.apache.catalina.core.StandardContext.stop(StandardContext.java:4649) at org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:924) at org.apache.catalina.startup.HostConfig.undeployApps(HostConfig.java:1319) at org.apache.catalina.startup.HostConfig.stop(HostConfig.java:1290) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:323) at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119) at org.apache.catalina.core.ContainerBase.stop(ContainerBase.java:1086) at org.apache.catalina.core.ContainerBase.stop(ContainerBase.java:1098) at org.apache.catalina.core.StandardEngine.stop(StandardEngine.java:448) at org.apache.catalina.core.StandardService.stop(StandardService.java:587) at org.apache.catalina.core.StandardServer.stop(StandardServer.java:744) at org.apache.catalina.startup.Catalina.stop(Catalina.java:648) at org.apache.catalina.startup.Catalina.start(Catalina.java:615) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323) at java.security.AccessController.checkPermission(AccessController.java:546) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.Class.getClassLoader(Class.java:594) at org.apache.catalina.loader.JdbcLeakPrevention.clearJdbcDriverRegistrations(JdbcLeakPrevention.java:49) ... 27 more I see an AllPermission grant in the default catalina.policy that I would have expected to prevent this problem, but haven't given much thought as to why it doesn't. It is reproducible here, simply by shutting down Tomcat with a still-registered JDBC driver (and with a security manager in place, obviously). If you'd like any additional information, just let me know.
This works for me with the latest 6.0.x code. I don't recall any relevant changes since 6.0.26. If you still see this issue, please feel free to re-open but you'll need to provide the simplest complete set of steps to reproduce this from a clean 6.0.26 install.
The problem still exists on Tomcat 6.0.29 Steps: to reproduce Run MySQL DBCP Example from http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html on Tomcat with enabled security. ./catalina.sh run -security I will add demo application and Context confiuration as attachment. To reproduce you need copy my-webapp.war to /webapps,my-webapp.xml to Catalina/localhost, also you need to add JDBC driver to /lib. Exception will occur only if security is enabled.
Created attachment 26042 [details] MySQL DBCP Example APP
Created attachment 26043 [details] Context configuration
Created attachment 26049 [details] Patch for tomcat 6.0.29 I managed to reproduce the problem. The thing is that the JdbcLeakPrevention class called by WebappClassLoader.clearReferencesJdbc() is not loaded by the same ClassLoader as the other parts of catalina. It is loaded by the classloader of the webapp, but without any ProtectionDomain defined. My patch just calls defineClass passing the current ProtectionDomain of the WebappClassLoader class so that from a security policy point of view, the loaded JdbcLeakPrevention class has the same privileges as the rest of catalina as it would have if it had been loaded normally. I tested my patch with java 1.6.0_20 on OSX 10.6. I suppose the issue also applies to tomcat 7 but did not check.
Thanks for the patch. Fixed in trunk and proposed for 6.0.x
Fixed in 6.0.x and will be in 6.0.30 onwards. Thanks again for the patch.