leiningenで作るuberjarがmavenでできたらいいと思ったら出来なかった話
Leiningenでuberjarを作る
Clojureの日本語ガイドにあるように -> Part7: どのようにして Heroku へデプロイするか
Leiningenから lein uberjar
と打てばいわゆるFAT Jarができる。これは依存ライブラリを全て含んでいるのでJavaさえあれば実行できる。
Mavenからそれはできないか
似たようなものはできた。以下、設定したproject.clj
- 肝心な部分は
maven-shade-plugin
ManifestResourceTransformer
は Maven側でManifest.mfを書き換えて、実行するメインクラスを定めてくれるfinalName
- これを
${project.artifactId}-${project.version}-standalone
で設定すると、leiningenがデフォルトで出力するuberjarの名前になるハズ
- これを
実行は lein pom
してから mvn clojure:compile package
(defproject uber "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :uberjar-name "uber-clj.jar" :min-lein-version "2.5.3" :dependencies [[org.clojure/clojure "1.8.0"]] :pom-plugins [[com.theoryinpractise/clojure-maven-plugin "1.3.8" {:configuration ([:mainClass "uber.core"] [:sourceDirectories [:sourceDirectory "src/main/clj"]])}] [org.apache.maven.plugins/maven-shade-plugin "2.4.3" [:executions [:execution ([:phase "package"] [:goals [:goal "shade"]] [:configuration [:transformers [:transformer {:implementation "org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer"}] [:transformer {:implementation "org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer"}] [:transformer {:implementation "org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"} [:mainClass "uber.core"]] ] ;[:finalName "${project.artifactId}-${project.version}-standalone"] [:finalName "uber-clj"] [:filters [:filter [:includes [:include "**/*.js"] [:include "**/*.class"] [:include "**/*.xml"]]]]])]]]] :source-paths ["src/main/clj"] :test-paths ["src/test/clj"] :resource-paths ["resources"] :profiles {:dev {:env {:dev true }} :uberjar {:aot :all :main uber.core}})
動かない理由
ただし、この方法で作ったjarは動かない。それにはどうやらClojureのAOTコンパイルが関係しているらしい。
ClojureのAOTコンパイルは、タイムスタンプによってAOTコンパイル済みか判定する。maven-shade-pluginはこれをおかしくさせてしまうようだ。 むーん、maven-shade-pluginにプルリクする?
追記
簡単なスクリプト程度だと、Mavenから動かしても動くバイナリができるようだ。ringなどのライブラリを混ぜると動かない感じになる。