JavaFx в режиме без головы

Можно ли запустить JavaFx в режиме без головы (в Java 7)? Он используется для генерации изображений на сервере, но запрашивает X-сервер. Существует ли что-то вроде java.awt.headless в JavaFx?(Я не могу использовать Xvfb)

5 ответов

Вот как я решил эту проблему для создания образа на стороне сервера в среде Ubuntu Linux с сервером приложений Jetty. Он использует xvfb, но только как "библиотека" - без каких-либо дополнительных специальных действий на сервере:

apt-get install xvfb

// then on application server start:

export DISPLAY=":99"

start-stop-daemon --start --background --user jetty --exec "/usr/bin/sudo" -- -u jetty /usr/bin/Xvfb :99 -screen 0 1024x768x24

Вы можете увидеть подробности моего решения для генерации изображений на стороне сервера в этом вопросе SO.

Ответ от Shreyas Dave больше не работал для меня. Хотя я не знаю почему, вот что я сделал:

public static void main(String[] args) {
    // to avoid
    // [JRSAppKitAWT markAppIsDaemon]: Process manager already initialized: can't fully enable headless mode.
    System.setProperty("javafx.macosx.embedded", "true");
    java.awt.Toolkit.getDefaultToolkit();
    // end
    launch(args);
}

Это также было указано здесь: исключение без заголовка JavaFX screencapture на OSX

Это своего рода проблема, с которой я столкнулся при съемке изображений в Mac OS.

Я решил эту проблему с помощью

static {

        System.setProperty("java.awt.headless", "false");
}

Для справки: Ошибка безголовой среды в классе java.awt.Robot с MAC OS

У меня есть приложение, которое можно использовать в интерактивном режиме (с отображением диалогов JavaFx), но оно также должно быть в состоянии работать неинтерактивно на сервере без отображения.
Хотя в неинтерактивном режиме элемент GUI не используется, мы получили

    Caused by: java.lang.UnsupportedOperationException: Unable to open DISPLAY
    at com.sun.glass.ui.gtk.GtkApplication.<init>(GtkApplication.java:68)

Это происходит, как только класс, полученный из javafx.application.Application создается, что вы обычно делаете с вашим основным классом.

Вот как я решил проблему:

  • Я создал дополнительный класс GuiAppExecution:

    import java.util.List;
    
    import javafx.application.Application;
    import javafx.stage.Stage;
    
    /**
     * JavaFx launch class for {@link AppExecution}.
     */
    public class GuiAppExecution extends Application {
    
      @Override
      public void start(Stage stage) throws Exception {
        List<String> parameters = getParameters().getRaw();
        AppExecution appExecution = new AppExecution();
        appExecution.launch(parameters);
      }
    
      /**
       * Launches the {@link AppExecution} as JavaFx {@link Application}.
       *
       * @param parameters program parameters
       */
      public void launchGui(String[] parameters) {
        launch(parameters);
      }
    }
    
  • В основной класс AppExecution Я создал метод
    public void launch(List<String> parameters) {
    который анализирует параметры и запускает приложение для интерактивного и неинтерактивного выполнения.

  • main Метод выглядит так:

    public static void main(String[] parameters) {
      List<String> parameterList = Arrays.asList(parameters);
      if (parameterList.stream().anyMatch(p -> p.equalsIgnoreCase(BATCH_PARAMETER))) {
        AppExecution appExecution = new AppExecution();
        appExecution.launch(parameterList);
      }
      else {
        GuiAppExecution guiAppExecution = new GuiAppExecution();
        guiAppExecution.launchGui(parameters);
      }
    }
    

    с

    private static final String BATCH_PARAMETER = "-batch";
    

    в качестве опции программы, которая запрашивает неинтерактивное выполнение.

поскольку GuiAppExecution (который получен из javafx.application.Application) не создается для неинтерактивного выполнения, среда JavaFx не запускается.

Если у вас есть исходный код приложения JavaFX, вы также можете попробовать использовать TestFX для запуска приложения в автономном режиме, управления им и создания снимков экрана. Чтобы запустить приложение TestFX в режиме без головы, вы должны запустить его со следующими параметрами JVM (чтобы включить Monocle):

-Dtestfx.robot=glass -Dglass.platform=Monocle -Dmonocle.platform=Headless -Dprism.order=sw

Кроме того, вам может понадобиться сначала установить Monocle. См. Безголовое тестирование с JavaFx и TestFx для получения дополнительной информации.

Другие вопросы по тегам