Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
So I'm putting together a Windows 2008 R2 x64 RC Java image for a client (more on
that later), and everything's breezing along fine. Install the OS, check. Install
JDK 1.6 (u13) into the machine, check. Install Tomcat 6 into the machine, running
as a native Windows service, check. Open localhost on port 8080, and... not check.
Times out, no response, not good.
Naturally, the first thing to check is the logs, and I get the strangest error
I've seen in a while. "Cannot create Java". This is odd—what's happening,
in the aggregate, is easy enough to understand, in that the native Windows .exe launcher
(ProcRun, a generic service launcher from Apache) is using JNI to create the JVM inside
the launched service process and, for some reason, failing; what's not clear is why.
Unfortunately, the error codes offered up by the two players involved (Tomcat/ProcRun
and the Windows OS) are not helpful—the Windows Event Log basically says "Service
failed to start. Check the error code", which reports 0 (not helpful, thanks),
and the Tomcat "jakarta_service_date.log" file reports something
along the lines of...
[2009-05-23 17:33:41] [1343 prunsrv.c] [debug] Procrun log initialized
[2009-05-23 17:33:41] [info] Procrun (2.0.4.0) started
[2009-05-23 17:33:41] [1166 prunsrv.c] [debug] Inside ServiceMain...
[2009-05-23 17:33:41] [info] Starting service...
[2009-05-23 17:33:41] [174 javajni.c] [error] The specified module could not be found.
[2009-05-23 17:33:41] [994 prunsrv.c] [error] Failed creating java C:\Java\Tomcat6.0\jre64\bin\server\jvm.dll
[2009-05-23 17:33:41] [1269 prunsrv.c] [error] ServiceStart returned 1
[2009-05-23 17:33:41] [info] Procrun finished.
... which is not really all that helpful, either.
Hmm.
The fact that it can't create Java is not a really strong clue, so I start searching
the Web for some solutions. Several people report running into this same problem,
but solutions are not easily found—one web page reports that there's a missing "msvcr71.dll"
file from the Windows installer installation script, and that copying the file into
C:\WINDOWS\System32 fixes it, but when I go look in that directory, no dice—the DLL's
there, and a quick "DUMPBIN" on the file reveals it looks good, no accidental
file corruption or anything. Rats.
Maybe the problem's somewhere in the service configuration—it's possible that the
Tomcat installer put the wrong configuration in or something. So I fire up the Tomcat
configuration (tomcat6w.exe) from the "bin" directory, and just to be sure,
I go hunting up the Service entry in the Registry (on the off-chance that the configuration
utility is the source of the bug). Granted, this is kind of a stretch, but unfortunately,
like I said, there's not much to go on. Sure enough, make a few changes (one of which
is to tell the Tomcat native launcher to use the "server" VM, instead of
the "client" VM, by default—why, oh why, hasn't Apache changed that yet?!?),
verify that the changes are percolating all the way through into the Registry, and
try kicking off the service. Still no luck. Still the same error.
While I'm rooting around in the Registry, I notice that there's another node in there
that I'm not familiar with—the Wow6432Node. And buried underneath it (thank you, Registry
Search, for finding this!) is a node for Apache Software Foundation/ProcRun2.0/Tomcat6,
and a whole slew of configuration options under there, as well. Hmm. Errors in the
ProcRun configuration perhaps? Sure enough... no, everything's working fine.
But now the synapses are firing in a different direction—the ProcRun bits are underneath
the "Wow6432Node", and the "Wow" part of that name has me wondering—in
the old 16-bit-to-32-bit transition Windows went through once before, "Wow"
was an acronym for "Windows-on-Windows", meaning that the 32-bit version
of Windows was opening up an emulation layer to run 16-bit programs. Given that this
is an x64 image that I'm working with... is it that the service wants to be using
the x64 version of Java rather than the 32-bit version I downloaded out of pure habit?
Hmm. Go grab the x64 image, install it, and... still no love.
The WoW64 thing is still tickling at the back of my brain, though, and suddenly a
new synapse fires off. If this is a 64-bit version of Windows, then there has to be....
Yep, sure enough, underneath the C:\WINDOWS directory there are not two, but three,
"system" directories—the "C:\WINDOWS\System" directory that used
to be the hangout place for 16-bit DLLs, the "C:\WINDOWS\System32" directory
where 32-bit DLLs were encouraged to reside, and, just as pretty as you please, there
it is, a "C:\WINDOWS\SysWOW64" directory, and inside there... no "msvcr71.dll".
Copy the "msvcr71.dll" over from System32 into SysWOW64, and.... Voila.
Service starts, log file looks good, and "localhost:8080" comes back with
the Tomcat home page.
What have we learned from this little experience? A couple of things, some personal,
some observational about the state of the universe and the industry:
Meanwhile, my installations continue....
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. Contact
me for details.