You're viewing all posts tagged with scala

java.lang.NoClassDefFoundError: scala/ScalaObject with sbt

Spent some time trying to figure out why sbt no longer worked for me when I upgraded the sbt-launch jar to the 0.11.0 version.  It would complain about a NoClassDefFoundError on scala/ScalaObject.  0.10.0 and earlier versions of sbt ran perfectly.  The problem wasn’t related to a project configuration file as this error occurred even if I ran sbt in a completely empty directory.

Since I’m knew to scala and sbt, I wasn’t sure what it was doing behind the scenes, so I didn’t know where to look.  I’m sure it’s documented somewhere but the troubleshooting link I found didn’t help. 

I knew sbt managed scala versions behind the scenes, so not finding ScalaObject meant that the download was perhaps corrupt.  So the solution was to figure out where sbt puts these things.  I knew it created a local boot folder for new projects I created, but it turns out sbt also keeps a global boot folder under your home folder in ~/.sbt/boot/ (which was C:/Users/<username>/.sbt on my Windows 7 machine). 

Deleting this global boot folder so sbt recreates it was the key.  If you get a similar error message for a specific project, the local boot folder would probably be the culprit in that case.

hello world from scalatra

There’s been some buzz lately about Scalatra, which is a Sinatra like framework for Scala.  Sinatra is a very scaled down platform for web programming in Ruby.  Unlike many web frameworks (such as Lift, JSF, etc.) which tend to be very stateful and try to abstract away from the HTML and web technologies, Sinatra does no such thing.  It’s very low level, which can make it very fast to get up and going for smaller, stateless web applications, especially REST based services.  Scalatra is an attempt to bring that to the Scala world.

To create our Hello World webapp in Scalatra, we’ll first create a dummy project.  Create a new folder to hold our project and use the simple build tool (sbt) to create your project.

md HelloScalatra
cd HelloScalatra
sbt

You’ll get output like this:

Project does not exist, create new project? (y/N/s) y
Name: HelloScalatra
Organization: test
Version [1.0]:
Scala version [2.7.7]: 2.8.0
sbt version [0.7.4]:

Now you need to tell the simple build tool what additional libraries you need for your project. We’ll create a project build file to do that. This works kind of like a Gemfile in the sense that it lets the build tool know what dependencies we have. The build file is written in Scala itself.

Create the file ScalatraBuild.scala in the HelloScalatra/project/build folder.

// save as project/build/HelloScalatraBuild.scala
import sbt._

class ScalatraBuild(info: ProjectInfo) extends DefaultWebProject(info) 
{
  // scalatra
  val sonatypeNexusSnapshots = "Sonatype Nexus Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
  val sonatypeNexusReleases = "Sonatype Nexus Releases" at "https://oss.sonatype.org/content/repositories/releases"
  val scalatra = "org.scalatra" %% "scalatra" % "2.0.0-SNAPSHOT"
 
  // jetty
  val jetty6 = "org.mortbay.jetty" % "jetty" % "6.1.22" % "test"
  val servletApi = "org.mortbay.jetty" % "servlet-api" % "2.5-20081211" % "provided"
}

Now download the dependencies. This is similar to running bundle install in a Rails app.

sbt update

One drawback of Scalatra is that it is a Servlet-based framework. That means we aren’t getting away without creating a web.xml file. So let’s set that up. Since simple build tool uses maven conventions, we need to do that in the HelloWorld/src/main/webapp/WEB-INF folder.

HelloWorld/src/main/webapp/WEB-INF/web.xml:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
    <servlet>
        <servlet-name>HelloWorld
        <servlet-class>com.test.HelloWorld
    </servlet>

    <servlet-mapping>
        <servlet-name>HelloWorld
        <url-pattern>/*
    </servlet-mapping>
</web-app>

This says that we will have a Servlet handled by the com.test.HelloWorld.scala file (which we haven’t written yet) and it will respond on all URL patterns.

Now we can actually write our app. Simply create the HelloWorld/src/main/scala/com/test/HelloWorld.scala file:

HelloWorld/src/main/scala/com/test/HelloWorld.scala:

package com.test

import org.scalatra._

class HelloWorld extends ScalatraServlet {
    get("/") {
        "Hello World"
    }
}

Now we can start the web server:

sbt jetty

And we can browse to http://localhost:8080/ and we’ll see:

Hello World

#playframework, #scala, #siena, #gae fun

In my last post, I mentioned that I created a simple (very simple!) Google App Engine hosted Play! webapp, written using Scala.  The webapp simply tracks people who visit my blog.  More accurately, it tracks people who view a little PNG that one of the methods renders.  If someone GETs the image, I capture the visitor’s IP address and the time.  This won’t be replacing anyone’s use of Google Analytics anytime soon, I can assure you.

But for the edification of those who may want to play with Play! and Scala, this is what I did:

  • using Play! 1.1, create a new module: play new —with=scala
  • also add siena and gae to your application.conf
  • define the paths in your controller.  I just have two, the root path lists the recent visitors, and “/track” which renders the image and captures the visitor’s information.
controllers.scala:

def index {
val visits = Visit.recent
render(visits)
}

def track {
val trackedIP = new Visit
trackedIP.remoteAddress = request.remoteAddress
trackedIP.referer = request.headers.getOrElse("referer", None)
// store it in The Cloud(tm)
trackedIP.insert()
// this is the image they see
val file = Play.getFile("/public/images/favicon.png")
renderBinary(file)
}

Note the “getOrElse” call above. This is one of the nice features of Scala. This is there because request.headers is a Map and the referer key isn’t guaranteed to be there. In Java, we would do this:

Http.Header refererHeader = request.headers.get("referer");
String referer = "";
if (refererHeader != null) {
referer = refererHeader.toString();
}
trackedIP.referer = referer;

That’s quite a mouthful, and the Scala version is much more readable.

  • now, define the model.  Because we are deploying to Google App Engine, we will use the Siena module as Siena works much more naturally with that type of datastore than Hibernate.  I’ve never been able to get JPA with Hibernate to work on Google App Engine anyway.

The Visit class extends siena.Model and declares the properties that we will store on the database. The Visit object is a singleton; if we were writing a Java object, the static/class methods we put on the Visit.class are what we are putting in the Visit object here.  In our case, we simply create a method “recent” which returns up to 20 of the most recent visitors. The @Index on the date field is necessary so Siena can order by date, which we will do in reverse order (because we want the most RECENT visitors.)

models.scala:

import play._
import play.data.validation._
import siena._
import java.util.Date

class Visit extends Model {
@Id var id:Long = _
var remoteAddress : String = _
var referer: String = _
@Index(Array("date_index")) var date : Date = new Date
}

object Visit {
def recent:java.util.List[Visit] = Model.all(classOf[Visit]).order("-date").fetch(20)
}

Your views are done in the same manner that you would do them in a Java-based Play! application: via Groovy templates.  Of course, you can always replace the template engine with Scalate or whatever else you prefer, via Play! plugins.

One handy trick I learned was the use of the JavaConversions helper class, introduced in Scala 2.8, which adds some implicit conversions between Java and Scala collections classes. This way, if you want to process the result of our call to Visit.recent using Scala style closures, you could do this:

import scala.collection.JavaConversions._

Visit.recent.foreach(v => println(v.remoteAddress))

This isn’t the most useful application, but it does provide a nice starting point for toying with the language.

play!ing with scala

I decided to try my hand at learning Scala.  It’s supposedly the “next big JVM language” and the “Java killer” if you believe the hype machine.  Personally, I don’t think that’s true.  I think the next big JVM language that replaces Java will be a future Java.  If there’s one thing Oracle knows how to do well, it’s making money, and that can’t be bad for the future of Java.

That being said, it appears like it will be a few more years before we can get any meaningful improvements to the Java language, such as language support for properties, better type inference, and closures.  So for personal projects I find my eyes wandering away from the Java realm towards more recent developments like Scala or Fantom.  A part of me actually likes the Fantom language better, because of the pragmatic, boring by design, philosophy behind the language.  But Scala seems to be more mature, so — for the moment — I’ve decided to take a stab at learning it instead.

I’ve been using a self-contained Play! environment that the makers of the Play! framework released.  This runs a web environment on your local machine that makes it very easy experiment with the language: just edit a source file and hit refresh and to see the results.

I’ve also found that the Play! framework is an ideal way to play around with the language, and it made it dead simple to get a webapp up on Google App Engine written in the language.  I’ll talk about that webapp a little more in my next post.