简体   繁体   中英

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

I am trying to call some Clojure code from Java, but I get this error when trying to "require" the file:

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 

The Clojure code is as follows:

(ns proj.core)

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

and the java code:

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"));
    }
}

I've tried following this guide, for calling clojure code from java when the files are in the same project: https://push-language.hampshire.edu/t/calling-clojure-code-from-java/865

I've also seen this post, but it didn't help with my issue: Calling clojure from java

EDIT: Both files are in the same package

EDIT: The file system layout is as follows

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

Also, I am using the default IntelliJ Application configuration to run the app, and I have a Leiningen configuration as well for testing the Clojure functions directly from REPL

Here is a full minimal working version showing Clojure called from Java.

Project layout:

.
├── 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");
    }
}

Build uberjar and run:

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

Run output:

Steffan Hello, World!

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

If you wish to run the project directly In IntelliJ you will need to configure the project module in Project Settings > Project Structure > Modules. In the "Sources" tab, select the entry src/clojure (it will be coloured blue as a "Source Folder") then click the button "Resources" to mark it as a resources root instead. This ensures the.clj files are present on the classpath when running the Java application in IntelliJ. You can now run the application by clicking on the green arrow in the gutter by Java method main in class proj.Main . You'll need to reapply this module change each time Cursive refreshes the Leiningen project, as the change does not stick.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM