Two articles worth reading:
-
http://www.artima.com/scalazine/articles/stackable_trait_pattern.html:
an example of why trait ordering is significant, and a use case for
that flexbility.
-
http://jim-mcbeath.blogspot.com/2009/08/scala-class-linearization.html:
details of how the order is determined.
Now, as we look at the lift-json code, note that:
* JsonSupport overrides contentTypeInferrer.
* LiftJsonRequestBody extends ApiFormats, which overrides contentTypeInferrer
class Servlet1 extends ScalatraServlet with LiftJsonRequestBody with
JsonSupport {
// Linearization:
// JsonSupport
// LiftJsonRequestBody
// ApiFormats
// ScalatraServlet
// ...
// So JsonSupport's contentTypeInferrer runs before ApiFormats'
}
class Servlet2 extends ScalatraServlet with JsonSupport with
LiftJsonRequestBody {
// Linearization:
// LiftJsonRequestBody
// ApiFormats
// JsonSupport
// ScalatraServlet
// ...
// So ApiFormats' contentTypeInferrer runs before JsonSupport's
}
In theory, LiftJsonRequestBody could be written as:
trait LiftJsonRequestBody extends ScalatraKernel with ApiFormats
with JsonSupport
This would linearize JsonSupport before ApiFormats in both servlets
above, which is what you want. Whether that's what everybody would
want is a question I'm going to leave to Ivan, because he wrote these
modules and probably grasps nuances that I don't. :-)