本文介绍了如何直接从 Java 调用 Clojure 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 Clojure 函数 generate-id.

I have Clojure function 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
  • 我尝试过这样的代码:

    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 命名空间:

    You forgot to require the Clojure namespace:

    这是项目结构:

    -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类:

    Here is the Java class that calls the embedded Clojure function:

    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 文件:

    Clojure file:

    (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 测试文件:

    Clojure test file:

    (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
    

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

    and now we can run from the command line:

     > ./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 测试:

    We can also use lein to run the Clojure -main or the Clojure tests:

    > 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
    

    这篇关于如何直接从 Java 调用 Clojure 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 23:31