从 java 调用 clojure 时无法在类路径中找到 proj/core.clj

Could not locate proj/core.clj on classpath when calling clojure from java

我正在尝试从 Java 调用一些 Clojure 代码,但在尝试“要求”文件时出现此错误:

Could not locate proj/core__init.class, proj/core.clj or proj/core.cljc on classpath.
    at clojure.lang.RT.load(RT.java:462)
    at clojure.lang.RT.load(RT.java:424)
    at clojure.core$load$fn__6839.invoke(core.clj:6126)
    at clojure.core$load.invokeStatic(core.clj:6125)
    at clojure.core$load.doInvoke(core.clj:6109)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invokeStatic(core.clj:5908)
    at clojure.core$load_one.invoke(core.clj:5903)
    at clojure.core$load_lib$fn__6780.invoke(core.clj:5948)
    at clojure.core$load_lib.invokeStatic(core.clj:5947)
    at clojure.core$load_lib.doInvoke(core.clj:5928)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invokeStatic(core.clj:667)
    at clojure.core$load_libs.invokeStatic(core.clj:5985)
    at clojure.core$load_libs.doInvoke(core.clj:5969)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invokeStatic(core.clj:667)
    at clojure.core$require.invokeStatic(core.clj:6007)
    at clojure.core$require.doInvoke(core.clj:6007)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.lang.Var.invoke(Var.java:384)
    at proj.Main.main 

Clojure代码如下:

(ns proj.core)

(defn foo
  "I don't do a whole lot."
  [x]
  (println x "Hello, World!"))

和java代码:

package proj;

import clojure.java.api.Clojure;
import clojure.lang.IFn;

public class Main {
    public static void main(String[] args) {
        IFn require = Clojure.var("clojure.core", "require");
        require.invoke(Clojure.read("proj.core"));
    }
}

我已经尝试按照本指南进行操作,以便在文件位于同一项目中时从 java 调用 clojure 代码:https://push-language.hampshire.edu/t/calling-clojure-code-from-java/865

我也看过这个 post,但它对我的问题没有帮助:Calling clojure from java

编辑: 两个文件都在同一个包中

编辑: 文件系统布局如下

D:.
│   first_try.iml
│   project.clj
│
├───src
│   └───proj
│           core.clj
│           Main.java
│
└───target
    └───classes
        └───proj
                Main.class

此外,我正在使用默认的 IntelliJ 应用程序配置 运行 应用程序,我还有一个 Leiningen 配置以及直接从 REPL 测试 Clojure 函数

这是一个完整的最小工作版本,显示了从 Java 调用的 Clojure。

项目布局:

.
├── project.clj
├── resources
└── src
    ├── clojure
    │   └── proj
    │       └── core.clj
    └── java
        └── proj
            └── Main.java

project.clj:

(defproject overflow-java "0.1.0-SNAPSHOT"
  :source-paths ["src/clojure"]
  :java-source-paths ["src/java"]
  :dependencies [[org.clojure/clojure "1.10.1"]]
  :repl-options {:init-ns proj.core})

src/clojure/proj/core.clj:

(ns proj.core)

(defn foo
  "I don't do a whole lot."
  [x]
  (println x "Hello, World!"))

src/java/proj/Main.java:

package proj;

import clojure.java.api.Clojure;
import clojure.lang.IFn;

public class Main {
    public static void main(String[] args) {
        IFn require = Clojure.var("clojure.core", "require");
        require.invoke(Clojure.read("proj.core"));
        IFn foo = Clojure.var("proj.core", "foo");
        foo.invoke("Steffan");
    }
}

构建 uberjar 和 运行:

$ lein uberjar
$ java -cp target/overflow-java-0.1.0-SNAPSHOT-standalone.jar proj.Main

运行 输出:

Steffan Hello, World!

Leiningen docs advise putting Java and Clojure source files in their own source roots.

如果您希望 运行 项目直接在 IntelliJ 中,您需要在项目设置 > 项目结构 > 模块中配置项目模块。在“资源”选项卡中,select 条目 src/clojure(它将显示为蓝色作为“源文件夹”),然后单击“资源”按钮将其标记为资源根目录。当 运行 在 IntelliJ 中使用 Java 应用程序时,这可确保 .clj 文件出现在 class 路径中。您现在可以通过 Java 方法 main 在 class proj.Main 中单击装订线中的绿色箭头来 运行 应用程序。每次 Cursive 刷新 Leiningen 项目时,您都需要重新应用此模块更改,因为更改不会生效。