Scalatra-Scalate 8. Deployment Aggro

Robert Crowther Apr 2022
Last Modified: Feb 2023

Ptev

Easy? This ain’t easy. Only way it’s easy is if they kill you.

Errors with WAR deployment

I’m not going to pretend all is good here. Your webapp could fail for many reasons. Here are two I faced,

... did not find org.eclipse.jetty.jsp.JettyJspServlet
... java.lang.NoClassDefFoundError: javax/servlet/ServletContextListener

Jetty did launch, told me the context of my app, and that ‘503 Service Unavailable’. Which is any error you can think of—Jetty was unable to handle the webapp.

Of the two errors, JSP stands for Java Service Pages, the Java templating system. I figured that may be because, at this point, I had Scalate gear in the WAR. So, for interest, I loaded the Jetty JSP module. That error disappeared. As for the second error, that was because I was running Scalatra, geared for Jetty 9, on Jetty 11. See back one step for the story. On Jetty 10, no error.

Issues with WAR deployment

My SBT packaged with WAR filenames like,

/target/scala-2.13/adaysearch_2.13-0.0.1.war

The Scalatra guides showed some ‘‐SNAPSHOT.’ type filenames.

Why is this significant? Java. a Servlet container uses a thing they call a ‘Context’. What this means, because you can have several apps in one container, they are namespaced. Namespaced in URLs too. So,

http://host/appName1/originalURL
http://host/appName2/originalURL
http://host/appName3/originalURL
...

This is what the Scalatra instructions are on when they talk about moving Tomcat root. That you have an extra URL segment to account for. Difficult, error‐prone. Any way round this? From Jetty documentation, if you name the WAR file

ROOT.war

it will deploy as an empty context. Sorry, I’ve not tried this, so can’t confirm.

It gets worse. The context seemed to come,not from the name of the Scalatra project (logical), but from the filename of the WAR. So my initial WAR packages need to be called as,

http://host/projectName_2.13-0.0.1/hello

Java. If you have only one app, two‐down‐difficult. Any way round this? At least having a manageable context name? I’d say no. It’s in SBT, and SBT is unconfigurable. I gave the problem ten minutes, found the build definition in Scalatra source, weighed that I can’t change that, that I have no start for an override, that I have no idea how to change anything in SBT anyway…. then used a BASH hack and URL jiggery for local deployment.

More modules for Jetty

Jetty has a range of modules available. The modules are to the point, extensive, and easy to configure. List them and have a look. Considering what we said this server was for, you may be interested in,

https

Adds HTTPS protocol support to the TLS(SSL) Connector

http‐forwarded

Enables processing of the ”Forwarded” HTTP header (and it’s predecessors ”X‐Forwarded‐*” HTTP headers)

gzip

Enables GzipHandler for dynamic gzip compression for the entire server (though the Scalatra fix will do this one for you)

quickstart

Enables the Jetty Quickstart module for rapid deployment of preconfigured web applications. When Jetty says ‘quickstart’… for some mucking about with understanding, this module can bring deployment down from seconds to milliseconds

threadpool

Enables and configures the Server ThreadPool. That’s what it says, but Jetty uses a threadpool anyway, this lets you configure it. I think you must have some heavy needs to be doing that

unixsocket

Enables a Unix Domain Socket Connector

If running on a UNIX machine, you may be interested in UNIX sockets. These are sockets like web‐facing sockets. Ports and all that, but internal. They allow one program to connect to another. UNIX sockets are not the last word in interprocess communication, but they’re fast and can easily connect one program to another. So a server that can handle them (NGINX, I recall, but not Apache) can talk to the Jetty server. Through a connection that has no interface to the outside, which is a win everyway I can think.

Towards deployment

Not going into all this, but,

Key line for automation

These references are environmental variables,

Jetty is started by executing $JETTY_HOME/start.jar from within a $JETTY_BASE directory,

Slightly more about Jetty and $JETTY_HOME, $JETTY_BASE

Jetty splits sites—it has the runnable someplace, the config elsewhere. Because the above is a guide to a test deploy, I put it all in one place. This is not the best, Jetty deliberately splits these things and there are reasons. First you can use different configurations for one install of Jetty and, second, it makes auto‐start of Jetty easier.

Sadly, the way to set Jetty is environment by variables. In UNIX, for a single user,

sudo nano ~/.bashrc

Add,

export JETTY_HOME= pathToJetty
export JETTY_BASE= pathToAConfigurationDirectory
export SCALATRA_ENVIRONMENT=production

For all users,

sudo nano /etc/profile.d/jetty-locations.sh

Add,

export JETTY_HOME= pathToJetty
export JETTY_BASE= pathToAConfigurationDirectory
export SCALATRA_ENVIRONMENT=production

Yeh, I pushed in an environment variable for Scalatra too. To enable, add to ScalatraBootstrap,

context.setInitParameter("org.scalatra.environment", sys.env.get("SCALATRA_ENVIRONMENT"))

‘sys.env’ is quiet, returns empty string if finds nothing, so Scalatra installations will without the environment variable default to ‘development’.

End of Part Eight

I made it. Test server Jetty runs WARS. I don’t know about you. I have a story.

Story

I was once put in contact with a woman. Within seconds I could tell she had the skill to see. She was studying computing at university, a season of database and Java. She was in a wasteland. She faced the storm. She was an uncrushable person, so Java and the Evangelists had stamped her into the floor. She had lost the path, and now wandered the dark. I hope she finds a home. Someone needs her.

Refs

There’s acres of Java, it’s impossible to map, nobody ever comes back, but this page does as well as any page ever will,

https://genius.com/Pere-ubu-hell-lyrics