Web Application Deployment
When using the Jetty server libraries in your code, web applications are typically assembled by composing the required Handlers, as explained in this section.
When the Server instance is started, web applications are also started; there typically is no deployer component that can deploy web applications after the Server instance is started.
The deployer component is the key component to deploy web applications when using Jetty as a standalone server, and it is detailed here.
However, it is possible to use the Jetty server libraries in your code with the deployer component, so that you can deploy web applications after the Server instance is started.
The Maven artifact coordinates are:
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-deploy</artifactId>
<version>12.1.4</version>
</dependency>
The main components to set up are:
-
A
Deployer, by defaultorg.eclipse.jetty.deploy.StandardDeployer. The deployer component is responsible for adding and removing aContextHandler(or subclass) instance, that represents a web application, from theHandlertree, and is responsible for the lifecycle (starting and stopping) theContextHandler. -
A
DeploymentScanner, that scans directories for files or directories that represent web applications. Typical web application files are*.war,*.propertiesand*.xmlfiles. When a web application file or directory is added/updated/removed,DeploymentScannercreates or retrieves (depending on the event) the correspondingContextHandlerand calls theDeployerto deploy/redeploy/undeploy the web application.
Each web application is deployed to a specific environment.
The environment allows you to specify environmental properties that will be available to all web applications, as well as a ClassLoader that loads classes that are specific to the environment.
Furthermore, the environment determines how the web application file should be interpreted: if it is a directory, whether it should be interpreted as a Jetty Static web application, or as a Jetty Core web application, or as a Jakarta EE exploded *.war.
By default, there are no environments; you must always create at least one, depending on the type of deployment you want for your web applications.
Simple Deployer Setup
The simplest deployer setup is when you deploy a web application via Jetty context XML file:
Server server = new Server();
// ContextHandlerCollection is required by the deployer.
ContextHandlerCollection contexts = new ContextHandlerCollection();
server.setHandler(contexts);
// Optional, shows the contexts deployed on the Server.
server.setDefaultHandler(new DefaultHandler());
// Create the deployer.
Deployer deployer = new StandardDeployer(contexts);
// Create the DeploymentScanner to monitor the webapps directory.
DeploymentScanner scanner = new DeploymentScanner(server, deployer);
scanner.setWebappsDirectories(List.of(Path.of("/path/to/webapps")));
// Link the lifecycle of the DeploymentScanner to the Server.
server.addBean(scanner);
// Create an environment, with the name of your choice,
// and no extra class-path or module-path.
EnvironmentBuilder envBuilder = new EnvironmentBuilder("simple");
Environment environment = envBuilder.build();
// Tell the DeploymentScanner about the environment
// it should use to deploy web applications.
scanner.configureEnvironment(environment.getName());
server.start();
With this simple setup, you can only deploy Jetty context XML files. In the Jetty context XML files, you can only reference classes that you have in the class-path or module-path, for example:
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.server.handler.ContextHandler">
<Set name="contextPath">/acme</Set>
<Set name="handler">
<New class="com.acme.WebAppHandler" /> (1)
</Set>
</Configure>
| 1 | This class must be in the class-path or module-path. |
| Do not be tempted to use this simple setup to deploy Jetty Core web applications, Jetty Static web applications, or Jakarta web applications; their setup is described their respective sections below. |
Jetty Static Deployer Setup
For Jetty Static web applications, the setup is the following:
Server server = new Server();
// ContextHandlerCollection is required by the deployer.
ContextHandlerCollection contexts = new ContextHandlerCollection();
server.setHandler(contexts);
// Optional, shows the contexts deployed on the Server.
server.setDefaultHandler(new DefaultHandler());
// Create the deployer.
Deployer deployer = new StandardDeployer(contexts);
// Create the DeploymentScanner to monitor the webapps directory.
DeploymentScanner scanner = new DeploymentScanner(server, deployer);
scanner.setWebappsDirectories(List.of(Path.of("/path/to/webapps")));
// Link the lifecycle of the DeploymentScanner to the Server.
server.addBean(scanner);
// Create the static environment.
EnvironmentBuilder envBuilder = new EnvironmentBuilder("static");
envBuilder.addClassPath("/path/to/jetty-staticapp-12.1.4.jar"); (1)
Environment environment = envBuilder.build();
// Tell the DeploymentScanner about the environment, and configure it for deployment.
DeploymentScanner.EnvironmentConfig envConfig = scanner.configureEnvironment(environment.getName()); (2)
envConfig.setDefaultContextHandlerClassName("org.eclipse.jetty.staticapp.StaticAppContext");
server.start();
| 1 | The environment is configured with its own class-path. |
| 2 | Jetty Static web applications use StaticAppContext as their ContextHandler, so web application directories are interpreted as having the Jetty Static web application format. |
Your Jetty Static web application is a directory, for example acme-asset/, under /path/to/webapps/:
/path/to/webapps/
└── acme-assets/
├── css/
│ └── styles.css
└── index.html
Jetty Core Deployer Setup
For Jetty Core web applications, the setup is the following:
Server server = new Server();
// ContextHandlerCollection is required by the deployer.
ContextHandlerCollection contexts = new ContextHandlerCollection();
server.setHandler(contexts);
// Optional, shows the contexts deployed on the Server.
server.setDefaultHandler(new DefaultHandler());
// Create the deployer.
Deployer deployer = new StandardDeployer(contexts);
// Create the DeploymentScanner to monitor the webapps directory.
DeploymentScanner scanner = new DeploymentScanner(server, deployer);
scanner.setWebappsDirectories(List.of(Path.of("/path/to/webapps")));
// Link the lifecycle of the DeploymentScanner to the Server.
server.addBean(scanner);
// Create the core environment.
EnvironmentBuilder envBuilder = new EnvironmentBuilder("core");
envBuilder.addClassPath("/path/to/jetty-coreapp-12.1.4.jar"); (1)
Environment environment = envBuilder.build();
// Tell the DeploymentScanner about the environment, and configure it for deployment.
DeploymentScanner.EnvironmentConfig envConfig = scanner.configureEnvironment(environment.getName()); (2)
envConfig.setDefaultContextHandlerClassName("org.eclipse.jetty.coreapp.CoreAppContext");
server.start();
| 1 | The environment is configured with its own class-path. |
| 2 | Jetty Core web applications use CoreAppContext as their ContextHandler, so web application directories are interpreted as having the Jetty Core web application format. |
Your Jetty Core web application is a directory, for example acme-core-app/ under /path/to/webapps/:
/path/to/webapps/
└── acme-core-app/
├── static # Static files are served from this directory.
│ └── favicon.ico
├── classes # Where web application Java classes reside.
│ └── com
│ └── acme
│ └── AcmeHandler.class
├── lib # Where web application Java libraries reside.
│ └── acme-util.jar
└── jetty-web.xml # Web application specific configuration.
With this setup you have the following class loader hierarchy, with the standard parent first model for class loading:
System ClassLoader # jetty-server-12.1.4.jar, etc.
└── Environment ClassLoader # jetty-coreapp-12.1.4.jar
└── Jetty Core App ClassLoader # acme-core-app/classes/:acme-core-app/lib/acme-util.jar
Jakarta Deployer Setup
For Jakarta web applications, the setup is the following:
Server server = new Server();
// ContextHandlerCollection is required by the deployer.
ContextHandlerCollection contexts = new ContextHandlerCollection();
server.setHandler(contexts);
// Optional, shows the contexts deployed on the Server.
server.setDefaultHandler(new DefaultHandler());
// Create the deployer.
Deployer deployer = new StandardDeployer(contexts);
// Create the DeploymentScanner to monitor the webapps directory.
DeploymentScanner scanner = new DeploymentScanner(server, deployer);
scanner.setWebappsDirectories(List.of(Path.of("/path/to/webapps")));
// Link the lifecycle of the DeploymentScanner to the Server.
server.addBean(scanner);
// Create the ee11 environment.
EnvironmentBuilder envBuilder = new EnvironmentBuilder("ee11");
envBuilder.addClassPath("/path/to/jakarta.servlet-api-6.1.0.jar"); (1)
envBuilder.addClassPath("/path/to/jetty-ee11-servlet-12.1.4.jar");
envBuilder.addClassPath("/path/to/jetty-ee11-webapp-12.1.4.jar");
Environment environment = envBuilder.build();
// Tell the DeploymentScanner about the environment, and configure it for deployment.
DeploymentScanner.EnvironmentConfig envConfig = scanner.configureEnvironment(environment.getName());
envConfig.setDefaultContextHandlerClassName("org.eclipse.jetty.ee11.webapp.WebAppContext"); (2)
envConfig.setDefaultsDescriptor("/path/to/ee11-default-web.xml"); (3)
// Other relevant Jakarta environment configurations.
server.start();
| 1 | The environment is configured with its own class-path, that includes the Servlet API *.jar and the Jetty implementation `*.jar`s of the Servlet APIs. |
| 2 | Jakarta web applications use WebAppContext as their ContextHandler, so web application *.war files or directories are interpreted as having the Jakarta web application format. |
Your Jakarta web application is a *.war file, for example acme.war under /path/to/webapps/:
/path/to/webapps/
└── acme.war
With this setup you have the following class loader hierarchy, with the standard Jakarta web application first model for class loading:
System ClassLoader # jetty-server-12.1.4.jar: etc.
└── Environment ClassLoader # jakarta.servlet-api-6.1.0.jar: etc.
└── Jakarta Web App ClassLoader # acme.war!/WEB-INF/classes/:acme.war!/WEB-INF/lib/*.jar
Multiple Environments
If you need to deploy web applications to different environments, for example core and ee11, the setup is the following:
Server server = new Server();
// ContextHandlerCollection is required by the deployer.
ContextHandlerCollection contexts = new ContextHandlerCollection();
server.setHandler(contexts);
// Optional, shows the contexts deployed on the Server.
server.setDefaultHandler(new DefaultHandler());
// Create the deployer.
Deployer deployer = new StandardDeployer(contexts);
// Create the DeploymentScanner to monitor the webapps directory.
DeploymentScanner scanner = new DeploymentScanner(server, deployer);
scanner.setWebappsDirectories(List.of(Path.of("/path/to/webapps")));
// Link the lifecycle of the DeploymentScanner to the Server.
server.addBean(scanner);
// Create the core environment.
EnvironmentBuilder coreEnvBuilder = new EnvironmentBuilder("core");
coreEnvBuilder.addClassPath("/path/to/jetty-coreapp-12.1.4.jar");
Environment coreEnv = coreEnvBuilder.build();
// Create the ee11 environment.
EnvironmentBuilder jakartaEnvBuilder = new EnvironmentBuilder("ee11");
jakartaEnvBuilder.addClassPath("/path/to/jakarta.servlet-api-6.1.0.jar");
jakartaEnvBuilder.addClassPath("/path/to/jetty-ee11-servlet-12.1.4.jar");
jakartaEnvBuilder.addClassPath("/path/to/jetty-ee11-webapp-12.1.4.jar");
Environment jakartaEnv = jakartaEnvBuilder.build();
// Tell the DeploymentScanner about the environments, and configure them for deployment.
DeploymentScanner.EnvironmentConfig coreEnvConfig = scanner.configureEnvironment(coreEnv.getName());
coreEnvConfig.setDefaultContextHandlerClassName("org.eclipse.jetty.coreapp.CoreAppContext");
DeploymentScanner.EnvironmentConfig jakartaEnvConfig = scanner.configureEnvironment(jakartaEnv.getName());
jakartaEnvConfig.setDefaultContextHandlerClassName("org.eclipse.jetty.ee11.webapp.WebAppContext");
jakartaEnvConfig.setDefaultsDescriptor("/path/to/ee11-default-web.xml");
// Other relevant Jakarta environment configurations.
server.start();
The class loader hierarchy is the following:
System ClassLoader
├── core Environment ClassLoader
│ └── Jetty Core App ClassLoader
└── ee11 Environment ClassLoader
└── Jakarta Web App ClassLoader
With multiple environments, it is good practice to specify the web application *.properties file, as described in this section.