2009年11月23日月曜日

maven2を使ってScalaのHello Worldを書いてみた

先日@yuroyoro氏により開催されましたScala Hackathon #1に行ってきました。Scalaは初めてだったので、ハッカソン資料に従ってまずはHello Worldから作ってみました。資料によると、
  • インタラクティブコンソールを使う
  • Eclipseのプラグインを使う非推奨
  • NetBeansのプラグインを使う
  • IntelliJ IDEAのプラグインを使う
  • テキストエディタとMavenとmaven-scala-toolsを使う
  • テキストエディタとsbt(Simple build Tool)を使う
これだけの開発手法を選択することが出来るそうです。そこであえて私はMaven2を使ってScalaのHello Worldを書いてみることにしました。

参考にした資料はこちら。
http://dl.dropbox.com/u/261418/scala-hackathon/setup.html#maven2
参考にしたページはこちら。
http://scala-tools.org/mvnsites/maven-scala-plugin/plugin-info.html
http://scala-tools.org/mvnsites/maven-scala-plugin/usage_run.html


■まずはmvnプロジェクトを作る
基本的には資料に記載されている内容と全く同じです。次の殺人的に長いmvnコマンドを入力するだけでプロジェクトを作ってくれます。
mvn org.apache.maven.plugins:maven-archetype-plugin:1.0-alpha-7:create \
-DarchetypeGroupId=org.scala-tools.archetypes \
-DarchetypeArtifactId=scala-archetype-simple \
-DarchetypeVersion=1.2 \
-DremoteRepositories=http://scala-tools.org/repo-releases \
-DgroupId=scalahackathon.helloworld -DartifactId=scalahackathon.helloworld
ただし、このコマンドによって生成されたデフォルトのScalaプロジェクトではそのままビルド結果を実行することができません。多少不備があります。後ほど詳しく説明します。とりあえずビルドとテストはできるので後回しにします。


■Appクラスを書かなくちゃ始まらない
生成されたデフォルトのScalaプロジェクトにあるAppクラスを書きます。このAppクラスと言う奴が、いわゆるJavaでいうmain関数を持ったメインクラスの扱いになってるみたいです。
akisute scalahackathon.helloworld$ cd src/main/scala/scalahackathon/helloworld 
akisute helloworld$ vim App.scala
package scalahackathon.helloworld

/**
* Hello world!
*
*/
object App extends Application {
println("Hello World!");
val l = List(1, 2, 3, 4, 5, 6);
l.foreach(println(_));
}
Applicationを拡張したAppクラスの中身が、そのままmain関数相当になるみたいです。このあたりよく分かってませんが、Appクラスの中で再度main関数を定義すると思いっきり怒られるのできっとそうなんだと思います。


■さて実行、その前に
さてここで
mvn scala:run
を実行すればプロジェクトをビルドして実行してくれるのですが、実は先ほど申し上げましたようにこのままではビルドには成功しますが実行に失敗します。原因はメインクラスがpom.xmlで定義されていないためです。
実行するためには、以下のように直接メインクラスを指定するか、
mvn scala:run -DmainClass=scalahackathon.helloworld.App
または以下のようにpom.xmlを修正してから実行する必要があります。毎回毎回直接メインクラスを指定するのは骨が折れるので、pom.xmlを直してみましょう。
<!-- reportingの中を直す、build要素はそのままでよい -->
<reporting>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<configuration>
<scalaVersion>${scala.version}</scalaVersion>
<!-- このlaunchers要素を新規に作る。idとmainClassは必須。 -->
<launchers>
<launcher>
<id>app</id>
<mainClass>scalahackathon.helloworld.App</mainClass>
<!-- 以下、任意要素。 args と jvmArgs を指定できます。 -->
<!--
<args>
<arg>arg1</arg>
</args>
<jvmArgs>
<jvmArg>-Xmx128m</jvmArg>
<jvmArg>-Djava.library.path=...</jvmArg>
</jvmArgs>
-->
</launcher>
</launchers>
</configuration>
</plugin>
</plugins>
</reporting>
修正してからmvn scala:runを実行すると、長い長いjarダウンロードの末、以下のような結果が得られます。
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'scala'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Unnamed - scalahackathon.helloworld:scalahackathon.helloworld:jar:1.0-SNAPSHOT
[INFO] task-segment: [scala:run]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing scala:run
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [scala:compile {execution: default}]
[INFO] Checking for multiple versions of scala
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [scala:testCompile {execution: default}]
[INFO] Checking for multiple versions of scala
[INFO] Nothing to compile - all classes are up to date
[INFO] [scala:run]
[INFO] Checking for multiple versions of scala
[INFO] launcher 'app' selected => scalahackathon.helloworld.App
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
Hello World!
1
2
3
4
5
6
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
[INFO] Finished at: Mon Nov 23 20:59:51 JST 2009
[INFO] Final Memory: 18M/79M
[INFO] ------------------------------------------------------------------------
うまくいったみたいですね。