2015-02-11 1 views
2

Я хочу загрузить Java-класс с помощью URLClassLoader и вызвать метод main. Код ниже дает ошибку на последней строке, и я не могу понять, как это исправить.Clojure: как вызвать статический метод main из класса Java, загруженного URLClassLoader

 

(def classloader (URLClassLoader. (into-array files))) 

(def classname "example.Test") 
(def clazz (.. classloader (loadClass classname))) 

; I assume not the most effective way to get method "main" 
; additional feedback appreciated 
(def method (first (filter #(= (. % getName) "main") (. clazz getMethods)))) 

(def args (make-array String 1)) 
; specify single command line argument for method main(String[]args) 
(aset args 0 "my-file") 

; attempt to invoke static method using Java reflection API fails. 
(. method invoke nil args) 

 

Exception in thread "main" java.lang.IllegalArgumentException: 
argument type mismatch, compiling: 

Пожалуйста, обратите внимание, что класс не иначе доступен в загрузчиком классов по умолчанию, так

 

(example.Test/main "myfile") 

потерпит неудачу.

Спасибо, Павел

ответ

1

Вы путаете подпись вызова с подписью основного метода.

Сигнатура "основные" является (String [] args1) Сигнатуры "вызова" является (Object OBJ, объект ... args2)

args2 должен быть массивом с одним элементом на каждые пары в основном методе, поэтому он должен быть массивом из 1 элемента, причем элементом является String []. Итак:

(def invoke-args (into-array Object [args])) 
(. method invoke nil invoke-args) 

О более простой способ найти «главный» смотреть на http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getMethod(java.lang.String,%20java.lang.Class...)

+0

Спасибо, это сработало –

+0

Я понимаю, как это сделать это в Java, никаких проблем здесь. Моя проблема с этим подходом заключалась в том, что при вызове метода getMethod мне нужно указать точную подпись для типов параметров. В java это будет String []. Class. Я не мог понять, как это сделать в clojure. –

+0

Прямого представления нет. Я бы, вероятно, пошел (класс (в массив String [])). См. Http://asymmetrical-view.com/2009/07/02/clojure-primitive-arrays.html – DanLebrero

0

я обобщил результат обсуждения ниже. (Спасибо dAni за помощь).

 
    (let 
     [classname "example.Test" 
     clazz (.. classloader (loadClass classname))

method (. clazz getMethod "main" (into-array Class [(class (into-array String []))])) args (make-array String 1)] (aset args 0 "my-file") (. method invoke nil (into-array Object [args])))

Смежные вопросы