Clojure菜鸟。我无法获得:gen-class工作的基本示例。
$ lein new app pizza-parlor; project.clj
(defproject pizza-parlor "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
:url "https://www.eclipse.org/legal/epl-2.0/"}
:dependencies [[org.clojure/clojure "1.10.1"]]
:main ^:skip-aot pizza-parlor.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all
:jvm-opts ["-Dclojure.compiler.direct-linking=true"]}}); src/pizza_parlor/Deliverator.clj
(ns pizza-parlor.Deliverator
(:gen-class))
(defn -deliver [pizza]
(println "pipin' hot"))$ lein repl
pizza-parlor.core=> (require 'pizza-parlor.Deliverator)
nil
pizza-parlor.core=> (def d (pizza-parlor.Deliverator.))
Syntax error (ClassNotFoundException) compiling new at (/tmp/form-init10318668819087633543.clj:1:1).
pizza-man.Deliverator
pizza-man.core=> (import pizza-parlor.Deliverator)
Execution error (ClassNotFoundException) at java.net.URLClassLoader/findClass (URLClassLoader.java:435).
pizza-parlor.Deliverator我尝试了project.clj中的:aot选项,并在target/default中运行lein compile来生成类,但我得到了相同的错误。
通过gen-class定义Java类,然后将其与项目代码的其余部分一起使用,或者使用lein test运行的测试,正确的方法是什么
发布于 2021-03-11 14:06:48
您误解了如何在REPL中执行函数。
您不需要在Clojure中“创建类”。只需启动一个repl并调用一个函数。有几种选择:
(ns demo.core
; (:gen-class) ; uncomment to make runnable JAR file
)
(defn -main []
(println "main - enter")
)正如注释所说,如果您想创建一个可执行的JAR文件,那么您只需要ns表单中的(:gen-class)表达式。
方法一:切换到所需的命名空间,运行函数:
~/expr/demo > lein repl
demo.core=> (in-ns 'demo.core) ; single-quote is required
demo.core=> (-main)
main - enter方法2:只需使用完全限定的符号调用函数:
~/expr/demo > lein repl
demo.core=> (demo.core/-main) ; no quote!
main - enter这将仅适用于由表达式标识的"main“名词
:main demo.core在project.clj中。
方法3:请求名称空间,然后使用完全限定的符号调用函数:
> lein repl
demo.core=> (require 'demo.core) ; single-quote is required
demo.core=> (demo.core/-main)
main - enter这将适用于任何名称空间,即使是demo.core,如果REPL将您放在user名称空间中。
方法#4:构建一个可执行的uberjar
您必须确保(:gen-class)出现在(ns ...)表单中,并且您的project.clj中有:main demo.core。然后
~/expr/demo > lein uberjar
Created /home/alan/expr/demo/target/uberjar/demo-art-0.1.0-SNAPSHOT.jar
Created /home/alan/expr/demo/target/uberjar/demo-art-0.1.0-SNAPSHOT-standalone.jar
~/expr/demo > java -jar /home/alan/expr/demo/target/uberjar/demo-art-0.1.0-SNAPSHOT-standalone.jar
main - enter如果您看到如下错误消息:
~/expr/demo > java -jar /home/alan/expr/demo/target/uberjar/demo-art-0.1.0-SNAPSHOT-standalone.jar
Error: Could not find or load main class demo.core
Caused by: java.lang.ClassNotFoundException: demo.core然后,您忘记了在ns表单中包含(:gen-class)。
在这里查找more details on gen-class。
更新
如果您真的想从Clojure代码中创建一个Java类,则需要使用函数 gen-class, ns表达式。请参见:
更新#2
您真的需要从Clojure代码生成Java类吗?只在*.java源代码文件中编写一个Java类可能会更容易。Leiningen完全能够将Clojure和Java的混合源代码编译成单个可执行文件。这可能是最简单的方法。
发布于 2021-03-11 18:10:57
你必须注意你的名字/文件夹里面有一个破折号的-。
"some- clojure - namespace“的clojure命名空间将对应于java世界中的"some_clojure_namespace”(以及文件夹结构)。
所以在你的特殊情况下:
; src/pizza-parlor/Deliverator.clj
(ns pizza-parlor.Deliverator应该在"pizza_parlor“文件夹中,所以:
; src/pizza_parlor/Deliverator.clj
(ns pizza-parlor.Deliverator然后
(ns pizza-parlor.Deliverator)
将对应于(java)导入:
(import pizza_parlor.Deliverator)
(请注意此处的下划线)
但正如@Alan Thompson所说,您不需要在clojure中创建类并导入它们。您可以请求名称空间,并按照他所描述的方式调用它。如果必须与Java库或其他库进行互操作,则主要需要生成java类并导入它们。
您还可以直接使用gen-class来生成所需的任何Java类,请参阅许多示例here
https://stackoverflow.com/questions/66573386
复制相似问题