As I have mentioned earlier, I am a huge fan of grails and would love to ditch our existing java/spring/custom code framework and move to grails holistically. A few of our senior people on the team really want to move to scala to get rid of a lot of the clutter code we write in our java stacks. To further the grails cause, I decided to see if I could get the scala plugin for grails working and see how deeply I could integrate the scala code into the application. While I was at it I decided that I might as well throw in java as well for giggles. I really like both groovy and scala. Each language has its advantages, but there is a general consensus on the team at work that the statically typed scala would be better for our inline conversion of existing java code.
Setting Up The Environment
All the source code for this can be found at GitHub. You can pull it down via the command:
git clone [email protected]:ctoestreich/grails-scala.git
I am assuming you will be using IntelliJ (as it is my favorite IDE). If you are using Eclipse you will be on your own for a lot of the set up pieces. I am also assuming you have grails already setup on your machine correctly. The first thing to do is install the scala plugin for grails via the following grails command:
grails install-plugin scala
If you are using IntelliJ, you should also install the scala plugin for IDEA
Starting The Coding
I started the coding and realized that I needed to be conscious about what type of objects inherited from what type of interfaces/traits. I initially tried having everything inherit from a Java Interface. This solution compiled and worked okay. I then moved to trying to get everything to extend a groovy interface. The code exploded. It was immediately obvious that the scalac command was run first and compiling the scala and java sources before groovy. Having the java and scala extend a groovy interface wasn’t going to work. In the end I decided to go with a scala trait due to its enhanced functionality and support in scala and standard java interface usage. I spent the majority of my time fuddling with this compilation order problem and getting the three languages to compile nicely together.
First I defined a scala trait.
1 2 3 4 5 6
Then I created the following objects.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
One thing to note is that the directory structure matters. There is a bug with the scala grails plugin at the time I wrote this post with grails 1.3.5+ and scala plugin 0.5. I had to go into the scala plugin Events.groovy code and comment out the following line:
I found the following note on the now-depreciated plugin page (not sure why this is gone now since the version didn’t change).
NOTES: current 0.5 version seems incompatible with Grails 1.3 As quick and dirty fix we do the following to the installed script scala-0.5/scripts/Events.groovy:
* comment out //addScalaToCompileSrcPaths(compileBinding) * then we have to put scala sources under src/java (src/scala is not usable)
I have all my scala code under src/java/com/far/scape/scala. I decided to put it in a dir under the package named scala so it was easier to differentiate.
I created a regular grails service under grails-app/services/[package- name]/GrailsService.groovy. I mocked up a save method on the interface and put an implementation in each class. Ideally I will be able to actually persist the objects, but for now I just used save on the interface to see how well the trait worked across java, scala and groovy.
1 2 3 4 5 6 7 8 9 10 11 12 13
Testing The Code
I wrote a really simply integration test to pass all the object types to the grails service saveObject method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
To run the integration tests execute the command below. The -echoOut is to show the output from any print statements you have in your tests.
grails test-app -echoOut
Here is the result
I played around a bit with creating a scala service. I was able to get it working as a standard manually created bean, but didn’t get the auto- wiring/injection of the scala service working in the integration tests. Granted, I didn’t try that hard as I wanted to make that a topic of another post.
Client Side Code
I also added a simple controller and view to test adding different objects to gsp page.
1 2 3 4 5 6 7 8 9 10 11 12
Then I created an index.gsp under grails-app/views/moya.
1 2 3 4 5 6 7 8 9 10
This should render the following:
All the source code for this can be found at GitHub.