[連載]Clojureで作るAPIの6記事目です。
前回の記事はこちらです。
この記事ではビルドしてJARファイルを生成し、 java
コマンドでアプリケーションを実行できるようにしていきます。
JARファイルとは
まずJARファイルとは、Javaのライブラリやアプリケーションを配布するためにJavaクラスファイル、メタデータ、リソース(textや画像など)を1つのファイルにまとめた物です。
詳細については英語版のWikipediaをご覧ください。
JARファイルの他に uberjar
という言葉もありますが、これは実行に必要な全てのファイルやデータを含んだJARファイルを指します。
アプリケーションを実行するためには、uberjarであった方が都合がいいため、この先はJARファイルという言葉をubarjarであるという前提のもとで使用します。
tools.buildを使う
この目的のためにtools.buildというClojure公式ライブラリがあります。こちらを使っていきましょう。
基本的に公式サイトに載っている使い方の通りにやればうまくいきます。
まずライブラリを :build
というaliasに追加します。
;; ./deps.edn {:paths ["src"] :deps {org.clojure/clojure {:mvn/version "1.11.1"} info.sunng/ring-jetty9-adapter {:mvn/version "0.17.6" :exclusions [org.slf4j/slf4j-api]} spootnik/unilog {:mvn/version "0.7.30"} com.stuartsierra/component {:mvn/version "1.1.0"}} :aliases {:dev {:extra-paths ["dev"]} :build {:deps {io.github.clojure/tools.build {:git/tag "v0.8.2" :git/sha "ba1a2bf"}} :ns-default build}}}
次に build.clj
にビルドスクリプトを用意します。
;; ./build.clj (ns build (:require [clojure.tools.build.api :as b])) (def class-dir "target/classes") (def basis (b/create-basis {:project "deps.edn"})) (def uber-file "target/cljapi.jar") (defn uber [_] (b/copy-dir {:src-dirs ["src" "resources"] :target-dir class-dir}) (b/compile-clj {:basis basis :src-dirs ["src"] :class-dir class-dir}) (b/uber {:class-dir class-dir :uber-file uber-file :basis basis :main 'cljapi.core}))
最後にmain関数となる cljapi.core/-main
を実行できるようにするために、このnamespaceをクラスとして生成させます。
そのためには :gen-class
をつけます。
;; ./src/cljapi/core.clj (ns cljapi.core (:gen-class) (:require [cljapi.system :as system])) (defn -main [& _args] (system/start))
ここまで記述できたら clojure -T:build uber
を実行すれば実行可能なJARファイルを生成できます。
$ clojure -T:build uber # targetディレクトリにJARファイルが生成されました。 # 中身を見てみます。 $ cd target $ tree -L 3 . ├── classes │ ├── cljapi │ │ ├── component │ │ ├── core$_main.class │ │ ├── core$fn__1158.class │ │ ├── core$loading__6789__auto____140.class │ │ ├── core.class │ │ ├── core.clj │ │ ├── core__init.class │ │ ├── system$fn__1153.class │ │ ├── system$loading__6789__auto____142.class │ │ ├── system$new_system.class │ │ ├── system$start.class │ │ ├── system$stop.class │ │ ├── system.clj │ │ └── system__init.class │ ├── com │ │ └── stuartsierra │ └── ring │ ├── adapter │ ├── core │ └── util └── cljapi.jar
実行して確認してみましょう。
$ java -jar target/cljapi.jar # 別のterminalでcurlしてみる $ curl http://localhost:8000 Hello, Clojure API
Makefileに追記
オプションを覚えるということはしたくないので、Makefileにも追記しておきます。
# ./Makefile .PHONY: format format: cljstyle check .PHONY: lint lint: clj-kondo --lint src .PHONY: static-check static-check: format lint .PHONY: clean clean: rm -fr target/ .PHONY: build build: clean clojure -T:build uber
おわりに
ここまでで、単一のJARファイルを生成して java
コマンドでアプリケーションを起動できるようになりました。
コードはGitHubのリポジトリに上げてあります。 06_ビルドして実行できるようにするというタグからご覧ください。
次は設定を外部ファイルで管理できるようにして、開発環境、ステージング環境、本番環境で値を変えられるようにしていきます。
トヨクモでは一緒に働いてくれる技術が好きなエンジニアを募集しております。