Scalaでコードを書く時のビルドツールはたいていsbtを使うわけですが、Java EE関係のものを扱う時にはMavenの方が都合がいいことも多いので、1度MavenでScalaを扱う時の設定をメモっておきます。
個人的なテンプレートといった感じで。
pom.xmlを書いてみる
MavenでScalaを使う場合は、scala-maven-pluginを使います。
ドキュメントはこちら。
scala-maven-plugin – scala-maven-plugin
基本、こちらを見て設定していけばよいわけですが、自分が書いたものはこんな感じ。
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.littlewings</groupId> <artifactId>scala-maven-example</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <scala.major.version>2.12</scala.major.version> <scala.version>${scala.major.version}.1</scala.version> <scala.maven.plugin.version>3.2.2</scala.maven.plugin.version> </properties> <dependencies> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>${scala.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>${scala.maven.plugin.version}</version> <executions> <execution> <goals> <goal>compile</goal> <goal>testCompile</goal> </goals> </execution> </executions> <configuration> <scalaVersion>${scala.version}</scalaVersion> <args> <arg>-Xlint</arg> <arg>-unchecked</arg> <arg>-deprecation</arg> <arg>-feature</arg> </args> <recompileMode>incremental</recompileMode> </configuration> </plugin> </plugins> </build> </project>
Scalaのメジャーバージョンは、ライブラリの指定とかで使ったりするので、通常のバージョンとは別にプロパティ定義。Javaを使ってもいいように、Javaのコンパイラなどのバージョンも書いておきます。
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <scala.major.version>2.12</scala.major.version> <scala.version>${scala.major.version}.0</scala.version> <scala.maven.plugin.version>3.2.2</scala.maven.plugin.version> </properties>
依存関係にはscala-libraryを追加。
<dependencies> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>${scala.version}</version> </dependency> </dependencies>
<plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>${scala.maven.plugin.version}</version> <executions> <execution> <goals> <goal>compile</goal> <goal>testCompile</goal> </goals> </execution> </executions> <configuration> <scalaVersion>${scala.version}</scalaVersion> <args> <arg>-Xlint</arg> <arg>-unchecked</arg> <arg>-deprecation</arg> <arg>-feature</arg> </args> <recompileMode>incremental</recompileMode> </configuration> </plugin>
コンパイルオプションはお好みで、ですが、scalaVersionは指定しておきます。
実行
では、サンプルコードでも書いて実行してみましょう。
src/main/scala/org/littlewings/scala/HelloWorld.scala
package org.littlewings.scala object HelloWorld { def main(args: Array[String]): Unit = println("Hello Scala!!") }
$ mvn compile
実行は、「scala:run」で。
$ mvn scala:run -DmainClass=org.littlewings.scala.HelloWorld 〜省略〜 Hello Scala!!
まあ、「exec:java」でもいいといえばいいみたいです。
$ mvn exec:java -Dexec.mainClass=org.littlewings.scala.HelloWorld
テストコードを書く
では、今度はテストコードを書くことを考えてみます。Scalaでテストを書く時には自分はScalaTestを使っていますが、Mavenで実行する時にはJUnitも合わせておきます。
<dependency> <groupId>org.scalatest</groupId> <artifactId>scalatest_${scala.major.version}</artifactId> <version>3.0.1</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
Scalaのメジャーバージョンは、こういう時のために別プロパティにしたくなる…。
とりあえず、テスト対象のコードを書いておきます。
src/main/scala/org/littlewings/scala/CalcService.scala
package org.littlewings.scala class CalcService { def add(a: Int, b: Int): Int = a + b }
テストコード。
src/test/scala/org/littlewings/scala/CalcServiceTest.scala
package org.littlewings.scala import org.junit.Test import org.scalatest.Matchers class CalcServiceTest extends Matchers { @Test def addTest(): Unit = { val calcService = new CalcService calcService.add(1, 2) should be(3) } }
Matchersを使ってはいますが、@Testなど基本的にJUnitのスタイルで書くことになります。FunSpecとか継承して、describeとか書いても華麗に無視されます。
JUnitSuiteを使ってもよいでしょう。
src/test/scala/org/littlewings/scala/CalcServiceJUnitSuiteTest.scala
package org.littlewings.scala import org.junit.Test import org.scalatest.Matchers import org.scalatest.junit.JUnitSuite class CalcServiceJUnitSuiteTest extends JUnitSuite { @Test def addTest(): Unit = { val calcService = new CalcService assert(calcService.add(1, 2) === 3) } }
実行は、ふつうに「test」で。
$ mvn test
まとめ
とまあ、こんな感じに書いていこうかと。
今回書いたpom.xmlをまとめると、こんな感じです。
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.littlewings</groupId> <artifactId>scala-maven-example</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <scala.major.version>2.12</scala.major.version> <scala.version>${scala.major.version}.1</scala.version> <scala.maven.plugin.version>3.2.2</scala.maven.plugin.version> </properties> <dependencies> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>${scala.version}</version> </dependency> <dependency> <groupId>org.scalatest</groupId> <artifactId>scalatest_${scala.major.version}</artifactId> <version>3.0.1</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>${scala.maven.plugin.version}</version> <executions> <execution> <goals> <goal>compile</goal> <goal>testCompile</goal> </goals> </execution> </executions> <configuration> <scalaVersion>${scala.version}</scalaVersion> <args> <arg>-Xlint</arg> <arg>-unchecked</arg> <arg>-deprecation</arg> <arg>-feature</arg> </args> <recompileMode>incremental</recompileMode> </configuration> </plugin> </plugins> </build> </project>