Many third party products require a specific version of the JRE or JDK and many of our servers have multiple duties. Application teams argue they should not care where Java is installed. Most of the applications simply rely on environment variables (or whatever Java happens to be lying around) but those teams needing specific versions need to be told where to find their particular version. I don't like the fact that I can now not relocate a JVM without visiting all of the applications that may use it. The obvious answer is to create a program that hides the details from them and expose the location through an API. This solution would require every Java application be wrapped up in some script inquiring about the environment.
I don't like unnecessary complexity or reinventing the wheel. Is there some standard practice, feature built into Java, or obvious solution I am missing?
One I have thought of is for each application to manage a link in its path to point to the Java it wants but I would still need to tell them where it is.
Virtualisation is how we handle it where i work.
update - Sorry if i wasn't clear - we host each application on its own virtual server with only the JVM version it requires
Ideally you need to set two environment variables:
You can either create different scripts to start the various programs and set these variables differently in each case. Or you can configure each application to start under a different user account and set these variables in the users appropriate startup script.
$JAVA_HOME/bin needs to come first on the PATH to avoid any other java binaries on the default path being run instead.
The symbolic link approach is good, but consider that you might not want to upgrade the jvm for all applications at once.
If you are dealing with mission-critical applications, then you might want to have one JVM per application, or have each application point directly to a particular version of the JVM.
For example, where I work there is an application (call it A) that specifically works and was tested against a specific JDK and version (JDK 1.5.0_03), later versions are known to break it.
If application A and another application B both pointed to a symlink called java-5, and then when rolling out application B I decided to update java-5 to point at JDK 1.5.0_14, then application A would break.
As mentioned in "What’s the best practice for handling system-specific information under version control?", the path of a JVM can be part of a de-variabilization phase.
I.e. your configuration file can be re-written at:
That means, just at the beginning of the application, we put in all out program a query to a database which contains values that may change from session to session.
The final JVM path is one of them.
The query is based on the server (or pool of servers) name, and on the program name.
In *nix based systems you can use soft links. Then just write your startup script to use the least specific version it prefers. JRE_HOME = /usr/lib/jre/java-5
This is the method used by many Linux based systems. see /etc/alternitives and /usr/lib/jre for examples.
In Windows you could use environment variables to do something similar. Then your startup script could 'set JRE_HOME=%JAVA_5%'.
Application teams can't have it both ways.
If the application only supports one version of the JRE, then it should ship with it. It should be installed alongside the application.
I don't see why they would want it any other way. Doing it this way ensures that the exact JRE version they tested their application with is the same one you're deploying in production. To think you should "not care" about the JVM is a nice ideal when you're in school and Java is "write once, run anyhere". But frankly that view does not align with the real world, where Java is in fact "write once, test everywhere".
It would be a support nightmare for the application team to have to care about JVM-specific issues. Eliminate that uncertainty, suck it up and use a JVM per application. Disk space is cheap.
We just use symbolic links to the versions we want to use. We have a number of machines which have java installed in different locations and the application shouldn't need to know where they are on different boxes.
Another option is to use java webstart for you applications. In this case it will even download and install the right version if you don't have it.
I put everything in /opt/java-version using the extracted download from Sun (keeping the default directory name). Applications generally run as their own user and are started and stopped via an init script that sets all the variables for that application including $JAVA_HOME.
If I have an application I want to always use the "current" installation in /opt I create symlinks in /opt and make the init script point to that symlink. The symlink then gets adjusted when a new Java runtime is installed.