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.