tags:

views:

43

answers:

2

I am doing development of a Tomcat webapp and need to be able to restart Tomcat to load code changes. However, sometimes Tomcat takes a long time to startup as the main thread is stalled in the following place:

java.lang.Thread.State: RUNNABLE
    at org.apache.tomcat.jni.SSL.initialize(Native Method)
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.core.AprLifecycleListener.initializeSSL(AprLifecycleListener.java:214)
- locked <119e583> (a java.lang.Class)
at org.apache.catalina.core.AprLifecycleListener.lifecycleEvent(AprLifecycleListener.java:83)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.core.StandardServer.initialize(StandardServer.java:770)
at org.apache.catalina.startup.Catalina.load(Catalina.java:530)
at org.apache.catalina.startup.Catalina.load(Catalina.java:550)
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.load(Bootstrap.java:260)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:412)

This stall is caused by the available entropy (as shown by running cat /proc/sys/kernel/random/entropy_avail) is too low.

When I am developing code I don't care if the SSL engine is initialised with a good random number.

Is there any way for me to dump some fake entropy into /dev/rnd or force Tomcat to use some fake entropy?

I can push up the entropy more quickly by running "find /" but this takes a while to produce enough entropy.

+2  A: 

You could use /dev/urandom in a development environment, as it is faster (and obviously less secure) than /dev/random.

Note - This does not work in Windows, and I would expect that it is not required on Windows as the problem only manifests with usage of /dev/random. Windows uses Microsoft Crypto API (CAPI) when the /dev/random string is used to state the required PRNG source (i.e. the securerandom.source property in the JRE_HOME/lib/security/java.security file).

EDIT

Based on the other answer which requires setting the RANDFILE environment variable, the solution described here is applicable when the non-native (i.e. JSSE) implementation is used for SSL in Tomcat.

Vineet Reynolds
My Tomcat instance is running on Linux. Adding -Djava.security.egd=file:/dev/./urandom to my list of command line args seems to have no effect - startup is still very slow when the entropy pool is low. I am using Java HotSpot(TM) Server VM (build 10.0-b23, mixed mode). Is there any reason why a command line override of this property would be ignored by Java? In particular, my java.security file contains the line securerandom.source=file:/dev/urandom. Can the command line option override this?
mchr
Setting securerandom.source=file:/dev/./urandom in java.security still seems to have no effect on startup times. Maybe tomcat.jni.SSL.initialize is hardcoded to use /dev/random?
mchr
@mchr, can you try executing the following commands to verify that urandom is indeed faster than random on your installation: 1) cat /dev/random 2) cat /dev/urandom . On a test VMWare instance of mine, where random is meant to be slower than urandom, I can see a noticeable change in speed. It should be more or less the same for you.
Vineet Reynolds
I have found a solution for this - I'll post it a bit later when I'm back at my pc :)
mchr
+1  A: 

Setting the environment variable RANDFILE to "/dev/urandom" makes Tomcat use this source for SSL init.

mchr
Ah well, it was OpenSSL then - http://www.openssl.org/support/faq.cgi#USER1 . I'm afraid I missed looking at the JNI call in the stacktrace that also contained references to the AprLifecycleListener. But that explains why setting java.security.egd did not work. Tomcat was using APR which uses OpenSSL and not JSSE.
Vineet Reynolds