ScalaEE with OpenEJB?


Scala is one of the most buzzing language based on the JVM nowadays.

Scala is finally compiled into java bytecode so we should be able to use JEE in a scala program, no?

Here a simple sample prooving it works!

The example is the simple Hello World. It uses the SNAPSHOT which has some better integration with scalatest but with some more configuration it is doable with the last release (4.5.0).

First we’ll setup the project using sbt (if you prefer maven it is even easier ;)):

name := "scalaEE"

version := "1.1-SNAPSHOT"

scalaVersion := "2.9.1"

resolvers ++= Seq(
	"Local Maven Repository" at "file://" + Path.userHome.absolutePath + "/.m2/repository",
	"Apache Snapshots" at "https://repository.apache.org/content/groups/snapshots/"
)

libraryDependencies ++= Seq(
    "org.apache.openejb" % "javaee-api" % "6.0-4",
    "org.apache.openejb" % "openejb-core" % "4.5.1-SNAPSHOT" % "test",
    "org.scalatest" %% "scalatest" % "1.6.1" % "test"

)

Nothing special here, we just add the apache snapshot maven repository to let ivy find openejb snapshot (the local one is optional for this sample) and add openeb as dependencies.

Then we write a simple EJB:

package org.superbiz

import javax.ejb.{Singleton, LocalBean, Lock, LockType}

object GreetingService {
    val DefaultName = "Scala"
}

@LocalBean
@Singleton
@Lock(LockType.READ)
class GreetingService {
    def hi(name: String = GreetingService.DefaultName) = {
        if (name != null) {
            "hi " + name
        } else {
            "hi " + GreetingService.DefaultName
        }
    }
}

Just a standard bean with some JEE annotations :).

Now add an empty beans.xml in META-INF (i used src/main/resources for it) to let us use CDI later.

And now we add a test using the ‘inject’ hook of OpenEJB to get the service injected in the test class:

package org.superbiz

import org.scalatest._

import javax.ejb.LocalBean
import javax.ejb.embeddable.EJBContainer
import javax.inject.Inject

class GreetingServiceTest extends FunSuite with BeforeAndAfterAll with BeforeAndAfterEach {
  @Inject
  private var service: GreetingService = null

  test ("Hi scala") {
    val message = service hi "scala"
    assert (message == "hi scala")
  }

  test ("Default Hi") {
    val message = service.hi()
    assert (message == "hi Scala")
  }

  test ("Hi null") {
    val message = service.hi(null)
    assert (message == "hi Scala") // when called with null we use default name
  }

  /***************************************************************/
  /** the OpenEJB Hook to be able to inject beans in this class **/
  /** kind of internal of this test class, "hidden" being last  **/
  /***************************************************************/

  private var container: EJBContainer = null

  override def beforeAll () {
    container = EJBContainer.createEJBContainer ()
  }

  override def beforeEach () {
    container.getContext().bind ("inject", this)
  }

  override def afterAll () {
    if (container != null) {
        container.close()
    }
  }
}

This test uses scalatest framework and before/after hooks to initialize/stop the container: “as easy as in java” :).

This sample shows how to start to write a “scala-EE” project. On hello world we see no gain but now think to a real project with useful code: less useless code (getter/setter), power of scala language (+ scalatest framework ;))…

Side note: think to @BeanProperty of scala to force the getter/setter generation when you wrote POJO (JPA entities?) otherwise you’ll get surprise (scala doesn’t generate getter/setter by default as groovy does).

Last note: using scala maven plugin (http://scala-tools.org/mvnsites/maven-scala-plugin/) you can do the same based on maven. Depending on your build workflow it can be more relevant.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s