动态添加到 clojure repl 中的 classpath 以访问 java 类文件 (pomegranate/add-classpath)

Wil*_*ill 5 java clojure classpath read-eval-print-loop

我已经编译了类文件shortScreen/out/production/classes/com/rsw/并希望在 clojure repl 中使用它们。我认为挂断已经开始,add-classpath但我不熟悉应该发生什么。或者怎么解决。

(use '[cemerick.pomegranate :only (add-dependencies add-classpath)])
(import 'clojure.pprint)
(def myclasses "shortScreen/out/production/classes/com/rsw/")
; do i have the correct path?
(-> (clojure.java.io/file myclasses) (file-seq) (pprint)) ; shows many class files
(.exists (clojure.java.io/file myclasses "util.class")) ; true

; add the path
(add-classpath myclasses)

; but nothing like myclasses path in list
(def thiscp (.getURLs (java.lang.ClassLoader/getSystemClassLoader)))
(pprint thiscp)
(filter (fn [s] (re-seq #"out" s)) ;myclasses path should match "out"
     (for [x thiscp]
       (.toString x)))

; fails -- but not sure if this is the correct syntax anyway
(import 'com.rsw.util)
(util/msg "test")
Run Code Online (Sandbox Code Playgroud)

编辑:一个可重复的例子

mkdir example && cd $_
# java code
cat > util.java << EOF
 package com.util;
 public class util {
 public static void msg(String a){
   System.out.println(a);
  }
 }
EOF

# clojure depends
cat > deps.edn << EOF
  {:deps {
    :alembic {:mvn/version "0.3.2"}
    :com.cemerick/pomegranate {:mvn/version "1.0.0"}
    }
  }
EOF

# compile java to class
javac util.java
ls # util.java util.class

# try to load in repl
clj

  (use '[cemerick.pomegranate :only (add-dependencies add-classpath)])
  (add-classpath (-> (java.io.File. ".") .getAbsolutePath))
  (import 'com.util.util)
  ; ClassNotFoundException com.util  java.net.URLClassLoader.findClass (URLClassLoader.java:381)
Run Code Online (Sandbox Code Playgroud)

Mat*_*and 1

这个问题很老了,但由于没有公认的答案,我认为可能值得回应。

\n

java 类加载器系统使用类路径作为一组搜索根,并期望在以下位置找到实际的类:

\n

<classpath element>/<directory hierarchy representing package name>/<class name>.class

\n

在你的情况下,它看起来像这样:

\n
example\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 util\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Util.class\n        \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 Util.java\n
Run Code Online (Sandbox Code Playgroud)\n

即,在您的示例中,您似乎正在尝试加载类com.util.util,但将实际.class文件放在根目录中,而不是放在代表com.util包名称的适当目录层次结构下。

\n

我运行了您的可重现示例,经过此更改后,事情似乎有效:

\n
example\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 util\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Util.class\n        \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 Util.java\n
Run Code Online (Sandbox Code Playgroud)\n

(我将类名大写,否则我按原样运行你的示例)

\n