How do I find javac.exe programmatically?
-
06-07-2019 - |
Question
I'm calling javac from C# code. Originally I found its location only as follows:
protected static string JavaHome
{
get
{
return Environment.GetEnvironmentVariable("JAVA_HOME");
}
}
However, I just installed the JDK on a new computer and found that it didn't automatically set the JAVA_HOME environment variable. Requiring an environment variable is unacceptable in any Windows application for the last decade, so I need a way to find javac if the JAVA_HOME environment variable is not set:
protected static string JavaHome
{
get
{
string home = Environment.GetEnvironmentVariable("JAVA_HOME");
if (string.IsNullOrEmpty(home) || !Directory.Exists(home))
{
// TODO: find the JDK home directory some other way.
}
return home;
}
}
Solution
If you are on Windows, use registry:
HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit
If you are not, you are pretty much stuck with env variables. You might find this blog entry useful.
Edited by 280Z28:
Underneath that registry key is a CurrentVersion value. That value is used to find the Java home at the following location:
HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit\{CurrentVersion}\JavaHome
private static string javaHome;
protected static string JavaHome
{
get
{
string home = javaHome;
if (home == null)
{
home = Environment.GetEnvironmentVariable("JAVA_HOME");
if (string.IsNullOrEmpty(home) || !Directory.Exists(home))
{
home = CheckForJavaHome(Registry.CurrentUser);
if (home == null)
home = CheckForJavaHome(Registry.LocalMachine);
}
if (home != null && !Directory.Exists(home))
home = null;
javaHome = home;
}
return home;
}
}
protected static string CheckForJavaHome(RegistryKey key)
{
using (RegistryKey subkey = key.OpenSubKey(@"SOFTWARE\JavaSoft\Java Development Kit"))
{
if (subkey == null)
return null;
object value = subkey.GetValue("CurrentVersion", null, RegistryValueOptions.None);
if (value != null)
{
using (RegistryKey currentHomeKey = subkey.OpenSubKey(value.ToString()))
{
if (currentHomeKey == null)
return null;
value = currentHomeKey.GetValue("JavaHome", null, RegistryValueOptions.None);
if (value != null)
return value.ToString();
}
}
}
return null;
}
OTHER TIPS
You should probably search the registry for a JDK installation address.
As an alternative, see this discussion.
For 64-bit OS (Windows 7), the registry key may be under
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\JavaSoft\Java Development Kit
if you're running a 32-bit JDK. So if you've all written code based on the above, go test again.
I haven't yet got my head completely around the Microsoft registry redirection/reflection stuff yet.