Default to headless mode
mprimi opened this issue · comments
elle-cli
should probably run by default in (Java) headless mode, since it's a command-line application without a GUI.
Currently, it does not and this creates a couple of inconveniences:
MacOS: when Elle-cli
is running there is an application (e.g. shows in alt-tab list of running applications). And it steals focus from the currently active application. So if you have it running in background on a bunch of traces, it's impossible to do anything else, because it keeps going foreground.
Linux (Ubuntu 20.04 with java-default-headless
installed):
Caused by: java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
at java.desktop/sun.awt.HeadlessToolkit.getMenuShortcutKeyMask(HeadlessToolkit.java:135)
at rhizome.viz__init.load(Unknown Source)
at rhizome.viz__init.<clinit>(Unknown Source)
... 126 more
There is a simple workaround that fixes both cases:
java -Djava.awt.headless=true -jar ${ELLE_CLI_JAR}
But it would be nice if Elle-cli
was headless-ready out of the box.
More info: https://www.baeldung.com/java-headless-mode
Thanks for reporting this!
Actually -Djava.awt.headless=true
is passed in project.clj
, see
Line 7 in 7970c59
Seems it is not enough.
Regarding a problem with running on Ubuntu with installed java-default-headless
- it is recommended to set DISPLAY
,
see https://www.ibm.com/support/pages/launcheradminsh-script-generates-no-x11-display-variable-was-set-program-performed-operation-which-requires-it-error I do this in CI, see
elle-cli/.github/workflows/test.yaml
Lines 59 to 63 in 7970c59
But it would be nice if
elle-cli
was headless-ready out of the box.
Agree. I left the issue unresolved.
Actually -Djava.awt.headless=true is passed in project.clj, see
Ah, interesting. I am guessing the property gets lost in translation when creating the UberJar (or maybe it's set, but too late during lifecycle)?
Setting display seems like a workaround. It should not be necessary if headless mode was working as expected.
Setting display seems like a workaround. It should not be necessary if headless mode was working as expected.
Confirmed this, see these PR tests passing on ubuntu after removing DISPLAY: #51
So my theory is: setting :jvm-opts
works for lein run
and similar, but the headless property is lost when creating the uberjar.
And here's evidence this is correct:
- Add a print in the first statement of main:
(defn -main
[& args]
(println "HEADLESS? " (System/getProperty "java.awt.headless"))
(try
- Run with lein:
$ lein run
Compiling elle_cli.cli
HEADLESS? true
elle-cli - command-line transactional safety checker.
So far so good, headless mode property is passed, as expected.
However:
- Build and run the uberjar:
$ lein uberjar
(...)
$ java -jar target/elle-cli-0.1.3-standalone.jar
HEADLESS? nil
elle-cli - command-line transactional safety checker.
So it does look like those :jvm-opts
are not carried over to the uberjar.
In this case you do want "java.awt.headless" to be always set in the uberjar.
I'm not familiar with lein or Clojure, but I'm sure there's multiple ways to achieve that (bundle a property file as resource, for example)
Once that's done, you could remove any hack you had to do in testing, because the uberjar will always run in headless mode (which is what you want for a pure CLI tool, I think).
Thanks for research!
Once that's done, you could remove any hack you had to do in testing
I'll try to fix it.
Thank you for the quick turnaround on this! @ligurio