scalapugnosuchmethoderrorscalatrascalate

java.lang.NoSuchMethodError in Scalatra using Scalate with Markdown


So I have a Scalatra app (using Scalatra 2.2.1). I'm building views using Scalate; I've decided to go with the Jade/Markdown one-two. Only one problem: if I try to use markdown in a jade template (started with the :markdown tag), I get this:

scala.Predef$.any2ArrowAssoc(Ljava/lang/Object;)Lscala/Predef$ArrowAssoc;
java.lang.NoSuchMethodError: scala.Predef$.any2ArrowAssoc(Ljava/lang/Object;)Lscala/Predef$ArrowAssoc;

at org.fusesource.scalamd.Markdown$.<init>(md.scala:119)
at org.fusesource.scalamd.Markdown$.<clinit>(md.scala:-1)
at org.fusesource.scalate.filter.ScalaMarkdownFilter$.filter(ScalaMarkdownFilter.scala:32)
at org.fusesource.scalate.RenderContext$class.filter(RenderContext.scala:276)
at org.fusesource.scalate.DefaultRenderContext.filter(DefaultRenderContext.scala:30)
at org.fusesource.scalate.RenderContext$class.value(RenderContext.scala:235)
at org.fusesource.scalate.DefaultRenderContext.value(DefaultRenderContext.scala:30)
at templates.views.$_scalate_$about_jade$.$_scalate_$render(about_jade.scala:37)
at templates.views.$_scalate_$about_jade.render(about_jade.scala:48)
at org.fusesource.scalate.DefaultRenderContext.capture(DefaultRenderContext.scala:92)
at org.fusesource.scalate.layout.DefaultLayoutStrategy.layout(DefaultLayoutStrategy.scala:45)
at org.fusesource.scalate.TemplateEngine$$anonfun$layout$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(TemplateEngine.scala:559)
at org.fusesource.scalate.TemplateEngine$$anonfun$layout$1$$anonfun$apply$mcV$sp$1.apply(TemplateEngine.scala:559)
at org.fusesource.scalate.TemplateEngine$$anonfun$layout$1$$anonfun$apply$mcV$sp$1.apply(TemplateEngine.scala:559)

So that's pretty cool. The error vanishes as soon as I remove the :markdown flag, and beyond that everything compiles (beyond markdown not getting rendered correctly).

Things I know and have found so far:

  1. There's some thought that this error is the biproduct of incompatible Scala versions somewhere in the build. My build.scala defines Scala version as 2.10.0, which Scalatra is explicitly compatible with.
  2. ...that said, I have no idea which version of Scalate Scalatra pulls in, and my attempts to override it have not worked so far. I know the current stable of Scalate (1.6.1) is only compatible up to Scala 2.10.0 -- but that's what I'm using.
  3. I am, however, sure that my classpath is clean. I have no conflicting Scala versions. Everything is 2.10.0 in the dependencies.

Has anybody worked with this one before? Any ideas?

EDIT

Per request, here are my build definitions:

//build.sbt 
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M5b" % "test"                                                                                                                                     
                                                                                                                                                                                                           
libraryDependencies += "org.twitter4j" % "twitter4j-core" % "3.0.3"                                                                                                                                            
                                                                                                                                                                                                           
libraryDependencies += "org.fusesource.scalamd" % "scalamd" % "1.5" 

//build.properties
sbt.version=0.12.3

//build.scala
import sbt._                                                                                                                                                                                                   
import Keys._                                                                                                                                                                                                  
import org.scalatra.sbt._                                                                                                                                                                                      
import org.scalatra.sbt.PluginKeys._                                                                                                                                                                           
import com.mojolly.scalate.ScalatePlugin._                                                                                                                                                                     
import ScalateKeys._                                                                                                                                                                                           
                                                                                                                                                                                                               
object TheRangeBuild extends Build {                                                                                                                                                                           
  val Organization = "com.gastove"                                                                                                                                                                             
  val Name = "The Range"                                                                                                                                                                                       
  val Version = "0.1.0-SNAPSHOT"                                                                                                                                                                               
  val ScalaVersion = "2.10.0"                                                                                                                                                                                  
  val ScalatraVersion = "2.2.1"                                                                                                                                                                                
                                                                                                                                                                                                               
  lazy val project = Project (                                                                                                                                                                                 
    "the-range",                                                                                                                                                                                               
    file("."),                                                                                                                                                                                                 
    settings = Defaults.defaultSettings ++ ScalatraPlugin.scalatraWithJRebel ++ scalateSettings ++ Seq(                                                                                                        
      organization := Organization,                                                                                                                                                                            
      name := Name,                                                                                                                                                                                            
      version := Version,                                                                                                                                                                                      
      scalaVersion := ScalaVersion,                                                                                                                                                                            
      resolvers += Classpaths.typesafeReleases,                                                                                                                                                                
      libraryDependencies ++= Seq(                                                                                                                                                                             
        "org.scalatra" %% "scalatra" % ScalatraVersion,                                                                                                                                                        
        "org.scalatra" %% "scalatra-scalate" % ScalatraVersion,                                                                                                                                                
        "org.scalatra" %% "scalatra-specs2" % ScalatraVersion % "test",                                                                                                                                        
        "ch.qos.logback" % "logback-classic" % "1.0.6" % "runtime",                                                                                                                                            
        "org.eclipse.jetty" % "jetty-webapp" % "8.1.8.v20121106" % "compile;container",                                                                                                                        
        "org.eclipse.jetty.orbit" % "javax.servlet" % "3.0.0.v201112011016" % "compile;container;provided;test" artifacts (Artifact("javax.servlet", "jar", "jar"))                                            
      ),                                                                                                                                                                                                       
      scalateTemplateConfig in Compile <<= (sourceDirectory in Compile){ base =>                                                                                                                               
        Seq(                                                                                                                                                                                                   
          TemplateConfig(                                                                                                                                                                                      
            base / "webapp" / "WEB-INF" / "templates",                                                                                                                                                         
            Seq.empty,  /* default imports should be added here */                                                                                                                                             
            Seq(                                                                                                                                                                                               
              Binding("context", "_root_.org.scalatra.scalate.ScalatraRenderContext", importMembers = true, isImplicit = true)                                                                                 
            ),  /* add extra bindings here */                                                                                                                                                                  
            Some("templates")                                                                                                                                                                                  
          )                                                                                                                                                                                                    
        )                                                                                                                                                                                                      
      }                                                                                                                                                                                                        
    ) ++ seq(com.typesafe.startscript.StartScriptPlugin.startScriptForClassesSettings: _*)                                                                                                                     
  )                                                                                                                                                                                                            
}

Solution

  • When using the markdown filter, you need to add the scalamd library as runtime dependency:

    "org.fusesource.scalamd" %% "scalamd" % "1.6"
    

    The most recent version can be found on Maven Central

    Also you can delete the build.sbt file and put the dependencies into build.scala file which makes things a bit simpler.

    import sbt._
    import Keys._
    import org.scalatra.sbt._
    import org.scalatra.sbt.PluginKeys._
    import com.mojolly.scalate.ScalatePlugin._
    import ScalateKeys._
    object TheRangeBuild extends Build {
      val Organization = "com.gastove"
      val Name = "The Range"
      val Version = "0.1.0-SNAPSHOT"
      val ScalaVersion = "2.10.0"
      val ScalatraVersion = "2.2.1"
      lazy val project = Project(
        "the-range",
        file("."),
        settings = Defaults.defaultSettings ++ ScalatraPlugin.scalatraWithJRebel ++ scalateSettings ++ Seq(
          organization := Organization,
          name := Name,
          version := Version,
          scalaVersion := ScalaVersion,
          resolvers += Classpaths.typesafeReleases,
          libraryDependencies ++= Seq(  // adding this Seq to the libraryDependencies
            "org.scalatra" %% "scalatra" % ScalatraVersion,
            "org.scalatra" %% "scalatra-scalate" % ScalatraVersion,
            "org.scalatra" %% "scalatra-specs2" % ScalatraVersion % "test",
            "ch.qos.logback" % "logback-classic" % "1.0.6" % "runtime",
            "org.eclipse.jetty" % "jetty-webapp" % "8.1.8.v20121106" % "compile;container",
            "org.scalatest" %% "scalatest" % "2.0.M5b" % "test",
            "org.twitter4j" % "twitter4j-core" % "3.0.3",
            "org.fusesource.scalamd" % "scalamd" % "1.6",
            "org.eclipse.jetty.orbit" % "javax.servlet" % "3.0.0.v201112011016" % "compile;container;provided;test" artifacts (Artifact("javax.servlet", "jar", "jar"))
          ),
          scalateTemplateConfig in Compile <<= (sourceDirectory in Compile){ base =>
            Seq(
              TemplateConfig(
                base / "webapp" / "WEB-INF" / "templates",
                Seq.empty,  /* default imports should be added here */
                Seq(
                  Binding("context", "_root_.org.scalatra.scalate.ScalatraRenderContext", importMembers = true, isImplicit = true)
                ),  /* add extra bindings here */
                Some("templates")
              )
            )
          }
        ) ++ seq(com.typesafe.startscript.StartScriptPlugin.startScriptForClassesSettings: _*)
      )
    }