Scala on Stripes/Spring (I)

12 07 2009

All the cool kids on the block are talking about Scala. Is Scala the next big thing? the Golden Hammer?

The Hype is justified

First of all, yes, the hype is justified, Scala is a gorgeous language: powerful, elegant and fun.

Not the same “fun” that bring us Python or Groovy, is more an “Intellectual Fun”. Scala have many features and constructs that can teach a lot of Computer Science and language design, maybe more than another language, and for a Geek like me this is a lot of fun

But, beware, as the Uncle Ben Parker says: “With great power comes great responsability”. Scala is a very complex language, some times Scala is overwhelming. Personally I (think that) dominate Java in 3 years including a SCJP: easily Scala will take me 2 or 3 times to tame. Scala have features that, poorly used, can make your code a mess, and is probably that you can’t read your own code in six months. So is necesary a good amount of discipline and good praxis

In the other side of the coin, this mean a long (and fun) way of learning and auto discovery that’s will keep you interested for a long, long time

Why Stripes/Spring if exists Lift?

I most confess that I don’t know Lift more than a couple of quicks looks at Lift’s Site, seems good but the Maven thing scare me a lot, but the most important reason is simple; I’m a Big Fan of Stripes/Spring. I spend the last 3 years on both frameworks, So, Why throw away all my hard earned experience, if I can use both frameworks with Scala?

Lets code

Many tutorials have an academic approach, but for some people is more easy with an example project, this is the approach with this tutorial. Although I’m not a Scala expert, I’ll try to do the best I can

The Project

In IntelliStripes’s repository we have a toy project that we use to make functional test, you can see the java code
in http://code.google.com/p/intellistripes/source/browse/#svn/trunk/functional-test
or use a SVN Client to checkout

This project is a “bare bones” web app for Task Management (very original), nothing fancy here just create an account, create your tasks and delete them

The Domain (or is the model??)

We have 2 simples entities User and Task, just simple java beans

User.scala

package com.simpletasks.domain
/**
* Created by IntelliJ IDEA.
* User: Mario Arias
* Date: 15/05/2009
* Time: 10:09:57 PM
*/
class User {
  private var id: Int = 0
  private var email: String = _
  private var password: String = _
  private var name: String = _
  private var lastName: String = _
  def getEmail: String = email
  def setEmail(email: String) = this.email = email
  def getId: Int = id
  def setId(id: Int) = this.id = id
  def getLastName: String = lastName
  def setLastName(lastName: String) = this.lastName = lastName
  def getName: String = name
  def setName(name: String) = this.name = name
  def getPassword: String = password
  def setPassword(password: String) = this.password = password
  override def toString: String = "User{" +
    "email='" + email + '\'' +
    ", id=" + id +
    ", password='" + password + '\'' +
    ", name='" + name + '\'' +
    ", lastName='" + lastName + '\'' +
    '}'
}

Java version

Let’s see line by line and go deeper in Scala concepts on the way.

  • Scala Files: In Java you need to declare the file with the same name of a public class (interface, enum) in Scala you don´t have the same limitation. You can have several classes, even many packages, or an entire application in one file, I don’t know if you can want this, but is posbile, in the other side, navigate into this files could be frustrating
  • line 00 Packages: packages in scala have the same sintax that in java, but also you can declare as the namespaces in C#. Example:
    package com{
      package simpletaks.domain{
      }
    }
  • line 01 Comments: Same as Java.
  • line 07 Access Modifiers: All is public by default, but also exists private and protected. Access Modifiers are more powerful than in Java, but for now is enough. More on this later
  • line 07 Class Declaration:Similar to Java, More on this later
  • line 08 Look ma’ no semicolons:Scala don’t need semicolons, but you can add them if you want
  • line 08 Vars: The var keyword means that this field will change in the time, in other words is a variable (D’oh)
  • line 08 Type:The type of a field or a method is declared after the name and separated with colon
  • line 08 (Not So)Primitives:Scala don’t have primitives; all in Scala is an object, so the concept here is called basic types. The basic types are
    Byte 8-bit signed two’s complement integer (-27 to 27 – 1, inclusive)
    Short 16-bit signed two’s complement integer (-215 to 215 – 1, inclusive)
    Int 32-bit signed two’s complement integer (-231 to 231 – 1, inclusive)
    Long 64-bit signed two’s complement integer (-263 to 263 – 1, inclusive)
    Char 16-bit unsigned Unicode character (0 to 216 – 1, inclusive)
    String a sequence of Chars
    Float 32-bit IEEE 754 single-precision float
    Double 64-bit IEEE 754 double-precision float
    Boolean true or false
  • line 08 Assign: Same as Java
  • line 09 Placeholder:You’ll see the _ character a lot in Scala code, this is a placeholder and have many, many uses, in this case is the same as null. But why you want to assign null to a field?. ’cause in Scala when you don’t assign a value to a field is the same as have and abstract method in Java; In fact do you need to declare abstract your Scala class. In conclusion an abstract Scala class could have abstract fields or methods. This is weird coming from the Java world, but is pretty useful
  • line 13 Function declaration:All the functions (methods) in Scala start with the def keyword
  • line 13 Look ma’ no parenthesis (neither braces, nor return):Well that’s is less code, but all have and explanation, the lack of parenthesis = absence of parameters, the lack of braces = one-line function, the lack of return = pretty similar to Groovy, the last line of a function is the return; but like Groovy you can made the return explicit
  • line 14 Look ma’ no void:Yes and not, remember that scala is functional/object language, so all functions have a return type, in the case that function return nothing, the type of the function is Unit. So the same could be declared as def setEmail(email: String):Unit = this.email = email.
  • line 13 and 14 Getters and Setters and @BeanProperty Hot topic. Many of you will blame me for write myself Getters and Setter when I could use the @BeanProperty and write less code just like this @BeanProperty
    private var id:Int = 0
    and voila!! the compiler will generate a nice shiny get/set pair for me… you read well the compiler, thats mean that I cannot invoke this get/set pair on my own code, for me is almost useless, but a lot of people like this approach. Before you start to complain that I could declare the var as “public” and call it directly, I remember you that this is a Scala on Stripes/Spring tutorial and I need too use this class in the JSP so I need the get/set pair
  • line 23 Function override:When you need override a function, you must add the keyword override this must will protect you from accidentally override a function without know.
  • line 23 String concat:Same as Java, but with a great difference… in fact this is not a string concat… this is only a function invocation. "Hello " + "World" is the same as "Hello ".+("World"). So in Scala do you have operator overloading; and this is how the concat happens. Then you can call any one-parameter function without the dot and the parenthesis. if the function have many parameters you can call without the dot, but with parenthesis

Task.scala
package com.simpletasks.domain
import java.util.Date
class Task {
  private var id: Int = 0
  private var title: String = _
  private var detail: String = _
  private var finished: Boolean = false
  private var createDate: Date = _
  private var endDate: Date = _
  def getCreateDate: Date = createDate
  def setCreateDate(createDate: Date) = this.createDate = createDate
  def getDetail: String = detail
  def setDetail(detail: String) = this.detail = detail
  def getEndDate: Date = endDate
  def setEndDate(endDate: Date) = this.endDate = endDate
  def getId: Int = id
  def setId(id: Int) = this.id = id
  def getTitle: String = title
  def setTitle(title: String) = this.title = title
  def isFinished: Boolean = finished;
  def setFinished(finished: Boolean) = this.finished = finished
  override def toString: String = "Task{" +
    "createDate=" + createDate +
    ", id=" + id +
    ", title='" + title + '\'' +
    ", detail='" + detail + '\'' +
    ", finished=" + finished +
    ", endDate=" + endDate +
    '}';
}

Java Version

  • line 01 Imports Similar in to Java, but a little more powerful. If you need to import two class of the same package you only need a line import java.util.{Date,List} But if you need all the classes on a package, our old friend placeholder will help us import java.util._. More on this topic in the next chapters.

UserNotFoundException.scala
package com.simpletasks.domain.exceptions
class UserNotFoundException extends Exception

Java Version

  • line 01 extends: The extends keyword is similar to Java, but have little differences, but in this tutorial we don’t touch this concept very deeply.
  • line 01 Look ma’ no braces: You don’t need to add braces if your class don’t have a body

Is ok for now, maybe this chapter isn’t so exciting, but I promise you that the next chapters will be bring some OOOHHH, and many WOWWWW. In the next chapter we’ll use some Spring JDBC and take a closer look to the Scala Syntax.


Actions

Information

15 responses

13 07 2009
Remco

Hi Mario,

I tried Stripes with Scala a while ago. It works great! I only had problems with nested annotations for validations which will be fixed in Scala 2.8.

13 07 2009
jau

I don’t agree. I think that Java is lot more difficult then Scala. Java has primitive types, enums, equals method, no pattern matching and closures, which makes it quite ancient.

Maybe one could say that assembler is simpler then Java, because it has only few important instructions, but I think it doesn’t show the whole truth.

13 07 2009
dhaat

@Remco

+1 I think that this combination is optimal and a have plus: Cool acronym :SoSS, SoS/S or SSS

@jau

Yeah Closures and pattern matching are Cool; but for some people aren’t easy (people like me that pass all the time stuck with Java :)), also Scala have a BIG plus here and is that you don’t need all the fancy toys right now, you can program as you do in Java, and then slowly you could add more Scala features when you feel comfortable.

17 07 2009
Alexey Tarasevich

Hi Mario. Why do use this Java-style stuff:
private var id: Int = 0
def getId: Int = id
def setId(id: Int) = this.id = id

when the following is enough to get the same effect (google for more info):

@BeanProperty
var id: Int = _

17 07 2009
dhaat

Hi Alexay:

Yeah, I know, in fact I touch the subject on the comments for the lines 13-14 of the first class.

So seems that you don’t read the full post 😉

Thanks for the visit.

19 07 2009
Alexey Tarasevich

Sorry Mario,
you are right about my reading of the post 🙂 But on the other hand you still not explained why 🙂 Sure you cannot use bar.setFoo(…); but you can use bar.foo = …;
So maybe you can specify other problems which I will run into if I use @BeanProperty.

21 07 2009
dhaat

In this point I think that is a matter of personal taste and IDE use.

In intelliJ you have very good auto-complete features for Spring files and JSP files, both technologies have heavy use of getters/setters, so if you use @BeanProperty you’ll loose all the nice features that provide good IDE’s like IntelliJ.

One solution is to have a separate module with all the classes that need @BeanProperty, compile, pack and use them in your main project, in big projects could be a solution but for this example is overkill.

22 07 2009
Alexey

thanks 🙂 you’d better put this comment into the blogpost itself.

22 07 2009
dhaat

I want to add a chapter on the current state of IntelliJ support for this combination

24 07 2009
Mark

You should take a look at scala.reflect.BeanProperty, THen you can write

@BeanProperty var id = 0

which is equivalent to

  private var id = 0
  def getId: Int = id
  def setId(id: Int) = this.id = id
24 07 2009
dhaat

Hi Mark

Thanks for the interest in this post, but… you don’t read the full post or all the comments, I touch the subject on the comments for the lines 13-14 and also in the blog post comments.

25 07 2009
Steven Calderon

@BeanProperty cooool
reduce duplicate code and made coding more fun, waiting for next post

28 07 2009
Chris Herron

Hi Mario,

I’m also looking forward to Intellij support for @BeanProperty – its just a matter of time. Its part of the Scala language spec, and we should soon have Scala property auto-completion from within JSPs and Java classes. Nested annotations will be great for Stripes work once Scala 2.8 is finalized.

Anybody interested should watch/vote for the related IntelliJ JIRA issues: http://www.jetbrains.net/jira/browse/SCL-980
http://www.jetbrains.net/jira/browse/SCL-1280

Chris.

28 07 2009
dhaat

Hi Chris

Thanks for the info.

18 09 2009
Thomas

Hi Chris,

Great article on Stripes and Scala. Thank you for that. I am still looking for the killer-web-framework for Scala. Lift looks good, but unfortunately Lift has quite a few “esoteric” aspects, the documentation isn’t all that complete, and then there is the Maven tie-in you mentioned…

The stuff about @BeanProperty is typical for Java frameworks that have not been designed for Scala. I guess we just have to wait until more native Scala frameworks emerge. Or I might write my own… now that would be a silly idea. 🙂

Leave a reply to Steven Calderon Cancel reply