Блог о Gentoo и около-линуксовым штукам

7 января 2019 г.

Пара слов о Gentoo, openJDK, JavaFX и idea

03:30 Опубликовал Дмитрий Исаенко , 9 коммент.
Сегодня разберёмся как с Gentoo поставить OpenJDK 11 или любой последней версии, настроить idea на работу с ней. Поставим и настроим JavaFX (openJFX SDK). Прикрутим её к IDEA и обозначим подводные камни при сборке всё-в-одном-jar для десктопного приложения используя Maven.

Итак, в списке доступных без плясок Gentoo Java VM есть icedtea (версии 8, т. е. условно тот самый openJDK 8) и страшно бесящий при обновлении oracle-jdk (его блобы нужно каждый раз качать с офф-сайта oracle и ложить в distfiles). OpenJDK как бы и доступен, но обёртки в виде 'eselect' прописывающие все полезные переменные окружения а-ля $JAVA_HOME спрятаны в USE-флаг 'gentoo-vm', который замаскирован. Если интересны подробности таких стрессов, можно почитать что пишут по этому поводу (даже) в самом ebuild:
$ vim -R /usr/portage/dev-java/openjdk/openjdk-11.0.1_p13.ebuild 
C openJFX вообще всё странно. Пакета нет, хотя в багзилле тикету пошел четвёртый год https://bugs.gentoo.org/547918. Intellij Idea традиционно обновляется один-два раза в год.. впрочем это уже другая печальная история со счастливым workaround.

Начинаем!

Для начала включим пакету gentoo-vm USE:
# echo 'dev-java/openjdk-bin gentoo-vm' >> /etc/portage/package.use/all
Теперь ставим собственно JDK (binary):
# emerge  openjdk-bin
Выбираем его для пользователя (нужно зайти в терминал пользователем):
$ eselect java-vm list 
Available Java Virtual Machines:
 [1]   icedtea-bin-8   system-vm
 [2]   openjdk-bin-11

$ eselect java-vm set user 2
Проверяем:
$ eselect java-vm list
Available Java Virtual Machines: 
  [1]   icedtea-bin-8  system-vm
  [2]   openjdk-bin-11  user-vm
Посмотрим переменные для пользователя:
$ file $JAVA_HOME 
/home/username/.gentoo/java-config-2/current-user-vm: symbolic link to /usr/lib/jvm//openjdk-bin-11 

IntelliJ IDEA

Сначала качаем JavaFX SDK: http://gluonhq.com/download/javafx-11-0-1-sdk-linux/
И разархивируем, например, в домашнюю папку.

Заходим в idea. Открываем RunEdit Configuration...
Переходим в TemplatesApplication
И прописываем для 'VM Options:'
--module-path /home/<USERNAME>/javafx-sdk-11.0.1/lib --add-modules=javafx.controls,javafx.fxml


Такое же можно (нужно) прописать для уже существующих записей в 'Application'.

Maven

Для десктоп-приложений можно засунуть всё что касается JavaFX прямо в приложение. Для этого прописываем в POM зависимости:
<dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>11</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-media</artifactId>
            <version>11</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>11</version>
            <scope>compile</scope>
</dependency>
На счёт необходимости засовывания "javafx-media" я не уверен.
И на этом всё!

p.s.
А теперь немного не по теме. При переходе с 8ки на 11ку (в которой уже давно есть понятие модулей), мой готовый JAR со всеми зависимостями отказался запускаться выдавая:
Error: JavaFX runtime components are missing, and are required to run this application
Тут конечно можно сделать всё нормально, через испоьзование более в новых языковых конструктов (ключевые слова: modules, module-info.java) а можно добавить надстройку над основным классом (который с main() и который наследуется от Application).
package simplepackage;

public class Main {
    public static void main(String[] args){ MainFX.main(args); }
}
Где MainFX — класс, наследуемый от Application.

Ну и прописать его в манифесте основным. Для POM выглядит это так:
<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-assembly-plugin</artifactId>
 <version>3.1.0</version>
 <configuration>
  <archive>
<manifest>
 <mainClass>simplepackage.Main</mainClass>
</manifest>
  </archive>
  <descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
  </descriptorRefs>
 </configuration>
 <executions>
  <execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
 <goal>single</goal>
</goals>
  </execution>
 </executions>
</plugin>
И никаких проблем.

UPD: Как теперь быть с падающим Android-studio?

После перехода на JDK11 у меня начал падать android-studio поставленый из портажей. Код ошибки приводить не буду, но чтобы исправить можно сделать так:

Сначала смотрим что у нас в /usr/lib/jvm/
ls /usr/lib/jvm/
Далее пишем алиас для android-studio:
$ vim ~/.bashrc
alias android-studio="JAVA_HOME=/usr/lib/jvm/icedtea-bin-8 JDK_HOME=/usr/lib/jvm/icedtea-bin-8 JAVAC=/usr/lib/jvm/icedtea-bin-8/bin/javac android-studio"
После этого студия начинает работать как надо. В новом терминале разумеется.

Ссылки:
https://wiki.openjdk.java.net/display/OpenJFX/Using+an+IDE#UsinganIDE-UsingIntelliJIDEA
https://stackoverflow.com/questions/52467561/intellij-cant-recognize-javafx-11-with-openjdk-11/52470141#52470141

9 комментариев:

  1. Большое человеческое спасибо за статью.

    ОтветитьУдалить
    Ответы
    1. Нет проблем =) Чуть исправил.. Не делайте openjdk системным VM а то будут ошибки и какие-то бока на ровном месте. Лучше его сделать 'user-vm' и всё.

      Удалить
  2. Этот комментарий был удален автором.

    ОтветитьУдалить
  3. А у вас работает сглаживание шрифтов в android-studio с icedtea?

    ОтветитьУдалить
    Ответы
    1. Работает. По крайней мере никакой разницы между android-studio и idea я так на глаз не вижу.

      Удалить
    2. У меня почему-то с openjdk отличное сглаживание, как во всех других приложениях, а c icedtea намного хуже.

      Удалить
  4. Буквально после танцев с бубном, заработало сглаживание на icedtea. Как говориться, если что-то долго ломать, оно сломается.

    ОтветитьУдалить
  5. непонятно, конечно, откуда в eselect появляется выбор новопоставленной джавы. проблема же именно в том, что её там нет.

    ОтветитьУдалить
    Ответы
    1. И то верно. В таком случае поможет включение gentoo-vm use для этого пакета.
      # echo 'dev-java/openjdk-bin gentoo-vm' >> /etc/portage/package.use/all

      Удалить