При использовании формы 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
, но у меня былонекоторые проблемы с его использованием по мере роста моего проекта.)