Clojure+Java 使用 deps.edn 混合构建

简述

  公司有一个项目我用 clojure 写了一个数据处理的 SDK,里面混合了 Java 和 Clojure 的代码,之前用习惯了 Leiningen,不过慢慢的感觉 Leiningen 越来越慢了(不知道是不是错觉),这次打算使用 deps.edn 管理项目。

环境准备(包含开发工具相关的包)

  • windows: 建议使用 scoop 进行软件的安装
  • linux: 建议使用 mise
  • macos: 那肯定是使用 brew 啦, 当然也可以用 mise

# windows
PS> scoop install openjdk
PS> scoop install clojure
PS> scoop install clojure-lsp
PS> scoop install clj-deps

# mise
$ mise install java
$ mise install clojure
$ sudo bash < <(curl -s https://raw.githubusercontent.com/clojure-lsp/clojure-lsp/master/install)

# macos
$ brew install openjdk
$ brew install clojure
$ brew install clojure-lsp/brew/clojure-lsp-native

添加 deps.edn 文件

添加 deps.edn 文件,并添加 tools.build 依赖


{:deps      {org.clojure/clojure    {:mvn/version "1.11.3"}}

 :paths     ["src/main/clojure", "src/main/java", "src/main/resources", "src/test/clojure"]

 :aliases   {:build {:deps       {io.github.clojure/tools.build {:mvn/version "0.10.5"}}
                     :ns-default build}}}

添加 build.clj 文件

在项目根目录添加 build.clj 用于项目构建


(ns build
  (:require [clojure.tools.build.api :as b])
  (:import java.io.File))


(def lib 'io.github.leejoker/your-package-name)
(def version "1.0.0")
(def class-dir "target/classes")
(def basis (delay (b/create-basis {:project "deps.edn"})))
(def jar-file (format "target/%s-%s.jar" (name lib) version))
(def uber-file (format "target/%s-%s-standalone.jar" (name lib) version))

(defn clean [_]
  (b/delete {:path "target"}))

(defn copy-src [_]
  (b/copy-dir {:src-dirs   ["src/main/clojure" "src/main/resources"]
               :target-dir class-dir}))

(defn compile-java [_]
  (if (not-empty (.listFiles (File. "src/main/java")))
    (b/javac {:src-dirs   ["src/main/java"]
              :class-dir  class-dir
              :basis      @basis
              :javac-opts ["--release" "11"]})
    (println "java file not found")))

(defn compile-clojure [_]
  (b/compile-clj {:basis      @basis
                  :ns-compile '[io.github.leejoker.app] ;; 需要暴露的ns,用于生成提供static方法的类
                  :class-dir  class-dir}))

(defn compile-all [_]
  (clean nil)
  (b/write-pom {:class-dir class-dir
                :lib       lib
                :version   version
                :basis     @basis
                :src-dirs  ["src/main/clojure"]})
  (copy-src nil)
  (compile-java nil)
  (compile-clojure nil))

(defn jar [_]
  (compile-all nil)
  (b/jar {:class-dir class-dir
          :jar-file  jar-file}))

(defn uber [_]
  (compile-all nil)
  (b/uber {:class-dir class-dir
           :uber-file uber-file
           :basis     @basis
           :main      'io.github.leejoker.app})) ;; 向jar包中添加main-class信息,如果是SDK其实可以没有

这样就基本上完成了。

使用 clj 命令进行编译


# 清理 target 目录
$ clj -T:build clean

# 编译java文件
$ clj -T:build compile-java

# 编译clojure文件
$ clj -T:build compile-clojure

# 编译所有文件
$ clj -T:build compile-all

# 编译不含依赖的jar
$ clj -T:build jar

# 编译fat jar
$ clj -T:build uber

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3190 引用 • 8214 回帖 • 1 关注
  • Clojure
    3 引用 • 3 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...