#clojure
#clojure
Вопрос:
При использовании import
формы в Clojure я бы хотел, чтобы эта форма использовала JavaSourceClassLoader
из библиотеки Janino, чтобы при попытке импортировать класс этот пользовательский загрузчик просматривал исходный каталог Java и на лету компилировал класс Java, который импортируется.
В корне моего проекта Leiningen у меня есть dynjava/
каталог, куда я помещаю свои исходные файлы Java. Я написал немного кода для создания JavaSourceClassLoader:
(ns playground.classloading
(:import [org.codehaus.janino JavaSourceClassLoader])
(:require [clojure.java.io :as io]))
(defn current-loader []
(.deref clojure.lang.Compiler/LOADER))
(defn make-source-loader
([]
(make-source-loader (current-loader)))
([parent]
(JavaSourceClassLoader.
parent
(into-array [(io/file "dynjava")])
nil)))
У меня есть образец файла, dynjava/Magic.java
который выглядит следующим образом, чтобы протестировать его:
public class Magic {
public int getNumber() {
return 119;
}
}
И я действительно могу из REPL компилировать, загружать и создавать экземпляры этого класса, например
(.getNumber (.newInstance (.loadClass (make-source-loader) "Magic")))
;; => 119
Теперь я хотел бы использовать JavaSourceClassLoader с import
формой, поэтому я попробовал это:
(def src-loader (make-source-loader))
(.bindRoot clojure.lang.Compiler/LOADER src-loader)
(.set clojure.lang.Compiler/LOADER src-loader)
(println "The var is " clojure.lang.Compiler/LOADER)
(if (.isBound clojure.lang.Compiler/LOADER)
(println "The compiler loader is "
(.deref clojure.lang.Compiler/LOADER)))
который отображает это:
The var is #<Var: --unnamed--> The compiler loader is #object[clojure.lang.DynamicClassLoader 0x9b1fcd3 clojure.lang.DynamicClassLoader@9b1fcd3] playground.classloading>
Из этого вывода ясно, что я делаю что-то не так при попытке изменить LOADER
var, потому что это не экземпляр JavaSourceClassLoader
.
И попытка импортировать Magic
класс, который я написал ранее, не работает:
;; (import 'Magic) results in an Error
Мой вопрос: как я могу изменить загрузчик классов, используемый import
в Clojure, чтобы он был экземпляром JavaSourceClassLoader?
(Кстати, я в курсе lein-virgil
, но у меня возникли некоторые проблемы с его использованием по мере того, как мой проект разрастался.)