Permalink
Browse files

Look for main functions on Java classes in run task. Fixes #249.

  • Loading branch information...
1 parent dee34fa commit d3797fe408275c7a73eca45db4fa1ff1eaa926bd @technomancy committed Nov 10, 2011
View
@@ -2,6 +2,8 @@ Leiningen NEWS -- history of user-visible changes
= 1.6.2 / ???
+* Let run task work with main functions from Java classes.
+
* Fix bug where exceptions would break interactive task.
* Default to Clojure 1.3.0 for new projects.
View
@@ -1,23 +1,30 @@
(ns leiningen.run
"Run a -main function with optional command-line arguments."
(:use [leiningen.compile :only [eval-in-project]]
- [leiningen.core :only [abort]]))
+ [leiningen.core :only [abort]])
+ (:import (java.io FileNotFoundException)
+ (clojure.lang Reflector)))
-(defn- get-ns-and-fn [given]
- (if (= 'clojure.main given) ; special-case this oddity
- ['clojure.main 'main]
- (let [[given-ns given-sym] ((juxt namespace name) given)]
- (map symbol (if given-ns
- [given-ns given-sym]
- [given-sym "-main"])))))
+(defn- normalize-main [given]
+ (if (namespace (symbol given))
+ (symbol given)
+ (symbol (name given) "-main")))
+
+(defn- run-form [given args]
+ `(let [v# (resolve '~(normalize-main given))]
+ (if (ifn? v#)
+ (v# ~@args)
+ (Reflector/invokeStaticMethod
+ ~(name given) "main" (into-array [(into-array String '~args)])))))
(defn- run-main
"Loads the project namespaces as well as all its dependencies and then calls
ns/f, passing it the args."
- ([project given-main & args]
- (let [[main-ns main-fn] (get-ns-and-fn (symbol given-main))]
- (eval-in-project project `((ns-resolve '~main-ns '~main-fn) ~@args)
- nil nil `(require '~main-ns)))))
+ [project given & args]
+ (eval-in-project project (run-form given args)
+ nil nil `(try (require '~(symbol (namespace
+ (normalize-main given))))
+ (catch FileNotFoundException _#))))
(defn ^{:help-arglists '([])} run
"Run the project's -main function.
@@ -2,9 +2,10 @@
(:use [clojure.test]
[clojure.java.io :only [delete-file]]
[leiningen.core :only [read-project]]
+ [leiningen.javac :only [javac]]
[leiningen.run]
[leiningen.util.file :only [tmp-dir]]
- [leiningen.test.helper :only [tricky-name-project]]))
+ [leiningen.test.helper :only [tricky-name-project dev-deps-project]]))
(def out-file (format "%s/lein-test" tmp-dir))
@@ -33,3 +34,7 @@
(is (= "nom::bbb" (slurp out-file)))
(is (zero? (run tricky-name-project "--" "-m")))
(is (= "nom:-m" (slurp out-file))))
+
+(deftest test-run-java-main
+ (javac dev-deps-project)
+ (is (zero? (run dev-deps-project))))
@@ -1,4 +1,4 @@
(defproject dev-deps-only "1.0.0-SNAPSHOT"
:java-source-path [["src"] ["src2"]]
:dev-dependencies [[org.clojure/clojure "1.2.0"]]
- :main dev-deps-only.Junk)
+ :main dev_deps_only.Junk)
@@ -1,3 +1,7 @@
package dev_deps_only;
-class Junk {}
+public class Junk {
+ public static void main(String[] args) {
+ ;
+ }
+}
View
@@ -14,8 +14,8 @@ See also https://github.com/technomancy/leiningen/issues
- [X] don't let multiple versions of a plugin interfere with each other (#301)
- [X] non-jar deps on classpath (#244)
- [X] recover from error in interactive (#234)
+ - [X] use java class in run task (#249)
- [ ] fix deploy with new maven-ant-tasks
- - [ ] use java class in run task (#249)
- [ ] signed deps for plugins (#247)
- [ ] jvm-specific deps (JSR 310)
* For 1.6.1

0 comments on commit d3797fe

Please sign in to comment.