IntelliJ IDEAハンズオン――基本操作からプロジェクト管理までマスター

技術評論社さんから今井さんと山本ユースケさんのIntelliJ本をお送りいただきました。ありがとうございます!ScalaIOのためしばらく留守にしていたので受け取りが遅くなってしまったのですが、この週末にざっと目を通してみました。

ページ数は200ページちょっとでスクリーンショットが多くなりがちなIDEの本としてはさほど多くないのですが、IntelliJは機能の豊富さの割に覚えることが少なくて、基本的な部分だけ押さえておけばいろんな機能を使えるという感じがあります。この本の構成や分量にもそれが現れているのではないかと思います。

全体的には入門者向けの本ではあると思うのですが、普段IntelliJを使っている自分でも知らない機能や設定、ショートカットがちょこちょこあったりして眺めているだけでも結構楽しいです。データベース機能やChrononを使用したデバッグなど、Ultimateの販促コンテンツ(?)もあります。

特に序盤の補完機能については自分もあまり使いこなせていないなぁと思いましたが、IntelliJではCTRL+SPACE(コード補完)とSHIFT×2(なんでも検索)、Command+F12(クイックアウトライン)、ALT+ENTER(クイックフィックス)くらいを覚えておけばそれなりに便利なので、細かい便利機能をなかなか覚えられないんですよねw この本でIntelliJをさらに使いこなしていきたいと思います。

Scalatra 2.6.0をリリースしました

Scala用のSinatraライクなWebフレームワークScalatraの最新バージョン2.6.0をリリースしました。

github.com

今回は新しいバリデーションフレームワークとしてscalatra-formsが追加されました。これは元々GitBucketで使用していたものをScalatra本体の1モジュールとして取り込んだものです。PlayのFormのような感じでリクエストパラメータのバリデーションとScalaオブジェクトへのマッピングを行うことができます。

また、今後のメンテナンスコスト削減のために2.5.x以前のバージョンで非推奨になっていた機能を削除するとともに、あまり使われていない機能やメンテナンスが難しい機能などを非推奨にしています。これらの機能は2.7.0で廃止される予定です。

詳細な変更内容は以下のアナウンスを参照していただければと思います。 http://scalatra.org/2017/11/11/2017-11-11-scalatra-2-6-0-released.html

今回は@magnolia-kさんにコミッタになっていただいてから初めてのリリースだったのですが、ドキュメントやサンプル、sbtプラグインの修正など、自分が見落としていた部分をかなりカバーしていただきました。また、@xuwei-kさんにも多くのプルリクエストをいただきました。ありがとうございました。

次の2.7.0では非推奨機能の廃止に加えてSwagger 3.0のサポートなどを予定しています。

次期Scalatraのバックエンドとしてのhttp4s

Scalatraの次期バックエンドをhttp4sにしようという計画は数年前からありつつ中々進んでいなかったのですが(ブランチに途中まで試みたと思われる残骸があるのですが、そもそもScalatraの開発自体が停滞しており絶賛放置されていました)、そろそろやってみようかと思いhttp4sを触り始めています。

github.com

http4sとは?

http4sはいわゆるノンブロッキングなHTTPツールキットで、今だとAkka HTTPが競合になるかと思います。http4sはAkka HTTP同様ルーティング用のDSLも備えていて単体でシンプルなWebフレームワークとして使用することもできます。

http4sの特徴の1つとして、http4s用に開発したアプリケーション(http4sではサービスと呼びます)を、サーブレットとして動かすためのアダプタが用意されているという点があります。現在ScalatraはサーブレットベースのWebフレームワークであることで、

といったメリットがあります。これらは既存のJavaベースのシステムに部分的にScalaを導入して行く際に便利なのですが、バックエンドをhttp4sに移行することでサーブレットを使うか、ハイパフォーマンスなblaze(fs2)を使うかを選択することができるようになり、Scalatraの活用の幅がより広がるのではないかと思います。

http4sを動かしてみる

http4sのサービスはこんな感じで実装します(最新のマイルストーンビルドである0.18.0-M5を使用しています)。

package com.example.http4squickstart

import cats.effect.IO
import io.circe._
import org.http4s._
import org.http4s.circe._
import org.http4s.dsl.Http4sDsl

object HelloWorldService extends Http4sDsl[IO] {
  val service = HttpService[IO] {
    case GET -> Root / "hello" / name =>
    Ok(Json.obj("message" -> Json.fromString(s"Hello, ${name}")))
  }
}

blazeで動かす場合はこんな感じ。

package com.example.http4squickstart

import cats.effect.IO
import org.http4s.dsl.Http4sDsl
import org.http4s.server.blaze.BlazeBuilder
import org.http4s.util.StreamApp

object BlazeServer extends StreamApp[IO] with Http4sDsl[IO] {
  def stream(args: List[String], requestShutdown: IO[Unit]) =
    BlazeBuilder[IO]
      .bindHttp(8080, "0.0.0.0")
      .mountService(HelloWorldService.service, "/")
      .serve
}

サーブレットで動かす場合はこんな感じのリスナーを作っておけばOKです。これをxsbt-web-pluginで実行したり、warにしてサーブレットコンテナにデプロイする感じかと思います。

package com.example.http4squickstart

import javax.servlet.annotation.WebListener
import javax.servlet.{ServletContextEvent, ServletContextListener}
import org.http4s.servlet.syntax.ServletContextSyntax

@WebListener
class Bootstrap extends ServletContextListener with ServletContextSyntax {
  override def contextInitialized(sce: ServletContextEvent) = {
    val context = sce.getServletContext
    context.mountService("helloService", HelloWorldService.service)
  }
  override def contextDestroyed(sce: ServletContextEvent) = ()
}

まだ細かいところまで見れていませんが、同じサービスがバックエンドを変えても動作することが確認できました。

http4sは国内ではだいぶマイナー感がありますが、Typelevelプロジェクトの1つ(まだIncubatorですが)ということもあり、海外ではそこそこ使われている気配があります。今のところ開発も活発ですが、Scalatraのバックエンドに採用したものの、肝心のhttp4sの開発が止まってしまうと厳しいので、そのあたりの様子も見つつ本当に移行できるかどうかを検討していきたいと思います。

ScalaIO 2017に参加してきました

f:id:takezoe:20171107031414j:plain

11月2日、3日にフランスのリヨンで開催されたScalaIO 2017にスピーカーとして参加してきました。このエントリでは参加したセッションの中から印象に残ったものを紹介したいと思います。

Compiling like a boss!

Scalaで分散コンパイルによるコンパイル速度の高速化を実現するHydraのセッション。事前のスケジュールではTriplequoteのお二方でのトークとなっていましたが、Iulianさんは不在でMircoさん単独でのトークでした。

ScalaDaysでのセッションとほとんど同じ内容だったと思いますが、今回のプレゼンテーションではIntelliJでのサポートが利用可能になる、Hydraのモニタリングが可能になるという2点のアップデートがありました。以下のスライドは今年のScalaDaysで使用したもののようですが、上記二点のアップデート以外は今回も同じ内容のものだったと思います。

Move fast and fix things

Scala Italyの主催者でもあるbuildoのGabriele PetronellaさんによるScalafixのセッション。

Scalafixのコンセプトや、内部でどのようなことをしているのかがわかりやすく説明されていました。ScalametaがASTだけでなくソースコードの情報も持っているので、単にプログラムをASTで操作するだけでなく、コメントを残して部分的にパッチをあてたりできるというところが面白かったです。

The Making of an IO

SlamDataのDaniel SpiewakさんによるIOモナドの話…だったのですが、Scalaz7のTaskを壮絶にディスった後cats-effectの紹介をするという流れでした。スレッドプールをどう分けるべきか、どのくらいのスレッドを割り当てるべきかの指針も示されていました。

Danielさんが異常にハイテンションかつオーバーアクションでステージを常に動き回っているのが印象的でした。早口だったので聞き取れない部分も多かったのですが、とにかく勢いがあり、時間の経過をわすれさせる熱量がありました。

The Design of the Scalaz 8 Effect System

こちらはSlamDataのCTO、John A. De Goesさんのセッション、両者ともSlamData所属、catsとScalazのIOということで完全に狙った配置だと思いますが、Danielさんによるcatsのセッションの直後に同じ会場でScalaz8 Effect Systemの話でした。

Scalaz8のEffect Systemはスレッドではなくfiberを生成するfork/joinフレームワークに基づいており、リソースのリークもなく性能も非常に優れているとのことでした。

Johnさんは11月11日〜13日にサンフランシスコで開催されるScale By the Bay 2017でも同じ話をされるようです。また、ScalaMatsuri 2018にもトークを応募されているようです。タイトルは違いますがIOの話のようなので同じ話が日本でも聞けるかもしれません。

Case classes ate my RAM

FindifyのRoman Grebennikovさんによるセッション(Findifyはスウェーデンの企業のようですが、Romanさんはロシア在住のようです)。Scalaのコレクション(に格納されるケースクラス)のメモリのフットプリントを気合いで圧縮するという話でした。

Shapelessでケースクラスをほげほげしてプロパティの値を直接メモリ(バイト列?)にマッピング/復元するという荒技を使っているようです。まだプロダクションでは使っていないとのことでしたが、圧縮・展開にかかるオーバーヘッドとメモリ削減のトレードオフなどベンチマーク結果に対する考察もあり、面白いセッションでした。

github.com

こちらも11月23日〜25日にスロベニアで開催されるBeeScala 2017で同じ話をされるようです。

Next generation Scala builds with CBT

Slickなどでお馴染みJan Christopher Vogtさんのセッションで、Scala Days New Yorkでも聞いたcbtのセッションです。

ScalaDaysで聞いたときは正直完全にネタだと思っていたのですが、かなり本気で取り組んでいるようで、ビルドツールとして必要な機能は一通り実装されたようです。cbtのコンセプトを説明した後はデモ中心で各機能の紹介をしていました。IntelliJサポートもIntelliJの次のバージョンから利用可能になるとのことです。

ちなみにこのIntelliJサポートはロシアの学生さんがGoogle Summer of Codeで開発したものだそうで、本人が壇上でデモをしていたのですが、後で話したらめっちゃ緊張してたそうです。全然そんな感じには見えなかったし、英語も苦手と言ってたのに上手ですごいなぁと思いました。

github.com

Q&Aでの突っ込みがかなり激しかったのですが、個人的にビルドツールに自分の名前を付けてしまうお茶目さに惹かれているのでワンチャン目指してこれからも頑張って欲しいです。

Open Source Spreeについて

自分はずっとトークを聞いていたので参加しなかったのですが、会場ではトークセッションの他にハンズオンやScala Center主催のOpen Source Spreeなどが開催されていました。Open Source SpreeというのはScala関連のOSSにその場でコントリビュートしてみよう(コントリビュートするとTシャツがもらえる)というもので、Scala Centerが各地のScalaカンファレンスで開催しているようです。

github.com

https://camo.githubusercontent.com/ff0133f2a3c26674002a16eb36e19d66cdd8e1d4/68747470733a2f2f7062732e7477696d672e636f6d2f6d656469612f43746e43727476574141414f306e452e6a70673a736d616c6c

今回のScalaIOではトークも採択されたScalaz、scalafix、cbt、hamstersなどのコミッターがチューターとして協力していたようです。自分もPredictionIOやGitBucket、Scalatraなどで協力できたらとは思ったものの、さすがに英語力的に厳しいと思ったので今回は手を挙げませんでしたが、将来的にはこういうこともできるといいなと思います。

全体的な感想など

ここ1〜2年ほど、Scalaのカンファレンスではどこもかしこもフリーモナドの話ばかりだったような気がするのですが、今回はFreestyleのトークが1つあったくらいでフリーモナドブーム(?)は一段落したのかなという印象でしたw ScalaDays後で大きなトピックがなかったせいか、逆にバラエティ豊かなトークが揃っていたのではないかと思います。ショートセッションやLTも多様性という意味でよく機能していたと思います。

今回初めてScalaDays以外の海外カンファレンスに参加したのですが、ScalaMatsuriなどと同じく現地コミュニティの方々の尽力で運営されている様子がよくわかりました。また、それと同時にScalaMatsuriの運営の素晴らしさも感じました。海外スピーカーの豪華さはScalaMatsuriも引けを取っていないと思うのですが、やはりスピーカーが作者だったりコミッタだったりするケースが多いのでそういう部分での質の高さや、Q&Aのやり取りなどにレベルの高さを感じました。

全体的にはScalaDaysとは一味違ったアットホームな雰囲気があり、リラックスして参加できるカンファレンスだったと思います。フランス語のセッションと英語のセッションがあり、自分は英語のセッションに参加していたのですが(フランス語はまるでわからないので…)、フランス語のセッションの中でもscala-hamstersの作者の方の話や、Alpakkaにコントリビュートしてみた話などは興味があったので可能であれば参加してみたかったです。

Akka HTTPでWebJarsとTwirlを使う

仕事でちょっとしたツール(Webアプリ)を作るのに試しにAkka HTTPを使ってみています。Akka HTTPでJSONを使う方法については以前このブログでも紹介しましたが、

takezoe.hatenablog.com

今回はいわゆるHTMLを返すシンプルな作りの管理ツールなのでJavaScriptCSSライブラリはWebJarsで、HTMLのレンダリングはTwirlを使うようにしてみました。

WebJars

ThoughtWorksリポジトリにAkka HTTPでWebJarsを使うためのライブラリがありました。

github.com

メンテが止まっているようですが、リポジトリ内のWebJarsSupportは現在のAkka HTTPでもそのまま利用できます。実装としては非常にシンプルで、webjars-locatorで取得したクラスパス内のリソースをgetFromResource()で返しているだけです。

これを使う場合はbuild.sbtに以下の依存関係を追加する必要があります。

"org.webjars" % "webjars-locator" % "0.32"

WebJarsのリソースを返すエンドポイントはこんな感じ。/webjars/jquery.jsのようなパスでWebJarsでインポートしたJavaScriptCSSを参照できます。

import com.thoughtworks.akka.http.WebJarsSupport._

get {
  pathPrefix("webjars") {
    webJars
  }
}

Twirl

Twirlもライブラリを作っている人がいました。

github.com

こちらも最新のAkka HTTPのバージョンには追従できていないようですが、TwirlのHtml型などに対応するマーシャラーを定義しているだけのシンプルなものなので、リポジトリ内のTwirlSupportをそのまま持ってきて使ってもよいでしょう。

これを使う場合は普通にTwirlを使う場合と同様の設定が必要になります。まずはproject/plugins.sbtにTwirlプラグインを追加。

addSbtPlugin("com.typesafe.sbt" % "sbt-twirl" % "1.3.4")

build.sbtでTwirlプラグインを有効化します。

enablePlugins(SbtTwirl)

Twirlのテンプレートファイルはsrc/main/twirlディレクトリ配下に作成し、エンドポイントからは以下のようにして呼び出します。

import akkahttptwirl.TwirlSupport._

get {
  path("hello") {
    // src/main/twirl/hello.scala.html
    complete(html.hello())
  } ~
}

おまけ:静的ファイルを返す

おまけとしてAkka HTTPで静的ファイルを返す方法を書いておきます。ファイルシステム上のファイルを返す場合はこんな感じ。

get {
  pathPrefix("assets") {
    getFromDirectory("assets")
  }
}

クラスパス内のリソースを返すこともできます。

get {
  pathPrefix("assets") {
    getFromResourceDirectory("assets")
  }
}

とりあえずこのくらいでAkka HTTPで普通のWebアプリを作ることができるんじゃないかと思います。フォームのバリデーションなどもあると便利ですが、そのあたりも拡張して便利に使えるものを組み込んでしまうのがよさそうです。

オープンソースの機械学習プラットフォームまとめ

PredictionIOは機械学習を使用したアプリケーションを開発・運用するためのプラットフォームを提供するためのOSSですが、世の中には他にも同じ領域のOSSが存在します。PredictionIO含めて各プロダクトの特徴をまとめてみました(PredictionIO以外はドキュメントやソースをチラ見して書いているので見落としていることなどあるかもしれませんがご容赦いただければと思います)。

PredictionIO

github.com

Apache Software Foundationで開発されている機械学習プラットフォームです。基本的にSpark上で動作する機械学習ライブラリをターゲットにしていますが、最近はPython対応なども行われています。作成したマイクロサービスはSprayベースのAPIサーバとして起動することが可能です。用途に応じたテンプレートが多数用意されており、それをカスタマイズして使用できるのが特徴です。

Apacheのプロジェクトですし、ドキュメントやサンプルもそれなりに揃っています。日本人コミッタもおり、国内でのイベントも開催しているので、他のプロダクトと比べると情報を得やすいのもメリットといえます。

PredictionIOの概要については以下のQiitaの記事が参考になります。日本語のハウツー記事も多いので、ググってみていただけるとよいかと思います。

qiita.com

Seldon

github.com

基本的にはPredictionIO同様のユースケースが想定されており、Predict、Recommend用のサービスを構築可能。Spark、scikit-learn、TensorFlow、Kerasなどの機械学習ライブラリをサポートしていたり、作成したマイクロサービスをDockerコンテナとしてデプロイ可能、Graphanaによるマイクロサービスのモニタリング機能も自前で備えているなど機能的にはPredictionIOよりも先行している部分がありますが、ドキュメントが豊富とはいえず、日本語はもちろんのこと英語での情報もまだまだ少ないようです。ただ、企業がやっているOSSなので、そこはコンサルしますよということなのかもしれません。

日本語では以下のQiitaの記事が参考になると思います。

qiita.com

MLeap

github.com

MLパイプラインをシリアライズ/デシリアライズし、実行するためのライブラリを提供します。Spark、scikit-learn、TensorFlowをサポート。生成した予測モデルを使用してマイクロサービスとしてデプロイするためのDockerイメージも用意されています。PredictionIOやSeldonと違って機械学習を運用するためのプラットフォームというよりはパイプラインや予測モデルのポータビリティを実現するためのライブラリという感じです。

ドキュメントはSeldonと比べるとかなりしっかりしていますが、日本語情報は今のところ皆無です。

まとめ

アプリケーションに機械学習を活用した機能を組み込むことが一般的になるにつれ、それらを効率よく開発・運用するためにこのような機械学習プラットフォームの必要性は高まってくると考えています。SeldonやMLeapのように複数の機械学習ライブラリを扱うことができる仕組みも必要になってくると思いますし、逆に機械学習の専門家がいないチームではPredictionIOのように予め用意されているテンプレートを使用することで機械学習を利用できるというメリットもあるでしょう。

どのプロダクトも作成した予測モデルをマイクロサービスとしてデプロイしてアプリケーションから利用するという形は共通していますが、一方でバッチ的に使用したい場合やオンライン学習などのユースケースをどう取り込んでいくのかという点についても今後の注目ポイントかもしれないと思います。

また、今回はOSS機械学習プラットフォームを紹介しましたが、AWSやAzure、GCPなどで提供されているマネージドな機械学習プラットフォームももちろん有力なオプションです。機械学習プラットフォームの動向という意味ではこれらについても注視していく必要がありそうです。

PredictionIOがApache Software Foundationのトップレベルプロジェクトになりました!

弊社のメンバーもコミッタとして開発に参加しているApache PredictionIOですが、このたびめでたくIncubatorプロジェクトを卒業してトップレベルプロジェクトに昇格することができました。ASFからのリリースには弊社のチーフサイエンティストである@shinsuke_sugayaさんもコメントを寄せています。

"We are very interested in PredictionIO for solving any Machine Learning tasks," said Shinsuke Sugaya, Chief Scientist at BizReach, Inc. "At BizReach, using PredictionIO, we have built a data-analysis platform for HR, which fits learning models from about 5 million job descriptions and recommends preferred items from them to users everyday. PredictionIO has accelerated our analysis and development tasks for data scientists and developers, and simplified infrastructure from data management to prediction server."

また、ASFからのリリースとは別にSalesforce社のブログにもPredictionIOの共同創業者兼CEOだったSimon Chan氏によるエントリが上がっていました。

PredictionIOはもともと彼らが起業したスタートアップで開発されていたOSSだったのですが、昨年Salesforce社に買収され、その後はApache Incubatorで開発されていました。少し停滞してこれは時間がかかるかな…と思った時期もあったのですが、14ヶ月(弊社のメンバーが正式にコミッタになってからは約半年)でのトップレベルプロジェクト昇格というのはまあまあ早いほうなのではないかと思います。

現在はSalesforce社のメンバーと弊社のメンバーが中心となって開発が行われていますが、まだまだ改善すべき点も多いですし、機械学習を使用したサービス構築のためのフレームワークという領域には競合もそれなりに存在するので引き続き頑張っていきたいと思います。

また、先日Scala福岡でのPredictionIOに関する発表をタイミングよく記事にしていただきましたので、是非こちらもご覧いただければと思います。

codeiq.jp