Search code examples
scalaplayframeworksqueryl

No Class Definitions found scala/reflect/ClassManifest using play 2 bars tutorial


I'm trying to build the bars tutorial project from "Getting Started with Play 2, Scala, and Squeryl" by James Ward, Ryan Knight July 11, 2012.

I can get it to work okay until I enter the URL for the bars list (//localhost:9000/bars). At that point I receive the following error in my browser: "Execution Exception [RuntimeException: java.lang.NoClassDefFoundError: scala/reflect/ClassManifest]". If I refresh my browser I then get the following error: "[RuntimeException: java.lang.NoClassDefFoundError: Could not initialize class com.codahale.jerkson.Json$]".

I've tried creating this project using Activator, Command Line Play and Eclipse.

I know there are differences in the versions of dependencies, Scala and Play 2 between the tutorial and what I'm using and that may be causing my problem. But I don't know what that might be. I'm assuming that I'm missing something to do with scala/reflect/ClassManifest. But, I have a dependency included for "org.scala-lang" % "scala-reflect" % "2.10.3".

I'm running Play 2.2.1 built with Scala 2.20.3 running Java 1.7.0.

I've tried to include all the relevant code below.

Any help would be appreciated. Thanks

build.sbt

> import AddSettings._ name := "mysquerylapp"
> 
> version := "1.0-SNAPSHOT"
> 
> libraryDependencies ++= Seq(
>     "org.webjars" %% "webjars-play" % "2.2.0",
>     "org.webjars" % "bootstrap" % "2.3.1",
>     "org.scala-lang" % "scala-reflect" % "2.10.3",
>     "org.scalatest" % "scalatest_2.10" % "2.0.M8",
>     "com.codahale" % "jerkson_2.9.1" % "0.5.0",
>     "org.squeryl" % "squeryl_2.10" % "0.9.5-6",
>     "postgresql" % "postgresql" % "9.1-901-1.jdbc4",   jdbc,   anorm,   cache )
> 
> lazy val main = Project(id="main",
> base=file(".")).settings(play.Project.playScalaSettings:_*).autoSettings(userSettings,
> allPlugins, defaultSbtFiles)
> 
> //play.Project.playScalaSettings

application.conf

> # This is the main configuration file for the application.
> # ~~~~~
> 
> # Secret key
> # ~~~~~
> # The secret key is used to secure cryptographics functions.
> # If you deploy your application to several instances be sure to use the same key!
> application.secret="GZXuoBh0fnkNJh8B__1IsG5_YIi/Fw:W?=8[WB^k?=F?gR?X^oQ1J]fTqJB<ZZi1"
> 
> # The application languages
> # ~~~~~ application.langs="en"
> 
> # Global object class
> # ~~~~~
> # Define the Global object class for this application.
> # Default to Global in the root package.
> # application.global=Global
> 
> # Router
> # ~~~~~
> # Define the Router object to use for this application.
> # This router will be looked up first when the application is starting up,
> # so make sure this is the entry point.
> # Furthermore, it's assumed your route file is named properly.
> # So for an application router like `my.application.Router`,
> # you may need to define a router file `conf/my.application.routes`.
> # Default to Routes in the root package (and conf/routes)
> # application.router=my.application.Routes
> 
> # Database configuration
> # ~~~~~
> # You can declare as many datasources as you want.
> # By convention, the default datasource is named `default`
> #  db.default.driver=org.h2.Driver  db.default.url="jdbc:h2:mem:play"
> # db.default.user=sa
> # db.default.password=""
> 
> # Evolutions
> # ~~~~~
> # You can disable evolutions if needed
> # evolutionplugin=disabled
> 
> # Logger
> # ~~~~~
> # You can also configure logback (http://logback.qos.ch/),
> # by providing an application-logger.xml file in the conf directory.
> 
> # Root logger: logger.root=ERROR
> 
> # Logger used by the framework: logger.play=INFO
> 
> # Logger provided to your application: logger.application=DEBUG

routes

# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~

# Home page
GET     /                           controllers.Application.index
POST    /bars                       controllers.Application.addBar
GET     /bars                       controllers.Application.getBars

# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.at(path="/public", file)

1.sql

# --- First database schema

# --- !Ups

create sequence s_bar_id;

create table bar (
  id    bigint DEFAULT nextval('s_bar_id'),
  name  varchar(128)
);


# --- !Downs

drop table bar;
drop sequence s_bar_id;

Global.scala

import org.squeryl.adapters.{H2Adapter, PostgreSqlAdapter}
import org.squeryl.internals.DatabaseAdapter
import org.squeryl.{Session, SessionFactory}
import play.api.db.DB
import play.api.GlobalSettings

import play.api.Application

object Global extends GlobalSettings {

  override def onStart(app: Application) {
    SessionFactory.concreteFactory = app.configuration.getString("db.default.driver") match {
      case Some("org.h2.Driver") => Some(() => getSession(new H2Adapter, app))
      case Some("org.postgresql.Driver") => Some(() => getSession(new PostgreSqlAdapter, app))
      case _ => sys.error("Database driver must be either org.h2.Driver or org.postgresql.Driver")
    }
  }

  def getSession(adapter:DatabaseAdapter, app: Application) = Session.create(DB.getConnection()(app), adapter)

}

index.scala.html

@(form: play.api.data.Form[Bar])

@main("Welcome to Play 2.0") {

    @helper.form(action = routes.Application.addBar) {
        @helper.inputText(form("name"))
        <input type="submit"/>
    }

}

bar.scala

package models

import org.squeryl.{Schema, KeyedEntity}

case class Bar(name: Option[String]) extends KeyedEntity[Long] {
  val id: Long = 0
}

object AppDB extends Schema {
  val barTable = table[Bar]("bar")
}

application.scala

package controllers

import play.api.mvc._

import com.codahale.jerkson.Json
import play.api.data.Form
import play.api.data.Forms.{mapping, text, optional}

import org.squeryl.PrimitiveTypeMode._
import models.{AppDB, Bar}


object Application extends Controller {

  val barForm = Form(
    mapping(
      "name" -> optional(text)
    )(Bar.apply)(Bar.unapply)
  )

  def index = Action {
    Ok(views.html.index(barForm))
  }

  def addBar = Action { implicit request =>
    barForm.bindFromRequest.value map { bar =>
      inTransaction(AppDB.barTable insert bar)
      Redirect(routes.Application.index())
    } getOrElse BadRequest
  }

  def getBars = Action {
    val json = inTransaction {
      val bars = from(AppDB.barTable)(barTable =>
        select(barTable)
      )
      Json.generate(bars)
    }
    Ok(json).as(JSON)
  }

Solution

  • Changed the "com.codahale" % "jerkson_2.9.1" % "0.5.0" to "com.cloudphysics" % "jerkson_2.10" % "0.6.3" in the build.sbt file and that allowed me to move on.