37

I always wondered why I have to manually set the JAVA_HOME environment variable after installing the Java SDK.

JAVA_HOME=c:\Program Files\Java\jdk1.6.0_12

Visual Studio at least provides a batch file to set these kind of environment variables:

call "c:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"

Does Java have something similar? I'm trying to make a build script that should simply work after installing the Java SDK. I don't want people to mess with environment variables on their PC.

unwind
  • 391,730
  • 64
  • 469
  • 606
compie
  • 10,135
  • 15
  • 54
  • 78

6 Answers6

39

You can install as many versions of Java as you like.

It would be dangerous for the setup to modify a local environment variable such as JAVA_HOME, since it might reference an existing Java installation.

This has nothing to do with an alleged "platform dependent issue". ;)

Since scripts might depend on JAVA_HOME to launch themselves, again, this would be disasterous for a new Java install to modify JAVA_HOME: all those scripts would suddenly have to be launched with a new potentially incompatible JVM.

Plus, by setting $JAVA_HOME/bin or %JAVA_HOME%/bin in your path, you can dynamically change JAVA_HOME to whatever version of Java you want to use without having to much with your PATH variable.


Michael Borgwardt has made in the comments the interesting followup's question

Still, this does not explain why the installer does not set JAVA_HOME when it is not previously set at all.

The answer is simple:

The setup cannot know if a script already depends on JAVA_HOME or not.

Meaning: some scripts could test for JAVA_HOME value, and if not set, refer to another JVM installed elsewhere (and do not forget that by "install", one can only refer to "copied": a JDK/JRE is not always installed by a setup)

If you set JAVA_HOME, that can disrupt the default behavior of some of your scripts.

Not wanting to disturb hypothetical scripts that depend on a env var not being set sound pointlessly paranoid to me - If a script does that, then it clearly WANTS to use a different JVM when one is installed - no reason to avoid that.

Mmm... Sweet. For dealing with massive deployment issues on a daily-basis (for internal application in my shop), I can assure you: it is very sane "paranoid" treat to have.
When you deploy to a (very) large set of users, you do not want to make any assumption about their platform and configurations. "clearly WANTS" is an assumption I would not dare to make (or I redirect my phone to yours ;) and you handle the angry calls).

For instance, we have many scripts which launches with a 1.4.2 JVM from sun (JAVA_HOME not set on development platform, default path set directly in the script), or with 1.4.2 from JRockit (JAVA_HOME set, as it is the intended target on integration, pre-production and production platforms).

But we install regularly the new JDK1.6.x since we use it for launching eclipse.

Assume that those scripts want their JAVA_HOME set... and nothing works anymore.

... To which Robert Grant makes this on-the-spot critic:

You're describing scripts that require one specific version, but still look at global JAVA_HOME. That's just badly thought out scripts.

While that may or may not be true, that also illustrates precisely my point:
"you do not want to make any assumption": no assumption on their platform/settings, and no assumption on their "best practices".
The former may sound paranoid, the latter is plain common-sense: thinking that your product (here a JDK setup) will not break anything on the user's environment because the user has "correctly" thought out his scripts... would be insane.


GvS suggests:

Or it could just have option to do it, disabled by default

That would mean another option to include in the setup screens, option which should be carefully reviewed by the user, and which may have unintended consequences, even when the user selects it thinking he knows what he is doing...

It is simply not worth it.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 3
    Still, this does not explain why the installer does not set JAVA_HOME when it is not previously set at all. – Michael Borgwardt Feb 18 '09 at 12:39
  • 1
    Or it could just have option to do it, disabled by default. – TJL Feb 18 '09 at 12:41
  • Not wanting to disturb hypothetical scripts that depend on a env var not being set sound pointlessly paranoid to me - If a script does that, then it clearly WANTS to use a different JVM when one is installed - no reason to avoid that. – Michael Borgwardt Feb 18 '09 at 12:49
  • Yeah...still sounds paranoid :) If the scripts are designed to work with a specific version of Java, then they can specify that version. You're describing scripts that require one specific version, but still look at global JAVA_HOME. That's just badly thought out scripts. – Rob Grant Feb 18 '09 at 13:28
  • @Robert: "That's just badly thought out scripts". Nice. No information whatsoever about the specifics or the history of our settings and yet, you are able to make that on-the-spot evaluation... Impressive. – VonC Feb 18 '09 at 13:44
  • I agree on above answer for JDK, but is there the same principle when installing JRE? JRE should set JAVA_HOME even if it was set to something else. Would you agree on that? – ante.sabo Aug 24 '09 at 13:16
  • @as: Errr... I would not. Anything (JDK, JRE) that disrupt my old JAVA_HOME set (for scripting reason for instance) to an *old* jdk would be *not* welcomed. – VonC Aug 24 '09 at 13:31
  • As I read on your answer, it sounds more and more as if you're trying to find an excuse for not setting the variable. @GvS 's suggestion seems great even considering your (indeed) paranoid scenario of scripts using a default JVM. It is much worse and much common scenario when a user tries to launch a Java application and receives an unexplained error due to unset variable. – Elist Aug 25 '14 at 09:27
  • There could easily be a switch (non-default) which would allow such a setting of java home and/or path. It is very much an omission. – demongolem Sep 03 '14 at 18:27
  • What's the point of installing or updating java if it doesn't set the Java_home variable by itself? – Luxalpa Apr 24 '17 at 09:23
  • "all those scripts would suddenly have to be launched with a new potentially incompatible JVM." This comment makes sense. However, when a JRE updates, isn't it the same problem of breaking scripts? If I'm a programmer, Oracle doesn't know that the JRE will break my scripts that run on the default JRE. To me, it's more about programmers being more technical and configuring their own environments statically with SDK rather than JRE (they can handle manual configs). A tick-box on the Oracle installer to do it for us is merited by the 28+ upvotes on the question IMO. – Fuhrmanator Jul 28 '18 at 13:51
  • 1
    @Fuhrmanator Oracle? Darn... when I wrote this answer, this was still Sun! (https://en.wikipedia.org/wiki/Sun_acquisition_by_Oracle) – VonC Jul 28 '18 at 14:47
11

I don't think JAVA_HOME is a convention invented or supported by Sun.

They probably remember the fiasco that was the CLASSPATH environment variable** all too well and prefer to stay the hell away from environment variables.

** This was encouraged as the primary way to set the JVM classpath in earlier Java SDKs and literature, and resulted in the user and various applications messing with the environment variable, overwriting each other's changes and depending on mutually contradictive contents.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
3

The vcvarsall.bat mechanism is a convenient way for Visual C++ to provide a console with the correct variables without messing with the user's/system's environment variables. However, it assumes that Installshield is the only way to get code onto the system. The JDK should tolerate being cut'n'pasted from one location to another.

If you're looking for java.exe, the Installshield installer should put it in %windir%\system32, so it is available on the PATH.

You can gain some hints about the location of installed apps by querying the registry:

C:>REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit\1.6" /v JavaHome

! REG.EXE VERSION 3.0

HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit\1.6
    JavaHome    REG_SZ  C:\dev\Java\jdk1.6.0_05

However, you can't rely on this absolutely because this makes some assumptions about vendor, version and installation mechanism.

McDowell
  • 107,573
  • 31
  • 204
  • 267
1

This may help someone else out who ends up here like me. I just want to use Java as a tool, not adopt it as a way of life, so I only needed to know how JAVA_HOME was getting set and why it was not correct. The answer turned out to be that the WinAnt installation sets JAVA_HOME (along with ANT_HOME), but only based on the currently installed Java. So if you need to change the version of Java, and you are using Ant, the correct way to do it is to uninstall WinAnt, uninstall Java, install the new Java, and then reinstall WinAnt.

Allan Miller
  • 341
  • 2
  • 4
0

I'm not sure why this is, because the installers clearly solve platform dependant issues (which is ofcourse the whole point of a JVM). Are you sure you aren't mixing the JRE with the JSDK?

Maybe there's a way for your program to search where java is installed (that would be a script I guess), and then set JAVA_HOME and possibly add it to the path.

IBM seems to be doing this trick already: http://www-01.ibm.com/support/docview.wss?rs=180&uid=swg21199220

Other interesting post hinting at the difference between JRE and JSDK installations: http://confluence.atlassian.com/display/CONF26/Set+JAVA_HOME+variable+in+Windows

Hope this helps.

Rolf
  • 7,098
  • 5
  • 38
  • 55
-1

I guess java doesn't want to do anything which is platform-dependent. In Windows, classpaths are set differently from LINUX/UNIX.

tehvan
  • 10,189
  • 5
  • 27
  • 31