WAR Deployment
Java web applications are commonly deployed to web containers, also called Servlet containers or application servers. Web containers manage the runtime environment and lifecycle of an application. Popular web containers include Jetty, Tomcat, and JBoss. Some hosting services such as AWS Elastic Beanstalk also function as web containers.
To deploy an application to a web container, you must package it as a
Web Archive
(WAR) file. A WAR file is just a Java [JAR] file with
a particular internal layout and a .war
extension.
Step One: Prepare Your Project
When running your application locally at the REPL, you will want to have your choice of servlet container running inside your JVM, and so the servlet container, and the Pedestal adaptor for the container, will be a dependency of your project.
In this mode, you are running the servlet container embedded within your application; you application starts and, as part of that, starts the servlet container.
For example, if you are using Jetty, then you’ll want the io.pedestal/pedestal.jetty
library.
This is a perfectly fine way to run your applications in production, but since you are reading this page, you are interested in deploying as a WAR instead, and the rules are slightly different.
By contrast, a WAR file should not contain dependencies on the servlet container. At runtime, the servlet container starts up, then creates a new class loader to load your WAR. Having the servlet container’s classes present in the WAR will create deployment conflicts.
A WAR file contains all the dependencies of your application, but it should not contain any dependencies which would conflict with the web container itself.
You should ensure that your application only depends on the io.pedestal/pedestal.service
library; the dependency on a container (such as pedestal.jetty
) should be in a dev-only or test-only path.
Step Two: Configure Your Servlets
A WAR file must contain a special file called web.xml
which tells
the web container how to configure the application.
In the root directory of your project, create a file called web.xml
like the following example:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0" metadata-complete="true"> <description>Pedestal HTTP Servlet</description> <display-name>Pedestal HTTP Servlet</display-name> <servlet> <servlet-name>PedestalServlet</servlet-name> <servlet-class>io.pedestal.servlet.ClojureVarServlet</servlet-class> <init-param> <param-name>init</param-name> <param-value>YOUR_APP_SERVER_NAMESPACE/servlet-init</param-value> </init-param> <init-param> <param-name>service</param-name> <param-value>YOUR_APP_SERVER_NAMESPACE/servlet-service</param-value> </init-param> <init-param> <param-name>destroy</param-name> <param-value>YOUR_APP_SERVER_NAMESPACE/servlet-destroy</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>PedestalServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
Replace YOUR_APP_SERVER_NAMESPACE
with the "server" namespace
generated for your application by the Pedestal template. If your app
is called "myapp" then this would be the namespace myapp.server
.
The template-generated source file at src/myapp/server.clj
should contain
functions named servlet-init
, servlet-destroy
, and
servlet-service
.
Note: The url-pattern
in the XML above must match the routes
your Pedestal application is expected to handle and must match the
conventions of your web container. For example, if you are deploying
an application in the file myapp.war
, a typical web container will
expect it to have <url-pattern>/myapp/*</url-pattern>
. Therefore, your
application should have routes that begin with /myapp/
.
If your application will be deployed as the "root" web application in
the container, then you should leave <url-pattern>/*</url-pattern>
as
shown in the example above. Consult the documentation of your web
container for more details on Servlet mappings.
Step Three: Build the WAR (leinigen)
These instruction are out of date, surely there are Leiningen plugins to do this all? |
Working from a standard Unix shell (or Cygwin on Windows), run the following commands in your project directory.
Getting dependencies:
lein clean lein pom mvn dependency:copy-dependencies -DoutputDirectory=target/war/WEB-INF/lib
Copying your application files:
mkdir -p target/war/WEB-INF/classes cp -R src/* config/* resources/* target/war/WEB-INF/classes
Copying web.xml
:
cp web.xml target/war/WEB-INF
Creating the WAR file:
jar cvf target/YOUR_APPLICATION.war -C target/war WEB-INF
Replace YOUR_APPLICATION
with the name of your application.