seratch's weblog in Japanese

About Scala, Java and Ruby programming in Japaense. If you need English information, go to http://blog.seratch.net/

Javaと共存したScalaプロジェクトで開発する

記事

既存のJavaのコードにScalaで書かれたコードを共存させる、ScalaプロジェクトでJavaのコードも書く、というように一つのプロジェクトでScalaJavaの開発を共存させる場合、pom.xmlセクションから以下の記述を削除します。

  <build>
    <!--
     <sourceDirectory>src/main/scala</sourceDirectory>
     <testSourceDirectory>src/test/scala</testSourceDirectory>
    -->
    ・・・

mvn compileでsrc/main/配下の*.javaと*.scalaがコンパイルされtarget/classes/配下に*.classファイルが出力されるようになります。

ただし、この状態だとIntelliJ IDEA上ではmvn idea:ideaの結果、src/main/javaだけがSource Rootとして設定されるようになります。
その場合、src/main/scalaを右クリック>Mark Directory As>Source Rootを選択すると、src/main/javaとsrc/main/scalaが共にソースフォルダとして認識されるようになります。

上記の成果物ではsrc/main/javaにPerson.java、src/main/scalaにはCompany.scalaを実装し、正常にcompile、実行できる事を確認しています。

  • src/main/java/scalahatenadiary/withjava/Person.java
package scalahatenadiary.withjava;

public class Person {

    private final String name;

    public Person(String name) {
        this.name = name;
    }

    public String name() {
        return this.name;
    }
}
  • src/main/scala/scalahatenadiary/withjava/Company.scala
package scalahatenadiary.withjava

class Company {

  var workers: List[Person] = Nil
  var specialists: List[Specialist] = Nil

  def employ(newcomer: Person): Unit = {
    workers = (newcomer :: workers).reverse
    newcomer match {
      case Specialist(name) => {
        specialists = Specialist(name) :: specialists
      }
      case _ =>
    }
  }

  def fire(firee: Person): Unit = {
    workers = workers.filter(_.name != firee.name)
    specialists = specialists.filter(_.name != firee.name)
  }

  def getWorkers(): List[Person] = this.workers

  def getSpecialists(): List[Specialist] = this.specialists

  def displayWorkers(): Unit = {
    print("All: ")
    getWorkers foreach {
      worker => print(worker.name + " ")
    }
    println("")
  }

  def displaySpecialists(): Unit = {
    print("Specialists: ")
    getSpecialists foreach {
      specialist => print(specialist.name + " ")
    }
    println("")
  }

}

case class Specialist(override val name: String) extends Person(name)
  • 実行
object Main extends Application {

  val co = new Company
  val taro = Specialist("Taro")
  val jiro = new Person("Jiro")
  val saburo = new Person("Saburo")

  co.employ(taro)
  co.employ(jiro)
  co.displayWorkers()
  co.displaySpecialists()

  co.fire(taro)
  co.employ(saburo)
  co.displayWorkers()
  co.displaySpecialists()

}