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 java.awt.headless in JavaFx ?(I can't use Xvfb )
问题:
回答1:
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.
回答2:
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
回答3:
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
回答4:
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.
回答5:
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.