Wednesday, January 21, 2009

Hudson Gets an AccessControlException when starting on Ubuntu Tomcat

With fresh install of Ubuntu 8.10 I grabbed Tomcat 6 from Synaptic. Then, I dropped the hudson.war into the Tomcat webapps directory, and was greeted with an AccessControlException and a Hudson that would not start.

This is because on Ubuntu, Tomcat default installs with the Tomcat Security Manager enabled. This is probably a good thing for many installs of Tomcat, but it interferes with Hudson. When we finally found the problem, we took the lazy road and disabled the Tomcat Security. Depending on your install, this may be an unsafe decision. I would check the Tomcat documentation before doing this if your server is externally exposed. In our environment, the build server is on a completely trusted network. So, we didn't care much.

Here is the stack trace that is displayed when first trying to browse to the Hudson app:


HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: Error instantiating servlet class org.kohsuke.stapler.Stapler
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:636)

root cause

java.lang.ExceptionInInitializerError
org.apache.commons.beanutils.ConvertUtilsBean.(ConvertUtilsBean.java:130)
org.kohsuke.stapler.Stapler.(Stapler.java:659)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:532)
java.lang.Class.newInstance0(Class.java:372)
java.lang.Class.newInstance(Class.java:325)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:636)

root cause

java.security.AccessControlException: access denied (java.util.PropertyPermission org.apache.commons.logging.LogFactory.HashtableImpl read)
java.security.AccessControlContext.checkPermission(AccessControlContext.java:342)
java.security.AccessController.checkPermission(AccessController.java:553)
java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1302)
java.lang.System.getProperty(System.java:669)
org.apache.commons.logging.LogFactory.createFactoryStore(LogFactory.java:320)
org.apache.commons.logging.LogFactory.(LogFactory.java:1725)
org.apache.commons.beanutils.ConvertUtilsBean.(ConvertUtilsBean.java:130)
org.kohsuke.stapler.Stapler.(Stapler.java:659)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:532)
java.lang.Class.newInstance0(Class.java:372)
java.lang.Class.newInstance(Class.java:325)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:636)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.18 logs.



This was fixed by changing:

/etc/default/tomcat6


And setting the following property:

# Use the Java security manager? (yes/no, default: yes)
# WARNING: Do not disable the security manager unless you understand
# the consequences!
#TOMCAT6_SECURITY=yes
TOMCAT6_SECURITY=no


Note that we left the commented example in place for future reference. I hope this helps someone else. Mostly, I'm hoping that by writing this down, I will remember this in the future or at least be able to find the solution quicker.

Go forth and write tests...

5 comments:

Kohsuke Kawaguchi said...

Thanks for posting this. I filed an issue so that Hudson can provide more human-friendly error message for this.

Eric Anderson said...

Thank you for the quick response. And thanks for the work that you do on Hudson.

Anonymous said...

Thanks for blogging this. You just saved me hours of frustration.

Eric Anderson said...

No problem. I'm glad that MY hours of frustration have limited yours :)

Anonymous said...

Thanks for your blog! Tomcat security is moot. I would *never* deploy it outside a trusted subnet. That said, Ubuntu has actually made it worse with a non-standard setup which invites people to mess things up even worse in an attempt to get Hudson working. Thanks Sun. And thanks even less to Canonical.

Yeah. I'm disgusted. Bad design makes me sick.