Scalatra-Scalate 5. I just wanna be

Robert Crowther Apr 2022
Last Modified: Feb 2023

PrevNext

Ok, we got through Post Two. A project has templates—that’s enough for a something. You’re now out there. But I will not leave you. I’d have that on my conscience.

Scattered answers about Scalate

Mostly, this is about the SSP template form, which is the most comfortable. But many of the remarks will give clues about the other Scalate forms.

How to get an object into a template

…given that Scatatra/Scatalte can spew an error “xxx not found: type ListRow’? Scala has this big deal that it is strongly typed. For this reason, you need to declare variables at the start of the template. And give types. The form for this is in the SSP reference documentation. This will give errors, but is correct in form,

<%@ val lr: ListRow %>

There is a variant—if you import a single object, you can break out the attributes using an ‘import’ statement,

<%@ import val lr: ListRow %>

This would let you address fields in an object directly. So not,

<%= ListRow.address %>

but,

<%= address %>

Like I said, will give an error. We need to address the issue of Java packaging.

How to import a class into a template

Or, how Java/Scala packaging works. Java has this big deal—packaging depends on folder structure, and yes, if you compile from different points in the structure, then packaging changes. Ah, and the name of a class in a file must match the name of the file. For some reason Scala decided to abandon these flexible and powerful conventions, and insist that you name the package at the top of the file. Possibly they did that because they did not understand the rigorous disciple that generations of lost man‐hours has brought to the Java community.

Anyway, to find the name of a Scala package, look in the file for the package declaration. If you put a class in the Servelet, then it’s probably at some mutation of the reverse URL name,

<%@ val lr: com.yourName.app.ListRow %>

Oh, wow, now I’ve got a different error! In Java‐wotld, I can charge money for that.

How to loop a Seq in an object?

So can it print repetitious HTML (surely the point of templates, hiding that stuff away?)? Java, and it’s template syatem JSP, make a big deal out of how their templates have ‘no logic’. Then that you can run any Java code in them. Anyway, how much lack of logic? Can we loop an object like a Seq() at all? This is where neither Scalatra nor Scalate documentation has answers.

First thing you need to know, Scala has a weird way of declaring object looping. Well, it has other ways, such as a groovy foreach() function, but that’s not going to work in a template. Actually, Scala’s ‘for’ declaration is syntactically elegant, cute, and logical—it’s other languages that get strange with their for…in syntax. Scala’s version is,

for (var x <- seqOfXes) {
  ...
}

Said you’d love it. And guess what? If we deduce how that is stated in a template, it works,

#for (x <- seqOfXes)
  ...
#end

I hope you followed how I did that. because, if you have no background here, you are in for a clamber through trenches of mud, in the rain, with dark coming, as rain jabs in your skin.

Precompiling

The Scalate site talks about pre‐compiling templates. And caching. I can find nothing on this. Though the sinatra‐scalate I used was recent, and it’s URL points to Scalatra.org, I could find no information about it, or a source. So, no idea if it is pre‐compiling, or pre‐compiles on WAR deployment. The only clue I had was from Scalate documentation,

Scalate can sometimes struggle with ClassLoaders…

My setup was showing these problems. So perhaps my setup wasn’t pre‐compiling? I unzipped the sinatra‐scalate JAR to find clues. I found a lot of stuff I never asked for.

I’m twitchy about these kinds of Java‐world issues. I’m suspicious of undocumented code installed with promises. I don’t know or care what scalatra‐scalate is. I’m not wasting time there. I have a way out. I’d used Scalte enough to whittle my app down to a couple of small templates. So I rewrote the templates as simple string‐builders, then tore out all Scalte from my app.

Scattered answers about Scalatra

A Java coder may say, “All they’ve done [the Scalatra coders] is configured the usual Servlet method with Jetty, then jazzed it up some. I can do it all in Java.” True, go back to your pie and chips. There’s a stunning amount of gear built into the Scalatra code. It wraps the Java gear with API access points. It has handlers for use cases like before(), after() and error(), and can construct URLs with url(). It can flow into asynchronous operation. There’s too much for the online guides—if you want to know more, download source. IF you want to know the supplementary code Scalatra has on board, look in,

scalatra-main/project/Dependencies.scala

where you will find Scalatra (2022) has Akka—the Scala multithread environment—a multipurpose JSON front‐end with the specific Jackson plugin, and a bucketload of metrics—performance testing—and unit test gear. Also look in,

scalatra-main/core/src/main/scala/org/scalatra/ScalatraBase.scala

If you can avoid the funny‐look type annotations, you’ll soon get an idea about Scalatra’s enhancement of Servlets—you’ll see the URL‐building functions, the enhanced request/response objects, the hooks for utility methods, and so forth. Finally, if you are serious about building an advanced app with power features, out there is a book about Scalatra, Scalatra In Action.

How do I add libraries?

Well, there’s this deal about things called Mavern and Ivy and Ant and a load more Java gear. In this SBT setup, it’s being automated for you. Use the instructions in Part 2. Briefly—search for the SBT line in Mavern Central, paste the line into ‘build.sbt’, run SBT. Despite the ‘continued development’ environment, you may need to restart SBT to make libraries download and install.

How to adjust headers and other features of response?

It’s probably not clear if this is handled by Jetty, Java or Scalatra. It’s Java, negotiated by Scalatra. You’re into a deep delve of source here. And knowing ‘rich’ means ‘enhanced’ in Scala. So a Scala‐enhanced version of the Java Servlet response is available,

/pathToSource/scalatra-main/core/src/main/scala/org/scalatra/servlet/RichResponse.scala

Look over Java Documentation of Servlet Responses. Or guess. Scala‐enhanced, this is the API of the super‐obvious, so these should work,

response.headers.set(name, value)
response.headers.update(name, value)

Where’s the context path?

I thought,

servletContext.contextPath

But this works,

servletContext.getRealPath("")

This is deep‐water Java. I get you moving.

Errors

You can catch errors from code and throw a reply,


  error (
      (e) => {
        halt(status = 506, body = <h1>Errot thrown in execution</h1>)
      }
  )

That there is what is called a partial function. ‘e’ is the exception thrown.

Can I GZip?

Here’s Scalatra documentation of the automatic way. Does quite a lot, Checks for GZip acceptance, then zips and adds a header.

Or gzip yourself—you need to zip the data, then add the header.

Can I modify Scalatra?

Agg. If you, to run this project, followed this guide then you used something called ‘g8’. This is Giter8, a configured piece of software that built the folder structure, ready for SBT to make a Servlet container project. The template then inserted the libraries like SBT, Scala, Jetty, Scalatra etc. These libraries were pre‐compiled versions, downloaded from Maven or other repositories. So no, you can’t change a compiled Scalatra.

Of course, there are ways out of this. One would be to allow the template to build the project, then remove SBT’s reference to Scalatra, replace with Scalatra source code. Then SBT can build it. Another would be to abandon the template, kindle a Java IDE like IntelliJ IDEA or Eclipse, then duplicate the template by creating a web container project. Into which you can insert Scalatra, the Jetty plugin, and the other gear you want. You would be building, but from basics. The fact these paragraphs have descended into gobbledegook ought to warn you, it is not worth the time.

End of Part Five

Yeh, this is Java‐world. Remember, it’s your fault. You’re to blame. However, you got extra code in there. That may be enough. You may be out there, trekking. Or you may not have taken enough. Part Six awaits.

Refs

Scalatra main guides,

https://scalatra.org/guides/2.8/

Scalate user guides,

https://scalate.github.io/scalate/documentation/user-guide.html