I'm developing JavaFx application that will be run under Linux, both in environments that support GUI and environments that do not support GUI. Meaning, if I connect to machine where application will be run with "ssh -X" when application is started GUI should open, and if I connect using just "ssh" (without -X) then console version of application should start.
How can I achieve this when using JavaFx?
I tried it in the following way:
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource("MainGui.fxml"));
SplitPane page = null;
try {
page = (SplitPane) loader.load();
} catch (IOException e) {
System.exit(1);
}
Scene scene = new Scene(page);
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
}
public static void main(String[] args) {
if (args.length == 1 && args[0].equals("nogui")) {
System.out.println("NOGUI SELECTED");
} else {
launch(args);
}
}
}
But it didn't work, and when I tried to connect via SSH to another machine without -X option, I still receive error:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.UnsupportedOperationException: Unable to open DISPLAY
at com.sun.glass.ui.gtk.GtkApplication.<init>(GtkApplication.java:68)
at com.sun.glass.ui.gtk.GtkPlatformFactory.createApplication(GtkPlatformFactory.java:41)
at com.sun.glass.ui.Application.run(Application.java:146)
at com.sun.javafx.tk.quantum.QuantumToolkit.startup(QuantumToolkit.java:257)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:211)
at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:675)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:337)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
... 5 more
I also noticed if I run application in environment with GUI, giving "nogui" command line option, I would receive printout "NOGUI SELECTED", but application would not end it's execution instead it would just hang there.
Can you help me how I can achieve this?
I am not sure what exactly is causing this issue that you are facing. But JavaFX is known to have thread issues, this could be related to JavaFX Main Class spawning child thread(s). But I am not knowledgeable enough to answer that.
But what I can do is, provide an alternative, if you are looking for one. You can create a separate class (Not extending Application class) with the main method and then call the Main class if required from there, this way your application will exit if nogui is passed.
If you don't wish to pass arguments, then you can simply use
Main.launch(Main.class)
instead ofMain.launch(Main.class, args)
. I have not tested this out, but it should work.Quoting an answer from elsewhere that worked for me with javafx as root on Ubuntu ... Maybe this can help someone else. I had the same question as you but for a normal user. Let's say I want to start firefox using the user account foo. I'm logged in as bar:
[bar@localhost ~]$ sudo -u foo -H firefox
Sadly that command failed with the same error as in the question (i.e. no protocol specified & cannot open display)
My solution was to simply add the user foo to the list of authorised access to the X server.
xhost si:localuser:foo
And that was it, I was then able to launch Firefox (and other X application) using sudo and the user foo.