eyecatch
Sat, Apr 16, 2016

Pcap4J in Kotlin

Groovyに続いて、KotlinでPcap4Jを使ってパケットキャプチャしてみた。 KotlinからでもPcap4Jちゃんと動くよということを実証するのが主な目的。 また、今後JavaなアプリはKotlinで書こうかと思っているので、その予習も兼ねている。 Kotlinとは KotlinはJVM言語、つまりJavaのバイトコードにコンパイルされてJavaの実行環境で動くプログラミング言語のひとつ。 IntelliJ IDEAで有名なJetBrains社によってOSSとして開発されている。 2011年に生まれた新しめな言語で、2016/2/17にv1がリリースされ、主にAndroidアプリの開発用として注目されている。 「実用的」であることを売りにしていて、つまり少ない学習コストで導入でき、既存のJavaコードやMavenなどのツールとの相互運用性を持つとされている。 IntelliJ IDEA、Android Studio、Eclipseといった主要なIDEのサポートもあり、開発環境は整っている。 v1以降の後方互換性の維持も表明されていて、長期サポートが必要な製品開発にも堪える。 さらに、厳格な静的型付けやNullable/Non-Null型などにより安全性を確保しつつ、型推論やラムダ式などで生産性を高めている。 Javaのバイトコードだけでなく、JavaScriptを生成するバックエンドを持っているのも大きな特徴。 ユースケースがよく分からないが。 GitHubにホストされているKotlinプロジェクトは、2016/4/15現在、全体の 0.1% (3493⁄3215549) しかない。 v1のリリースは結構注目を集めたので、この割合は今後増えていくと期待される。 Kotlinのインストール チュートリアルに従えば、IDEやテキストエディタ+コマンドラインの環境を整えてHello Worldを書いて実行するところまで簡単にできる。 筆者はEclipse(Mars)とコマンドラインの環境をWindows 7上で作った。 Kotlinのバージョンは1.0.1-2。 コマンドラインについては、GitHub Releasesからアーカイブをダウンロードして、適当なところに展開してbinフォルダにパスを通すだけ。 前提となるJavaについては、環境変数JAVA_HOMEを設定するか、javaコマンドにパスを通せばいい模様。 因みにKotlinの書き方は、Kotlin Koansという例題集をオンラインのIDEで解きながらを学ぶことができる。 パケットキャプチャ with Pcap4J in Java Pcap4Jでパケットキャプチャするコードを普通にJavaで書くと以下の様になる。 (Groovyの時のと一緒。) これを実行すると、パケットキャプチャするネットワークインターフェースを選択し、5つのパケットをキャプチャしてタイムスタンプと共にコンソールに表示する。 パケットキャプチャ with Pcap4J in Kotlin 上記処理をKotlinで書くと以下の様になる。 メインクラスはGroovy同様書かなくていいが、main関数は必要。 型推論があってとても楽。 ラムダ式、補間文字列(String interpolation)、名前付き引数といったモダンめな機能は普通に使える。 (名前付き引数はJavaで書いたメソッドをKotlinから呼ぶときは使えない。) オープンクラスを実現する機能であるExtensionsをPcapHandleに使ってみた。 なんだか便利そう。 Nullable/Non-Null型がすごい。言語仕様でNullPointerExceptionが発生しないように守ってくれる。 例えばfilterは宣言の時点では初期化文でnullが入る可能性があるのでNullableなStringという型に推論されるが、filter?.letというNullチェックをするメソッドに渡したブロック内では自動でNon-NullなStringにキャストされ、filter.lengthを安全に評価できるようになっている。 Nullチェックをしないでfilter.lengthと書くとコンパイルエラーになる。すごい。 けどJavaのコードから返ってくるオブジェクトは普通、プラットフォーム型というものになり、このNullセーフな仕組みが働かない。 これに対してはNull可能性アノテーションを使えば幸せになれるらしい。 さらに、上記コードには表れていないが、キャストも安全になっている模様。(cf. スマートキャスト、セーフキャスト) Kotlinは基本コンパイラ言語なので、上記コードを実行するには以下ようなコマンドで一旦コンパイルする必要がある。 kotlinc -cp pcap4j-core.jar Pcap4jLoop.kt -include-runtime -d Pcap4jLoop.jar このコマンドだとKotlinのランタイム入りjarファイルができる。 このjarを、Pcap4J
eyecatch
Sun, Apr 10, 2016

Pcap4J in Groovy

GroovyでPcap4Jを使ってパケットキャプチャしてみた。 GroovyからでもPcap4Jちゃんと動くよということを実証するのが主な目的。 また、さすがにそろそろMavenを卒業してGradle(下記)使おうと思うので、予習も兼ねている。 Groovyとは GroovyはJVM言語、つまりJavaのバイトコードにコンパイルされてJavaの実行環境で動くプログラミング言語のひとつ。 Javaのプログラマにとってとっつきやすい文法を保ちつつ、動的型付けを実現し、またRubyなどのスクリプト言語の記法や機能を取り入れ、生産性を高めている。 現在はApacheソフトウェア財団によって管理され、OSSとして開発が進められている。 WebアプリケーションフレームワークのGrails やビルドツールのGradleで採用されている。 Gradleは最近Javaプロジェクトのビルドツールの主流になっていて、Groovyはその定義ファイルを記述する言語として知名度が高いが、Groovyで開発されているプロジェクトとなるとあまり多くないようだ。 GitHubにホストされているGroovyプロジェクトは、2016/4/9現在 0.8%弱 (25,087/3,200,229) しかない。 なぜ人気がないのかはよく分からないが、少なくとも、長くて打ちにくい名前とダサいロゴは不評のようだ。 Groovyのインストール Windows 7にGroovy 2.4.6をインストールする。 本家サイトの手順に従い、Binary Releaseのアーカイブをダウンロードして、適当なところに展開して、展開したフォルダのパスを環境変数GROOVY_HOMEにセットし、%GROOVY_HOME%\binをPATHに追加するだけ。 Java 6以降が前提なので、JAVA_HOMEにJDK 1.7.0_17のパスをセットしておいた。JREでもいいはず。 パケットキャプチャ with Pcap4J in Java Pcap4Jでパケットキャプチャするコードを普通にJavaで書くと以下の様になる。 これを実行すると、パケットキャプチャするネットワークインターフェースを選択し、5つのパケットをキャプチャしてタイムスタンプと共にコンソールに表示する。 パケットキャプチャ with Pcap4J in Groovy 上記処理をGroovyで書くと以下の様になる。 メインクラスを書かなくていいところが大きい。 変数の型を書かなくていいのも楽。 ラムダ式でクロージャも作れるし補間文字列(String interpolation)も使える。 また、ここでは使っていないが、オープンクラスなどのメタプログラミングもサポートされている。 上記コードは、Pcap4J 1.6.2、Slf4J 1.7.12、JNA 4.2.1を使って、以下のコマンドで実行できることを確認した。 groovy -cp "pcap4j-core.jar;jna.jar;slf4j-api.jar;pcap4j-packetfactory-static.jar" Pcap4jLoop.groovy tcp これはスクリプト的な実行方法だが、groovycコマンドで事前にコンパイルしてclassファイルを生成し、javaコマンドで実行することもできる。 困ったところ 本家サイトのドキュメントが分かり辛い。 頭から読んでいくと急にディープな部分に引き込まれ、なかなかコードを書き始められなかった。 最近の言語やフレームワークのサイトはチュートリアルに従って動くコードを見ながら概要から詳細に理解を深められる形になっていることが多いので、仕様の詳細が羅列されている感じのGroovyサイトはなんとも読みにくかった。 クラスパスの指定が上手くできない。 groovyコマンドにオプションで複数のクラスパスを指定するのに、普通に-cp pcap4j-core.jar;jna.jarみたいにしたら最初のpcap4j-core.jarにしかクラスパスが通らなかった。 区切りを:にするとどちらにも通らない。 環境変数CLASSPATHにpcap4j-core.jar;jna.jarをセットしておくと-cpを使わなくても正しく両方に通るし、%userprofile%\.groovy\にjarを入れておくだけでもいいみたいなんだけど、-cpが中途半端にしか機能しないのが気持ち悪い。 のでちょっとソースを見たら、groovyコマンドはバッチで書かれていることに気付いた。 バッチだと、;で区切られているものは半角スペースで区切られているのと同じで別々の引数になってしまうので、上のような書き方だとjna.jarは-cpの値として処理されない。 クラスパス全体をダブルコーテーションで囲って、-cp "pcap4j-core.jar;jna.jar"みたいにしたらできた。なんか残念な出来。。。