Scalatra-Scalate 7. Deployment
The Scalatra website has instructions about deployment. For Java‐world, these instructions are well‐explained and concise. However, I’m going to walk a through‐line through them. We’re going to build a deployment server that is intended to sit behind another server, so will not face the web, so needs no tricks or security considerations. The server Jetty, which is used for the development, is good for this. Also, to talk about Jetty adds to the Scalatra guides.
Config Scalatra for generating WAR files
Check /pathToYourApp/target/webapp/WEB‐INF/web.xml. It should read,
This is where Java Servlet apps are traditionally configured for serving. But the Scala developers have tapped the configuration to make a nicer API. So check ‘/pathToYourApp/src/main/scala/ScalatraBootstrap.scala’, it should read as,
Add this line to kill the development returns that list debug info, like templates tried, errors thrown, etc. (any name not started with ’dev…’ will be ok). You can do this with an environment variable also, which is will work automatically on deployment. Here’s the direct way using configuration,
And here’s what you would add to ScalaraBootsrap for the environment variable,
Set the SCALATRA_ENVIRONMENT variable to a value starting in ‘dev’ and the Scalatra instance is in development mode. Set it to anything else, or don’t set at all, and the Scalatra instance is in production mode.
You can influence some other things in the ScalatraBootstrap function, such as change ports, change headers, bootstrap database connections etc. Here I switch CORS off (either the server routes accept no user data, or the headers are handled by a proxy server), and jetty runs on localhost with a new port,
There’s plenty more. We’re not bothered.
Choose a Servlet container
The Scalatra instructions talk about a few ways to do this. As the Scalatra writers say, “there are many Servlet containers available”. Which to choose? The problem is they are all different, and loaded with Java‐world jargon. Scalatra’s example is of Apache Tomcat. Tomcat is an old server. It is intended as a reference Servlet container, and comes with a few extras such as templating engines, file serving and temporary re‐routing (note: the Apache server itself can not run Servlets—Tomcat is sometimes used behind it). I can’t be bothered to wade through the promotional material to reach some facts. For this guide I use Jetty again. Jetty is a server for when you have no extra needs, and one thing on your mind.
You need a Java JVM on your machine. OpenJRE will work. Now you need Jetty. But you get to the site, which version to get? I’m going to tell you—2022 you need Jetty 10. Now you can skip the text under this heading. But if you wade into trouble, come back, see what I did.
A short story of picking a Jetty version
You could look in ‘/pathToMyApp/build.sbt’, see which Jetty version the development environment uses. That’s got some guarantees. Then again, these components are supposed to work to an interface standard, yes? For what it’s worth, my Scalatra used Jetty 9.4. But 10 and 11 are the supported Jetty versions, so I downloaded 11.0.
I made WAR deployment before Jetty threw an error I was not equipped to handle,
The error was an issue. Javax is a tag for “we, the Java maintainers, are clearing this code for release, but it’s new, untried, or not core provision”. But, I complain, Servelets are stock Java from Java culture. And, except in rare scenarios, Java culture is strong for backwards compatibility. ServletContextListener has been about for, I guess, near 12 years. I found a reference in the logback‐classic‐1.2.3.jar,which makes sense—the logger wants to know when contexts start and stop. This API is used directly in Scalatra for boot and shutdown callbacks. I go rooting in the JAR files in Jetty and there is no file of that name.
I have no idea where the error comes from. So I try tighten error margins. I get a Jetty 9 same as the development build uses—‐got to give hope, yes? And I get Jetty 10 too, because it has a curious README note about being current with Jetty 11 but with an API change (not for Servelets, surely?). Jetty 9 gives me grief about filepaths, but at this point I don’t care. Then it works. So it looks like Java Servlets, or Jetty’s handling of them, has changed. And then, Jetty 10 works. Alright. Jetty 10 it is. Now I can work on useful things.
Install Jetty
Download a Jetty. Put it somewhere (/opt/ is the usual, but whatever) and extract. Start a terminal,
Note something. Jetty documentation keeps talking about $JETTY_HOME. This is the place you are now, /jettyTopDirectory/, so I’m stripping all that. Jetty will issue warnings—a security risk, and messy for multiple configurations—but we build here a trail deploy, not the final version. You’re running the start.jar for most of this, ok? Go to the directory, work direct. Run,
Should return errors. Because the Jetty you have is a minimal shell. Jetty has nothing to run.
Jetty Modules
Let’s look what’s available,
What this doesn’t tell us is what Scalatra’s rig contains. Now, I’ve already talked about how it is beyond mortality to ask for that information from SBT. I going to do everyone a favour, you and me, and tell you Scalatra configures this, and a whole load more, in ‘/home/rob/Downloads/scalatra‐main/project/Dependencies.scala’. Here it is,
jetty‐server
jetty‐plus (enables Servlet 3.1 resource injection)
jetty‐servlet
websocket‐server
jetty‐webapp
We’re after a bare minimum, behind proxy server, so that’s the basics. But you also need, because this is not a development server, the ‘deploy’ and ‘http’ modules,
deploy
Enables web application deployment from the $JETTY_BASE/webapps/ directory
http
Basic outward facing HTTP delivery
This assumes web, not UNIX, sockets. Now we know what the development server uses, let’s put the bare bones into the deploy server (the rest for you to choose),
You may not need JSP, but Scalatra is geared into JSP, and the build will spit warnings. And, ok, if you’re interested in a Unix Socket… note that Java 16+ will use a new module, unixdomain‐http. Also, you don’t need http module for a unixsocket. For now,
You may also want,
You’ll find, via dependency resolution, these may pull in other modules.
List modules,
Can I remove a module? No, but you could clear out the initialisation trigger in ‘/start.d’. That will disable them. Also good,
I assume you are already on a packed development machine, or maybe a test deploy. If you have Scalatra on the same machine, it will be using that overloaded port 8080, so you’ll need a new port. If you need that, in ‘/start.d/http.ini’ uncomment,
Then change to something else. Now,
if you go visit, you get a 404 error,
But that 404 error is a Jetty response! Ask me that’s ace. No package management, with it’s undocumented configurations and placements, no computer language installations, no permissions issues (that’s my responsibility, later). And configuration in a few well‐placed files. And solid help straight from the commandline. Java as it could have been, should be.
Deploy the webapp
Ok, this is welcome! A running server. Time to see if this Servlet/WAR placement gear works. Back to the Scalatra development environment. Run SBT but don’t launch the server, run this command (if you must, ‘task’),
Mine didn’t tell me where the package went. It’s in ‘/pathToYpurApp/target/scala‐X.XX.appnane_versionString.war’.
Copy the WAR file to Jetty. Put it in the ‘webapps’ directory (if the directory not exists, you didn’t install the ‘deploy’ module). Now Jetty must be restarted. From Jetty documentation,
The auto discovery features of the Servlet Specification can make deployments slow and uncertain. Auto discovery of web application configuration can be useful during the development as it allows new features and frameworks to be enabled simply by dropping in a jar file. However for production deployment, the need to scan the contents of many jars can have a significant impact at startup time.
Applies to all Servelet containers. Jetty configures for this.
Choose if and when to extract WARs.
End of Part Seven
End of Part 7. Ought to be the end of things. But it isn’t, because it never is, not here. In this world, it never is. And, if you’ve been following, I’d be selling and selling short if I left it here. Part Eight awaits.
Refs
Apache documentation on Jetty. You will need quiet, coffee, and endurance,
https://www.eclipse.org/jetty/documentation/jetty-11/operations-guide/index.html
Good instructions (in this world, miraculous) on server deployment,