从 java 调用 clojure

2023-12-29

大多数“从 java 调用 clojure”的热门 google 搜索结果都已过时,建议使用clojure.lang.RT编译源代码。假设您已经从 Clojure 项目构建了一个 jar 并将其包含在类路径中,您能否帮助清楚地解释如何从 Java 调用 Clojure?


Update:自从发布这个答案以来,一些可用的工具已经发生了变化。在原始答案之后,有一个更新,包括有关如何使用当前工具构建示例的信息。

它并不像编译成 jar 并调用内部方法那么简单。不过,似乎确实有一些技巧可以让这一切发挥作用。下面是一个可以编译为 jar 的简单 Clojure 文件的示例:

(ns com.domain.tiny
  (:gen-class
    :name com.domain.tiny
    :methods [#^{:static true} [binomial [int int] double]]))

(defn binomial
  "Calculate the binomial coefficient."
  [n k]
  (let [a (inc n)]
    (loop [b 1
           c 1]
      (if (> b k)
        c
        (recur (inc b) (* (/ (- a b) b) c))))))

(defn -binomial
  "A Java-callable wrapper around the 'binomial' function."
  [n k]
  (binomial n k))

(defn -main []
  (println (str "(binomial 5 3): " (binomial 5 3)))
  (println (str "(binomial 10042 111): " (binomial 10042 111)))
)

如果运行它,您应该看到类似以下内容:

(binomial 5 3): 10
(binomial 10042 111): 49068389575068144946633777...

这是一个 Java 程序,它调用-binomial函数在tiny.jar.

import com.domain.tiny;

public class Main {

    public static void main(String[] args) {
        System.out.println("(binomial 5 3): " + tiny.binomial(5, 3));
        System.out.println("(binomial 10042, 111): " + tiny.binomial(10042, 111));
    }
}

它的输出是:

(binomial 5 3): 10.0
(binomial 10042, 111): 4.9068389575068143E263

第一个魔法是使用:methods中的关键字gen-class陈述。这似乎是让您访问 Clojure 函数所必需的,就像 Java 中的静态方法一样。

第二件事是创建一个可以被Java调用的包装函数。请注意,第二个版本-binomial前面有一个破折号。

当然,Clojure jar 本身必须位于类路径上。此示例使用 Clojure-1.1.0 jar。

Update:这个答案已经使用以下工具重新测试:

  • Clojure 1.5.1
  • 莱宁根2.1.3
  • JDK 1.7.0 更新 25

Clojure 部分

首先使用 Leiningen 创建一个项目和关联的目录结构:

C:\projects>lein new com.domain.tiny

现在,切换到项目目录。

C:\projects>cd com.domain.tiny

在项目目录中,打开project.clj文件并编辑它,内容如下所示。

(defproject com.domain.tiny "0.1.0-SNAPSHOT"
  :description "An example of stand alone Clojure-Java interop"
  :url "http://clarkonium.net/2013/06/java-clojure-interop-an-update/"
  :license {:name "Eclipse Public License"
  :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.5.1"]]
  :aot :all
  :main com.domain.tiny)

现在,确保所有依赖项 (Clojure) 均可用。

C:\projects\com.domain.tiny>lein deps

此时您可能会看到一条有关下载 Clojure jar 的消息。

现在编辑 Clojure 文件C:\projects\com.domain.tiny\src\com\domain\tiny.clj这样它就包含了原始答案中显示的 Clojure 程序。 (此文件是在 Leiningen 创建项目时创建的。)

这里的大部分魔力都在于命名空间声明。这:gen-class告诉系统创建一个名为com.domain.tiny使用一个名为的静态方法binomial,一个接受两个整数参数并返回一个双精度值的函数。有两个类似名称的函数binomial,一个传统的 Clojure 函数,以及-binomial和可从 Java 访问的包装器。注意函数名称中的连字符-binomial。默认前缀是连字符,但如果需要,可以将其更改为其他内容。这-main函数只是对二项式函数进行几次调用,以确保我们得到正确的结果。为此,请编译该类并运行该程序。

C:\projects\com.domain.tiny>lein run

您应该看到原始答案中显示的输出。

现在将其包装在罐子中并放在方便的地方。将 Clojure jar 也复制到那里。

C:\projects\com.domain.tiny>lein jar
Created C:\projects\com.domain.tiny\target\com.domain.tiny-0.1.0-SNAPSHOT.jar
C:\projects\com.domain.tiny>mkdir \target\lib

C:\projects\com.domain.tiny>copy target\com.domain.tiny-0.1.0-SNAPSHOT.jar target\lib\
        1 file(s) copied.

C:\projects\com.domain.tiny>copy "C:<path to clojure jar>\clojure-1.5.1.jar" target\lib\
        1 file(s) copied.

Java部分

Leiningen 有一个内置任务,lein-javac,这应该能够帮助Java编译。不幸的是,它似乎在 2.1.3 版本中被破坏了。它找不到已安装的 JDK,也找不到 Maven 存储库。两者的路径在我的系统上都嵌入了空格。我认为这就是问题所在。任何 Java IDE 也可以处理编译和打包。但对于这篇文章,我们将采用老式方法并在命令行中进行操作。

首先创建文件Main.java与原始答案中显示的内容。

编译java部分

javac -g -cp target\com.domain.tiny-0.1.0-SNAPSHOT.jar -d target\src\com\domain\Main.java

现在创建一个包含一些元信息的文件以添加到我们想要构建的 jar 中。在Manifest.txt,添加以下文本

Class-Path: lib\com.domain.tiny-0.1.0-SNAPSHOT.jar lib\clojure-1.5.1.jar
Main-Class: Main

现在将其全部打包到一个大 jar 文件中,包括我们的 Clojure 程序和 Clojure jar。

C:\projects\com.domain.tiny\target>jar cfm Interop.jar Manifest.txt Main.class lib\com.domain.tiny-0.1.0-SNAPSHOT.jar lib\clojure-1.5.1.jar

运行程序:

C:\projects\com.domain.tiny\target>java -jar Interop.jar
(binomial 5 3): 10.0
(binomial 10042, 111): 4.9068389575068143E263

输出基本上与单独使用 Clojure 生成的结果相同,但结果已转换为 Java double。

如前所述,Java IDE 可能会处理混乱的编译参数和打包。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 java 调用 clojure 的相关文章

  • 在Java中将*s打印为三角形?

    我在 Java 课程中的作业是制作 3 个三角形 一份左对齐 一份右对齐 一份居中 我必须为什么类型的三角形制作一个菜单 然后输入需要多少行 三角形必须看起来像这样 到目前为止 我能够完成左对齐的三角形 但我似乎无法获得其他两个 我尝试用谷
  • android.view.InflateException:二进制 XML 文件行 #11:膨胀类 ImageView 时出错

    我只是尝试制作一个小的 android java xml 应用程序来计算游戏的分数 它给了我这个错误 Error inflateing class ImageView 有人知道解决方案吗 我实际上搜索了 ppl 说添加这个 android
  • 如何使用 Maven Failsafe 插件运行 JUnit 5 集成测试?

    当我运行命令时 Maven Failsafe 插件找不到我的 JUnit 5 集成测试mvn clean failsafe integration test 尽管它可以找到文件 我有junit jupiter api and junit j
  • Quarkus 不以编程方式选择 bean

    我试图以编程方式选择 bean 但 quarkus 不会注入 bean 并引发异常 不支持吗 public enum ReportType ONE TWO Qualifier Retention RUNTIME Target METHOD
  • 尝试获取屏幕上绘制的每个随机圆圈的 x、y 坐标

    您好 我正在制作一款游戏 该游戏将在屏幕上创建随机圆圈 随机创建的圆圈的值为红色或绿色 我的问题是 我希望不仅能够确定用户何时单击其中一个圆圈 而且还能够确定他们最终单击的圆圈 红色或绿色 下面是我的代码 我的主要问题是试图找到将要绘制的圆
  • 具有 CRUD 功能的基于 Spring Web 的管理工具

    在 PHP Symfony 世界里有一个工具叫 Sonata Adminhttps sonata project org https sonata project org 基于 AdminLTE 模板 这是一款一体化管理工具 具有登录 菜单
  • OpenNLP 与斯坦福 CoreNLP

    我一直在对这两个包进行一些比较 但不确定该往哪个方向走 我简单地寻找的是 命名实体识别 人 地点 组织等 性别识别 一个不错的训练 API 据我所知 OpenNLP 和斯坦福 CoreNLP 提供了非常相似的功能 然而 Stanford C
  • 需要正则表达式帮助

    我正在尝试替换两次或多次出现的 br like br br br 标签与两个一起 br br 具有以下模式 Pattern brTagPattern Pattern compile lt s br s s gt s 2 Pattern CA
  • java.lang.Object的hashCode具体使用的算法是什么

    中使用的算法是什么JVM实施java lang Object的隐含的hashCode 方法 OpenJDK or Oracle JDK答案中首选 它依赖于实现 并且在很大程度上 该算法是entirely取决于实施 只要它是一致的 但是 根据
  • Java 中的 ExecuteUpdate sql 语句不起作用

    我正在学习如何将 SQL 与 Java 结合使用 我已成功安装 JDBC 驱动程序 并且能够从数据库读取记录并将其打印在屏幕上 我的问题发生在尝试执行更新或插入语句时 没有任何反应 这是我的代码 问题所在的方法 public static
  • 如何使用 swagger-codegen-plugin (maven) 生成客户端代码?

    我需要使用 swagger codegen plugin for maven 在 eclipse 中生成服务器存根代码 你能帮忙怎么做吗 以及需要什么配置 在 pom xml 中 我找到了这个答案 您只需要像下面这样更改 pom xml 即
  • 是否有最新的 Facebook Java SDK? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 好像没找到最近更新的 如果没有 是否有一个好的 Java 库来执行与 Facebook 的 API 交
  • 改变 Java 中凯撒移位的方向

    用户可以通过选择 1 向左或 2 向右移动字母来选择向左或向右移动 左边工作正常 右边不行 现在它显示了完全相同的循环 但我已经改变了所有 and 以不同的方式进行标记 最终我总是得到奇怪的字符 如何让程序将字符向相反方向移动 如果用户输入
  • Jetty Plugin 9启动不喜欢icu4j-2.6.1.jar

    我对 mortbay 的 Maven jetty 插件 6 有相同的配置
  • 在循环中按名称访问变量

    我正在开发一个 Android 项目 并且有很多可绘制对象 这些绘图的名称都类似于icon 0 png icon 1 png icon 100 png 我想将这些可绘制对象的所有资源 ID 添加到整数 ArrayList 中 对于那些不了解
  • Java和手动执行finalize

    如果我打电话finalize 在我的程序代码中的一个对象上 JVM当垃圾收集器处理这个对象时仍然再次运行该方法吗 这是一个大概的例子 MyObject m new MyObject m finalize m null System gc 是
  • Java:一个函数有多种返回类型...可以使用泛型吗?

    为了简单起见 我有一些程序 如下所示 public String fetchValueAsString String key public DateTime fetchValueAsDateTime String key 我想要类似的东西
  • 传递 Android DialogFragment 参数时,onCreateDialog 捆绑参数意外为 null

    我正在尝试使用 DialogFragment 在 Android 中显示一个基本对话框 并使用对话框消息的参数 如中所述StackOverflow线程 https stackoverflow com questions 15459209 p
  • 在 Freemarker 模板中检查 Spring 安全角色和记录的用户名

    有谁知道 freemarker 标签来检查 freemarker 文件中的 spring 安全角色和用户名 我从网络上的几个资源中发现以下代码将打印登录的用户名 但它没有打印用户名 而是打印 登录为
  • 如何使用 Jest 从 ElasticSearch 获取索引列表

    我正在尝试使用 Jest 检索索引列表 但我只得到 Stats statistics new Stats Builder build result client execute statistics 如何从结果中检索索引列表 除了统计之外

随机推荐

  • 在 Windows XP 中设置 Tomcat 服务的默认区域设置

    我已在 Windows XP 计算机中安装了 Apache Tomcat 6 作为服务 法语 我的问题是 Tomcat 本身和所有网络应用程序 Sonar 和 Hudson 现在显示法语消息 我当然想要英文消息 所以我进入控制面板中的 区域
  • 如何将 @State 值分配给另一个 viewModel 发布的属性

    如何将一个视图中的 State 值 secondaryMarked 分配给 Published SampleViewModel 属性 喜欢 SampleViewModel secondMarked 这是示例 struct ContentVi
  • 编译 openCV 代码时出现“函数未在此范围内声明”错误

    我正在尝试编写一些使用 openCV 函数的代码 我首先采用文档中提供的一些示例代码 include
  • VBScript 中的 XPath 计数

    我尝试使用 XPath 计数函数获取 XML 文件中特定节点的数量 但是 这不断返回错误 msxml3 dll 类型的异常 表达式不返回 DOM 节点 如何使用 VBScript 和 MSXML DOM 从 XPath 计数获取返回值 Di
  • 以数组为原型的 Javascript 对象成员由所有类实例共享

    以前有人注意到这种行为吗 这真的让我很失望 我本来期望原型数组对于每个类实例都是私有的 而不是在所有类实例之间共享 有人可以验证这是正确的行为 并且也许可以更详细地解释这种行为吗 请注意注释的代码以及它如何影响脚本的行为
  • 有没有好的交互式 3D 图形库?

    我正在寻找一个库 它将以 3D 方式布局和显示图形 即网络图 而不是图表 并具有一些交互性 例如选择和拖动节点 旋转显示等 我想在网页中执行此操作 因此 Javascript或 Flash 更好 我也会考虑 Java 自我审视后 我意识到选
  • Action<>多参数语法说明

    有时我无法理解最简单的事情 我确信它就在我的脸上 只是我看不到它 我尝试为这个简单类中的方法创建委托 public static class BalloonTip public static BalloonType BalType get
  • Linux下Git克隆fsync输入/输出错误

    我正在尝试克隆张量流 模型存储库 我通过 ssh 连接到远程计算机 我尝试了很多解决问题的建议 但没有一个对我有用 git clone recursive https github com tensorflow models git Clo
  • Firebase 云消息传递是否需要服务器?

    我目前正在开发一个 Android 应用程序 我想包含 Firebase Cloud Messaging 我计划让 Raspberry Pi 每 5 分钟左右检查一次网站 并在发生变化时发送推送通知 在官方文档中 他们说我需要一个 应用程序
  • 检查 Pandas 数据框是否存在异常值[重复]

    这个问题在这里已经有答案了 传感器图 https i stack imgur com OahnS png 我对包含 8 个电极的传感器进行了实验 上图是电极输出与时间的关系图 正如您在图中看到的 8 个电极之一显然是异常值 可能是由于某些电
  • -ObjC 链接器标志有什么作用?

    我有一个可以使用和不使用链接器标志的应用程序 但是 如果没有链接器标志 向视图添加数据时我会得到非常不同的行为 该标志使链接器加载库中定义 Objective C 类或类别的每个目标文件 虽然此选项通常会导致更大的可执行文件 由于将额外的目
  • 迭代加深 A Star (IDA*) 在 Java 中解决 n-puzzle(滑动拼图)

    我已经实现了一个能够解决这个问题的程序n 拼图问题 http en wikipedia org wiki Fifteen puzzle与 A 由于状态空间太大 我无法预编译它 我必须在运行时计算可能的状态 通过这种方式 A 对于 3 谜题来
  • 错误:我的所有函数都出现“函数的隐式声明...”

    这是代码 main short sMax SHRT MAX int iMax INT MAX long lMax LONG MAX Printing min and max values for types short int and lo
  • 如何在 py.test 中显示警告

    我刚刚跑了py test http pytest org在我的代码上并得到以下输出 6 passed 2 pytest warnings in 40 79 seconds 但是 我看不到什么py test想警告我一下 如何打开控制台的警告输
  • 带蓝牙麦克风的 Android 语音识别器

    我一直在编写一个与蓝牙耳机 耳机配合使用的聊天应用程序 到目前为止 我已经能够通过蓝牙耳机中的麦克风录制音频文件 我已经能够使用 Android 设备的内置麦克风 使用 RecogniserIntent 等实现语音转文本功能 但我找不到让
  • 从 JSON 文件推断字符串文字类型

    我正在读取一个大的 JSON 文件 TypeScript 足够智能推断类型所有属性中除了一个 一个简化的例子 type Animal bear cat dog const data name Max age 3 animal dog 100
  • Control.BeginInvoke 的 MethodInvoker 与 Action

    哪个更正确 为什么 Control BeginInvoke new Action DoSomething null private void DoSomething MessageBox Show What a great post or
  • 一个用户的访问控制允许来源错误

    我有一个 WCF 服务与另一个 Web 应用程序托管在同一服务器上 但端口不同 Web 应用程序使用 jQuery 在 WCF 服务上执行 get post 请求 在配置 WCF 服务以允许跨源请求后 它可以正常工作并符合预期 一个问题是有
  • 如何取消 Alamofire 共享管理器中的所有请求

    如何取消Alamofire共享管理器中的所有请求 这是我的功能 class func cancelAllRequests Alamofire Manager sharedInstance session getTasksWithComple
  • 从 java 调用 clojure

    大多数 从 java 调用 clojure 的热门 google 搜索结果都已过时 建议使用clojure lang RT编译源代码 假设您已经从 Clojure 项目构建了一个 jar 并将其包含在类路径中 您能否帮助清楚地解释如何从 J