Calling clojure from java

前端 未结 9 1501
梦毁少年i
梦毁少年i 2020-11-22 11:13

Most of the top google hits for \"calling clojure from java\" are outdated and recommend using clojure.lang.RT to compile the source code. Could you help with a

9条回答
  •  谎友^
    谎友^ (楼主)
    2020-11-22 11:48

    If the use case is to include a JAR built with Clojure in a Java application, I have found having a separate namespace for the interface between the two worlds to be beneficial:

    (ns example-app.interop
      (:require [example-app.core :as core])
    
    ;; This example covers two-way communication: the Clojure library 
    ;; relies on the wrapping Java app for some functionality (through
    ;; an interface that the Clojure library provides and the Java app
    ;; implements) and the Java app calls the Clojure library to perform 
    ;; work. The latter case is covered by a class provided by the Clojure lib.
    ;; 
    ;; This namespace should be AOT compiled.
    
    ;; The interface that the java app can implement
    (gen-interface
      :name com.example.WeatherForecast
      :methods [[getTemperature [] Double]])
    
    ;; The class that the java app instantiates
    (gen-class
      :name com.example.HighTemperatureMailer
      :state state
      :init init
      ;; Dependency injection - take an instance of the previously defined
      ;; interface as a constructor argument
      :constructors {[com.example.WeatherForecast] []}
      :methods [[sendMails [] void]])
    
    (defn -init [weather-forecast]
      [[] {:weather-forecast weather-forecast}])
    
    ;; The actual work is done in the core namespace
    (defn -sendMails
      [this]
      (core/send-mails (.state this)))
    

    The core namespace can use the injected instance to accomplish its tasks:

    (ns example-app.core)
    
    (defn send-mails 
      [{:keys [weather-forecast]}]
      (let [temp (.getTemperature weather-forecast)] ...)) 
    

    For testing purposes, the interface can be stubbed:

    (example-app.core/send-mails 
      (reify com.example.WeatherForecast (getTemperature [this] ...)))
    

提交回复
热议问题