leiningen:“lein 运行”/“lein uberjar”项目中存在 class 的 ClassNotFoundException
leiningen: ClassNotFoundException for class present in project on “lein run” / “lein uberjar”
我正在尝试实现我正在使用的遗留 运行time 所需的 Java 接口,并实例化此实现的实例以将其传递给 运行time .但是当我 运行 lein uberjar
我看到一个例外,找不到 class。这两个名称空间都在同一个 leiningen 项目中定义,所以我本以为它们会看到彼此以及它们生成的 classes。
(ns man.core
(:require (man.gateway))
(:import (man ManGate)
(eu.m2machine.gw GatewayComponentFactory))
(:gen-class))
(defn -main [& args]
(let [starter (.starter (GatewayComponentFactory/get))
gateway (ManGate.)]
(.startup starter gateway)))
此代码尝试使用在同一项目中实现的 class:
(ns man.gateway
(:import [eu.m2machine.gw.text GatewayIDFormatter])
(:gen-class
:name man.ManGate
:implements [eu.m2machine.gw.Gateway]
:prefix "gateway-"))
(defn gateway-startup [this])
(defn gateway-shutdown [this])
接口需要的两个方法目前只有存根实现。在我编译代码后,他们会得到他们的代码。接口已定义(在添加为依赖项的工件中):
package eu.m2machine.gw;
public interface Gateway {
void startup();
void shutdown();
}
我得到的异常是:
Exception in thread "main" java.lang.ClassNotFoundException: man.ManGate, compiling:(man/core.clj:1:1)
at clojure.lang.Compiler.load(Compiler.java:7391)
at clojure.lang.RT.loadResourceScript(RT.java:372)
at clojure.lang.RT.loadResourceScript(RT.java:363)
at clojure.lang.RT.load(RT.java:453)
at clojure.lang.RT.load(RT.java:419)
at clojure.core$load$fn__5677.invoke(core.clj:5893)
at clojure.core$load.invokeStatic(core.clj:5892)
at clojure.core$load.doInvoke(core.clj:5876)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invokeStatic(core.clj:5697)
at clojure.core$load_one.invoke(core.clj:5692)
at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
at clojure.core$load_lib.invokeStatic(core.clj:5736)
at clojure.core$load_lib.doInvoke(core.clj:5717)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invokeStatic(core.clj:648)
at clojure.core$load_libs.invokeStatic(core.clj:5774)
at clojure.core$load_libs.doInvoke(core.clj:5758)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invokeStatic(core.clj:648)
at clojure.core$require.invokeStatic(core.clj:5796)
at clojure.core$require.doInvoke(core.clj:5796)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at user$eval5$fn__7.invoke(form-init2162986879369932757.clj:1)
at user$eval5.invokeStatic(form-init2162986879369932757.clj:1)
at user$eval5.invoke(form-init2162986879369932757.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6927)
at clojure.lang.Compiler.eval(Compiler.java:6917)
at clojure.lang.Compiler.load(Compiler.java:7379)
at clojure.lang.Compiler.loadFile(Compiler.java:7317)
at clojure.main$load_script.invokeStatic(main.clj:275)
at clojure.main$init_opt.invokeStatic(main.clj:277)
at clojure.main$init_opt.invoke(main.clj:277)
at clojure.main$initialize.invokeStatic(main.clj:308)
at clojure.main$null_opt.invokeStatic(main.clj:342)
at clojure.main$null_opt.invoke(main.clj:339)
at clojure.main$main.invokeStatic(main.clj:421)
at clojure.main$main.doInvoke(main.clj:384)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:383)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: java.lang.ClassNotFoundException: man.ManGate
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at clojure.lang.DynamicClassLoader.findClass(DynamicClassLoader.java:69)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at clojure.lang.RT.classForName(RT.java:2168)
at clojure.lang.RT.classForNameNonLoading(RT.java:2181)
at man.core$eval20$loading__5569__auto____21.invoke(core.clj:1)
at man.core$eval20.invokeStatic(core.clj:1)
at man.core$eval20.invoke(core.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6927)
at clojure.lang.Compiler.eval(Compiler.java:6916)
at clojure.lang.Compiler.load(Compiler.java:7379)
... 42 more
我想知道这是否与名称空间的编译顺序有关。也许 leiningen 在 class man.ManGate
被创建之前正在处理 man.core
!?
编辑:
我可以通过改变实现接口的方式来解决我的问题:
(ns man.gateway
(:import [eu.m2machine.gw Gateway]))
(defn gateway []
(reify Gateway
(startup [this])
(shutdown [this]))
)
并且在命名空间 man.core 中,我将构造函数调用 ManGate.
替换为对 man.gateway/gateway
.
的调用
我仍然很想知道为什么上面的解决方案不起作用。
您 class 是在命名空间 man.gateway
中定义的,但它的完全限定 class 名称是 man.ManGate
。在 core.clj
和 gateway.clj
中将 FQCN 更改为 man.gateway.ManGate
应该可以解决问题。
我花了很多时间想办法解决类似的问题,我的 lein 本地存储库中有所需的 jar,但 lein run
总是因 ClassNotFoundException 而失败。结果是,尽管我已经在我的 project.clj
中定义了所需的依赖项,但我错过了 require
在我的文件中引用库方法的确切库。所以,这是一个非常愚蠢的 mistake.But,我把这个答案放在这里,以防万一,它对 Clojure 新手有帮助。
我正在尝试实现我正在使用的遗留 运行time 所需的 Java 接口,并实例化此实现的实例以将其传递给 运行time .但是当我 运行 lein uberjar
我看到一个例外,找不到 class。这两个名称空间都在同一个 leiningen 项目中定义,所以我本以为它们会看到彼此以及它们生成的 classes。
(ns man.core
(:require (man.gateway))
(:import (man ManGate)
(eu.m2machine.gw GatewayComponentFactory))
(:gen-class))
(defn -main [& args]
(let [starter (.starter (GatewayComponentFactory/get))
gateway (ManGate.)]
(.startup starter gateway)))
此代码尝试使用在同一项目中实现的 class:
(ns man.gateway
(:import [eu.m2machine.gw.text GatewayIDFormatter])
(:gen-class
:name man.ManGate
:implements [eu.m2machine.gw.Gateway]
:prefix "gateway-"))
(defn gateway-startup [this])
(defn gateway-shutdown [this])
接口需要的两个方法目前只有存根实现。在我编译代码后,他们会得到他们的代码。接口已定义(在添加为依赖项的工件中):
package eu.m2machine.gw;
public interface Gateway {
void startup();
void shutdown();
}
我得到的异常是:
Exception in thread "main" java.lang.ClassNotFoundException: man.ManGate, compiling:(man/core.clj:1:1)
at clojure.lang.Compiler.load(Compiler.java:7391)
at clojure.lang.RT.loadResourceScript(RT.java:372)
at clojure.lang.RT.loadResourceScript(RT.java:363)
at clojure.lang.RT.load(RT.java:453)
at clojure.lang.RT.load(RT.java:419)
at clojure.core$load$fn__5677.invoke(core.clj:5893)
at clojure.core$load.invokeStatic(core.clj:5892)
at clojure.core$load.doInvoke(core.clj:5876)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invokeStatic(core.clj:5697)
at clojure.core$load_one.invoke(core.clj:5692)
at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
at clojure.core$load_lib.invokeStatic(core.clj:5736)
at clojure.core$load_lib.doInvoke(core.clj:5717)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invokeStatic(core.clj:648)
at clojure.core$load_libs.invokeStatic(core.clj:5774)
at clojure.core$load_libs.doInvoke(core.clj:5758)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invokeStatic(core.clj:648)
at clojure.core$require.invokeStatic(core.clj:5796)
at clojure.core$require.doInvoke(core.clj:5796)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at user$eval5$fn__7.invoke(form-init2162986879369932757.clj:1)
at user$eval5.invokeStatic(form-init2162986879369932757.clj:1)
at user$eval5.invoke(form-init2162986879369932757.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6927)
at clojure.lang.Compiler.eval(Compiler.java:6917)
at clojure.lang.Compiler.load(Compiler.java:7379)
at clojure.lang.Compiler.loadFile(Compiler.java:7317)
at clojure.main$load_script.invokeStatic(main.clj:275)
at clojure.main$init_opt.invokeStatic(main.clj:277)
at clojure.main$init_opt.invoke(main.clj:277)
at clojure.main$initialize.invokeStatic(main.clj:308)
at clojure.main$null_opt.invokeStatic(main.clj:342)
at clojure.main$null_opt.invoke(main.clj:339)
at clojure.main$main.invokeStatic(main.clj:421)
at clojure.main$main.doInvoke(main.clj:384)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:383)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: java.lang.ClassNotFoundException: man.ManGate
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at clojure.lang.DynamicClassLoader.findClass(DynamicClassLoader.java:69)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at clojure.lang.RT.classForName(RT.java:2168)
at clojure.lang.RT.classForNameNonLoading(RT.java:2181)
at man.core$eval20$loading__5569__auto____21.invoke(core.clj:1)
at man.core$eval20.invokeStatic(core.clj:1)
at man.core$eval20.invoke(core.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6927)
at clojure.lang.Compiler.eval(Compiler.java:6916)
at clojure.lang.Compiler.load(Compiler.java:7379)
... 42 more
我想知道这是否与名称空间的编译顺序有关。也许 leiningen 在 class man.ManGate
被创建之前正在处理 man.core
!?
编辑:
我可以通过改变实现接口的方式来解决我的问题:
(ns man.gateway
(:import [eu.m2machine.gw Gateway]))
(defn gateway []
(reify Gateway
(startup [this])
(shutdown [this]))
)
并且在命名空间 man.core 中,我将构造函数调用 ManGate.
替换为对 man.gateway/gateway
.
我仍然很想知道为什么上面的解决方案不起作用。
您 class 是在命名空间 man.gateway
中定义的,但它的完全限定 class 名称是 man.ManGate
。在 core.clj
和 gateway.clj
中将 FQCN 更改为 man.gateway.ManGate
应该可以解决问题。
我花了很多时间想办法解决类似的问题,我的 lein 本地存储库中有所需的 jar,但 lein run
总是因 ClassNotFoundException 而失败。结果是,尽管我已经在我的 project.clj
中定义了所需的依赖项,但我错过了 require
在我的文件中引用库方法的确切库。所以,这是一个非常愚蠢的 mistake.But,我把这个答案放在这里,以防万一,它对 Clojure 新手有帮助。