update-java-alternatives does not change the JAVA_HOME

Bug #45348 reported by R. A. Rivas Diaz
44
This bug affects 4 people
Affects Status Importance Assigned to Milestone
eclipse (Ubuntu)
Invalid
Undecided
Unassigned
java-common (Ubuntu)
Won't Fix
Wishlist
Unassigned

Bug Description

java-common define a mechanism to define the variable JAVA_HOME for scripts/packages that require this variable. (could be eclipse, ant...).

The script update-java-alternatives, that can be used to update the alternatives system for changing the implementation of the java commands, does not update the mechanism used for selecting the JAVA_HOME (used with /usr/share/java-common/jvm-find.sh and /etc/jvm). So even if I say thru update-java-alternatives that I want to use a specific version of java, the scripts that find Java using jvm-find.sh could use other Java VM commands, not the ones that I configured.

Revision history for this message
R. A. Rivas Diaz (rivasdiaz) wrote : One possible solution
Download full text (3.2 KiB)

After thining about this problem, I have arrived to a very simple solution using update-alternatives:

java-common should create the directories:

/etc/java/home/default/jdk --> Default JDK HOME
/etc/java/home/default/jre --> Default JRE HOME

And two for every supported version of java:
/etc/java/home/<java version>/jdk --> JDK <java version> HOME
/etc/java/home/<java version>/jre --> JRE <java version> HOME

For example:
/etc/java/home/1.5/jdk --> JDK 1.5 HOME
/etc/java/home/1.5/jre --> JRE 1.5 HOME
/etc/java/home/1.4/jdk --> JDK 1.4 HOME
/etc/java/home/1.4/jre --> JRE 1.4 HOME

Every Java Runtime/JDK installed, should update thru update-alteratives, the link to this directories, for example, sun-java5 (which is sadly configured with priority 53) should run after install:

update-alternatives --install /etc/java/home/default/jdk java_home_default_jdk /usr/lib/jvm/java-1.5.0-sun-1.5.0.06 53
update-alternatives --install /etc/java/home/default/jre java_home_default_jre /usr/lib/jvm/java-1.5.0-sun-1.5.0.06/jre 53
update-alternatives --install /etc/java/home/1.5/jdk java_home_1_5_jdk /usr/lib/jvm/java-1.5.0-sun-1.5.0.06 53
update-alternatives --install /etc/java/home/1.5/jre java_home_1_5_jre /usr/lib/jvm/java-1.5.0-sun-1.5.0.06/jre 53
update-alternatives --install /etc/java/home/default/jdk java_home_default_jdk /usr/lib/jvm/java-1.5.0-sun-1.5.0.06 53
update-alternatives --install /etc/java/home/default/jre java_home_default_jre /usr/lib/jvm/java-1.5.0-sun-1.5.0.06/jre 53
update-alternatives --install /etc/java/home/1.4/jdk java_home_1_4_jdk /usr/lib/jvm/java-1.5.0-sun-1.5.0.06 53
update-alternatives --install /etc/java/home/1.4/jre java_home_1_4_jre /usr/lib/jvm/java-1.5.0-sun-1.5.0.06/jre 53

And the list goes down until java 1.0 or which ever the sun-java5 maintainers consider appropiate.

The same should happen for GCJ equivalent, gcj-compat and gcj-compat-dev

gcj-compat is only a JRE, and claims support for 1.4.2. Currently the priority is set to 1041, so they should run after install:

update-alternatives --install /etc/java/home/default/jre java_home_default_jre /usr/lib/jvm/java-1.4.2-gcj-4.1-1.4.2.0/jre 1041
update-alternatives --install /etc/java/home/1.4/jre java_home_1_4_jre /usr/lib/jvm/java-1.4.2-gcj-4.1-1.4.2.0/jre 1041

And gcj-compat-dev, being the JDK complement, should run after install:

update-alternatives --install /etc/java/home/default/jdk java_home_default_jdk /usr/lib/jvm/java-1.4.2-gcj-4.1-1.4.2.0 1041
update-alternatives --install /etc/java/home/1.4/jdk java_home_1_4_jdk /usr/lib/jvm/java-1.4.2-gcj-4.1-1.4.2.0 1041

After those steps, the java home will be completelly configurable using update-alternatives. Every package who require a JAVA_HOME JDK, should only point to:

/etc/java/home/default/jdk

And if the package requires a java 5 compliant version, the link should be:

/etc/java/home/1.5/jdk

The only missing part is for the scripts installed with java-common, that should be updated tu support this structure. update-java-alternatives should add support for this new entries, and jvm-find.sh should return

JAVA_HOME=/etc/java/home/default/jdk

for compatibil...

Read more...

Revision history for this message
Joachim Beckers (jbeckers) wrote :

seems like a big change, probably to be made in dapper+1. or am I wrong here?

Revision history for this message
AdrianGygax (adrian-gygax) wrote :

Has there been any development regarding this issue? Edgy still doesn't set the JAVA_HOME variable automatically. Although it's easy to set by hand, it clearly lowers the out-of-the-box usefulness for Java developers. The SuSE distribution also uses the update-alternatives mechanism and there JAVA_HOME is set accordingly. I could have a look at how they do it if that would help.

Revision history for this message
Jerome Haltom (wasabi) wrote :

I don't believe I am particularly interested in setting JAVA_HOME by default. After all, given a choice of N different JVMs a user may have installed, which one should be chosen?

Additionally, Debian policy (unsure about Ubuntu's) does not allow a program to require a certain environmental variable to be set to run properly. Knowing that then, which program is it you are running that does not function without JAVA_HOME?

update-alternatives is also not very useful in the current Java situation (this will change with OpenJDK). At this point there are some applications which require certain JVMs to be able to function. Basically, a per-app compatibility list. The /etc/jvm.d mechanism seeks to address this.

Hopefully, when we have one completely functional standard JDK, this won't be an issue though.

Revision history for this message
Jerome Haltom (wasabi) wrote :

R. A. Rivas Diaz:

Your idea doesn't address the current need of applications to be particular about which JVMs they support for a default experience. Not all applications can point to a single system-wide default JVM.

Added to this, I suspect per-user configuration of which JVM is used would still be desired, up until the point where we have only one JVM. If that point is even attainable.

Revision history for this message
R. A. Rivas Diaz (rivasdiaz) wrote :

What I was trying to solve is that some (almost all) not apt-gettable Java applications require a definition of JAVA_HOME.

 - Some not available as DEBs (like Maven (maven.apache.org)).
 - Some available but a new version is required (Ant, Eclipse).

Obviously I can edit the launch scripts to add
export JAVA_HOME=$(bash /usr/share/java-common/jvm-find.sh).

But my idea is to simplify this step. java-gcj-compat is in fact an attempt to create a compatible Java environment. DEB based applications are adapted if needed so no special Java compatible environment is really required, but having java-gcj-compat simplifies the modifications needed in packages that expect the same folder structure as Sun JDK structure. So almost no modification is required. The same happens to JAVA_HOME environment variable and Java compatible folder structure. If java-common package added a symliked folder, this simplification process could be simpler for a lot of java packages. Using update-java-alternatives as the only way of updating java configuration is, IMHO, the way to go.

The day we have OpenJDK in apt repos in think this will be obsolete, but who knows what will happen then... Maybe GCJ will live for another 20 years....

Revision history for this message
Jerome Haltom (wasabi) wrote : Re: [Bug 45348] Re: update-java-alternatives does not change the JAVA_HOME

> could be simpler for a lot of java packages. Using update-java-
> alternatives as the only way of updating java configuration is, IMHO,
> the way to go.

I don't believe update-java-alternatives solves the per-user case, which
at least in my situations, has been very desired. Also, you need root
access to run it. The java-common jvm search mechanism goes through
~/.jvm as well.

>
> The day we have OpenJDK in apt repos in think this will be obsolete, but
> who knows what will happen then... Maybe GCJ will live for another 20
> years....
>

Revision history for this message
R. A. Rivas Diaz (rivasdiaz) wrote :

And why not mount the jvm scheme over the update-alternatives scheme?

In my case, I installed maven. Maven searches for /etc/mavenrc and ~/.mavenrc

If I create one of those files, Maven works OK. But as I see it, local configurations are needed if I don't want to use my default configuration, so if I want to use Java SE 6 globally, but J2SE 5 for maven, editing /etc/mavenrc is the way to go. But if I want to use Maven with my default Java installation, I should be able to configure Java in one place, and my specific application (maven in this case) should use my global Java configuration.

Currently we have update-java-alternatives as a way to configure the java related commands in only one script, but if I need to configure a java compatible environment I have to edit /etc/jvm or ~/.jvm

Maybe if update-java-alternatives could generate (provably based on priority and/or manual mode selection) a base for jvm/java-common to check if no override is created (~/.jvm and /etc/jvm) both worlds could benefit from each other. This could be update-java-alternatives generating a /etc/jvm.default (not much feasible) or java-common returning a default folder maintained by update-java-alternatives if ~/.jvm nor /etc/jvm is found.

If I want to customize my default jvm I create a ~/.jvm, but if I happy with the default instalation, everything should work out of the box.

Revision history for this message
Jerome Haltom (wasabi) wrote :

Uh huh. Sounds about like how it works now, no? update-java-alternatives configures a JVM tree at /usr. Or, enough of a JVM tree to work. Listing /usr in either ~/.jvm or /etc/jvm should work fine.

Revision history for this message
Tiago Sousa (tiagoboldt) wrote :

This is kind of a big issue..

Eclipse is practically unusable without a proper jvm.. It goes from 170MB right after starting it, to 17MB using java-6!

Is a workable workaround was found, it would be great!

Changed in eclipse:
status: New → Confirmed
Changed in java-common:
status: New → Confirmed
Revision history for this message
Daniel T Chen (crimsun) wrote :

Orthogonal task.

Changed in eclipse:
status: Confirmed → Invalid
Changed in java-common:
importance: Medium → Wishlist
Revision history for this message
Cefn (6-launchpad-net-cefn-com) wrote :

I agree that update-java-alternatives should undertake to use all available mechanisms to establish the user's chosen default version of java gets communicated to loading applications which are simply making standard assumptions about the way this dependency injection gets resolved.

Above someone raises the question 'given a choice of N different JVMs a user may have installed, which one should be chosen?' and I feel the clear answer is 'the default version'. Indeed that's what the definition of a default version is! It's the one you choose when you don't know any better. A default version is ALREADY being chosen for a loading application, it's just out of the user's control, which is unfortunate.

I'm not a technical idiot, but even after reading this series of posts, it's unclear to me how I get eclipse to pick up the sun JVM using the .jvm or /etc/jvm files. It's been mentioned that you should 'edit' these files. I can go and find out, no doubt, but I already went looking for that, and found update-java-alternatives was the recommended mechanism. The only problem - it doesn't influence the default version of java as loaded through established java-compliant mechanisms, which would surprise most people.

A sun version of java is what Eclipse (and many other systems, such as OxygenXML) requires to work. I've set it as my default, and reloaded eclipse. Still no dice.

I feel a mechanism designed to set a globally default version of java can't be prissy about the way java actually works, and assert that debian policies are better, leaving users of mainstream java-based programs in the lurch, caught between two sets of developers who each feel they have a fantastic mechanism, if only the other side would accept their superior reasoning.

One of the great advantages of java is its cross-platform availability. That's one of the reasons I can freely migrate to linux from the windows and mac alternatives without losing an important set of well-maintained development tools.

The java community, as adopters of cross-platform tools, are heavily on the side of open source, and a change to update-java-alternatives which ensures that unmodified scripts load the user's chosen default will help migrators migrate without needless headaches, allowing their colleagues to snipe from the wings 'you can't even load Eclipse on that OS - go back to windows'.

Another unfortunate consequence of the current policy could be that rather than merely checking for Java VM validity (through versioning information), the Eclipse and OxygenXML load scripts get hard coded with mechanisms to seek out a Sun JVM, making it difficult to migrate back to a free JVM as your global setting when it indeed does get stable enough and standard enough to load these applications.

Revision history for this message
Cefn (6-launchpad-net-cefn-com) wrote :

For reference, people wanting to get eclipse to work with the JVM it requires for compatibility, you should edit /etc/eclipse/java_home and add a comment (#) mark at the start of each line up to the one which identifies your chosen jvm.

Don't know who this file is maintained by, but if eclipse is the issue which drives this bug, then perhaps the bug should focus on a change to this file, so that the sun jvm is at the top of the list.

Revision history for this message
Cefn (6-launchpad-net-cefn-com) wrote :

Getting to the bottom of the eclipse case, I'm starting to agree with earlier posters.

If you specifically drop the JAVA_HOME which the eclipse script has carefully introspected, and just use the java binary which is available to you on the default path, leaving the final lines of /usr/bin/eclipse as...

unset JAVA_HOME
JAVACMD=java

# Do the actual launch of Eclipse with the selected VM.
exec /usr/lib/eclipse/eclipse \
    -vm "${JAVACMD}" \
    -install "${INSTALL}" \
    -startup "${STARTUP}" \
    ${CMDLINEARGS} \
    -vmargs -Djava.library.path=/usr/lib/jni \
            -Dgnu.gcj.precompiled.db.path=/var/lib/gcj-4.2/classmap.db \
            -Dgnu.gcj.runtime.VMClassLoader.library_control=never \
            -Dosgi.locking=none ${VMARGS}

...the eclipse application seems to load perfectly fine. In other words, if it simply runs 'java' then it picks up the default version as determined by update-java-alternatives, and yet it's chosen a byzantine way to load java, through JAVA_HOME, then generating a java binary location based on JAVA_HOME.

Using the environment variable approach requires that presumably every script has to load up with the JAVA_HOME environment variable set, even though it's entirely irrelevant for most scripts.

If this happens for every application and every dependency, not just JAVA, but also Corba, IP Networking Gateways and everything else, because specific environment variables are allowed as an assumption on the part of loading applications, the tables get very large very quickly and everything slows down.

Perhaps a concrete recommendation might be that JAVA_HOME in the eclipse script should get derived from the path of the 'java' binary, rather than the other way around, then it would be possible for ubuntu to meet its expectations without throwing environment variables around.

Revision history for this message
Niels Thykier (niels-thykier) wrote :

Hi

I am closing this as invalid[1]. In general, programs should work without requiring a particular environment variable is set. Secondly it is impossible for update-java-alternatives to update the variable of any running terminal or X11 session. Also, as I recall, messing with /etc/environment is generally not acceptable (but I could be wrong here).

~Niels

[1] I would have used "Wont fix", but is not available to me.

Changed in java-common (Ubuntu):
status: Confirmed → Invalid
Benjamin Drung (bdrung)
Changed in java-common (Ubuntu):
status: Invalid → Won't Fix
Revision history for this message
Maxim Veksler (maxim-vekslers) wrote :

Guys,

Some solution should be found, and it's not necessarily update-alternatives.

The JAVA_HOME setting is something _every_ java user on Ubuntu has to do, and as such I think a solution should be made.

Please don't assume this is a "corporate" only requirement, large and highly successful open source projects do this assumption as well.

For reference (and the reason that brought me here), the Hadoop installation guide mentions:

"""
Unpack the downloaded Hadoop distribution. In the distribution, edit the file conf/hadoop-env.sh to define at least JAVA_HOME to be the root of your Java installation.
""" source: http://hadoop.apache.org/common/docs/current/quickstart.html

I think this issue should be reopened as an enhancement with high priority (server & desktop alike) rather then closed as "wont fix".

Revision history for this message
Niels Thykier (niels-thykier) wrote : Re: [Bug 45348] Re: update-java-alternatives does not change the JAVA_HOME
Download full text (3.9 KiB)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

On 2010-07-30 18:57, Maxim Veksler wrote:
> Guys,
>
> Some solution should be found, and it's not necessarily update-
> alternatives.
>
> The JAVA_HOME setting is something _every_ java user on Ubuntu has to
> do, and as such I think a solution should be made.
>

I disagree with you here; I believe there are many Java users on Debian
and Ubuntu that do not need to set JAVA_HOME - unsurprisingly I am one
such user. Every Java program available via Debian or Ubuntu must work
without JAVA_HOME being set; they may allow themselves to be influenced
by it, but never require it.
  Nevertheless, it may still be useful to some Java users...

> Please don't assume this is a "corporate" only requirement, large and
> highly successful open source projects do this assumption as well.
>

Never intended to do so.

> For reference (and the reason that brought me here), the Hadoop
> installation guide mentions:
>
> """
> Unpack the downloaded Hadoop distribution. In the distribution, edit the file conf/hadoop-env.sh to define at least JAVA_HOME to be the root of your Java installation.
> """ source: http://hadoop.apache.org/common/docs/current/quickstart.html
>

On a related note: Hadoop is packaged in Debian/Squeeze and
Ubuntu/Maverick; the packaged solution will work without setting
JAVA_HOME (if you experience otherwise, please do file a bug against the
hadoop package).

>
> I think this issue should be reopened as an enhancement with high priority (server & desktop alike) rather then closed as "wont fix".
>

Let me just briefly outline the situation (as I understand it):

You (and others) are interested in JAVA_HOME being set by default for
all users on the system. update-(java-)alternatives should update it, so
that running update-(java-)alternatives also updates JAVA_HOME.

Starting from the end; modifying JAVA_HOME is just not possible for
running sessions. That being said, we can work around it by setting
JAVA_HOME to a symlink that uses alternatives and then update the
alternatives symlink. That would work.

However, there is still the problem where some Debian/Ubuntu packaged
Java programs are affected by JAVA_HOME. Since JAVA_HOME would now
always be set, they will no longer use /usr/bin/java{,c} - this can
cause a regression for our users and I cannot think of a decent way to
handle it.

Furthermore, we need a method to actually get JAVA_HOME set to this
symlink. I am not sure how to get that done... and it does not help that
unless this can be done by java-common (or one of its binary packages)
that JAVA_HOME will have to be set to a non-existent folder.

Finally, we would have to convince the Debian Java Team that this should
fix this.

What we need is a solution to the two problems (getting JAVA_HOME set
and how to handle the Debian/Ubuntu programs that may use JAVA_HOME
instead of java{,c}) - and I cannot provide a solution to this.
  By the way, the order is by no means specific and in fact if you want
this solved, it might be a good idea to start with convincing the Debian
Java Team about this, there are a lot of people with experience there,
which may become useful in solving this...

Read more...

Revision history for this message
lrkwz (luca-orlandi) wrote :

I think tha JAVA_HOME should be automatically updated, or at least there should be a way to triggere a custom script to update it.
GVM has a nice

 # Attempt to set JAVA_HOME if it's not already set.
 if [ -z "${JAVA_HOME}" ] ; then
    if ${darwin} ; then
        [ -z "${JAVA_HOME}" -a -f "/usr/libexec/java_home" ] && export JAVA_HOME=$(/usr/libexec/java_home)
        [ -z "${JAVA_HOME}" -a -d "/Library/Java/Home" ] && export JAVA_HOME="/Library/Java/Home"
        [ -z "${JAVA_HOME}" -a -d "/System/Library/Frameworks/JavaVM.framework/Home" ] && export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Home"
    else
        javaExecutable="$(which javac 2> /dev/null)"
        [[ -z "${javaExecutable}" ]] && echo "GVM: JAVA_HOME not set and cannot find javac to deduce location, please set JAVA_HOME." && return

        readLink="$(which readlink 2> /dev/null)"
        [[ -z "${readLink}" ]] && echo "GVM: JAVA_HOME not set and readlink not available, please set JAVA_HOME." && return

        javaExecutable="$(readlink -f "${javaExecutable}")"
        javaHome="$(dirname "${javaExecutable}")"
        javaHome=$(expr "${javaHome}" : '\(.*\)/bin')
        JAVA_HOME="${javaHome}"
        [[ -z "${JAVA_HOME}" ]] && echo "GVM: could not find java, please set JAVA_HOME" && return
        export JAVA_HOME
    fi
 fi

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.