Windows – Tomcat 7.0.22 Windows service breaks with JRE update

javatomcatwindows

If JRE update is run without first manually stopping the Tomcat service, Tomcat will no longer start after the next time it is stopped. This most often happens after rebooting per the JRE installer's request.

To reproduce the error

  • Install the latest Tomcat 7 as a Windows service with Java 6 u29 installed. Tomcat should run just fine.
  • Update to Java 6u31 without first stopping the Tomcat service. Java requires a server reboot and after the reboot the Tomcat service will no longer start.

Logs following reboot

Tomcat 7 stdout

2012-04-03 12:25:02 Commons Daemon procrun stdout initialized 
2012-04-03 12:42:25 Commons Daemon procrun stdout initialized 
Error occurred during initialization of VM java/lang/NoClassDefFoundError: java/lang/Object 

Last part of Tomcat7 stderr (the only line after the Java update and restart)

2012-04-03 12:42:25 Commons Daemon procrun stderr initialized

Best Answer

We have observed this with a long-running (but not Tomcat) Java app that runs as a Windows service. We create it as a Windows service with the 'procrun' mechanism in Apache Commons Daemon, which is the same way the Tomcat Windows service works.

From hints of other reports of this, it seems like the Java update process moves/renames files as part of upgrading to the new version. There might be one or two renames left to do when the install finishes, and those renames are supposed to happen after a reboot. But if there's a long-running Java app running at the same time as the update is taking place, that app will have various Java libs and exe's (like the main jre.exe) locked, and the Java update fails.

One symptom of this is to open a command window and type "java -version". If you get the noclassdeffound error for java/lang/Object, it's a pretty good bet that the combination of a JDK upgrade with a long-running Java app has left you with a corrupt JDK/JRE.

We have found two workarounds: (1) reinstall the app; (2) reinstall Java. (1) usually works for us because we have an installer for the app which will also install a clean version of Java if required. Sometimes even that fails, though, with the message "The jar-file 'reach-stream-installer-izpack.jar' could not be executed." (IzPack being the automated installer tool we use). In this case we fall back to (2).

Neither workaround is very nice. It's a shame that the automated JDK update facility provided by Java breaks our application.

Have you made any progress with this since your original posting?