Scala は JVM 上で動作するバイトコードにコンパイルできる言語です。JAVA よりも柔軟な記述ができます。事前にこちらからダウンロードおよびインストールしておいてください。以下は Maven を利用する前提での記述になっています。以下のようにしてプロジェクトのテンプレートを生成します。
scala-quickstart-archetype (GitHub)
$ mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-scala-app -Dversion=1.0 \
-DarchetypeGroupId=pl.org.miki -DarchetypeArtifactId=scala-quickstart-archetype -DinteractiveMode=false
scala や scalac コマンドを用いてコンパイルしていってもよいのですが mvn を利用していると成果物 jar を汎用的な手順で生成できます。
src/main/scala/com/mycompany/app/HelloWorld.scala
package com.mycompany.app
object HelloWorld {
def main(args: Array[String]) {
println("Hello, world!")
}
}
以下のコマンドで jar を生成します。
$ mvn package
「-cp jarファイルのクラス検索パス」オプションを利用して成果物 jar を実行してみます。
$ jar tf target/my-scala-app-1.0.jar
META-INF/
META-INF/MANIFEST.MF
com/
com/mycompany/
com/mycompany/app/
com/mycompany/app/HelloWorld$.class
com/mycompany/app/HelloWorld.class
META-INF/maven/
META-INF/maven/com.mycompany.app/
META-INF/maven/com.mycompany.app/my-scala-app/
META-INF/maven/com.mycompany.app/my-scala-app/pom.xml
META-INF/maven/com.mycompany.app/my-scala-app/pom.properties
$ scala -cp target/my-scala-app-1.0.jar com.mycompany.app.HelloWorld
Hello, world!
ただしこのままでは java では実行できません。java は scala ライブラリの所在を知らないためです。
$ java -cp target/my-scala-app-1.0.jar com.mycompany.app.HelloWorld
Exception in thread "main" java.lang.NoClassDefFoundError: scala/Predef$
at com.mycompany.app.HelloWorld$.main(HelloWorld.scala:5)
at com.mycompany.app.HelloWorld.main(HelloWorld.scala)
...
Maven の Assembly Plugin を利用すると mvn package で生成される jar 内に依存関係がある外部 jar をすべて含めることができます。scala ライブラリが jar に含められるため java でも実行できるようになります。利用方法は簡単です。pom.xml に以下の内容を追記します。
<plugin>
<!-- NOTE: We don't need a groupId specification because the group is
org.apache.maven.plugins ...which is assumed by default.
-->
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.mycompany.app.HelloWorld</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
再度 jar を生成して実行してみましょう。
$ mvn package
$ java -jar target/my-scala-app-1.0-jar-with-dependencies.jar
Hello, world!
このうち以下の部分を削除すると -jar オプションで実行はできなくなります。メイン・マニフェスト情報がないためです。
<archive>
<manifest>
<mainClass>com.mycompany.app.HelloWorld</mainClass>
</manifest>
</archive>
実行例
$ mvn package
$ java -jar target/my-scala-app-1.0-jar-with-dependencies.jar
target/my-scala-app-1.0-jar-with-dependencies.jarにメイン・マニフェスト属性がありません
$ java -cp target/my-scala-app-1.0-jar-with-dependencies.jar com.mycompany.app.HelloWorld
Hello, world!