Tuesday, February 15, 2011

Using Rails from Scala

Using Rails from Scala? Yes, it is possible if you use RailsCrossing (https://github.com/yokolet/RailsCrossing). This is a following chapter of my previous blog post, The second step to Rails on RadBridge. As I wrote "I'll try Rails from Scala next." at the end of that blog post, I tried it today. How did it go? It worked just fine. Here's how I used Rails from Scala.

1. Preparation of Java web application project and Rails app

These are exactly the same as the previous post. See steps 1 through 3. This time, I named Java web application "Sycamore," but the rest of all are the same.

2. Scala Servlet for Rails

Writing Servlet by Scala is really easy. I read the article, The busy Java developer's guide to Scala: Scala and servlets for that and could easily follow. I don't explain about what is Scala Servlet because that's not my purpose. So, it's good for you to google or goto some sites to learn what it is.

Here's the Scala Servlet that initializes Rails app and dispatches HTTP request to Rails app:

package com.servletgarden.sycamore

import javax.servlet.ServletConfig
import javax.servlet.http.{HttpServlet, HttpServletRequest => HSReq, HttpServletResponse => HSResp}
import com.servletgarden.railsxing.CrossingServlet

class RailsScalaServlet extends CrossingServlet {
override def init(config: ServletConfig) = super.init(config)

override def doGet(request: HSReq, response: HSResp) = dispatch(request, response)

override def doPost(request: HSReq, response: HSResp) = dispatch(request, response)

Compare RailsScalaServlet above and SimpleSample Servlet in the previous post. Basically, both Servlet do the same thing. See the previous post for details about what those two servlets are doing.

That's it.

3. Scala Servlet Compilation

Before executing Scala Servlet, the Servlet needs to be compiled. The article mentioned above, "The busy...," explains how to do that. Also, Scala Ant Tasks section of Developer's Guides will help you to understand how to write build.xml. I'm using NetBeans and its Java web application projects, so I directly edited NetBeans' build.xml. My build.xml is https://gist.github.com/828420. It assumes the directory tree below:

Sycamore -+- src -+- java -+- com -+- servletgarden -+- sycamore -+- RailsScalaServlet.scala
+- web -+- META-INF -+- context.xml
+- WEB-INF -+- lib -+- Gemfile
| +- Gemfile.lock
| +- RailsCrossing.jar
| +- blog -+- Gemfile
| | +- README
| | +- Rakefile
| | +- ...
| +- jruby-complete.jar
| +- jruby -+- 1.8 -+- bin -+- bundle
| | | +- erubis
| | | +- ....
| | +- cache -+- ...
| | +- doc
| | +- gem -+- abstract-1.0.0 -+- ..
| | +- gem -+- .... -+- ..
| | +- gem -+- bundler-1.0.10 -+- ..
| | +- gem -+- .... -+- ..
| | +- specifications -+- ...
| +- scala-compiler.jar
| +- scala-library.jar
+- index.jsp

In my case, NetBeans' build menu compiles Scala files and puts compiled classes under Sycamore/build/web/WEB-INF/classes directory.

4. Configurations

SimpleSample Servlet in the previous post uses annotation to configure the Servlet, thus, no web.xml is there. On the other hand, RailsScalaServlet uses web.xml to set rail_path and gem_path, and path mapping. The web.xml file is https://gist.github.com/828572.

Double check the context name of this Java web application has been changed to "blog." See "5. One More Setup" of the previous post.

5. Run Scala Servlet to use Rails

After starting tomcat, request http://localhost:8080/blog/home/index from a web client. Like in the previous post, familiar Rails default page will show up.

As I wrote how to here, using Rails from Scala is relatively easy. If you want to mix Scala code and Rails results, you can use methods of CrossingHelpers bypassing CrossingServlet. Also, you can use JRuby's ScriptingContainer to take Rails classes out to call methods of them. Try this new Rails way.

No comments: