Skip to content
This repository was archived by the owner on May 6, 2021. It is now read-only.

Latest commit

 

History

History
189 lines (140 loc) · 6.8 KB

File metadata and controls

189 lines (140 loc) · 6.8 KB
title order layout
How to Run and Deploy a Flow Application on Jetty
3
page

How to Deploy a Flow Application on Jetty

This article explains how to deploy a Vaadin Flow application on Jetty.

Jetty is an open-source project providing an HTTP server, HTTP client, and javax.servlet container.

Applications can be deployed to Jetty servers in 2 different ways:

  1. Embedded Jetty

    • (Using the Jetty Maven Plugin, only during development)

    • Starting the Jetty server Programmatically

  2. Standalone Jetty

    • Deploy web applications as a WAR package

    • Deploy web applications as an exploded directory

    • Deploy web applications using a Context File

Embedded Jetty

Using Jetty has the advantage that it can be instantiated and used in a standard Java program, meaning that it does not need to be separately installed on the server.

"Don’t deploy your application in Jetty, deploy Jetty in your application!" by Jetty.

Running Jetty programmatically requires some manual configuration to make it work with Vaadin.

main.java
public final class ManualJetty {
    public static void main(String[] args) throws Exception {
        Server server = new Server(8080);

        // Specifies the order in which the configurations are scanned
        Configuration.ClassList classlist = Configuration.ClassList.setServerDefault(server);
        classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration", "org.eclipse.jetty.plus.webapp.EnvConfiguration", "org.eclipse.jetty.plus.webapp.PlusConfiguration");
        classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration", "org.eclipse.jetty.annotations.AnnotationConfiguration");

        // Creation of a temporal directory
        File tempDir = new File(System.getProperty("java.io.tmpdir"), "JettyTest");
        if (tempDir.exists()) {
            if (!tempDir.isDirectory()) {
                throw new RuntimeException("Not a directory: " + tempDir);
            }
        } else if (!tempDir.mkdirs()) {
            throw new RuntimeException("Could not make: " + tempDir);
        }

        WebAppContext context = new WebAppContext();
        context.setInitParameter("productionMode", "true");

        // Context path of the application
        context.setContextPath("");

        // Exploded WAR or not
        context.setExtractWAR(false);
        context.setTempDirectory(tempDir);

        // It pulls the respective config from the VaadinServlet
        context.addServlet(VaadinServlet.class, "/*");

        context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*");

        context.setParentLoaderPriority(true);
        server.setHandler(context);

        // This add jars to the jetty classpath in a certain syntax and the pattern makes sure to load all of them
        List<Resource> resourceList = new ArrayList<>();
        for (String entry : ClassPathHelper.getAllClassPathEntries()) {
            File file = new File(entry);
            if (entry.endsWith(".jar")) {
                resourceList.add(Resource.newResource("jar:" + file.toURI().toURL() + "!/"));
            } else {
                resourceList.add(Resource.newResource(entry));
            }
        }

        // It adds the web application resources. Styles, client-side components, ...
        resourceList.add(Resource.newResource("./src/main/webapp"));

        // The base resource is where jetty serves its static content from
        context.setBaseResource(new ResourceCollection(resourceList.toArray(new Resource[0])));

        server.start();
        server.join();
    }
}

This programmatic configuration requires some extra dependencies in pom.xml:

pom.xml
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-project</artifactId>
    <version>${project.version}</version>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-webapp</artifactId>
    <version>${jetty.version}</version>
</dependency>
Note
Depending of Jetty’s configuration, it could require additional dependencies, such as: jetty-annotations,jetty-continuation,javax-websocket-server-impl, …​ For more information about jetty, please consult Jetty Documentation.

Standalone Jetty

Deploying to a standalone Jetty server can be done either by using a WAR file or an exploded directory with the application in it.

It is possible to change the name of the WAR file and exploded directory specifying the finalName in pom.xml:

pom.xml
<build>
    <finalName>application</finalName>
    ...
</build>

Deploying by Copying WAR

The easiest way to deploy a web application on a Jetty server is probably by copying the WAR file into the webapps directory of Jetty.

The WAR file can be generated executing the following Maven goal:

mvn package -Pproduction

After copying the WAR file into the webapps directory, you can start Jetty by navigating to Jetty’s folder and running the following command:

java -jar start.jar

Deploying by Copying Exploded Directory

An exploded directory is a folder containing the unzipped (exploded) contents and all the application files. It is actually an extracted WAR file (as WAR files are ZIP files).

The command mvn package creates the exploded directory before creating the WAR file, and can be used here as well.

Note
The WAR file and the exploded directory can be found with the same name in the target directory.

Deploying Using Context File

Jetty web server offers the possibility of deploying a web archive located anywhere in the file system by creating a context file for it.

jetty-app.xml
<?xml version="1.0"  encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
  "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
    <Set name="contextPath">/jetty</Set>
    <Set name="war">absolute/path/to/jetty-app.war</Set>
</Configure>

Spring Boot

If your Vaadin application is using Spring Boot, it requires an additional configuration for several aspects of the application.

One example of this is urlMapping:

vaadin.urlMapping=/my_mapping/*

An additional Servlet is required to handle the frontend resources for non-root servlets, such as /my_mapping/*. The servlet can be defined in your application class, see here for an example.

For more information about Spring configuration, please consult the Vaadin Spring configuration guide.