Welcome! Please see the About page for a little more info on how this works.

0 votes
in Java Interop by

I managed to get an interactive CLI working from: https://stackoverflow.com/questions/56541688/how-to-run-an-interactive-cli-program-from-within-clojure

but I also need to set the environment varibles, https://stackoverflow.com/questions/30574972/java-processbuilder-and-using-environment-variables suggests pb.environment().put("ENV", "val") so I think it should be (-> pb .environment (put. env val)):

(defn process-interactive-cli
  [args & [working-directory envs]]
  (let [process-builder (java.lang.ProcessBuilder. args)
        inherit (java.lang.ProcessBuilder$Redirect/INHERIT)
        environment (.environment process-builder)]
    ;; change CWD
    (when working-directory
      (.directory process-builder (io/file working-directory)))
    ;; set environment variables
    (for [[env val] envs]
      (.put environment env val))
    (.redirectOutput process-builder inherit)
    (.redirectError process-builder inherit)
    (.redirectInput process-builder inherit)
    ;; print the executing command (~ set -x)
    (apply println ">" args)
    (.waitFor (.start process-builder))))

But debugging this gives me:
1. Unhandled java.lang.IllegalArgumentException No matching method put found taking 2 args for class java.lang.ProcessEnvironment$StringEnvironment

1 Answer

+1 vote
selected by
Best answer

In the inline code, replace (put. env val) with (.put env val).

In the code block, replace for with doseq.

But that won't solve the exception. It seems like you're hitting either https://clojure.atlassian.net/browse/CLJ-1243 (even though the description is not entirely the same, the root cause might be) or something very similar, and I can also reproduce it.

In order to fix it, add a type annotation: (.put ^java.util.Map environment env val).

Thank you, that type annotation solves my problem.