Тонкая настройка загрузчика классов для импорта - PullRequest
1 голос
/ 04 апреля 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...