Scala使いがまともなJava開発環境を模索する

まずはじめに、私はJavaが嫌いです。色々な意見があると思いますが、私は嫌いです。嫌いですが、仕事だとJavaを使えというお達しが良く来るので嫌々Javaを使っています。このとき、「Scalaならこう書けるのに…」「Playだったら…」「ScalikeJDBCなら…」「Scalatraなら…」「sbtなら…」「json4sなら…」などとよくぐちぐちと考えてしまうのですが、その苦しみを少しでも和らげるためにJava開発環境で2016年7月現在一番まとも(オレオレ基準)と思われる環境を模索してみました。

ただ、模索しただけで実業務で本当にこれでうまくいったかという検証はしていないですし、私自身がそもそも「Java嫌い」という立ち位置からスタートしているのでJava関連技術をほとんど知らなかったりとなんだか無茶苦茶な前提ではあります。ですので、この記事の内容を「これが最先端のJava環境や!!」みたいには思わないでください(そんなこと思う人は居ないだろうけど)。

同じようにScalaが好きなのだけどJavaで書くのはしんどい、Javaで書きたくない…でも書かなきゃいけない…と悩んでいる方の参考になればと思って書いてみました。ようはただのメモみたいなもんです。

使うライブラリ等

  • SpringBoot(Webフレームワーク)
  • ScalikeJDBC4J
  • Typesafe Config
  • Thymeleaf
  • Lombok
  • JUnit
  • Maven

それぞれ選定理由などを書いてみます。

SpringBoot

弊社の一番のJava使いな先輩に聞いてみましたところ、「今だったらSpringBootかDropwizard」とのことでした。SpringBootの方が情報が多そうなこと、アイコンが可愛いことなどの理由によりこちらを選びました。エンプラ系ではまだまだTomcatを使うことも多いですが、SpringBootならばFat jarからの起動とwarとしてのパッケージング、どちらにも対応できます。

SpringBootはScala贔屓Java嫌いの私からみても中々良さげなフレームワークで、jsonデータをPOJOオブジェクトにマップしたりその逆をやったりとかが非常にシンプルかつ直感的に書けます。アノーテーションを使ってインジェクションするスタイルも慣れればまぁ悪くない気がします。コードは汚いと思いますが1

ScalikeJDBC4J

Twitterで「SpringJDBCしんどい」とつぶやいたところ開発者の瀬良(@seratch)さんさんが教えてくれました。少しScalaコードが混じってしまいますが2、Spring(boot)でScalikeJDBCが使えます。Javaから使うためのラッパークラス等が色々入ってるみたい?です。

Spring JDBCも悪くは無いと思うのですが、RowMapperを定義するのが面倒なこと、トランザクション処理が隠ぺいされていて気持ち悪く、複雑な処理をしようと思った時にやり方を調べるのが面倒なこと、クエリを動的に組み立てる方法が良くわからない、などから避けました。ちゃんと調べれば各々解決方法があるのかもしれませんが、ちょっとそこまで調べるためのエネルギーが無いです。

ScalikeJDBCにしたのは、Scalaコードがちょっと入るので、「ちょっと入る」からScala使いを徐々に組織内に浸透させていきたいという政治的な理由もあります。

ちなみに我社ではMirage SQLのような2way-sqlが人気で、誰かが作ったライブラリがいくつかあり皆それを使っている(実は私もScalaのParser Combinatorで作った)のですが、あのBEGINとかIFとかいう記法がどうも好きになれません。このあたりは好みの問題もあるでしょう。

Typesafe Config

Typesafe Configだと設定ファイルがかなり柔軟に書けるためです。複数行文字列を格納できたり、時間を柔軟に書けたり、Jsonっぽく書けたりなどなどできます。ただ、SpringBoot自体がこれに対応しているわけではなく、完全に切り替えることは不可能なので通常のapplication.propertiesと併存することになります。すると二つの設定ファイルを管理せねばならず、後々管理の手間が増えそうなのでもしかしたら使わない方が良いかもしれません。

Thymeleaf

テンプレートエンジン。「フロントはAngularとかReactで作る」という場合も増えてきたと思いますが…。

テンプレートエンジンは個人的にTwirlが何でも出来るしテストも簡単なので好きなのですが、「ビューで何でも出来るとい設計がそもそもの間違い」という意見も同意できるところですし、ビルドツールにmavenを使う(後述)とちょっとコンパイルするのが面倒くさそうでした。

Thymeleafの良いところはモックとして静的に構築されたHTMLがあればそれを最大限流用できるという点だと思います。逆に悪い点はテンプレートとして完全に正しい(validな)xmlを構築しなければならないということでいささか書き方が面倒だったり、HTML/XML以外への応用ができなかったりということがあったのですが、Ver.3.0からは改善されたそうです。しかしながらSpringBootの最新リリース版である1.3系ではThymeleaf 3.0に対応していなかったりとちょっと面倒です。この記事が公開されているころにはもしかしたらSpringBoot 1.4がリリースされているかもしれませんが。

Lombok

GetterとかSetterとかhashCodeとかequalsとかをいい感じに実装してくれるプラグイン。型推論っぽい何かも使うことが出来る。Java使いならお馴染み?

Getter/SetterとかはIDEで自動生成できるじゃん、と言われそうですが、そもそもボイラープレートがマスターのソースコードにあるということ自体が気にくわない。

JUnit

テストフレームワーク。個人的にshould beとかいうDSLっぽい書き方が嫌いで、assertをゴリゴリ書いてくほうが分かりやすいと思ってるし、まあみんな使い慣れてるので。結局assertが一番わかり易いっすよ。

Maven

pom.xmlが個人的にまだまだXML地獄感あるのだけど、SpringBootでsbt使うのは色々しんどそうなのでsbtはまずパス。するとGradleとかも候補となるのだけど、正直Gradleが良くわかってないし、ネットで色々ググってもpom.xmlの書き方は必ず出てくるがGradleはそうでもないし、ググらなくても理解できるほどGradleの学習を進めるモチベーションも無いので我慢してmaven。

参考情報

上記で書いたことはほぼそのまま下記のサンプルでやっていることに等しいです。というか、このサンプルプロジェクトの真似みたいなもんです。

spring-boot-scalikejdbc4j-sample

実業務適用してみる

で、上記の組み合わせでちょっと業務で使ってみようと思います。ダメなところは改めてなんとかJavaでマシな開発ができるよう頑張っていきたい。


  1. PlayもInjectionを使うようになりましたが、同じように汚いと思ってます。使ってれば慣れるとは思いますけど。 
  2. しまいますと書くとデメリットのように感じますが、クエリを書くようなところはScalaで書けた方が楽でしょう