Какова правильная цель для переменной среды JAVA_HOME для дистрибутива Linux OpenJDK на основе Debian?

В Windows JAVA_HOME должен указывать на папку установки JDK (чтобы JAVA_HOME/bin содержал все исполняемые файлы, а JAVA_HOME/libs содержал все jar библиотеки по умолчанию).

Если я загружу пакет Sun JDK и установлю его в Linux, это будет та же процедура.

Однако мне нужно использовать пакет OpenJDK Kubuntu по умолчанию. Проблема в том, что все исполняемые файлы помещаются в /usr/bin. Но баночки помещаются в /usr/share/java. Поскольку они не находятся в одной и той же папке JAVA_HOME, у меня возникают проблемы с Grails и, возможно, будут проблемы с другими приложениями, которые ожидают стандартную структуру Java.

  1. Если я использую:

    JAVA_HOME=/usr
    

    Все приложения и сценарии, которые хотят использовать любой исполняемый файл Java, могут использовать стандартную процедуру call $JAVA_HOME/bin/executable. Однако, поскольку банки находятся в другом месте, они не всегда находятся (пример: в Grails я получаю ClassDefNotFound вместо native2ascii).

  2. С другой стороны, если я использую:

    JAVA_HOME=/usr/share/java
    

    Ни один из исполняемых файлов Java (java, javac и т. д.) не найден.

Итак, как правильно обращаться с переменной JAVA_HOME в Linux на основе Debian?

Спасибо за помощь, Луис


person Luis Soeiro    schedule 19.03.2009    source источник


Ответы (14)


То, что в конечном итоге сработало для меня (теперь Grails работает гладко), работает почти так, как указал Стив Б.:

JAVA_HOME=/usr/lib/jvm/default-java

Таким образом, если пользователь изменит JDK по умолчанию для системы, JAVA_HOME все равно будет работать.

default-java — символическая ссылка на текущую JVM.

person Luis Soeiro    schedule 19.03.2009
comment
Вроде на Debian 7 такой ссылки нет - person a1an; 09.01.2014
comment
В RHEL5.10 это /usr/lib/jvm/java. - person Engineer2021; 25.04.2014
comment
Я использовал /usr/lib/jvm/java-7-openjdk-amd64 - person Randall Bohn; 06.08.2014
comment
Для Oracle Linux 7 (это должно применяться к CentOS и RHEL) я создал файл с именем /etc/profile.d/java.sh и заполнил его следующим: JAVA_HOME=/usr/lib/ jvm/jre-openjdk экспортирует JAVA_HOME после повторного поиска /etc/profile (путем запуска исходного кода /etc/profile) JAVA_HOME был заполнен, как и ожидалось. - person darnold0714; 04.03.2020

Если вы используете альтернативы для управления несколькими версиями java, вы можете установить JAVA_HOME на основе символической ссылки java (или javac) следующим образом:

export JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:bin/java::")
person bbaassssiiee    schedule 18.07.2012
comment
Это работает для меня: JAVA_HOME=$(readlink -f /usr/bin/java | sed s:/jre/bin/java::) - person dpnsan; 25.07.2013
comment
Блестящее решение, решает мои многолетние головные боли с JAVA_HOME, который имеет тенденцию указывать на разные места в разных операционных системах. - person Datageek; 07.03.2014
comment
обратите внимание, что это умное решение не будет работать на таких дистрибутивах, как Gentoo, в которых /usr/bin/java указывает на скрипт (/usr/libexec/eselect-java/run-java-tool.bash). тем не менее, это хороший подход. единственное, что я бы изменил, это использовать встроенную замену Bash, чтобы избежать появления sed, например: JAVA_HOME=$( j=$( readlink -f /usr/bin/java ) ; echo ${j%%/bin/java} ) - person RubyTuesdayDONO; 29.03.2014
comment
Это хорошо работает :) Может потребоваться изменить javac на java, потому что не у всех установлен JDK; только JRE - person Hanxue; 11.04.2014
comment
@AlexisWilke теперь java вместо javac - person bbaassssiiee; 07.05.2016
comment
моя символическая ссылка /use/bin/java указывает на jre/bin/java, это вызывает ошибку во время компиляции, так как мне нужно, чтобы она указывала на дом Java jdk. - person user2441441; 04.04.2017

Стандартная установка Ubuntu помещает различные версии Java в /usr/lib/jvm. javac, java, который вы найдете на своем пути, будет программно ссылаться на это.

Нет проблем с установкой вашей собственной версии Java в любом месте, если вы установите переменную среды JAVA_HOME и убедитесь, что на вашем пути есть новая версия Java bin.

Простой способ сделать это - создать домашнюю страницу Java в виде программной ссылки, поэтому, если вы хотите обновить или переключить версии, вам нужно будет только изменить каталог, на который он указывает, например:

/usr/bin/java --> /opt/jdk/bin/java,

/opt/jdk --> /opt/jdk1.6.011
person Steve B.    schedule 19.03.2009
comment
опасно рекомендовать решения Ubuntu с Debian. Они могут быть и различаются. - person RichieHH; 05.08.2010
comment
Обратите внимание, что запросчик сказал, что он использовал Kubuntu, поэтому решения Ubuntu должны подойти. - person Joseph Holsten; 26.05.2011

Обычно у меня нет переменной среды JAVA_HOME. Java может настроить его самостоятельно. Внутри java должно быть доступно системное свойство java.home.

person iny    schedule 19.03.2009
comment
У меня его тоже обычно нет. Однако, если я его не настрою, Grails жалуется, что JAVA_HOME отсутствует, и прерывает работу. - person Luis Soeiro; 19.03.2009
comment
муравей тоже нуждается в этом в debian, который является контекстом - person RichieHH; 05.08.2010

Попробуйте также установить переменную JAVA_LIB.

person Cantillon    schedule 19.03.2009

Если у вас есть проблемы с тем, что файлы JAR не найдены, я бы также позаботился о том, чтобы ваш CLASSPATH включал расположение этих файлов. Однако я обнаружил, что CLASSPATH часто нужно устанавливать по-разному для разных программ, и часто это оказывается чем-то уникальным для отдельных программ.

person MVang    schedule 14.03.2011

Обновленный ответ, который решит вашу проблему, а также общие рекомендации по установке Oracle Java 7 в Ubuntu можно найти здесь: http://www.wikihow.com/Install-Oracle-Java-on-Ubuntu-Linux

person Jack    schedule 12.06.2012

Я обнаружил аналогичные проблемы с пакетами openjdk-6-jre и openjdk-6-jre-headless в Ubuntu.

Моя проблема была решена путем очистки пакетов openjdk-6-jre и openjdk-6-jre-headless и переустановки. Альтернативы обновляются только при новой установке пакетов openjdk-6-jre и openjdk-6-jre-headless.

Ниже приведен пример установки после очистки:

aptitude purge openjdk-6-jre openjdk-6-jre-headless # to ensure no configuration exists
aptitude install --without-recommends openjdk-6-jre # Installing without some extras
Reading package lists... Done
Building dependency tree
Reading state information... Done
Reading extended state information
Initializing package states... Done
The following NEW packages will be installed:
  ca-certificates-java{a} java-common{a} libavahi-client3{a} libavahi-common-data{a} libavahi-common3{a} libcups2{a} libflac8{a} libgif4{a} libnspr4-0d{a} libnss3-1d{a} libogg0{a} libpulse0{a} libsndfile1{a} libvorbis0a{a} libvorbisenc2{a} libxi6{a} libxtst6{a}
  openjdk-6-jre openjdk-6-jre-headless{a} openjdk-6-jre-lib{a} tzdata-java{a}
The following packages are RECOMMENDED but will NOT be installed:
  icedtea-6-jre-cacao icedtea-netx ttf-dejavu-extra
0 packages upgraded, 21 newly installed, 0 to remove and 119 not upgraded.
Need to get 0B/34.5MB of archives. After unpacking 97.6MB will be used.
Do you want to continue? [Y/n/?]
Writing extended state information... Done
Selecting previously deselected package openjdk-6-jre-lib.
(Reading database ... 62267 files and directories currently installed.)
Unpacking openjdk-6-jre-lib (from .../openjdk-6-jre-lib_6b24-1.11.5-0ubuntu1~10.04.2_all.deb) ...
...
Processing triggers for man-db ...
Setting up tzdata-java (2012e-0ubuntu0.10.04) ...
...
Setting up openjdk-6-jre-headless (6b24-1.11.5-0ubuntu1~10.04.2) ...
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/java to provide /usr/bin/java (java) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/keytool to provide /usr/bin/keytool (keytool) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/pack200 to provide /usr/bin/pack200 (pack200) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/rmid to provide /usr/bin/rmid (rmid) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/rmiregistry to provide /usr/bin/rmiregistry (rmiregistry) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/unpack200 to provide /usr/bin/unpack200 (unpack200) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/orbd to provide /usr/bin/orbd (orbd) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/servertool to provide /usr/bin/servertool (servertool) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/tnameserv to provide /usr/bin/tnameserv (tnameserv) in auto mode.
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/lib/jexec to provide /usr/bin/jexec (jexec) in auto mode.
Setting up openjdk-6-jre (6b24-1.11.5-0ubuntu1~10.04.2) ...
update-alternatives: using /usr/lib/jvm/java-6-openjdk/jre/bin/policytool to provide /usr/bin/policytool (policytool) in auto mode.
...

Вы можете видеть выше, что update-alternatives запускается для установки ссылок на различные двоичные файлы Java.

После этой установки также есть ссылки в /usr/bin, ссылки в /etc/alternatives и файлы для каждого двоичного файла в /var/lib/dpkg/alternatives.

ls -l /usr/bin/java /etc/alternatives/java /var/lib/dpkg/alternatives/java
lrwxrwxrwx 1 root root  40 2013-01-16 14:44 /etc/alternatives/java -> /usr/lib/jvm/java-6-openjdk/jre/bin/java
lrwxrwxrwx 1 root root  22 2013-01-16 14:44 /usr/bin/java -> /etc/alternatives/java
-rw-r--r-- 1 root root 158 2013-01-16 14:44 /var/lib/dpkg/alternatives/java

Давайте сравним это с установкой без очистки.

aptitude remove openjdk-6-jre
aptitude install --without-recommends openjdk-6-jre
Reading package lists... Done
Building dependency tree
Reading state information... Done
Reading extended state information
Initializing package states... Done
The following NEW packages will be installed:
  ca-certificates-java{a} java-common{a} libavahi-client3{a} libavahi-common-data{a} libavahi-common3{a} libcups2{a} libflac8{a} libgif4{a} libnspr4-0d{a} libnss3-1d{a} libogg0{a} libpulse0{a} libsndfile1{a} libvorbis0a{a} libvorbisenc2{a} libxi6{a} libxtst6{a}
  openjdk-6-jre openjdk-6-jre-headless{a} openjdk-6-jre-lib{a} tzdata-java{a}
The following packages are RECOMMENDED but will NOT be installed:
  icedtea-6-jre-cacao icedtea-netx ttf-dejavu-extra
0 packages upgraded, 21 newly installed, 0 to remove and 119 not upgraded.
Need to get 0B/34.5MB of archives. After unpacking 97.6MB will be used.
Do you want to continue? [Y/n/?]
Writing extended state information... Done
Selecting previously deselected package openjdk-6-jre-lib.
(Reading database ... 62293 files and directories currently installed.)
Unpacking openjdk-6-jre-lib (from .../openjdk-6-jre-lib_6b24-1.11.5-0ubuntu1~10.04.2_all.deb) ...
...
Processing triggers for man-db ...
...
Setting up openjdk-6-jre-headless (6b24-1.11.5-0ubuntu1~10.04.2) ...

Setting up openjdk-6-jre (6b24-1.11.5-0ubuntu1~10.04.2) ...
...

Как видите, update-alternatives не срабатывает.

После этой установки нет файлов для двоичных файлов Java в /var/lib/dpkg/alternatives, нет ссылок в /etc/alternatives и нет ссылок в /usr/bin.

Удаление файлов в /var/lib/dpkg/alternatives также ломает update-java-alternatives.

person Saturn Junction    schedule 16.01.2013

Ubuntu 12.04 работает...

JAVA_HOME=/usr/lib/jvm/java-6-openjdk-i386/jre

person Alex    schedule 06.03.2013

В качестве обновления для пользователя Fedora альтернативы устанавливают текущий каталог java в /usr/java/default.

поэтому вам нужно установить для JAVA_HOME значение /usr/java/default, чтобы всегда иметь альтернативный текущий выбор в вашем пути к классам.

ХТХ!

person Greg Henry    schedule 06.09.2015

Я всегда стремлюсь установить JAVA_HOME в соответствии с /usr/bin/java.

JAVA_HOME="$(dirname -- "$(dirname -- "$(readlink -f /usr/bin/java)")")"

Таким образом, обе альтернативы указывают на одно и то же место.

person Ivo    schedule 21.11.2019

Насколько я помню, я использовал скрипт update-java-alternatives вместо update-alternatives. И он правильно установил JAVA_HOME для меня.

person Tobias Schulte    schedule 20.03.2009
comment
В Ubuntu 20.4 этого нет. - person Martin Schröder; 09.11.2020

Пожалуйста, посмотрите, что делает команда update-alternatives (у нее хороший человек...).

Вкратце - что происходит, когда у вас есть java-sun-1.4 и java-opensouce-1.0... какой из них берет "java"? В Debian "/usr/bin/java" является символической ссылкой, а "/usr/bin/java-sun-1.4" является альтернативой "/usr/bin/java"

Изменить: как сказал Ричард, update-alternatives недостаточно. Вам действительно нужно использовать update-java-alternatives. Больше информации по адресу:

https://help.ubuntu.com/community/Java

person elcuco    schedule 19.03.2009
comment
обновлений-альтернатив недостаточно. Это должно быть обновление-java-альтернативы - person RichieHH; 05.08.2010
comment
@Richard: да, заметил. Впервые я об этом заговорил, поэтому погуглил и нашел документацию по Ubuntu. Спасибо! - person elcuco; 11.08.2010

Моя правильная цель всегда заключалась в том, чтобы загрузить его с Sun и просто установить таким образом. Тогда вы точно знаете, в каком каталоге все находится.

Но если вы предпочитаете придерживаться странного способа установки Debian, я бы предположил, что родительский каталог находится чуть выше, где расположены двоичные файлы java и javac.

(поскольку, когда вы указываете его в своем пути, это $JAVA_HOME/bin) (Так что в вашем случае это будет ... $JAVA_HOME/share, а $JAVA_HOME будет /usr?)

Эх, звучит не так...

Мне тоже интересно услышать ответ на этот вопрос!

person leeand00    schedule 19.03.2009
comment
При использовании Debian вам действительно нужно придерживаться структур Debian, иначе последующие обновления системы оставят вашу систему сломанной. - person RichieHH; 05.08.2010