(ns env "Clojure hack to overwrite the JVM's System/getenv map for environment variables without touching the actual environment. Definitely not safe." (:import (java.util Collections Map))) (defn -unsafe-set-env [new-env] (try (let [clazz (Class/forName "java.lang.ProcessEnvironment")] (doseq [field ["theEnvironment" "theCaseInsensitiveEnvironment"]] (let [env-field (doto (.getDeclaredField clazz field) (.setAccessible true))] (.putAll ^Map (.get env-field nil) new-env)))) (catch NoSuchFieldException e (let [env (System/getenv)] (doseq [clazz (.getDeclaredClasses Collections)] (when (= (.getName clazz) "java.util.Collections$UnmodifiableMap") (let [field (doto (.getDeclaredField clazz "m") (.setAccessible true)) obj (.get field env)] (.clear ^Map obj) (.putAll ^Map obj (into new-env env))))))))) (defmacro with-unsafe-merge-env [new-env-vars & body] `(let [env# (into {} (System/getenv)) _# (-unsafe-set-env (merge env# ~new-env-vars)) ret# (do ~@body)] (-unsafe-set-env env#) ret#))