Allow eval-in-project to exit the VM.

Ugh; ant's permissions are hairy.
This commit is contained in:
Phil Hagelberg 2010-05-19 23:13:18 -10:00
parent c84b717705
commit b969b6cf9e
2 changed files with 45 additions and 20 deletions

View file

@ -7,12 +7,33 @@
[clojure.contrib.io :only [file]] [clojure.contrib.io :only [file]]
[clojure.contrib.find-namespaces :only [find-namespaces-in-dir]]) [clojure.contrib.find-namespaces :only [find-namespaces-in-dir]])
(:refer-clojure :exclude [compile]) (:refer-clojure :exclude [compile])
(:import org.apache.tools.ant.taskdefs.Java (:import [org.apache.tools.ant.taskdefs Java]
java.lang.management.ManagementFactory [java.lang.management ManagementFactory]
(org.apache.tools.ant.types Environment$Variable))) [org.apache.tools.ant.types Environment$Variable
Permissions Permissions$Permission]))
(declare compile) (declare compile)
(def perm-list [{:class "java.lang.RuntimePermission"
:name "*"}
{:class "java.lang.reflect.ReflectPermission"
:name "*"}
{:class "java.io.FilePermission"
:name "<<ALL FILES>>"
:actions "read,write,delete,execute"}
{:class "java.util.PropertyPermission"
:name "*"
:actions "read,write"}])
;; This is ridiculous, but you can't exit the VM without it.
(defn add-perms [java]
(let [perms (.createPermissions java)]
(doseq [p perm-list]
(.addConfiguredGrant perms (doto (Permissions$Permission.)
(.setClass (:class p))
(.setName (:name p))
(.setActions (str (:actions p))))))))
(defn compilable-namespaces (defn compilable-namespaces
"Returns a seq of the namespaces that are compilable, regardless of whether "Returns a seq of the namespaces that are compilable, regardless of whether
their class files are present and up-to-date." their class files are present and up-to-date."
@ -84,6 +105,22 @@
(concat (.getInputArguments (ManagementFactory/getRuntimeMXBean)) (concat (.getInputArguments (ManagementFactory/getRuntimeMXBean))
(:jvm-opts project))) (:jvm-opts project)))
(defn set-args [project java form native-path]
(when (or (:fork project) (:jvm-opts project)
(= :macosx (get-os)) native-path)
(.setFork java true)
(doseq [arg (get-jvm-args project)]
(when-not (re-matches #"^-Xbootclasspath.+" arg)
(.setValue (.createJvmarg java) arg))))
(.setClassname java "clojure.main")
(.setValue (.createArg java) "-e")
(let [cp (str (.getClasspath (.getCommandLine java)))
form `(do (def ~'*classpath* ~cp)
(set! ~'*warn-on-reflection*
~(:warn-on-reflection project))
~form)]
(.setValue (.createArg java) (prn-str form))))
(defn eval-in-project (defn eval-in-project
"Executes form in an isolated classloader with the classpath and compile path "Executes form in an isolated classloader with the classpath and compile path
set correctly for the project. Pass in a handler function to have it called set correctly for the project. Pass in a handler function to have it called
@ -112,23 +149,11 @@
:default native-path))))) :default native-path)))))
(.setClasspath java (apply make-path (get-classpath project))) (.setClasspath java (apply make-path (get-classpath project)))
(.setFailonerror java true) (.setFailonerror java true)
(when (or (:fork project) (:jvm-opts project) (add-perms java)
(= :macosx (get-os)) native-path) (set-args project java form native-path)
(.setFork java true)
(doseq [arg (get-jvm-args project)]
(when-not (re-matches #"^-Xbootclasspath.+" arg)
(.setValue (.createJvmarg java) arg))))
(.setClassname java "clojure.main")
(.setValue (.createArg java) "-e")
(let [cp (str (.getClasspath (.getCommandLine java)))
form `(do (def ~'*classpath* ~cp)
(set! ~'*warn-on-reflection*
~(:warn-on-reflection project))
~form)]
(.setValue (.createArg java) (prn-str form)))
;; to allow plugins and other tasks to customize ;; to allow plugins and other tasks to customize
(when handler (handler java)) (when handler (handler java))
(.executeJava java))) (.execute java)))
(defn compile (defn compile
"Ahead-of-time compile the project. Looks for all namespaces under src/ "Ahead-of-time compile the project. Looks for all namespaces under src/

View file

@ -18,14 +18,14 @@ Leiningen TODOs
** DONE upgrade task (patch submitted) ** DONE upgrade task (patch submitted)
** DONE doc generation (autodoc plugin) ** DONE doc generation (autodoc plugin)
* For 1.2.0 * For 1.2.0
** TODO System/exit appropriately when testing based on pass/fail (abedra)
*** Needs to set permissions with the ant API's Java task
** TODO repl task exits on some projects (sample) (patch for this?) ** TODO repl task exits on some projects (sample) (patch for this?)
** TODO document all known project.clj keys ** TODO document all known project.clj keys
** TODO walk up the filesystem to find project.clj ** TODO walk up the filesystem to find project.clj
** TODO a list of dirs to include in the jar when building ** TODO a list of dirs to include in the jar when building
** TODO set arbitrary jar metadata ** TODO set arbitrary jar metadata
** TODO specify min. lein version in project.clj ** TODO specify min. lein version in project.clj
** DONE System/exit appropriately when testing based on pass/fail (abedra)
*** Needs to set permissions with the ant API's Java task
** DONE allow *warn-on-reflection* to be turned on in project.clj ** DONE allow *warn-on-reflection* to be turned on in project.clj
** DONE make org.clojure implied for clojure/contrib deps ** DONE make org.clojure implied for clojure/contrib deps
** DONE better way to force setFork in eval-in-project ** DONE better way to force setFork in eval-in-project