Ouertani Slim was born in Tunisia in 1981. Now he is a software engineer since 2004 and he is Java 6 and Spring certified with 100% and 94% respectively. He is very interested in Java technology, Scala and open source projects. He believes that programming is one of the hardest jobs and most beautiful in the world. Slim has posted 32 posts at DZone. You can read more from them at their website. View Full User Profile

Basic WS with Scala, Sbt and JEE 6

09.10.2011
| 3832 views |
  • submit to reddit
I recently had a chance to work on building an SOA platform using JEE 6 and Scala. I will share here some snippets that may be helpfull to start publishing web services using Scala, Sbt and JAX-WS.

Consider the example to calculate the quotient and remainder using a euclidean algorithm. Not very complex if the inputs are positives numbers.

I- Sbt

Let’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 WS

We 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.BeanProperty
III- 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 )

IV – test it
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!

Published at DZone with permission of its author, Slim Ouertani.

(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

NoClassDefFoundError: scala/ScalaObject 

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.

Mike Nishizawa replied on Fri, 2014/01/24 - 10:48pm

Is xsbt a reference to the sbt web plugin or something else?

Slim Ouertani replied on Sat, 2014/01/25 - 4:07am

xsbt was my sbt tool on 0.10 sbt version.  (As I deprecated my 0.7 version )


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.