【问题标题】:Could not locate proj/core.clj on classpath when calling clojure from java从 java 调用 clojure 时无法在类路径上找到 proj/core.clj
【发布时间】:2021-07-30 10:07:15
【问题描述】:

我正在尝试从 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

我也看过这篇文章,但对我的问题没有帮助: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 函数

【问题讨论】:

  • 您能否提供确切的文件系统布局?例如。使用find -type f 并可能将结果修剪为相关内容。还要添加您正在使用的构建工具以及如何运行它。一些构建工具可能只是忽略 java-src 树中的 .clj 文件,而不是像资源文件一样处理它们。
  • @cfrick 我编辑了问题以包括文件系统布局和构建工具。我不知道 IntelliJ 在 Windows 上使用的默认构建工具是什么,但我希望它已经足够了。

标签: java clojure clojure-java-interop


【解决方案1】:

这是一个完整的最小工作版本,显示从 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 中,您需要在项目设置 > 项目结构 > 模块中配置项目模块。在“源”选项卡中,选择条目src/clojure(它将作为“源文件夹”显示为蓝色),然后单击“资源”按钮将其标记为资源根目录。这可确保在 IntelliJ 中运行 Java 应用程序时 .clj 文件存在于类路径中。现在,您可以通过类proj.Main 中的Java 方法main 单击装订线中的绿色箭头来运行应用程序。每次 Cursive 刷新 Leiningen 项目时,您都需要重新应用此模块更改,因为更改不会生效。

【讨论】:

  • 这是无价之宝,就像一个魅力。我尝试将普通 jar(从 lein jar 创建)添加到项目依赖项中,但这似乎不起作用,但 uberjar 可以完美运行。我真的不明白为什么会这样,但我很高兴它有效。
  • lein uberjar 包括依赖项(以及它们所有的传递依赖项)以创建“独立”JAR。在这个最小的情况下,这些依赖是 Clojure 本身(加上它的依赖)。
猜你喜欢
  • 2015-01-08
  • 1970-01-01
  • 2013-12-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-09
  • 1970-01-01
  • 2012-11-10
  • 1970-01-01
相关资源
最近更新 更多