2024年Clojure状态调查!中分享您的看法。

欢迎!请访问关于页面以获取有关此如何工作的一些更多信息。

+1
" width="50" height="50" class="qa-avatar-image" alt=""> 编译器
编辑

假设已经有一个包含Clojure的.jar文件的Java应用程序在类路径上。还有一个文件目录/home/me/clojure-extensions/包含.clj文件,结构类似于一个一般的Clojure源目录,它不在应用程序的类路径上,也不能添加到类路径上,因为它是可配置的,不是应用程序的一部分。

如何从Java代码中调用函数myns.core/myfn?以便加载/home/me/clojure/extensions/myns/core.clj以及所有依赖文件?以便在再次调用Java调用时,如果这些文件已更改,则重新加载这些文件?

1 回答

0
by

根据您描述的场景,您需要在类路径上包含/home/me/clojure-extensions/

为了从Java调用Clojure,您可以使用Java API

https://clojure.github.io/clojure/javadoc/clojure/java/api/Clojure.html

为了重新加载,您需要通过Java API显式调用(

(require 'whatever :reload-all)

这看起来可能像这样

// this can be done once, statically
IFn require = Clojure.var("clojure.core", "require");

// to reload
require.invoke(Clojure.read("whatever"), Clojure.read(":reload-all"));

然后使用相同的设施在任意的。

如果无法将 `/home/me/clojure-extensions/` 添加到类路径中怎么办?因为它不是应用程序的一部分。它也可以在应用程序中进行配置。并且应用程序以可部署的 .war 文件形式发布,但没有包含扩展目录,该目录应由管理员提供。
我已经见过这种情况。但是我需要在同一路径上加载一个文件及其所有依赖文件。看来,我必须在 JVM 进程已经运行时扩展 Java 类路径,然后使用 Clojure API。
您不能更改类路径,但您可以在应用程序中创建一个新的类加载器上下文来运行,该上下文包括额外的目录(参见 URLClassLoader)。这样做需要您在第一次实例化 Clojure 运行时(通过 Java API 中的 Clojure 类)和在从 Clojure API 返回的对象类(因为应用程序上下文需要访问您返回的任何类)时要特别小心。特别是,如果您期望除了内置的 Java 接口(集合、列表、映射、字符串等)之外的任何内容,我建议创建 Java 接口并返回这些接口的实现实例。
...