当前位置: 首页 > 面试题库 >

如何直接从Java调用Clojure函数

孟昊空
2023-03-14
问题内容

我有Clojure功能generate-id

源代码:

(ns url62.core)
...
(defn generate-id []
  (int-to-base62 (java.math.BigInteger. (clojure.string/replace (str (java.util.UUID/randomUUID)) "-" "") 16)))
  • https://github.com/8protons/url62/blob/master/src/url62/core.clj

我需要从Java执行此功能。

我尝试使用这样的代码:

IFn generateId = Clojure.var("url62.core", "generate-id");
generateId.invoke(UUID.randomUUID());

但这不起作用:

java.lang.IllegalStateException: Attempting to call unbound fn: #'url62.core/generate-id

    at clojure.lang.Var$Unbound.throwArity(Var.java:43)
    at clojure.lang.AFn.invoke(AFn.java:32)
    at clojure.lang.Var.invoke(Var.java:379)

问题答案:

您忘记require了Clojure命名空间:

这是项目结构:

-rwxrwxr-x 1 alan alan  162 Sep 26 15:27 compile-run-java.bash*
-rwxrwxr-x 1 alan alan  439 Oct 19  2016 project.clj*
-rw-rw-r-- 1 alan alan  142 Sep 26 16:38 src/embedded_clojure/core.clj
-rw-rw-r-- 1 alan alan  586 Sep 26 15:21 src-java/mypkg/Main.java
-rw-rw-r-- 1 alan alan  125 Oct 19  2016 test/tst/embedded_clojure/core.clj

project.clj文件:

(defproject embedded-clojure "0.1.0-SNAPSHOT"
  :dependencies [
    [org.clojure/clojure "1.8.0"]
  ]
  :java-source-paths ["src-java"]
  :main embedded-clojure.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})

这是调用嵌入式Clojure函数的Java类:

package mypkg;
import clojure.java.api.Clojure;
import clojure.lang.IFn;
class Main {
  public static void main( String[] args ) {
    System.out.println( "Java Main.main()" );

    // clojure.core is automatically "required"; you don't need to
    IFn plus = Clojure.var("clojure.core", "+");
    System.out.println( "  plus: " + plus.invoke(1, 2) );

    // any other namespace needs to be "required"
    IFn require = Clojure.var("clojure.core", "require");
    require.invoke(Clojure.read("embedded-clojure.core"));

    IFn add  = Clojure.var("embedded-clojure.core", "add");
    System.out.println( "  add:  " +  add.invoke(2, 3) );
  }
}

Clojure文件:

(ns embedded-clojure.core
  (:gen-class))

(defn add [x y] (+ x y))

(defn -main [& args]
  (println "Clojure -main:  (add 4 5) =>" (add 4 5)))

Clojure测试文件:

(ns tst.embedded-clojure.core
  (:use embedded-clojure.core
        clojure.test))

(deftest simple-add
  (is (= 13 (add 6 7))))

运行脚本 compile-run-java.bash

#!/bin/bash  -v

lein clean
lein uberjar
# Use Java main()
java -cp /home/alan/demo/embedded-clojure/target/uberjar/embedded-clojure-0.1.0-SNAPSHOT-standalone.jar \
  mypkg.Main

# Use Clojure -main
java -cp /home/alan/demo/embedded-clojure/target/uberjar/embedded-clojure-0.1.0-SNAPSHOT-standalone.jar \
  embedded_clojure/core

现在我们可以从命令行运行:

 > ./compile-run-java.bash
#!/bin/bash  -v

lein clean
lein uberjar
Compiling 1 source files to /home/alan/demo/embedded-clojure/target/uberjar/classes
Compiling embedded-clojure.core
Created /home/alan/demo/embedded-clojure/target/uberjar/embedded-clojure-0.1.0-SNAPSHOT.jar
Created /home/alan/demo/embedded-clojure/target/uberjar/embedded-clojure-0.1.0-SNAPSHOT-standalone.jar
# Use Java main()
java -cp /home/alan/demo/embedded-clojure/target/uberjar/embedded-clojure-0.1.0-SNAPSHOT-standalone.jar \
  mypkg.Main
Java Main.main()
  plus: 3
  add:  5

# Use Clojure -main
java -cp /home/alan/demo/embedded-clojure/target/uberjar/embedded-clojure-0.1.0-SNAPSHOT-standalone.jar \
  embedded_clojure/core
Clojure -main:  (add 4 5) => 9

我们还可以lein用来运行Clojure -main或Clojure测试:

> lein test
lein test tst.embedded-clojure.core
Ran 1 tests containing 1 assertions.
0 failures, 0 errors.

> lein run
Clojure -main:  (add 4 5) => 9


 类似资料:
  • 从Clojoure调用Java非常简单明了,但反过来已被证明是不可预测的。 它们似乎有两种方式: 1)以下类别 2) 将clojure编译成uberjar,然后将其导入java代码。 我选择了第二个选项,因为它更直接。 这是clojure代码 这是Java代码。 当我做出“service.returned(4);”时,系统永远不会返回。我不太明白为什么对我来说,它会像函数没有从Clojure返回一

  • 问题内容: 对于“从Java调用Clojure”而言,大多数Google热门歌曲都已过时,建议您使用它clojure.lang.RT来编译源代码。假设您已经从Clojure项目构建了一个jar并将其包含在类路径中,那么您能否帮助您清楚地说明如何从Java调用Clojure? 问题答案: 从Clojure 1.6.0开始,有一种新的首选方式来加载和调用Clojure函数。现在,此方法优于直接调用RT

  • 问题内容: 我需要针对将返回零或一的数据库运行查询(检查是否存在特定条件)。我已获得审查的技术规范指出,我应该创建一个存储过程,该存储过程将返回单行,并带有称为“结果”的单列,该列将包含0或1的位值。我不确定存储过程将是最好的方法,但是不确定一点,所以我想请教您一些意见。我可以想到的两个选择是: 1:创建一个SQL标量值函数,该函数执行查询并返回一点。然后,可以使用“ TEXT” SqlComma

  • 问题内容: 我需要从Java调用C#函数,为此,我创建了以下代码。我有一个创建的Java头文件Authenticator.h,代码如下: 然后,我创建了一个身份验证的C#函数 然后,我尝试使用以下代码从C ++(项目创建dll)中调用C#函数; 最后创建一个需要从Java调用的dll。该dll已创建,并且可以在Java中很好地加载它,但是在Java中却收到此错误日志。我可能会错过什么。 问题答案:

  • 问题内容: 如何从C ++应用程序调用Java函数? 我知道从CMD(或类似技术)调用它们的方法,但我宁愿不使用它们。 问题答案: 例如,检查从C创建JVM。它显示了创建JVM和调用方法的示例过程。如果JVM已经存在;例如,您的C程序被Java程序调用(回调情况),则可以缓存JNIEnv *指针。 作为建议,请小心从C / C ++缓存指向JVM的指针,其中涉及到一些有关可以缓存的内容的语义,以后

  • 问题内容: 可以通过Java中的JNA接口调用C方法。我的问题是,如何使用Go达到相同的功能? 问题答案: 阅读有关Go Shared Libraries 的文档后 下面是一个简短的示例,可以集成Java Spring Batch中的调用Golang函数: Golang函数: 之后,执行命令生成二进制文件: 这将生成二进制文件: 最后,创建JNA类: 之后,从Main Java类中执行Result