JavaFx in headless mode

后端 未结 5 2036
抹茶落季
抹茶落季 2020-12-10 07:36

Is it possible to run JavaFx in headless mode(in Java 7)? It is being used to generate images on the server but is asking for an X-Server. Does there exist something like ja

相关标签:
5条回答
  • 2020-12-10 08:06

    I have an application that can be used interactively (displaying JavaFx dialogs) but also must be able to run non-interactive on a server without display.
    Even though no GUI element is used in non-interactive mode, we got

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

    This happens as soon as a class derived from javafx.application.Application is instantiated, which you normally do with your main class.

    Here is the way I solved the problem:

    • I created an additional class 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);
        }
      }
      
    • In the main class AppExecution I created a method
      public void launch(List<String> parameters) {
      which parses the parameters and launches the application for both interactive and non-interactive execution.

    • The main method looks like this:

      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);
        }
      }
      

      with

      private static final String BATCH_PARAMETER = "-batch";
      

      as the program option that request the non-interactive execution.

    Since GuiAppExecution (which is derived from javafx.application.Application) is not instantiated for non-interactive execution, the JavaFx environment is not started.

    0 讨论(0)
  • 2020-12-10 08:13

    Answer by Shreyas Dave didn't work for me anymore. Though I don't know why, here is what I did:

    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);
    }
    

    This was also pointed out here: JavaFX screencapture headless exception on OSX

    0 讨论(0)
  • 2020-12-10 08:14

    Here is how I solved this problem for server-side image geneartion on Ubuntu linux environment with jetty application server. It uses xvfb but only as a "library" - without any additional special actions on server:

    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
    

    You can see the details of my server-side image generation solution in this SO question.

    0 讨论(0)
  • 2020-12-10 08:14

    This is a kind of problem which I encountered while capturing images in Mac OS.

    I have solved this issue by using

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

    See for reference : Headless environment error in java.awt.Robot class with MAC OS

    0 讨论(0)
  • 2020-12-10 08:25

    If you have the source code of the JavaFX application you could also try to use TestFX run the application in a headless mode, to control it and to make screenshots. To run your TestFX application in headless mode you have to start it with the following JVM parameters (to enable Monocle):

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

    Moreover you might need to install Monocle first. See Headless testing with JavaFx and TestFx for more information.

    0 讨论(0)
提交回复
热议问题