Friday, May 16, 2008

Making java.exe Use a JDK on Windows

So let's say you're running an application, such as Sonar, that invokes java.exe directly and doesn't allow you to configure your java path (as far as I can tell, anyway). Now let's say you want to run in -server mode. You try it, but what pops up?
Error: no `server' JVM at `C:\Program Files\Java\jre1.6.0_06_\bin\server\jvm.dll'.
Oops. That's because you're running in a JRE, which doesn't include a server JVM. So you think, "Ok, well, I'll just fix my PATH variable to point at my JDK." Maybe you even try setting JAVA_HOME. But none of it works. Why not?

It doesn't work because Java is launched differently these days. If you look in \WINDOWS\System32, you'll notice that java.exe and javaw.exe are in there. When you launch java.exe, the copy that gets run is the one in System32.

If you look at the Properties of the java.exe file in System32, you'll notice it's tagged with the version of the JRE it came from. When you launch it, then, it looks in the registry for a compatible JRE, and gets resources from that JRE. The relevant registry key is HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment.

You'll notice if you fire up regedit and look at the above key that this key defines the value "JavaHome". Ah, wow, so now Java actually records different JAVA_HOME values for each version of the JRE. Now look at the value of JavaHome. You'll notice it points to your stand-alone JRE, not the JDK's JRE. So the solution is just to change the value to point at <JDK home>/jre.

Simple, eh? Now why isn't this documented anywhere?