Basic WS with Scala, Sbt and JEE 6
Consider the example to calculate the quotient and remainder using a euclidean algorithm. Not very complex if the inputs are positives numbers.
I- SbtLet’s create an sbt projet and add required dependencies
$ mkdir sws
$ cd sws
$ touch build.sbt
$ edit build.sbt as following :
name := "Euclide" version := "1.0" organization := "me.ouertani" scalaVersion := "2.9.1" scalaSource in Compile <<= baseDirectory(_ / "src") scalaSource in Test <<= baseDirectory(_ / "test") libraryDependencies += "javax" % "javaee-api" % "6.0" % "provided" libraryDependencies += "log4j" % "log4j" % "1.2.16" % "provided" libraryDependencies += "junit" % "junit" % "4.8.2" % "test"
$ mkdir src
$ touch src/Euclide.scala
That’a all for project configuration.
II- Create the WSWe will use a single Euclide.scala file for all class this will be easier for visibility
1 – Create a Request Class and don’t forget :
a – default constructor
b – field access annotation
@XmlAccessorType(XmlAccessType.FIELD)
case class Request(a : Int, b : Int ){ def this(){this(0,0)}}
2- Create a Response Class
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "output")
case class Response (c: Int, d: Int){ def this(){this(0,0)}}3- Why not create an exception class to handle exceptions like b is equal to 0?
@XmlAccessorType(XmlAccessType.FIELD)
case class ResponseException(why : String){ def this(){this("")}}
@XmlAccessorType(XmlAccessType.FIELD)
case class FaultResponse(@BeanProperty faultInfo : ResponseException) extends Exception { def this(){this(ResponseException(""))}} Don’t forget to add BeanProperty annotation to faultInfo input !
4- Let’s add an interceptor to log all ws method call
object TracingInterceptor{
import org.apache.log4j.Logger
val L = Logger.getLogger(classOf[TracingInterceptor])
}
import TracingInterceptor._
class TracingInterceptor {
@AroundInvoke
def log( context:InvocationContext):Object ={
try {
if (L.isDebugEnabled()) {
val clazz = context.getMethod().getDeclaringClass().getName()
val method = context.getMethod().getName()
L.debug(clazz + " : Is invoking method: " + method + " With Parameters : " + context.getParameters().mkString("[", ",","]"))
}
} catch {
case ex :Exception => L.warn("Unable to Intercept Method Call", ex)
}
context.proceed()
}
}
5- The WS class and it’s divide method using intercpetor and stateless EJB 3.1
@WebService(serviceName = "Euclide", targetNamespace = "http://slim.ouertani.me/")
@Stateless()
@Interceptors(Array(classOf[TracingInterceptor]))
class Euclide {
@throws(classOf[FaultResponse])
def divide( @WebParam(name="input" ) @XmlElement(required = true, nillable = false)
req :Request):Response = req match {
case Request(_, 0 ) => throw FaultResponse(ResponseException("Can't divide by ZERO!"))
case Request(a, b ) => Response(a / b ,a % b)
}
}6- Don’t forget package , imports at the head of file and it’s all :
package me.ouertani.scala.ws
import javax.interceptor.Interceptors
import javax.xml.bind.annotation.XmlElement
import javax.interceptor.{ AroundInvoke , InvocationContext }
import javax.xml.bind.annotation. { XmlAccessType , XmlAccessorType, XmlElement, XmlType}
import javax.ejb. { EJB ,Stateless }
import javax.jws. {WebService , WebParam }
import scala.reflect.BeanPropertyIII- packaging and run WS
1- Let’s start compiling our projet
$ xsbt compile
2- package the jar
$ xsbt package
3- deploy it to your JEE 6 container ( mine is Glassfish 3.1.1 )
1- After depoyed let’s test it using soapUI tool
Request 1 :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:slim="http://slim.ouertani.me/">
<soapenv:Header/>
<soapenv:Body>
<slim:divide>
<input>
<a>6</a>
<b>4</b>
</input>
</slim:divide>
</soapenv:Body>
</soapenv:Envelope>
Response 1 :
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:divideResponse xmlns:ns2="http://slim.ouertani.me/">
<return>
<c>3</c>
<d>0</d>
</return>
</ns2:divideResponse>
</S:Body>
</S:Envelope>Request 2 :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:slim="http://slim.ouertani.me/">
<soapenv:Header/>
<soapenv:Body>
<slim:divide>
<input>
<a>6</a>
<b>0</b>
</input>
</slim:divide>
</soapenv:Body>
</soapenv:Envelope>Response 2 :
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>me.ouertani.scala.ws.FaultResponse</faultstring>
<detail>
<ns2:FaultResponse xmlns:ns2="http://slim.ouertani.me/">
<faultInfo>
<why>Can't divide by ZERO!</why>
</faultInfo>
</ns2:FaultResponse>
</detail>
</S:Fault>
</S:Body>
</S:Envelope>
Fine!
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





Comments
Arpan Chaudhury replied on Wed, 2012/11/28 - 1:34am
Hi,
I am trying to build a simple web service in Scala. I followed the procedure as you mentioned above. Can you please explain how to deploy it on a Weblogic 10.6 server or Glassfish 3.1.1. That'll be immense helpful for me.
For me when I am trying to build it using SBT it is creating a .jar file which when deployed into a Weblogic10.3 server generating following error
Thanks and Regards,
Arpan Chaudhury
Slim Ouertani replied on Wed, 2013/03/20 - 9:39am
in response to:
Arpan Chaudhury
Sorry excuse me I read your comment too later. You should export scala libs to commun shared server lib for example.