Search code examples
clojureleiningenjline3

lein causes jline3 terminal to be dumb


I get a dumb terminal through lein whereas I get a non-dumb terminal through the uberjar. What's lein doing to cause this and how to fix it? This is happening on a Win 10 terminal

my project dependencies:

:dependencies [[org.clojure/clojure "1.9.0"]
               [org.jline/jline "3.11.0"]
               [org.fusesource.jansi/jansi "1.18"]]

the main function:

(defn -main
  [& args]
  (let [term (.. (TerminalBuilder/builder)
                 (system true)
                 (build))
        reader (.. LineReaderBuilder
                   (builder)
                   (terminal term)
                   (build))]
    (println (.getName term) (.getType term))
    (let [line (.readLine reader "hello world> ")]
      (.. term (writer) (println (str "====> " line)))
      (.flush term))))

thru lein run I get a dumb terminal:

> lein run
Jun 02, 2019 11:58:20 AM org.jline.utils.Log logr
WARNING: Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)
JLine terminal dumb
hello world> hi
====> hi

thru uberjar the terminal is not dumb:

> lein uberjar
...

> java -jar target\uberjar\terminal-0.1.0-SNAPSHOT-standalone.jar
JLine terminal windows-vtp
hello world> hi
====> hi

Solution

  • Leiningen starts up its own JVM to read project.clj, et cetera, and then lein run starts up a new JVM for your project; the lein JVM then delegates to yours. I suspect JLine is correctly detecting its stdin is not really a terminal, but a pipe from the lein JVM.

    If you want lein to get out of the way, you can use lein trampoline run. The job of trampoline is to pre-compute all tasks that will need to be done, and write those into a shell script, to be executed after closing the lein JVM.