Thursday, February 14, 2008

Using Scala in Webwork/Struts 2, Part 1

I have been searching for a language to learn, in addition to java, for 3 years now. For various reasons I wont get into (there are enough blogs about that topic as it is), none of them totally excited me for one reason or another, until I started reading about Scala the end of 2007.

I bought the Scala book from Artima and have read a bit of it, and also read Daniel's excellent Scala intro series. I havent yet read them for comprehension..just reading to get a feel for what Scala can do. I have to admit, so far, the potential of Scala excites me like Java did when i first started playing with it 10 years ago.

So..i sat down last night and decided to see if Scala would play nice with Webwork (we havent yet migrated to Struts 2, but i imagine if this code works in WebWork 2.2, it should work in Struts 2). Amazingly enough, Scala worked just fine with WebWork. The code is dumb, as I dont know enough Scala to be clever. Besides, I wanted to try the simplest thing i could first, to see what was possible.

I was able to subclass ActionSupport, wire it up in xwork.xml, and the action was called correctly and the jsp was displayed. Next i tried setting a field in my Scala action class, to see if webwork could set params, and if i would be able to access them in the jsp using the jstl expression language. I didnt really expect it to work, but to my surprise, it did! I havent tried anything more complicated yet, but i have proven that i can write a WebWork action in Scala, and WebWork will still set the variables for me from the request, and make them available in the jsp. Pretty sweet! I hope to try some more complicated integration over the next week or two and will blog the results.

For those of you who would like to see some sample code to try yourself, here are the steps/code i used.

1) Install Scala :)
2) I modified my Ant build based on the nice tutorial here (this also takes care of copying the 2 scala lib jars to my tomcat webapp directory).
3) I had to modify my NetBeans 6 project to included my build directory, so that it could find my compiled Scala class (and yes, code completion worked).
4) Created my ugly yet simple Scala Action class (ScalaTest2.scala):

import com.opensymphony.xwork.ActionSupport

class ScalaTest2 extends ActionSupport {
private var greeting:String = "bubba"
override def execute():String = {
println("hello from scala.....")
println("Greeting" + greeting)
"success"
}

def getGreeting():String = {
greeting
}

def setGreeting(greet:String):Unit = {
greeting = greet
}
}


Sorry about the formatting (how do you retain formatting when pasting code in a blog?). To get Webwork to set the parameter and make it available via the jsp, i had to use java style getters and setters. I bet there is a way around it doing something different in Scala, but again, my Scala knowledge is limited, and i wanted to test the simplest case i could to see if it would work at all). Notice i intialized greeting to a value, just to prove the value was getting overridden by WebWork from the request parameter. The println statements in the action was just to give me some serverside feedback.

5) Added a snipped to xwork.xml

<action name="scala" class="com.weather.vacationrentals.web.action.ScalaTest2">
<interceptor-ref name="fgBasicStack"/>
<result name="success">/pages/layouts/scalaTest.jsp</result>
</action>


Note that the interceptor is our custom stack (no relevance here yet) and this is declared in the webapp named "vacationrentals" and the webwork package "svc"

6) the jsp:

Hello from the scala action result: ${greeting}


7) Access the page via http://localhost/vacationrentals/svc/scala?greeting=steve

8) you get a page that says Hello from the scala action result: steve

Sweet! Again, this is a hello world type example, but it does show that it is possible to easily write WebWork actions in Scala with minimal work. I wont include the code here, but i wrote a utility class in Scala, and called it from a java WebWork action with no problems, too.

I cant wait to try a more complex integration when i get a bit of free time. I also need to learn enough Scala to write Scala, not Scala looking like Java.

Update: Thanks to Tom's tip in the comments, the Scala class can be rewritten (to remove the getter/setter) as:

import com.opensymphony.xwork.ActionSupport

class ScalaTest2 extends ActionSupport {
@scala.reflect.BeanProperty
private var greeting:String = "bubba"

override def execute():String = {
println("hello from scala2...")
println("Greeting" + greeting)
"success"
}
}

11 Comments:

At 10:17 AM, Anonymous Anonymous said...

Here's a short post I wrote on Scala bean properties to help with the getters and setters. That said, I'm still a newbie.

 
At 10:24 AM, Blogger Jeff C said...

Tom,

Thanks for the tip! I added the @scala.reflect.BeanProperty annotation to the var and removed the getter/setter and everything worked fine. excellent.

 
At 3:39 PM, OpenID villane said...

Now, if only all the frameworks would start supporting the Scala style getters and setters. While Scala makes defining the Java style accessors easy (with @BeanProperty), I like the Scala style even more:

When you type
var myProp = ...

Scala actually generates:
private[this] var someUniqueName = ...
def myProp() = someUniqueName
def myProp_=(newValue: TypeOfMyProp) someUniqueName = newValue

The last is actually setter that will be called when you do "obj.myProp = newValue"

So with Scala g/setters you always have uniform access! For the caller there is no difference between a method and a variable. This is way more powerful than Java's getter and setter explosion.

 
At 7:38 AM, Blogger Gregg Bolinger said...

I did something similar with Scala+Stripes as well as Groovy+Stripes. The thing about is, the cool factor kind of goes away once you realize what is happening. Neither ww/struts2 or stripes knows anything about scala/groovy. But as was "briefly" mentioned in the blog, the ANT script takes care of compiling the scripting languages down to bytecode. At that point its no different than a Java based Action compiled to bytecode.

I've thought about this process a whole lot and unless you are willing to move your entire stack to a scripting langauges (a la Grails) then what do you gain? Not much. You lose some getters/setters which most modern IDE's can generate for you anyway.

And if you are doing things right your Action (Controller) classes should be nothing more than getters/setters and events calling business services and handling the request.

 
At 2:17 PM, Blogger Jeff C said...

Greg,

Unless I am misunderstanding you, I disagree. I dont thnk the only benefits would be saving getters and setters. Ideally, i could run on top of a java web framework, like Struts2, Stripes, whatever..but do all of my coding in Scala. Thus i would have a layer in java (the web framework), but all the code for the application could be Scala. Then i could take advantage of most/all of the features of Scala, and still use a well tested and proven web framework underneath. That, to me, is a great way to introduce Scala into an organization.

 
At 2:05 AM, Anonymous Anonymous said...

[quote]
Now, if only all the frameworks would start supporting the Scala style getters and setters. While Scala makes defining the Java style accessors easy (with @BeanProperty),
I like the Scala style even more: ...
[/quote]

That's not going to happen soon.

What I don't understand is why scala invents its own naming scheme for accessor/mutator methods instead of using (always) the standard getter/setter pair. I prefer scala to Groovy, but IMO in this respect Groovy does it right.

 
At 11:19 AM, Blogger Gregg Bolinger said...

Jeff, you just slightly mis-understood what I said and/or don't understand grails. Grails uses SpringMVC so you are correct that the web framework itself doesn't need to be scala but what I was talking about when I said everything was model, controller, views, DAO, services. Everything pretty much except the underlying framework.

There are just a lot of things you won't get the benefit of by not going full stack. And if you truly want that then I'd suggest just picking up Grails. Of course there is a Scala based web framework also, can't remember the name.

 
At 9:03 PM, Blogger jambay said...

enjoyed your post, i've been playing with scala as well. regarding your comment on code-formatting in blog posts, i really enjoy using windows live writer (if you using a MS Windows platform). you can get plug-ins for code-formatting and i find it works pretty well to embed code in blog posts.
here is an example

 
At 11:41 AM, Blogger Gabriel C. said...

I've been playing with Scala too, and now is my favorite language!
I did a couple of blog entries about it too.

Gregg,
If we talk about Scala (don't know about Grails) the interoperability goes both ways: you can easily call Java code from Scala and vice versa, call Scala code from Java, that gives you the option to not switch the whole stack to Scala. You can have your favorite presentation framework in Java calling the application code concisely expressed in Scala which in turn access the database though your preferred and performant persistence framework. I think is a winning strategy.

Jeff,
I found that if you paste the code into Word or other MS app from Eclipse, it keeps the coloring (makes a hell of HTML code, though), I've used it a couple of times in my blog. Check to see if you like the results.

 
At 12:33 PM, Blogger Gregg Bolinger said...

With regards to code formatting I ran across this:

http://formatmysourcecode.blogspot.com/

And it works good. No syntax highlighting but the code looks nice. I've been using it recently on my weblog.

 
At 4:50 PM, Blogger Jeff C said...

Gents,

Thanks for the code formatting tips. I will try those out in my next blog (that contains code).

 

Post a Comment

Links to this post:

Create a Link

<< Home