Динамический импорт зависимостей?

Можно ли добавить новый материал в путь к классам (например, отредактировать project.clj и запустить lein deps), а затем импортировать его в существующий сеанс Clojure?

Это без необходимости отключаться, а затем снова подключаться.


person deprecated    schedule 15.05.2012    source источник


Ответы (2)


Вы можете использовать pomegranate для загрузки новых библиотек и добавления их в путь к классам во время выполнения. Он не будет читать напрямую из вашего проекта.clj, но использует совместимый синтаксис (используя библиотеку Aether, которую Leiningen 2 использует для собственного разрешения зависимостей).

Использование выглядит так (цитируя пример README):

=> (add-dependencies
      :coordinates '[[incanter "1.2.3"]]
      :repositories (merge cemerick.pomegranate.aether/maven-central
                           {"clojars" "http://clojars.org/repo"}))

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

person Charles Duffy    schedule 15.05.2012
comment
Приятно знать, что это возможно. Немного непрактично для ежедневного использования разработчиками, поскольку он не интегрирован с lein, но я вижу, как это может быть полезно для обновления развернутых запущенных приложений. - person deprecated; 15.05.2012
comment
Интеграция не должна быть такой сложной для создания — все, что вам нужно, это оболочка, которая читает project.clj и соответствующим образом вызывает надстройки-зависимости. Для своих собственных проектов я не использую lein (поскольку они интегрируются в более крупные проекты, один из которых имеет свои собственные зависимости от Maven, другой от Gradle)... но я вижу, как необязательная интеграция без потери автономного использования могла бы быть удобством. - person Charles Duffy; 15.05.2012
comment
Вы правы, особенно с учетом того, что автор граната намеренно использует формат Лейна. Буду разбираться! - person deprecated; 15.05.2012

Я предполагаю, что под сессией clojure вы подразумеваете REPL, запущенный lein repl.

Короткий ответ на ваш вопрос: нет, вы не можете этого сделать.

JVM поддерживает загрузчики классов для обеспечения этого динамического функции загрузки, и clojure использует их для поддержки динамических определений классов с помощью deftype gen-class и т. д.

Добавление новых сторонних классов (предположительно новой библиотеки jar) в путь к классам было бы пугающе сложным, если учесть, что вам придется раскручивать и перестраивать уже используемые загрузчики классов.

Подробнее о загрузке классов в clojure см. этот вопрос.

person sw1nn    schedule 15.05.2012
comment
Это не так уж плохо — экземпляры URLClassloader (которые очень распространены — если на то пошло, DynamicClassLoader Clojure является производным от того же) поддерживают вызов addURL, и если он еще не находится на вершине дерева, его можно добавить в разделе загрузчик классов контекста текущего потока во время выполнения. Я делаю это, чтобы разрешить использование граната для добавления новых зависимостей во время выполнения даже в изолированной среде OSGi, предоставляемой плагинам v2 JIRA. - person Charles Duffy; 15.05.2012