blob: d0cd4832f6679ca6f64fb8493ec69d564c1fa222 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.10">
<title>Eclipse Jetty: Old Documentation</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<link rel="stylesheet" href="./asciidoctor.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body class="article toc2 toc-left">
<div id="header">
<h1>Eclipse Jetty: Old Documentation</h1>
<div class="details">
<span id="author" class="author">Jetty Developers</span><br>
<span id="email" class="email"><a href="mailto:jetty-dev@eclipse.org">jetty-dev@eclipse.org</a></span><br>
<span id="revnumber">version 10.0.0-SNAPSHOT,</span>
<span id="revdate">2020-10-01</span>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Old Jetty Documentation</div>
<ul class="sectlevel1">
<li><a href="#_old-jetty-documentation">OLD JETTY DOCUMENTATION</a></li>
<li><a href="#alpn-chapter">Application Layer Protocol Negotiation (ALPN)</a>
<ul class="sectlevel2">
<li><a href="#alpn">Introducing ALPN</a>
<ul class="sectlevel3">
<li><a href="#alpn-conscrypt">ALPN and Conscrypt</a></li>
<li><a href="#alpn-jdk9">ALPN and JDK 9</a>
<ul class="sectlevel4">
<li><a href="#alpn-osgi">Starting in OSGi</a></li>
</ul>
</li>
<li><a href="#alpn-troubleshooting">ALPN Troubleshooting</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#annotations">Annotations</a>
<ul class="sectlevel2">
<li><a href="#annotations-quick-setup">Quick Setup</a>
<ul class="sectlevel3">
<li><a href="#_jetty-distribution">Jetty Distribution</a></li>
<li><a href="#_jetty-maven-plugin">Jetty Maven Plugin</a></li>
<li><a href="#_embedding">Embedding</a></li>
</ul>
</li>
<li><a href="#using-annotations">Working with Annotations</a>
<ul class="sectlevel3">
<li><a href="#_which-annotations-are-supported">Which Annotations Are Supported</a></li>
<li><a href="#discoverable_introspectable_annotations">Discovered vs Introspected Annotations</a></li>
<li><a href="#jars-scanned-for-annotations">Which Jar Files Are Scanned For Discovered Annotations</a></li>
<li><a href="#_multi-threaded-annotation-scanning">Multi-threaded Annotation Scanning</a></li>
<li><a href="#servlet-container-initializers">ServletContainerInitializers</a>
<ul class="sectlevel4">
<li><a href="#_controlling-the-order-of-servletcontainerinitializer-invocation">Controlling the order of ServletContainerInitializer invocation</a></li>
<li><a href="#excluding-scis">Excluding ServletContainerInitializers</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#using-annotations-embedded">Using Annotations with Jetty Embedded</a>
<ul class="sectlevel3">
<li><a href="#_setting-up-the-classpath">Setting up the Classpath</a></li>
<li><a href="#_example">Example</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#ant-and-jetty">Ant and Jetty</a>
<ul class="sectlevel2">
<li><a href="#jetty-ant">Ant Jetty Plugin</a>
<ul class="sectlevel3">
<li><a href="#jetty-ant-preparation">Preparing Your Project</a></li>
<li><a href="#_preparing-the-build-xml-file">Preparing the <code>build.xml</code> file</a></li>
<li><a href="#_starting-jetty-via-ant">Starting Jetty via Ant</a></li>
<li><a href="#_configuring-the-jetty-container">Configuring the Jetty Container</a></li>
<li><a href="#_deploying-a-web-application">Deploying a Web Application</a>
<ul class="sectlevel4">
<li><a href="#_configuring-the-web-application">Configuring the Web Application</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#architecture">Architecture</a>
<ul class="sectlevel2">
<li><a href="#jetty-classloading">Jetty Classloading</a>
<ul class="sectlevel3">
<li><a href="#configuring-webapp-classloading">Configuring Webapp Classloading</a>
<ul class="sectlevel4">
<li><a href="#controlling-webapp-classloader-priority">Controlling Webapp Classloader Priority</a></li>
<li><a href="#configuring-webapp-caching">Configuring Webapp Classloader Caching</a></li>
<li><a href="#classloading-setting-system-classes">Setting System Classes</a></li>
<li><a href="#setting-server-classes">Setting Server Classes</a></li>
</ul>
</li>
<li><a href="#adding-extra-classpaths">Adding Extra Classpaths to Jetty</a>
<ul class="sectlevel4">
<li><a href="#classpaths-using-start-jar">Using <code>start.jar</code></a></li>
<li><a href="#using-extra-classpath-method">Using the extraClasspath() method</a></li>
</ul>
</li>
<li><a href="#using-custom-webappclassloader">Using a Custom WebAppClassLoader</a></li>
<li><a href="#starting-jetty-custom-classloader">Starting Jetty with a Custom ClassLoader</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#configuring-connectors">Configuring Jetty Connectors</a>
<ul class="sectlevel2">
<li><a href="#jetty-connectors">Connector Configuration Overview</a>
<ul class="sectlevel3">
<li><a href="#_enabling-connectors">Enabling Connectors</a></li>
<li><a href="#_limiting-connections">Limiting Connections</a></li>
<li><a href="#_advanced-configuration">Advanced Configuration</a></li>
<li><a href="#_constructing-a-serverconnector">Constructing a ServerConnector</a></li>
<li><a href="#jetty-connectors-network-settings">Network Settings</a></li>
<li><a href="#jetty-connectors-http-configuration">HTTP Configuration</a></li>
<li><a href="#_ssl-context-configuration">SSL Context Configuration</a></li>
<li><a href="#_proxy-load-balancer-connection-configuration">Proxy / Load Balancer Connection Configuration</a>
<ul class="sectlevel4">
<li><a href="#_x-forward-for-configuration">X-Forward-for Configuration</a></li>
<li><a href="#_proxy-protocol">Proxy Protocol</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#configuring-ssl">Configuring SSL/TLS</a>
<ul class="sectlevel3">
<li><a href="#configuring-jetty-for-ssl">Configuring Jetty for SSL</a></li>
<li><a href="#tls-and-ssl-versions">TLS and SSL versions</a>
<ul class="sectlevel4">
<li><a href="#_older-protocols">Older Protocols</a></li>
</ul>
</li>
<li><a href="#understanding-certificates-and-keys">Understanding Certificates and Keys</a>
<ul class="sectlevel4">
<li><a href="#openssl-vs-keytool">OpenSSL vs. Keytool</a></li>
<li><a href="#generating-key-pairs-and-certificates">Generating Key Pairs and Certificates</a></li>
<li><a href="#requesting-trusted-certificate">Requesting a Trusted Certificate</a></li>
<li><a href="#loading-keys-and-certificates">Loading Keys and Certificates</a></li>
<li><a href="#renewing-certificates">Renewing Certificates</a></li>
<li><a href="#layout-of-keystore-and-truststore">Layout of keystore and truststore</a></li>
</ul>
</li>
<li><a href="#configuring-sslcontextfactory">Configuring the Jetty SslContextFactory</a></li>
<li><a href="#conscrypt">Conscrypt SSL</a></li>
<li><a href="#_configuring-sni">Configuring SNI</a></li>
<li><a href="#configuring-sslcontextfactory-cipherSuites">Disabling/Enabling Specific Cipher Suites</a></li>
<li><a href="#_sslcontextfactory-keystore-reload">SslContextFactory KeyStore Reload</a></li>
</ul>
</li>
<li><a href="#jetty-ssl-distribution">SSL in the Jetty Distribution</a>
<ul class="sectlevel3">
<li><a href="#_default-jsse-ssl-configuration">Default JSSE SSL Configuration</a></li>
<li><a href="#jetty-conscrypt-distribution">Conscrypt SSL Configuration</a></li>
<li><a href="#client-certificate-authentication">Client Certificate Authentication</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#configuring-contexts">Configuring Contexts</a>
<ul class="sectlevel2">
<li><a href="#setting-context-path">Setting a Context Path</a>
<ul class="sectlevel3">
<li><a href="#using-embedded-deployment">Using Embedded Deployment</a></li>
<li><a href="#usng-the-context-provider">By naming convention</a></li>
<li><a href="#using-the-webapp-provider">By Deployer configuration</a></li>
<li><a href="#embedding-web-inf-jetty-web.xml-file">Embedding a WEB-INF/jetty-web.xml File</a></li>
</ul>
</li>
<li><a href="#ref-temporary-directories">Temporary Directories</a>
<ul class="sectlevel3">
<li><a href="#_the-default-temp-directory">The Default Temp Directory</a>
<ul class="sectlevel4">
<li><a href="#_the-location-of-the-temp-directory">The location of the temp directory</a></li>
</ul>
</li>
<li><a href="#_setting-a-specific-temp-directory">Setting a Specific Temp Directory</a>
<ul class="sectlevel4">
<li><a href="#_call-webappcontext-settempdirectorystring-dir">Call WebAppContext.setTempDirectory(String dir)</a></li>
<li><a href="#_setting-the-javax-servlet-context-tempdir-context-attribute">Setting the javax.servlet.context.tempdir Context Attribute</a></li>
<li><a href="#_setting-the-temp-directory-on-the-command-line">Setting the Temp Directory on the Command Line</a></li>
</ul>
</li>
<li><a href="#_the-work-directory">The "work" Directory</a></li>
<li><a href="#_persisting-the-temp-directory">Persisting the temp directory</a></li>
</ul>
</li>
<li><a href="#custom-error-pages">Creating Custom Error Pages</a>
<ul class="sectlevel3">
<li><a href="#_defining-error-pages-in-web-xml">Defining error pages in web.xml</a></li>
<li><a href="#_configuring-error-pages-context-files">Configuring error pages context files</a></li>
<li><a href="#_custom-errorhandler-class">Custom ErrorHandler class</a></li>
<li><a href="#_server-level-404-error">Server level 404 error</a></li>
</ul>
</li>
<li><a href="#setting-form-size">Setting Max Form Size</a>
<ul class="sectlevel3">
<li><a href="#_for-a-single-webapp">For a Single Webapp</a></li>
<li><a href="#_for-all-apps-in-the-jvm">For All Apps in the JVM</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#advanced-debugging">Debugging</a>
<ul class="sectlevel2">
<li><a href="#_options">Options</a></li>
<li><a href="#enable-remote-debugging">Enable remote debugging</a>
<ul class="sectlevel3">
<li><a href="#remote-debugging">Remote Debugging</a>
<ul class="sectlevel4">
<li><a href="#_starting-jetty">Starting Jetty</a></li>
<li><a href="#_linking-with-your-ide">Linking with your IDE</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#debugging-with-intellij">Debugging With IntelliJ</a>
<ul class="sectlevel3">
<li><a href="#_linking-with-intellij">Linking with IntelliJ</a></li>
<li><a href="#intellij-within-intellij">Within IntelliJ</a></li>
</ul>
</li>
<li><a href="#debugging-with-eclipse">Debugging With Eclipse</a>
<ul class="sectlevel3">
<li><a href="#_linking-with-eclipse">Linking with Eclipse</a></li>
<li><a href="#eclipse-within-eclipse">Within Eclipse</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#configuring-deployment">Deploying to Jetty</a>
<ul class="sectlevel2">
<li><a href="#configuring-specific-webapp-deployment">Configuring a Specific Web Application Deployment</a>
<ul class="sectlevel3">
<li><a href="#deployable-descriptor-file">Jetty Deployable Descriptor XML File</a></li>
<li><a href="#using-basic-descriptor-files">Using Basic Descriptor Files</a></li>
<li><a href="#configuring-advanced-descriptor-files">Configuring Advanced Descriptor Files</a></li>
</ul>
</li>
<li><a href="#configuring-webapps">Deployment Processing of WebAppContexts</a>
<ul class="sectlevel3">
<li><a href="#webapp-configurations">Configuration Classes</a>
<ul class="sectlevel4">
<li><a href="#_anatomy-of-a-configuration-class">Anatomy of a Configuration Class</a></li>
<li><a href="#_extending-container-support-by-creating-extra-configurations">Extending Container Support by Creating Extra Configurations</a></li>
<li><a href="#_how-to-set-the-list-of-configurations">How to Set the List of Configurations</a></li>
</ul>
</li>
<li><a href="#webapp-context-attributes">Other Configuration</a>
<ul class="sectlevel4">
<li><a href="#container-include-jar-pattern">org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</a></li>
<li><a href="#web-inf-include-jar-pattern">org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#static-content-deployment">Configuring Static Content Deployment</a></li>
<li><a href="#deployment-architecture">Deployment Architecture</a>
<ul class="sectlevel3">
<li><a href="#udm-application-providers">Application Providers</a></li>
<li><a href="#udm-application-lifecycle-graph">Application LifeCycle Graph</a></li>
<li><a href="#udm-lifecycle-bindings">LifeCycle Bindings</a>
<ul class="sectlevel4">
<li><a href="#_using-globalwebappconfigbinding">Using GlobalWebappConfigBinding</a></li>
</ul>
</li>
<li><a href="#default-web-app-provider">Understanding the Default WebAppProvider</a></li>
</ul>
</li>
<li><a href="#quickstart-webapp">Quickstart Webapps</a>
<ul class="sectlevel3">
<li><a href="#_setting-up-quickstart">Setting up Quickstart</a>
<ul class="sectlevel4">
<li><a href="#_prerequisites">Prerequisites</a></li>
<li><a href="#_configuration">Configuration</a></li>
</ul>
</li>
<li><a href="#_avoiding-tld-scans-with-precompiled-jsps">Avoiding TLD Scans with precompiled JSPs</a></li>
<li><a href="#_bypassing-start-jar">Bypassing start.jar</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#advanced-embedding">Embedding</a>
<ul class="sectlevel2">
<li><a href="#jetty-helloworld">Jetty Embedded HelloWorld</a>
<ul class="sectlevel3">
<li><a href="#downloading-jars">Downloading the Jars</a></li>
<li><a href="#writing-helloworld-example">Writing a HelloWorld Example</a></li>
<li><a href="#compiling-helloworld-example">Compiling the HelloWord example</a></li>
<li><a href="#running-handler-and-server">Running the Handler and Server</a></li>
<li><a href="#next-steps">Next Steps</a></li>
</ul>
</li>
<li><a href="#embedding-jetty">Embedding Jetty</a>
<ul class="sectlevel3">
<li><a href="#_overview">Overview</a></li>
<li><a href="#_creating-the-server">Creating the Server</a></li>
<li><a href="#_using-handlers">Using Handlers</a>
<ul class="sectlevel4">
<li><a href="#_helloworld-handler">HelloWorld Handler</a></li>
<li><a href="#_running-helloworldhandler">Running HelloWorldHandler</a></li>
<li><a href="#_handler-collections-and-wrappers">Handler Collections and Wrappers</a></li>
<li><a href="#_scoped-handlers">Scoped Handlers</a></li>
<li><a href="#_resource-handler">Resource Handler</a></li>
</ul>
</li>
<li><a href="#_embedding-connectors">Embedding Connectors</a>
<ul class="sectlevel4">
<li><a href="#_one-connector">One Connector</a></li>
<li><a href="#_many-connectors">Many Connectors</a></li>
</ul>
</li>
<li><a href="#_embedding-servlets">Embedding Servlets</a></li>
<li><a href="#_embedding-contexts">Embedding Contexts</a></li>
<li><a href="#_embedding-servletcontexts">Embedding ServletContexts</a></li>
<li><a href="#_embedding-web-applications">Embedding Web Applications</a></li>
<li><a href="#_like-jetty-xml">Like Jetty XML</a></li>
</ul>
</li>
<li><a href="#embedded-examples">Embedded Examples</a>
<ul class="sectlevel3">
<li><a href="#embedded-file-server">Simple File Server</a>
<ul class="sectlevel4">
<li><a href="#_run-it">Run it!</a></li>
<li><a href="#_maven-coordinates">Maven Coordinates</a></li>
</ul>
</li>
<li><a href="#embedded-split-file-server">Split File Server</a>
<ul class="sectlevel4">
<li><a href="#_run-it-2">Run it!</a></li>
<li><a href="#_maven-coordinates-2">Maven Coordinates</a></li>
</ul>
</li>
<li><a href="#embedded-many-connectors">Multiple Connectors</a>
<ul class="sectlevel4">
<li><a href="#_walkthrough">Walkthrough</a></li>
<li><a href="#_maven-coordinates-3">Maven Coordinates</a></li>
</ul>
</li>
<li><a href="#embedded-secured-hello-handler">Secured Hello Handler</a>
<ul class="sectlevel4">
<li><a href="#_run-it-3">Run it!</a></li>
<li><a href="#_the-realm-properties-file">The Realm Properties File</a></li>
<li><a href="#_maven-coordinates-4">Maven Coordinates</a></li>
</ul>
</li>
<li><a href="#embedded-minimal-servlet">Minimal Servlet</a>
<ul class="sectlevel4">
<li><a href="#_walkthrough-2">Walkthrough</a></li>
<li><a href="#_maven-coordinates-5">Maven Coordinates</a></li>
</ul>
</li>
<li><a href="#embedded-one-webapp">Web Application</a>
<ul class="sectlevel4">
<li><a href="#_run-it-4">Run it!</a></li>
<li><a href="#_maven-coordinates-6">Maven Coordinates</a></li>
</ul>
</li>
<li><a href="#embedded-webapp-jsp">Web Application with JSP</a>
<ul class="sectlevel4">
<li><a href="#_run-it-5">Run it!</a></li>
<li><a href="#_maven-coordinates-7">Maven Coordinates</a></li>
</ul>
</li>
<li><a href="#adding-embedded-examples">Adding Examples</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#advanced-extras">Provided Servlets, Filters, and Handlers</a>
<ul class="sectlevel2">
<li><a href="#default-servlet">Default Servlet</a>
<ul class="sectlevel3">
<li><a href="#default-servlet-metadata">Info</a></li>
<li><a href="#default-servlet-usage">Usage</a></li>
<li><a href="#default-servlet-init">Init Parameters</a></li>
</ul>
</li>
<li><a href="#proxy-servlet">Proxy Servlet</a>
<ul class="sectlevel3">
<li><a href="#proxy-servlet-metadata">Info</a></li>
<li><a href="#proxy-servlet-usage">Usage</a></li>
<li><a href="#proxy-servlet-init">Init Parameters</a></li>
</ul>
</li>
<li><a href="#balancer-servlet">Balancer Servlet</a>
<ul class="sectlevel3">
<li><a href="#balancer-servlet-metadata">Info</a></li>
<li><a href="#balancer-servlet-usage">Usage</a></li>
</ul>
</li>
<li><a href="#cgi-servlet">CGI Servlet</a>
<ul class="sectlevel3">
<li><a href="#cgi-servlet-metadata">Info</a></li>
<li><a href="#cgi-servlet-usage">Usage</a></li>
</ul>
</li>
<li><a href="#qos-filter">Quality of Service Filter</a>
<ul class="sectlevel3">
<li><a href="#qos-filter-metadata">Info</a></li>
<li><a href="#qos-filter-usage">Usage</a></li>
<li><a href="#qos-understanding">Understanding the Problem</a>
<ul class="sectlevel4">
<li><a href="#_waiting-for-resources">Waiting for Resources</a></li>
<li><a href="#_prioritizing-resources">Prioritizing Resources</a></li>
</ul>
</li>
<li><a href="#qos-applying">Applying the QoSFilter</a>
<ul class="sectlevel4">
<li><a href="#_required-jars">Required JARs</a></li>
<li><a href="#_sample-configuration">Sample Configuration</a></li>
<li><a href="#qos-filter-init">Configuring QoS Filter Parameters</a></li>
<li><a href="#_mapping-to-urls">Mapping to URLs</a></li>
<li><a href="#_setting-the-request-priority">Setting the Request Priority</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#dos-filter">Denial of Service Filter</a>
<ul class="sectlevel3">
<li><a href="#dos-filter-metadata">Info</a></li>
<li><a href="#dos-filter-usage">Usage</a></li>
<li><a href="#dos-filter-using">Using the DoS Filter</a>
<ul class="sectlevel4">
<li><a href="#_required-jars-2">Required JARs</a></li>
<li><a href="#_sample-configuration-2">Sample Configuration</a></li>
<li><a href="#dos-filter-init">Configuring DoS Filter Parameters</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#header-filter">Header Filter</a>
<ul class="sectlevel3">
<li><a href="#header-filter-metadata">Info</a></li>
<li><a href="#header-filter-usage">Usage</a>
<ul class="sectlevel4">
<li><a href="#_required-jars-3">Required JARs</a></li>
<li><a href="#_sample-configuration-3">Sample Configuration</a></li>
<li><a href="#header-filter-init">Configuring Header Filter Parameters</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#gzip-filter">Gzip Handler</a>
<ul class="sectlevel3">
<li><a href="#gzip-filter-metadata">Info</a></li>
<li><a href="#gzip-filter-usage">Usage</a></li>
<li><a href="#gzip-filter-rules">Gzip Rules</a></li>
<li><a href="#gzip-filter-init">Gzip Configuration</a></li>
</ul>
</li>
<li><a href="#cross-origin-filter">Cross Origin Filter</a>
<ul class="sectlevel3">
<li><a href="#cross-origin-filter-metadata">Info</a></li>
<li><a href="#cross-origin-filter-usage">Usage</a></li>
<li><a href="#cross-origin-setup">Setup</a></li>
<li><a href="#cross-origin-config">Configuration</a></li>
</ul>
</li>
<li><a href="#resource-handler">Resource Handler</a>
<ul class="sectlevel3">
<li><a href="#resource-handler-metadata">Info</a></li>
<li><a href="#resource-handler-usage">Usage</a></li>
<li><a href="#_improving-the-look-and-feel">Improving the Look and Feel</a></li>
<li><a href="#_embedded-example">Embedded Example</a></li>
</ul>
</li>
<li><a href="#debug-handler">Debug Handler</a>
<ul class="sectlevel3">
<li><a href="#debug-handler-metadata">Info</a></li>
<li><a href="#debug-handler-usage">Usage</a></li>
<li><a href="#_usage-in-standard-distribution">Usage in Standard Distribution</a></li>
<li><a href="#_embedded-usage">Embedded usage</a></li>
<li><a href="#_example-output">Example output</a></li>
</ul>
</li>
<li><a href="#statistics-handler">Statistics Handler</a>
<ul class="sectlevel3">
<li><a href="#statistics-handler-metadata">Info</a></li>
<li><a href="#statistics-handler-usage">Usage</a></li>
<li><a href="#request-statistics">Request Statistics</a></li>
<li><a href="#connection-statistics">Connection Statistics</a></li>
<li><a href="#session-statistics">Session Statistics</a></li>
</ul>
</li>
<li><a href="#inetaccess-handler">InetAccess Handler</a>
<ul class="sectlevel3">
<li><a href="#inetaccess-handler-metadata">Info</a></li>
<li><a href="#inetaccess-handler-usage">Usage</a></li>
<li><a href="#_usage-in-standard-distribution-2">Usage in Standard Distribution</a></li>
</ul>
</li>
<li><a href="#moved-context-handler">Moved Context Handler</a>
<ul class="sectlevel3">
<li><a href="#moved-context-handler-metadata">Info</a></li>
<li><a href="#moved-context-handler-usage">Usage</a></li>
</ul>
</li>
<li><a href="#shutdown-handler">Shutdown Handler</a>
<ul class="sectlevel3">
<li><a href="#shutdown-handler-metadata">Info</a></li>
<li><a href="#shutdown-handler-usage">Usage</a></li>
</ul>
</li>
<li><a href="#default-handler">Default Handler</a>
<ul class="sectlevel3">
<li><a href="#default-handler-metadata">Info</a></li>
<li><a href="#default-handler-usage">Usage</a></li>
</ul>
</li>
<li><a href="#error-handler">Error Handler</a>
<ul class="sectlevel3">
<li><a href="#error-handler-metadata">Info</a></li>
<li><a href="#error-handler-usage">Usage</a></li>
</ul>
</li>
<li><a href="#rewrite-handler">Rewrite Handler</a>
<ul class="sectlevel3">
<li><a href="#rewrite-handler-metadata">Info</a></li>
<li><a href="#_usage">Usage</a>
<ul class="sectlevel4">
<li><a href="#_embedded-example-2">Embedded Example</a></li>
</ul>
</li>
<li><a href="#rewrite-rules">Rules</a>
<ul class="sectlevel4">
<li><a href="#_patternrule">PatternRule</a></li>
<li><a href="#_regexrule">RegexRule</a></li>
<li><a href="#_headerrule">HeaderRule</a></li>
<li><a href="#_others">Others</a></li>
<li><a href="#_rulecontainer">RuleContainer</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#fastcgi">FastCGI Support</a>
<ul class="sectlevel2">
<li><a href="#fastcgi-intro">FastCGI Introduction</a></li>
<li><a href="#configuring-fastcgi">Configuring Jetty for FastCGI</a>
<ul class="sectlevel3">
<li><a href="#configuring-fastcgi-http2">Configuring Jetty to Proxy HTTP/2 to FastCGI</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#frameworks">Frameworks</a>
<ul class="sectlevel2">
<li><a href="#framework-cdi">CDI</a>
<ul class="sectlevel3">
<li><a href="#_jetty-cdi-modules">Jetty CDI Modules</a>
<ul class="sectlevel4">
<li><a href="#_jetty-cdi-module">Jetty <code>cdi</code> Module</a></li>
<li><a href="#_jetty-cdi-decorate-module">Jetty <code>cdi-decorate</code> Module</a></li>
<li><a href="#_jetty-cdi-spi-module">Jetty <code>cdi-spi</code> Module</a></li>
<li><a href="#_jetty-cdi2-module">Jetty <code>cdi2</code> Module</a></li>
</ul>
</li>
<li><a href="#cdi-embedded">Embedded Jetty with CDI</a></li>
</ul>
</li>
<li><a href="#framework-jetty-spring">Spring Setup</a>
<ul class="sectlevel3">
<li><a href="#_jetty-spring-module">Jetty-Spring Module</a></li>
<li><a href="#_using-spring-to-configure-jetty">Using Spring to Configure Jetty</a></li>
</ul>
</li>
<li><a href="#framework-jetty-osgi">OSGI</a>
<ul class="sectlevel3">
<li><a href="#_introduction">Introduction</a></li>
<li><a href="#_general-setup">General Setup</a></li>
<li><a href="#_the-jetty-osgi-container">The Jetty OSGi Container</a>
<ul class="sectlevel4">
<li><a href="#_the-jetty-osgi-boot-jar">The jetty-osgi-boot jar</a></li>
<li><a href="#customize-jetty-container">Customizing the Jetty Container</a></li>
<li><a href="#_the-jetty-container-as-an-osgi-service">The Jetty Container as an OSGi Service</a></li>
<li><a href="#_adding-more-jetty-servers">Adding More Jetty Servers</a></li>
</ul>
</li>
<li><a href="#_deploying-bundles-as-webapps">Deploying Bundles as Webapps</a>
<ul class="sectlevel4">
<li><a href="#_determining-the-context-path-for-a-webapp-bundle">Determining the Context Path for a Webapp Bundle</a></li>
<li><a href="#_extra-properties-available-for-webapp-bundles">Extra Properties Available for Webapp Bundles</a></li>
</ul>
</li>
<li><a href="#_deploying-bundles-as-jetty-contexthandlers">Deploying Bundles as Jetty ContextHandlers</a>
<ul class="sectlevel4">
<li><a href="#_determining-the-context-path-for-a-contexthandler-bundle">Determining the Context Path for a ContextHandler Bundle</a></li>
<li><a href="#_extra-properties-available-for-context-xml-files">Extra Properties Available for Context Xml Files</a></li>
</ul>
</li>
<li><a href="#services-as-webapps">Deploying Services as Webapps</a></li>
<li><a href="#_deploying-services-as-contexthandlers">Deploying Services as ContextHandlers</a>
<ul class="sectlevel4">
<li><a href="#_extra-properties-available-for-context-xml-files-2">Extra Properties Available for Context Xml Files</a></li>
</ul>
</li>
<li><a href="#_support-for-the-osgi-service-platform-enterprise-specification">Support for the OSGi Service Platform Enterprise Specification</a>
<ul class="sectlevel4">
<li><a href="#_context-attributes">Context Attributes</a></li>
<li><a href="#_service-attributes">Service Attributes</a></li>
<li><a href="#_osgi-events">OSGi Events</a></li>
</ul>
</li>
<li><a href="#_using-jsps">Using JSPs</a>
<ul class="sectlevel4">
<li><a href="#_setup">Setup</a></li>
<li><a href="#_the-jetty-osgi-boot-jsp-jar">The jetty-osgi-boot-jsp jar</a></li>
</ul>
</li>
<li><a href="#osgi-annotations">Using Annotations/ServletContainerInitializers</a></li>
<li><a href="#_osgi-containers">OSGi Containers</a>
<ul class="sectlevel4">
<li><a href="#_felix">Felix</a></li>
<li><a href="#_eclipse">Eclipse</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#framework-metro">Metro</a>
<ul class="sectlevel3">
<li><a href="#metro-setup-distro">Metro Setup</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#introduction">Introducing Jetty</a>
<ul class="sectlevel2">
<li><a href="#what-is-jetty">What is Jetty?</a></li>
<li><a href="#what-jetty-version">What Version Do I Use?</a></li>
<li><a href="#jetty-javaee">Jetty and Java EE Web Profile</a>
<ul class="sectlevel3">
<li><a href="#jetty-javaee-7">Java EE 7 Web Profile</a></li>
<li><a href="#jetty-javaee-6">Jetty EE 6 Web Profile</a></li>
</ul>
</li>
<li><a href="#quickstart-jetty-coordinates">Finding Jetty in Maven</a>
<ul class="sectlevel3">
<li><a href="#_maven-coordinates-8">Maven Coordinates</a></li>
<li><a href="#_changelogs-in-maven-central">Changelogs in Maven Central</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#quick-start-getting-started">Using Jetty</a>
<ul class="sectlevel2">
<li><a href="#jetty-downloading">Downloading Jetty</a>
<ul class="sectlevel3">
<li><a href="#_downloading-the-jetty-distribution">Downloading the Jetty Distribution</a>
<ul class="sectlevel4">
<li><a href="#distribution-content">Distribution Content</a></li>
</ul>
</li>
<li><a href="#jetty-home-downloading">Downloading the Jetty-Home Distribution</a>
<ul class="sectlevel4">
<li><a href="#jetty-home-distribution-content">Distribution Content</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#quickstart-running-jetty">Running Jetty</a>
<ul class="sectlevel3">
<li><a href="#demo-webapps-base">Demo Base</a></li>
</ul>
</li>
<li><a href="#quickstart-common-config">Common Jetty Configuration</a>
<ul class="sectlevel3">
<li><a href="#creating-jetty-base">Creating a new Jetty Base</a></li>
<li><a href="#quickstart-changing-jetty-port">Changing the Jetty Port</a></li>
<li><a href="#quickstart-starting-https">Adding SSL for HTTPS &amp; HTTP2</a>
<ul class="sectlevel4">
<li><a href="#quickstart-changing-https-port">Changing the Jetty HTTPS Port</a></li>
</ul>
</li>
<li><a href="#_more-start-jar-options">More start.jar Options</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#quick-start-configure">An Introduction to Jetty Configuration</a>
<ul class="sectlevel2">
<li><a href="#quickstart-config-how">How to Configure Jetty</a>
<ul class="sectlevel3">
<li><a href="#_jetty-pojo-configuration">Jetty POJO Configuration</a></li>
<li><a href="#_jetty-start-configuration-files">Jetty Start Configuration Files</a></li>
<li><a href="#_a-closer-look">A Closer Look</a></li>
<li><a href="#_other-configuration-files">Other Configuration Files</a></li>
<li><a href="#_jetty-ioc-xml-format">Jetty IoC XML format</a></li>
</ul>
</li>
<li><a href="#quickstart-config-what">What to Configure in Jetty</a>
<ul class="sectlevel3">
<li><a href="#intro-jetty-configuration-server">Configuring the Server</a></li>
<li><a href="#intro-jetty-configuration-connectors">Configuring Connectors</a></li>
<li><a href="#intro-jetty-configuration-contexts">Configuring Contexts</a>
<ul class="sectlevel4">
<li><a href="#_context-configuration-by-api">Context Configuration by API</a></li>
<li><a href="#_context-configuration-by-ioc-xml">Context Configuration by IoC XML</a></li>
<li><a href="#intro-jetty-configuration-webapps">Configuring Web Applications</a></li>
<li><a href="#_setting-the-context-path">Setting the Context Path</a></li>
<li><a href="#quickstart-config-deployer">Web Application Deployment</a></li>
<li><a href="#_setting-an-authentication-realm">Setting an Authentication Realm</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#upgrading-jetty">Upgrading Jetty</a></li>
<li><a href="#http2">HTTP/2</a>
<ul class="sectlevel2">
<li><a href="#http2-configuring-push">Configuring HTTP/2 Push</a></li>
<li><a href="#http2-configuring-haproxy">Configuring HAProxy and Jetty</a>
<ul class="sectlevel3">
<li><a href="#http2-haproxy-install">Installing HAProxy</a></li>
<li><a href="#http2-haproxy-ssl">Setup SSL for HAProxy</a></li>
<li><a href="#http2-haproxy-cfg">HAProxy Configuration File</a></li>
<li><a href="#http2-haproxy-jetty">Setup Jetty for HTTP/2 and HTTP/1.1</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#reference-section">Jetty XML Reference</a>
<ul class="sectlevel2">
<li><a href="#jetty-xml-usage">Jetty XML Usage</a>
<ul class="sectlevel3">
<li><a href="#using-jettyxml">Using jetty.xml</a></li>
<li><a href="#using-multiple-configuration-files">Using Multiple Configuration Files</a></li>
<li><a href="#setting-parameters-in-configuration-files">Setting Parameters in Configuration Files</a></li>
</ul>
</li>
<li><a href="#jetty-xml-config">jetty.xml</a>
<ul class="sectlevel3">
<li><a href="#root-element-jetty-xml">Root Element</a></li>
<li><a href="#jetty-xml-examples">Examples</a></li>
<li><a href="#jetty-xml-additional-resources">Additional Resources</a></li>
</ul>
</li>
<li><a href="#jetty-web-xml-config">jetty-web.xml</a>
<ul class="sectlevel3">
<li><a href="#root-element-jetty-web-xml">Root Element</a></li>
<li><a href="#using-jetty-web-xml">Using jetty-web.xml</a></li>
<li><a href="#jetty-web-xml-examples">jetty-web.xml Examples</a></li>
<li><a href="#additional-jetty-web-xml-resources">Additional <code>jetty-web.xml</code> Resources</a></li>
</ul>
</li>
<li><a href="#jetty-env-xml">jetty-env.xml</a>
<ul class="sectlevel3">
<li><a href="#jetty-env-root-element">jetty-env.xml Root Element</a></li>
<li><a href="#using-jetty-env-xml">Using <code>jetty-env.xml</code></a></li>
<li><a href="#additional-jetty-env-xml-resources">Additional jetty-env.xml Resources</a></li>
</ul>
</li>
<li><a href="#webdefault-xml">webdefault.xml</a>
<ul class="sectlevel3">
<li><a href="#using-webdefault-xml">Using webdefault.xml</a>
<ul class="sectlevel4">
<li><a href="#creating-custom-webdefault-xml-one-webapp">Creating a Custom webdefault.xml for One WebApp</a></li>
<li><a href="#creating-custom-webdefault-xml-multiple-webapps">Creating a Custom webdefault.xml for Multiple WebApps</a></li>
<li><a href="#webdefault-xml-using-jetty-maven-plugin">Using the Jetty Maven Plugin</a></li>
<li><a href="#webdefault-xml-additional-resources">Additional Resources</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#override-web-xml">Jetty override-web.xml</a>
<ul class="sectlevel3">
<li><a href="#using-override-web-xml">Using override-web.xml</a></li>
<li><a href="#override-using-jetty-maven-plugin">Using the Jetty Maven Plugin</a></li>
<li><a href="#override-web-xml-additional-resources">Additional Resources</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#jmx-chapter">Java Management Extensions (JMX)</a>
<ul class="sectlevel2">
<li><a href="#using-jmx">Using JMX with Jetty</a>
<ul class="sectlevel3">
<li><a href="#configuring-jmx">Configuring JMX</a>
<ul class="sectlevel4">
<li><a href="#jmx-standalone-jetty">Standalone Jetty Server</a></li>
<li><a href="#jmx-embedded-jetty">Embedded Jetty Server</a></li>
<li><a href="#jmx-jetty-maven-plugin">Using the Jetty Maven Plugin with JMX</a></li>
</ul>
</li>
<li><a href="#accessing-jetty-mbeans">Using JConsole or Java Mission Control to Access Jetty MBeans</a></li>
<li><a href="#jmx-remote-access">Enabling JMX Remote Access</a>
<ul class="sectlevel4">
<li><a href="#_enabling-jmx-remote-access-in-standalone-jetty-server">Enabling JMX Remote Access in Standalone Jetty Server</a></li>
<li><a href="#_enabling-jmx-remote-access-in-embedded-jetty">Enabling JMX Remote Access in Embedded Jetty</a></li>
<li><a href="#jmx-remote-access-authorization">JMX Remote Access Authorization</a></li>
<li><a href="#_securing-jmx-remote-access-with-tls">Securing JMX Remote Access with TLS</a></li>
<li><a href="#jmx-remote-access-ssh-tunnel">JMX Remote Access with Port Forwarding via SSH Tunnel</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#jetty-jmx-annotations">Jetty JMX Annotations</a>
<ul class="sectlevel3">
<li><a href="#jmx-annotation-introspection">Annotation Introspection</a></li>
<li><a href="#jmx-managed-object">@ManagedObject</a></li>
<li><a href="#jmx-managed-attribute">@ManagedAttribute</a></li>
<li><a href="#jmx-managed-operation">@ManagedOperation</a></li>
<li><a href="#jmx-name-annotation">@Name</a></li>
<li><a href="#jmx-annotation-example">Example</a></li>
</ul>
</li>
<li><a href="#jetty-jconsole">Managing Jetty with JConsole and JMC</a>
<ul class="sectlevel3">
<li><a href="#_starting-jetty-standalone">Starting Jetty Standalone</a></li>
<li><a href="#jetty-jconsole-monitoring">Monitoring Jetty with JConsole</a>
<ul class="sectlevel4">
<li><a href="#_connecting-to-your-server-process">Connecting to your server process</a></li>
</ul>
</li>
<li><a href="#_managing-jetty-objects-with-jconsole">Managing Jetty Objects with JConsole</a></li>
<li><a href="#jetty-jmc-monitoring">Monitoring Jetty with JMC</a>
<ul class="sectlevel4">
<li><a href="#_connecting-to-your-server-process-2">Connecting to your server process</a></li>
</ul>
</li>
<li><a href="#_managing-jetty-objects-with-jconsole-2">Managing Jetty Objects with JConsole</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#jndi">Configuring JNDI</a>
<ul class="sectlevel2">
<li><a href="#jndi-quick-setup">Quick Setup</a></li>
<li><a href="#using-jetty-jndi">Working with Jetty JNDI</a>
<ul class="sectlevel3">
<li><a href="#_defining-the-web-xml">Defining the web.xml</a></li>
<li><a href="#defining-jndi-naming-entries">Declaring Resources</a></li>
<li><a href="#jndi-where-to-declare">Deciding Where to Declare Resources</a></li>
<li><a href="#jndi-name-scope">Scope of Resource Names</a></li>
<li><a href="#binding-objects-into-jetty-jndi">What Can Be Bound as a Resource?</a></li>
</ul>
</li>
<li><a href="#jndi-configuration">Configuring JNDI</a>
<ul class="sectlevel3">
<li><a href="#configuring-jndi-env-entries">Configuring JNDI <em>env-entries</em></a></li>
<li><a href="#configuring-resource-refs-and-resource-env-refs">Configuring <em>resource-refs</em> and <em>resource-env-refs</em></a></li>
<li><a href="#configuring-datasources">Configuring DataSources</a></li>
<li><a href="#configuring-jms-queues-topics-connectionfactories">Configuring JMS Queues, Topics and ConnectionFactories</a></li>
<li><a href="#configuring-mail-with-jndi">Configuring Mail</a></li>
<li><a href="#configuring-xa-transactions">Configuring XA Transactions</a></li>
<li><a href="#configuring-links">Configuring Links</a></li>
</ul>
</li>
<li><a href="#jndi-embedded">Using JNDI with Jetty Embedded</a>
<ul class="sectlevel3">
<li><a href="#_setting-up-the-classpath-2">Setting up the Classpath</a></li>
<li><a href="#_example-code">Example Code</a></li>
</ul>
</li>
<li><a href="#jndi-datasource-examples">Datasource Examples</a>
<ul class="sectlevel3">
<li><a href="#pooling-datasources">Pooling DataSources</a>
<ul class="sectlevel4">
<li><a href="#hikaricp-datasource">HikariCP</a></li>
<li><a href="#bonecp-datasource">BoneCP</a></li>
<li><a href="#c3p0-datasource">c3p0</a></li>
<li><a href="#dbcp-datasource">DBCP</a></li>
<li><a href="#atomikos-datasource">Atomikos 3.3.2+</a></li>
<li><a href="#mysql-pooled-datasource">MySQL</a></li>
<li><a href="#postgreSQL-pooled-datasource">PostgreSQL</a></li>
<li><a href="#DB2-pooled-datasource">DB2</a></li>
</ul>
</li>
<li><a href="#non-pooling-datasources">Non-pooling DataSources</a>
<ul class="sectlevel4">
<li><a href="#sql-server-2000-datasource">SQL Server 2000</a></li>
<li><a href="#oracle-9i10g-datasource">Oracle 9i/10g</a></li>
<li><a href="#postgreSQL-datasource">PostgreSQL</a></li>
<li><a href="#sybase-datasource">Sybase</a></li>
<li><a href="#DB2-datasource">DB2</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#configuring-jsp">Configuring JSP Support</a>
<ul class="sectlevel2">
<li><a href="#jsp-support">Configuring JSP</a>
<ul class="sectlevel3">
<li><a href="#which-jsp-implementation">Which JSP Implementation</a>
<ul class="sectlevel4">
<li><a href="#_logging">Logging</a></li>
<li><a href="#_jsps-and-embedding">JSPs and Embedding</a></li>
</ul>
</li>
<li><a href="#_precompiling-jsps">Precompiling JSPs</a>
<ul class="sectlevel4">
<li><a href="#compiling-jsps">Apache JSP Container</a></li>
<li><a href="#configuring-jsp-for-jetty">Configuration</a></li>
</ul>
</li>
<li><a href="#modifying-configuration">Modifying Configuration</a>
<ul class="sectlevel4">
<li><a href="#overriding-webdefault.xml">Overriding <code>webdefault.xml</code></a></li>
<li><a href="#configuring-jsp-servlet-in-web.xml">Configuring the JSP Servlet in web.xml</a></li>
<li><a href="#jsp-async-support">Configuring Async Support</a></li>
</ul>
</li>
<li><a href="#using-jstl-taglibs-for-jetty7-jetty8">Using JSTL Taglibs</a>
<ul class="sectlevel4">
<li><a href="#_embedding-2">Embedding</a></li>
</ul>
</li>
<li><a href="#using-jsf-taglibs">Using JSF Taglibs</a>
<ul class="sectlevel4">
<li><a href="#using-jsf-taglibs-with-jetty-standalone">Using JSF Taglibs with Jetty Distribution</a></li>
<li><a href="#using-jsf-taglibs-with-jetty-maven-plugin">Using JSF Taglibs with Jetty Maven Plugin</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#configuring-logging">Jetty Logging</a>
<ul class="sectlevel2">
<li><a href="#configuring-jetty-logging">Configuring Jetty Logging</a>
<ul class="sectlevel3">
<li><a href="#selecting-log-framework">Selecting the Log Framework</a></li>
<li><a href="#configuring-jetty-stderrlog">The jetty-logging.properties file</a></li>
</ul>
</li>
<li><a href="#default-logging-with-stderrlog">Default Logging with Jetty&#8217;s StdErrLog</a>
<ul class="sectlevel3">
<li><a href="#stderrlog-configuration">StdErrLog Configuration</a></li>
<li><a href="#deprecated-parameters">Deprecated Parameters</a></li>
</ul>
</li>
<li><a href="#configuring-jetty-request-logs">Configuring Jetty Request Logs</a>
<ul class="sectlevel3">
<li><a href="#constructing-request-log-entry">Constructing a Request Log Entry</a></li>
<li><a href="#implementing-request-log">Implementing a Request Log</a></li>
<li><a href="#configuring-request-log">Configuring the Request Log module</a></li>
<li><a href="#request-log-custom-writer">Introducing RequestLog.Writer</a></li>
<li><a href="#configuring-separate-request-log-for-web-application">Configuring a Separate Request Log For a Web Application</a></li>
</ul>
</li>
<li><a href="#configuring-logging-modules">Jetty Logging Integrations (SLF4J, Log4j, Logback, JCL, JUL)</a>
<ul class="sectlevel3">
<li><a href="#example-logging-slf4j">Logging with SLF4J</a></li>
<li><a href="#example-logging-log4j">Logging with Log4j and Log4j2</a></li>
<li><a href="#example-logging-logback">Logging with Logback</a></li>
<li><a href="#_logging-with-java-util-logging">Logging with Java Util Logging</a>
<ul class="sectlevel4">
<li><a href="#example-logging-java-util-logging">Java Util Logging with SLF4J</a></li>
</ul>
</li>
<li><a href="#_capturing-console-output">Capturing Console Output</a></li>
</ul>
</li>
<li><a href="#example-logging-logback-centralized">Centralized Logging using Logback</a></li>
<li><a href="#jetty-server-dump">Jetty Server Dump</a>
<ul class="sectlevel3">
<li><a href="#configuring-dump-feature">Configuring the Jetty Server Dump</a></li>
<li><a href="#extra-threadpool-info">Extra ThreadPool Information</a></li>
<li><a href="#dump-tool-via-jmx">Using the Dump Feature via JMX</a></li>
<li><a href="#examing-jetty-distro-dump">Explanation of the Dump Key</a></li>
<li><a href="#_jetty-server-dump-example">Jetty Server Dump Example</a></li>
</ul>
</li>
<li><a href="#jetty-maven-scanning">Files Scanned by the Jetty Maven Plugin</a>
<ul class="sectlevel3">
<li><a href="#scanner-matrix">Scanner Matrix</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#platforms">Platforms, Stacks and Alternative Distributions</a>
<ul class="sectlevel2">
<li><a href="#_many-many-options">Many many options&#8230;&#8203;</a></li>
<li><a href="#jelastic">Jelastic</a></li>
<li><a href="#cloudfoundry">CloudFoundry</a>
<ul class="sectlevel3">
<li><a href="#cloudfoundry-overview">Overview</a></li>
<li><a href="#cloudfoundry-usage">Usage</a></li>
<li><a href="#cloudfoundry-acknowledgements">Acknowledgements</a></li>
</ul>
</li>
<li><a href="#elastic-beanstalk">Amazon Elastic Beanstalk</a>
<ul class="sectlevel3">
<li><a href="#elastic-beanstalk-overview">Overview</a></li>
<li><a href="#elastic-beanstalk-maven">Maven Bits</a></li>
</ul>
</li>
<li><a href="#fedora">Fedora</a></li>
<li><a href="#ubuntu">Ubuntu</a></li>
</ul>
</li>
<li><a href="#runner">Jetty Runner</a>
<ul class="sectlevel2">
<li><a href="#jetty-runner">Use Jetty Without an Installed Distribution</a>
<ul class="sectlevel3">
<li><a href="#jetty-runner-preparation">Preparation</a></li>
<li><a href="#_deploying-a-simple-context">Deploying a Simple Context</a></li>
<li><a href="#_deploying-multiple-contexts">Deploying Multiple Contexts</a>
<ul class="sectlevel4">
<li><a href="#_changing-the-default-port">Changing the Default Port</a></li>
<li><a href="#_using-jetty-xml-files">Using jetty.xml Files</a></li>
</ul>
</li>
<li><a href="#runner-configuration-reference">Full Configuration Reference</a>
<ul class="sectlevel4">
<li><a href="#_printing-the-version">Printing the Version</a></li>
<li><a href="#_configuring-a-request-log">Configuring a Request Log</a></li>
<li><a href="#_configuring-the-output-log">Configuring the Output Log</a></li>
<li><a href="#_configuring-the-interface-for-http">Configuring the Interface for HTTP</a></li>
<li><a href="#_configuring-the-port-for-http">Configuring the Port for HTTP</a></li>
<li><a href="#_configuring-stop">Configuring Stop</a></li>
<li><a href="#_configuring-the-container-classpath">Configuring the Container Classpath</a></li>
<li><a href="#_gathering-statistics">Gathering Statistics</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#configuring-security">Configuring Security</a>
<ul class="sectlevel2">
<li><a href="#configuring-security-authentication">Authentication and Authorization</a>
<ul class="sectlevel3">
<li><a href="#_configuring-an-authentication-mechanism">Configuring an Authentication mechanism</a></li>
<li><a href="#security-realms">Security Realms</a></li>
<li><a href="#_scoping-security-realms">Scoping Security Realms</a>
<ul class="sectlevel4">
<li><a href="#_globally-scoped">Globally Scoped</a></li>
<li><a href="#_per-webapp-scoped">Per-Webapp Scoped</a></li>
</ul>
</li>
<li><a href="#configuring-login-service">Configuring a LoginService</a>
<ul class="sectlevel4">
<li><a href="#hash-login-service">HashLoginService</a></li>
<li><a href="#jdbc-login-service">JDBCLoginService</a></li>
</ul>
</li>
<li><a href="#_authorization">Authorization</a>
<ul class="sectlevel4">
<li><a href="#_configuring-authorization-with-context-xml-files">Configuring Authorization with Context XML Files</a></li>
</ul>
</li>
<li><a href="#_authentication-and-authorization-with-embedded-jetty">Authentication and Authorization with Embedded Jetty</a></li>
</ul>
</li>
<li><a href="#configuring-form-size">Limiting Form Content</a>
<ul class="sectlevel3">
<li><a href="#_configuring-form-limits-for-a-webapp">Configuring Form Limits for a Webapp</a></li>
<li><a href="#_configuring-form-limits-for-the-server">Configuring Form Limits for the Server</a></li>
</ul>
</li>
<li><a href="#serving-aliased-files">Aliased Files and Symbolic links</a>
<ul class="sectlevel3">
<li><a href="#_good-security-practise">Good Security Practise</a></li>
<li><a href="#file-alias-detection">Alias detection</a></li>
<li><a href="#file-alias-serving">Serving Aliases and Symbolic Links</a></li>
</ul>
</li>
<li><a href="#configuring-security-secure-passwords">Secure Password Obfuscation</a></li>
<li><a href="#setting-port80-access">Setting Port 80 Access for a Non-Root User</a>
<ul class="sectlevel3">
<li><a href="#using-ipchains">Using ipchains</a></li>
<li><a href="#using-iptables">Using iptables</a></li>
<li><a href="#configuring-jetty-setuid-feature">Configuring Jetty&#8217;s SetUID Feature</a></li>
<li><a href="#using-solaris10-user-rights-management-framework">Using the Solaris 10 User Rights Management Framework</a></li>
</ul>
</li>
<li><a href="#jaas-support">JAAS Support</a>
<ul class="sectlevel3">
<li><a href="#jetty-jaas">Jetty and JAAS</a></li>
<li><a href="#jaas-configuration">Configuration</a>
<ul class="sectlevel4">
<li><a href="#_step-1">Step 1</a></li>
<li><a href="#jaas-step-2">Step 2</a></li>
<li><a href="#_step-3">Step 3</a></li>
</ul>
</li>
<li><a href="#_a-closer-look-at-jaasloginservice">A Closer Look at JAASLoginService</a>
<ul class="sectlevel4">
<li><a href="#_callbackhandler">CallbackHandler</a></li>
<li><a href="#_role-principal-implementation-class">Role Principal Implementation Class</a></li>
<li><a href="#_sample-loginmodules">Sample LoginModules</a></li>
<li><a href="#_jdbcloginmodule">JDBCLoginModule</a></li>
<li><a href="#_datasourceloginmodule">DataSourceLoginModule</a></li>
<li><a href="#_propertyfileloginmodule">PropertyFileLoginModule</a></li>
<li><a href="#_ldaploginmodule">LdapLoginModule</a></li>
</ul>
</li>
<li><a href="#_writing-your-own-loginmodule">Writing your Own LoginModule</a></li>
<li><a href="#_other-goodies">Other Goodies</a>
<ul class="sectlevel4">
<li><a href="#_servletrequestcallback">ServletRequestCallback</a></li>
<li><a href="#_requestparametercallback">RequestParameterCallback</a></li>
<li><a href="#_example-jaas-webapp">Example JAAS WebApp</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#spnego-support">SPNEGO Support</a>
<ul class="sectlevel3">
<li><a href="#_configuring-jetty-and-spnego">Configuring Jetty and SPNEGO</a></li>
<li><a href="#_configuring-firefox">Configuring Firefox</a></li>
<li><a href="#_configuring-internet-explorer">Configuring Internet Explorer</a></li>
</ul>
</li>
<li><a href="#openid-support">OpenID Support</a>
<ul class="sectlevel3">
<li><a href="#_external-setup">External Setup</a>
<ul class="sectlevel4">
<li><a href="#_registering-an-app-with-openid-provider">Registering an App with OpenID Provider</a></li>
</ul>
</li>
<li><a href="#_distribution-configuration">Distribution Configuration</a>
<ul class="sectlevel4">
<li><a href="#_openid-provider-configuration">OpenID Provider Configuration</a></li>
<li><a href="#_webapp-specific-configuration-in-web-xml">WebApp Specific Configuration in web.xml</a></li>
</ul>
</li>
<li><a href="#_embedded-configuration">Embedded Configuration</a>
<ul class="sectlevel4">
<li><a href="#_define-the-openidconfiguration-for-a-specific-openid-provider">Define the <code>OpenIdConfiguration</code> for a specific OpenID Provider.</a></li>
<li><a href="#_configuring-an-openidloginservice">Configuring an <code>OpenIdLoginService</code></a></li>
<li><a href="#_configuring-an-openidauthenticator-with-openidconfiguration-and-error-page-redirect">Configuring an <code>OpenIdAuthenticator</code> with <code>OpenIdConfiguration</code> and Error Page Redirect</a></li>
<li><a href="#_usage-2">Usage</a></li>
</ul>
</li>
<li><a href="#_scopes">Scopes</a></li>
<li><a href="#_roles">Roles</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#startup">Starting Jetty</a>
<ul class="sectlevel2">
<li><a href="#startup-overview">Startup Overview</a>
<ul class="sectlevel3">
<li><a href="#_startup-example">Startup Example</a></li>
</ul>
</li>
<li><a href="#startup-base-and-home">Managing Jetty Base and Jetty Home</a>
<ul class="sectlevel3">
<li><a href="#demo-base">Demo-Base in the Jetty Distribution</a></li>
<li><a href="#_declaring-jetty-base">Declaring Jetty Base</a></li>
</ul>
</li>
<li><a href="#startup-classpath">Managing Server Classpath</a>
<ul class="sectlevel3">
<li><a href="#_interrogating-the-server-classpath">Interrogating the Server Classpath</a></li>
</ul>
</li>
<li><a href="#startup-modules">Managing Startup Modules</a>
<ul class="sectlevel3">
<li><a href="#enabling-modules">Enabling Modules</a></li>
<li><a href="#start-vs-startd">Start.ini vs. Start.d</a></li>
<li><a href="#startup-configuring-modules">Configuring Modules</a></li>
<li><a href="#startup-disable-module">Disabling Modules</a></li>
<li><a href="#startup-listing-modules">Listing Available and Active Modules</a>
<ul class="sectlevel4">
<li><a href="#_searching-modules">Searching Modules</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#custom-modules">Custom Modules</a>
<ul class="sectlevel3">
<li><a href="#custom-module-properties">Module Properties</a></li>
<li><a href="#custom-module-location">Location of Modules</a></li>
<li><a href="#custom-module-examples">Creating Custom Modules</a></li>
<li><a href="#_dependencies">Dependencies</a></li>
</ul>
</li>
<li><a href="#startup-xml-config">Managing XML Based Startup Configuration</a></li>
<li><a href="#startup-unix-service">Startup a Unix Service using jetty.sh</a>
<ul class="sectlevel3">
<li><a href="#_quick-start-a-jetty-service">Quick-Start a Jetty Service</a></li>
<li><a href="#_practical-setup-of-a-jetty-service">Practical Setup of a Jetty Service</a></li>
</ul>
</li>
<li><a href="#startup-windows-service">Startup via Windows Service</a></li>
<li><a href="#startup-jpms">Startup using the Java Platform Module System (JPMS)</a>
<ul class="sectlevel3">
<li><a href="#jpms-module-path">Starting Jetty on the module-path</a></li>
<li><a href="#jpms-advanced-config">Advanced JPMS Configuration</a></li>
<li><a href="#jpms-module-path-alternative">Alternative way to start Jetty on the module-path</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#troubleshooting">Troubleshooting</a>
<ul class="sectlevel2">
<li><a href="#troubleshooting-zip-exceptions">Troubleshooting Zip Exceptions</a>
<ul class="sectlevel3">
<li><a href="#remedy">Remedy</a></li>
</ul>
</li>
<li><a href="#troubleshooting-locked-files-on-windows">Troubleshooting Locked Files on Windows</a>
<ul class="sectlevel3">
<li><a href="#_remedy">Remedy</a>
<ul class="sectlevel4">
<li><a href="#_using-override-web-xml">Using override-web.xml</a></li>
<li><a href="#_using-a-context-xml-file">Using a Context XML File</a></li>
<li><a href="#_using-the-jetty-maven-plugin">Using the Jetty Maven Plugin</a></li>
</ul>
</li>
<li><a href="#_alternate-remedy">Alternate Remedy</a></li>
</ul>
</li>
<li><a href="#preventing-memory-leaks">Preventing Memory Leaks</a>
<ul class="sectlevel3">
<li><a href="#preventing-webapp-classloader-pinning">Preventing WebApp Classloader Pinning</a>
<ul class="sectlevel4">
<li><a href="#preventers-table">Preventers</a></li>
<li><a href="#configuring-preventers">Configuring Preventers</a></li>
</ul>
</li>
<li><a href="#jsp-bugs">JSP Bugs: Permgen Problems</a></li>
<li><a href="#jvm-bugs">JVM Bugs</a>
<ul class="sectlevel4">
<li><a href="#jvm-garbage-collection-problems">Garbage Collection Problems</a></li>
<li><a href="#direct-byte-buffers">Direct ByteBuffers</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#troubleshooting-slow-deployment">Troubleshooting Slow Deployment</a>
<ul class="sectlevel3">
<li><a href="#_remedies">Remedies</a>
<ul class="sectlevel4">
<li><a href="#_limit-which-servletcontainerinitializers-to-execute">Limit Which ServletContainerInitializers to Execute</a></li>
<li><a href="#_limit-which-jars-to-scan">Limit Which Jars to Scan</a></li>
<li><a href="#_limit-scanning-to-first-deployment-only-quickstart">Limit Scanning to First Deployment Only (Quickstart)</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#security-reports">Jetty Security Reports</a></li>
<li><a href="#watchservice">Java WatchService</a>
<ul class="sectlevel3">
<li><a href="#_remedy-2">Remedy</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#optimizing">Optimizing Jetty</a>
<ul class="sectlevel2">
<li><a href="#garbage-collection">Garbage Collection</a>
<ul class="sectlevel3">
<li><a href="#garbage-collection-logging-configuration">Garbage Collection Logging Configuration</a></li>
</ul>
</li>
<li><a href="#high-load">High Load</a>
<ul class="sectlevel3">
<li><a href="#_load-generation-for-load-testing">Load Generation for Load Testing</a></li>
<li><a href="#_operating-system-tuning">Operating System Tuning</a>
<ul class="sectlevel4">
<li><a href="#_linux">Linux</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#limit-load">Limiting Load</a>
<ul class="sectlevel3">
<li><a href="#_low-resources-monitor">Low Resources Monitor</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#websocket-intro">WebSocket Introduction</a>
<ul class="sectlevel2">
<li><a href="#ws-intro-provides">What Jetty provides</a></li>
<li><a href="#ws-intro-api">WebSocket APIs</a></li>
<li><a href="#_enabling-websocket">Enabling WebSocket</a></li>
</ul>
</li>
<li><a href="#websocket-jetty">Jetty Websocket API</a></li>
<li><a href="#websocket-java">Java Websocket API</a></li>
</ul>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="_old-jetty-documentation"><a class="anchor" href="#_old-jetty-documentation"></a><a class="link" href="#_old-jetty-documentation">OLD JETTY DOCUMENTATION</a></h2>
<div class="sectionbody">
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The Jetty documentation that follows refers to old Jetty versions, and it is currently being ported to the current Jetty version.</p>
</div>
<div class="paragraph">
<p>Please be patient if you find incorrect documentation for the current Jetty version: eventually, the old documentation will be ported to the current Jetty version and it will be up to date.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="alpn-chapter"><a class="anchor" href="#alpn-chapter"></a><a class="link" href="#alpn-chapter">Application Layer Protocol Negotiation (ALPN)</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>The development of new web protocols such as HTTP/2 raised the need of protocol
negotiation within a Transport Layer Security (TLS) handshake.
A protocol negotiation called ALPN (Application Layer Protocol Negotiation -
<a href="https://tools.ietf.org/html/rfc7301">RFC7301</a>) has been defined to accomplish this.</p>
</div>
<div class="paragraph">
<p>ALPN has now replaced the older (and now fully deprecated) NPN in the general Web
as of 2016.</p>
</div>
<div class="paragraph">
<p>For those browsers that support HTTP/2, they all now support ALPN.
Starting with Jetty 9.3.0, only ALPN is supported by Jetty.</p>
</div>
<div class="sect2">
<h3 id="alpn"><a class="anchor" href="#alpn"></a><a class="link" href="#alpn">Introducing ALPN</a></h3>
<div class="paragraph">
<p>Application Layer Protocol Negotiation (ALPN) is a TLS extension that allows client and server to negotiate the application protocol that they will use to communicate within the encryption provided by TLS.</p>
</div>
<div class="paragraph">
<p>Any protocol can be negotiated by ALPN within a TLS connection; the protocols that are most commonly negotiated are HTTP/2 and HTTP/1.1.</p>
</div>
<div class="paragraph">
<p>Browsers only support HTTP/2 over TLS by negotiating the HTTP/2 protocol via ALPN.
You need to configure the server to support TLS and ALPN if you want browsers to use
the HTTP/2 protocol, otherwise they will default to HTTP/1.1.</p>
</div>
<div class="paragraph">
<p>In the Jetty project, ALPN is <em>used</em> in two artifacts: <code>jetty-alpn-client</code> and <code>jetty-alpn-server</code>, respectively for the client and for the server.</p>
</div>
<div class="paragraph">
<p>When using Jetty as a standalone server via the Jetty distribution, the <code>jetty-alpn-server</code> artifact is automatically included in the server classpath by the Jetty module system.</p>
</div>
<div class="paragraph">
<p>When using Jetty embedded, the <code>jetty-alpn-client</code> and <code>jetty-alpn-server</code> artifacts must be included in the classpath, respectively for client and server use cases.</p>
</div>
<div class="paragraph">
<p>The ALPN implementation is <em>provided</em> to these two artifacts with the following three options:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>For JDK 8 or later, a provider based on the <a href="#conscrypt">Conscrypt security provider</a></p>
<div class="ulist">
<ul>
<li>
<p>Works with JDK 8 or later and provides improved performance</p>
</li>
<li>
<p>Binds to the OpenSSL native library shipped by Conscrypt and is therefore only available on the platforms supported by Conscrypt</p>
</li>
</ul>
</div>
</li>
<li>
<p>For JDK 9 or later, a provider based on the ALPN APIs present in the JDK</p>
<div class="ulist">
<ul>
<li>
<p>Works with JDK 9 or later, pure Java implementation</p>
</li>
<li>
<p>Lower performance than Conscrypt</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>The first, although hosted under the umbrella of the Jetty project, is independent of Jetty (the Servlet Container); you can use it in any other Java network server.</p>
</div>
<div class="paragraph">
<p>Each provider above provides an ALPN <em>service</em> implementation; Jetty uses the <code>ServiceLoader</code> mechanism to load these service implementations.
At least one valid provider must be present in the server classpath.
For example, using JDK 8 with the JDK 9 ALPN provider is an <em>invalid</em> combination.
The absence of valid implementations is an error at startup (see also the <a href="#alpn-troubleshooting">troubleshooting section</a>).</p>
</div>
<div class="paragraph">
<p>There may be multiple ALPN service providers in the server classpath.
When a new connection is created, an <code>SSLEngine</code> instance is associated to it; each <code>SSLEngine</code> is passed all service implementations, until one accepts it.</p>
</div>
<div class="paragraph">
<p>It is therefore possible to have multiple providers active at the same time, for example the JDK 9 provider and the Conscrypt provider, and at runtime the correct one will be chosen by the Jetty runtime.</p>
</div>
<div class="sect3">
<h4 id="alpn-conscrypt"><a class="anchor" href="#alpn-conscrypt"></a><a class="link" href="#alpn-conscrypt">ALPN and Conscrypt</a></h4>
<div class="paragraph">
<p>When using JDK 8 or later, you can use the <a href="https://conscrypt.org/">Conscrypt</a> security provider to provide the ALPN service implementation.</p>
</div>
<div class="paragraph">
<p>Conscrypt binds natively to BoringSSL (a fork of OpenSSL by Google), so ALPN will be supported via the support provided by BoringSSL (bundled together with Conscrypt).</p>
</div>
<div class="paragraph">
<p>When using Jetty as a standalone server via the Jetty distribution, ALPN is enabled by enabling the <code>conscrypt</code> module.</p>
</div>
<div class="paragraph">
<p>When using Jetty embedded, ALPN is enabled by the <code>jetty-alpn-conscrypt-client</code> and <code>jetty-alpn-conscrypt-server</code> artifacts, respectively for client usage and server usage.
In addition, you also need the Conscrypt artifacts, typically the <code>org.conscrypt:conscrypt-openjdk-uber</code> artifact.
All these artifacts must be added to the classpath.</p>
</div>
</div>
<div class="sect3">
<h4 id="alpn-jdk9"><a class="anchor" href="#alpn-jdk9"></a><a class="link" href="#alpn-jdk9">ALPN and JDK 9</a></h4>
<div class="paragraph">
<p>When using JDK 9 or later and Jetty as a standalone server via the Jetty distribution, ALPN support is automatically enabled when the <code>http2</code> module is enabled.
This enables transitively the <code>alpn-9</code> module which puts the <code>jetty-alpn-java-server</code> artifact in the server classpath, providing the ALPN JDK 9 service implementation.</p>
</div>
<div class="paragraph">
<p>When using JDK 9 or later and Jetty embedded, the ALPN service implementation is provided by the <code>jetty-alpn-java-client</code> and <code>jetty-alpn-java-server</code> artifacts, respectively for client usage and server usage, and must be added to the classpath.</p>
</div>
<div class="sect4">
<h5 id="alpn-osgi"><a class="anchor" href="#alpn-osgi"></a><a class="link" href="#alpn-osgi">Starting in OSGi</a></h5>
<div class="paragraph">
<p>To use ALPN in an OSGi environment, in addition to what described above, you will also need to deploy the <code>jetty-osgi-alpn</code> jar.
This jar contains a <code>Fragment-Host</code> directive that ensures the ALPN classes will be available from the system bundle.</p>
</div>
<div class="paragraph">
<p>You can download the <a href="https://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-alpn/">jetty-osgi-alpn jar</a> from Maven Central.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
OSGi <strong>requires</strong> a <code>ServiceLoader</code> implementation for Jetty to function properly.
OSGi leverages <a href="http://aries.apache.org/modules/spi-fly.html">Apache Aries SPI Fly</a> for this functionality.
You can read more about OSGi and <code>ServiceLoader</code> <a href="http://blog.osgi.org/2013/02/javautilserviceloader-in-osgi.html">here.</a>
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
</div>
<div class="sect3">
<h4 id="alpn-troubleshooting"><a class="anchor" href="#alpn-troubleshooting"></a><a class="link" href="#alpn-troubleshooting">ALPN Troubleshooting</a></h4>
<div class="paragraph">
<p>When starting the Jetty server, especially when using Jetty embedded, it may be possible that you see an error similar to this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">IllegalStateException: no ALPN processor</code></pre>
</div>
</div>
<div class="paragraph">
<p>The error means that you don&#8217;t have the ALPN dependencies setup correctly in your classpath.</p>
</div>
<div class="paragraph">
<p>For example, you do not have the <code>jetty-alpn-java-server</code> artifact in the classpath.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="annotations"><a class="anchor" href="#annotations"></a><a class="link" href="#annotations">Annotations</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Jetty supports the servlet specification annotations.
It is not enable by default, so the following sections show you how to enable it, and how to use them.</p>
</div>
<div class="sect2">
<h3 id="annotations-quick-setup"><a class="anchor" href="#annotations-quick-setup"></a><a class="link" href="#annotations-quick-setup">Quick Setup</a></h3>
<div class="sect3">
<h4 id="_jetty-distribution"><a class="anchor" href="#_jetty-distribution"></a><a class="link" href="#_jetty-distribution">Jetty Distribution</a></h4>
<div class="paragraph">
<p>If you are using the jetty distribution, then annotations are enabled by default.
The annotations <a href="#startup-modules">module</a> and its transitive dependencies are responsible for making annotation processing available.</p>
</div>
<div class="paragraph">
<p>Note that annotations that relate to <a href="#jndi">JNDI</a>, such as @Resource and @Resources are enabled via the JNDI module, which is a transitive dependency on the annotations module.</p>
</div>
</div>
<div class="sect3">
<h4 id="_jetty-maven-plugin"><a class="anchor" href="#_jetty-maven-plugin"></a><a class="link" href="#_jetty-maven-plugin">Jetty Maven Plugin</a></h4>
<div class="paragraph">
<p>Annotations and JNDI are pre-enabled for the Maven plugin.</p>
</div>
</div>
<div class="sect3">
<h4 id="_embedding"><a class="anchor" href="#_embedding"></a><a class="link" href="#_embedding">Embedding</a></h4>
<div class="paragraph">
<p>To use annotations in an embedded scenario, you will need to include the <code>jetty-annotations</code> jar and all its dependencies onto your classpath.
You will also need to include the <code>org.eclipse.jetty.annotations.AnnotationConfiguration</code> class into the list of <a href="#webapp-configurations">Configuration classes</a> applied to the <code>org.eclipse.jetty.webapp.WebAppContext</code> class representing your webapp.</p>
</div>
<div class="paragraph">
<p>Below is an example application that sets up the standard <code>test-spec.war</code> webapp from the distribution in embedded fashion.
It can also be found in the Jetty GitHub repository on the examples/embedded page as <a href="https://github.com/eclipse/jetty.project/tree/master/examples/embedded/src/main/java/org/eclipse/jetty/embedded"><code>ServerWithAnnotations.java</code>.</a>
Note that the <code>test-spec.war</code> uses not only annotations, but also <a href="#jndi">JNDI</a>, so this example also enables their processing (via the <a href="#jndi-configuration-classes">org.eclipse.jetty.plus.webapp.EnvConfiguration</a>, <a href="#jndi-configuration-classes">org.eclipse.jetty.plus.webapp.PlusConfiguration</a> and their related jars).</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in annotations/quick-annotations-setup.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/ServerWithAnnotations.java[]</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="using-annotations"><a class="anchor" href="#using-annotations"></a><a class="link" href="#using-annotations">Working with Annotations</a></h3>
<div class="sect3">
<h4 id="_which-annotations-are-supported"><a class="anchor" href="#_which-annotations-are-supported"></a><a class="link" href="#_which-annotations-are-supported">Which Annotations Are Supported</a></h4>
<div class="paragraph">
<p>Jetty supports interpretation and application of the following annotations:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>@Resource</p>
</li>
<li>
<p>@Resources</p>
</li>
<li>
<p>@PostConstruct</p>
</li>
<li>
<p>@PreDestroy</p>
</li>
<li>
<p>@DeclaredRoles</p>
</li>
<li>
<p>@RunAs</p>
</li>
<li>
<p>@MultipartConfig</p>
</li>
<li>
<p>@WebServlet</p>
</li>
<li>
<p>@WebFilter</p>
</li>
<li>
<p>@WebListener</p>
</li>
<li>
<p>@WebInitParam</p>
</li>
<li>
<p>@ServletSecurity, @HttpConstraint, @HttpMethodConstraint</p>
</li>
<li>
<p>@HandlesTypes (on ServletContainerInitializers)</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="discoverable_introspectable_annotations"><a class="anchor" href="#discoverable_introspectable_annotations"></a><a class="link" href="#discoverable_introspectable_annotations">Discovered vs Introspected Annotations</a></h4>
<div class="paragraph">
<p>Some types of annotation can be placed on any class, not necessarily just those with which the container interacts directly.
These type of annotations are referred to as "discovered" to indicate that the container must take proactive action to go out and find them.
The other type of annotation is call "introspected", meaning that they occur on classes with which the container interacts during their lifecycle (e.g. <code>javax.servlet.Servlet</code>, <code>javax.servlet.Filter</code>, &#8230;&#8203;etc.), and hence can be found by simple inspection of the class at that point.</p>
</div>
<div class="paragraph">
<p>Some examples of discovered annotations are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>@WebServlet</p>
</li>
<li>
<p>@WebFilter</p>
</li>
<li>
<p>@WebListener</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Some examples of introspected annotations are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>@PostConstruct</p>
</li>
<li>
<p>@PreDestroy</p>
</li>
<li>
<p>@Resource</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="jars-scanned-for-annotations"><a class="anchor" href="#jars-scanned-for-annotations"></a><a class="link" href="#jars-scanned-for-annotations">Which Jar Files Are Scanned For Discovered Annotations</a></h4>
<div class="paragraph">
<p>The web.xml file can contain the attribute <code>metadata-complete</code>.
If this is set to <code>true</code>, then <em>no</em> scanning of discoverable annotations takes place.
However, scanning of classes may <em>still</em> occur because of <a href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html">javax.servlet.ServletContainerInitializer</a>s.
Classes implementing this interface are found by Jetty using the <a href="http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html">javax.util.ServiceLoader</a> mechanism, and if one is present <em>and</em> it includes the @HandlesTypes annotation, then Jetty must scan the class hierarchy of the web application.
This may be very time-consuming if you have many jars in the container&#8217;s path or in the webapp&#8217;s WEB-INF/lib.</p>
</div>
<div class="paragraph">
<p>If scanning is to take place - because either <code>metadata-complete</code> is <code>false</code> or missing, or because there are one or more <a href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html">javax.servlet.ServletContainerIntializer</a>s with @HandlesTypes - then Jetty must consider both the container&#8217;s classpath and the webapp&#8217;s classpath.</p>
</div>
<div class="paragraph">
<p>By default, Jetty will <em>not</em> scan any classes that are on the container&#8217;s classpath.
If you need to cause jars and classes that are on the container&#8217;s classpath to be scanned, then you can use the <a href="#container-include-jar-pattern"><code>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</code></a> <a href="#context_attributes">context attribute</a> to specify a pattern for jars and directories from the container&#8217;s classpath to scan.</p>
</div>
<div class="paragraph">
<p>By default Jetty will scan <em>all</em>classes from <code>WEB-INF/classes</code> and all jars from <code>WEB-INF/lib</code> according to the order, if any, established by absolute or relative ordering clauses in web.xml.
If your webapp contains many jar files, you can significantly speed up deployment by omitting them from scanning.
To do this, use the <a href="#web-inf-include-jar-pattern">org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</a> <a href="#context_attributes">context attribute</a> to define the patterns of jars that you specifically want to be scanned.</p>
</div>
<div class="paragraph">
<p>Note that if you have configured an <a href="#using-extra-classpath-method">extraClasspath</a> for the webapp, then it participates in the scanning process too.
Any classes dirs are treated the same for scanning purposes as if they were in WEB-INF/classes and jars are treated as if they were in WEB-INF/lib.</p>
</div>
<div class="paragraph">
<p>See also the next section on <a href="#servlet-container-initializers">ServletContainerInitializers</a> if you need to <a href="#servlet-container-initializers">control the order in which they are applied</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="_multi-threaded-annotation-scanning"><a class="anchor" href="#_multi-threaded-annotation-scanning"></a><a class="link" href="#_multi-threaded-annotation-scanning">Multi-threaded Annotation Scanning</a></h4>
<div class="paragraph">
<p><a href="#jars-scanned-for-annotations">If annotation scanning is to be performed</a>, by default Jetty will do it in a multi-threaded manner in order to complete it in the minimum amount of time.</p>
</div>
<div class="paragraph">
<p>If for some reason you don&#8217;t want multi-threaded scanning, you can configure Jetty to revert to single-threaded scanning.
There are several ways to configure this:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Set the <a href="#context_attributes">context attribute</a> <code>org.eclipse.jetty.annotations.multiThreaded</code> to <code>false</code></p>
</li>
<li>
<p>Set the <a href="#server_attributes">Server attribute</a> <code>org.eclipse.jetty.annotations.multiThreaded</code> to <code>false</code></p>
</li>
<li>
<p>Set the System property <code>org.eclipse.jetty.annotations.multiThreaded</code> to <code>false</code></p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Method 1 will only affect the current webapp.
Method 2 will affect all webapps deployed to the same Server instance.
Method 3 will affect all webapps deployed in the same JVM.</p>
</div>
<div class="paragraph">
<p>By default, Jetty will wait a maximum of 60 seconds for all of the scanning threads to complete.
You can set this to a higher or lower number of seconds by doing one of the following:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Set the <a href="#context_attributes">context attribute</a> <code>org.eclipse.jetty.annotations.maxWait</code></p>
</li>
<li>
<p>Set the <a href="#server_attributes">Server attribute</a> <code>org.eclipse.jetty.annotations.maxWait</code></p>
</li>
<li>
<p>Set the System property <code>org.eclipse.jetty.annotations.maxWait</code></p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Method 1 will only affect the current webapp.
Method 2 will affect all webapps deployed to the same Server instance.
Method 3 will affect all webapps deployed in the same JVM.</p>
</div>
</div>
<div class="sect3">
<h4 id="servlet-container-initializers"><a class="anchor" href="#servlet-container-initializers"></a><a class="link" href="#servlet-container-initializers">ServletContainerInitializers</a></h4>
<div class="paragraph">
<p>The <a href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html">javax.servlet.ServletContainerInitializer</a> class can exist in: the container&#8217;s classpath, the webapp&#8217;s <code>WEB-INF/classes</code> directory, the webapp&#8217;s <code>WEB-INF/lib</code> jars, or any external <a href="#using-extra-classpath-method">extraClasspath</a> that you have configured on the webapp.</p>
</div>
<div class="paragraph">
<p>The <a href="http://jcp.org/aboutJava/communityprocess/final/jsr340/">Servlet Specification</a> does not define any order in which a <code>ServletContainerInitializer</code> must be called when the webapp starts.
By default Jetty will call them in the following order:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>ServletContainerInitializers from the container&#8217;s classpath</p>
</li>
<li>
<p>ServletContainerInitializers from WEB-INF/classes</p>
</li>
<li>
<p>ServletContainerInitializers from WEB-INF/lib jars <em>in the order established in web.xml</em>, or in the order that the SCI is returned by the <a href="http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html">javax.util.ServiceLoader</a> if there is <em>no</em> ordering</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>As is the case with annotation scanning, the <a href="#using-extra-classpath-method">extraClasspath</a> is fully considered for <code>ServletContainerInitializer</code> callbacks. <code>ServletContainerInitializer</code> derived from a classes directory on the <code>extraClasspath</code> and jars from an <code>extraClasspath</code> for the webapp are called in step 2 and 3, respectively.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
As of Jetty 10, Annotations will be discovered even for old versions of <code>web.xml</code> (2.5).
Users wishing not to use annotations from the webapp classpath must call <code>WebAppContext.setConfigurationDiscovered(false)</code> either programmatically or in xml.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect4">
<h5 id="_controlling-the-order-of-servletcontainerinitializer-invocation"><a class="anchor" href="#_controlling-the-order-of-servletcontainerinitializer-invocation"></a><a class="link" href="#_controlling-the-order-of-servletcontainerinitializer-invocation">Controlling the order of ServletContainerInitializer invocation</a></h5>
<div class="paragraph">
<p>If you need <code>ServletContainerInitializer</code> classes called in a specific order that is different from that outlined above, you can use the <a href="#context_attributes">context attribute</a> <code>org.eclipse.jetty.containerInitializerOrder</code>.
Set them to a list of comma separated class names of <code>ServletContainerInitializers</code> in the order that you want them applied.
You may optionally use the wildcard character "<strong>" *once</strong> in the list.
It will match all <code>ServletContainerInitializer</code> classed not explicitly named in the list.</p>
</div>
<div class="paragraph">
<p>Here is an example, setting the context attribute in code (although you can also do the <a href="#intro-jetty-configuration-webapps">same in xml</a>):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">WebAppContext context = new WebAppContext();
context.setAttribute("org.eclipse.jetty.containerInitializerOrder",
"org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer, com.acme.Foo.MySCI, *");</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, we ensure that the <code>WebSocketServerContainerInitializer</code> is the very first <code>ServletContainerInitializer</code> that is called, followed by MySCI and then any other <code>ServletContainerInitializer</code> instances that were discovered but not yet called.</p>
</div>
</div>
<div class="sect4">
<h5 id="excluding-scis"><a class="anchor" href="#excluding-scis"></a><a class="link" href="#excluding-scis">Excluding ServletContainerInitializers</a></h5>
<div class="paragraph">
<p>By default, as according to the Servlet Specification, all <code>ServletContainerInitializer</code> that are discovered are invoked (see above for how to control the invocation order).
Sometimes, depending on your requirements, you may need to prevent some being called at all.</p>
</div>
<div class="paragraph">
<p>In this case, you can define the <code>org.eclipse.jetty.containerInitializerExclusionPattern</code> <a href="#context_attributes">context attribute</a>.
This is a regular expression that defines <a href="http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html">patterns</a> of classnames that you want to exclude.
Here&#8217;s an example, setting the context attribute in code, although you may do exactly the <a href="#intro-jetty-configuration-webapps">same in xml</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">WebAppContext context = new WebAppContext();
context.setAttribute("org.eclipse.jetty.containerInitializerExclusionPattern",
"com.acme.*|com.corp.SlowContainerInitializer");</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example we exclude <strong>all</strong> <code>ServletContainerInitializer</code> instances in the com.acme package, and the <code>SlowContainerInitializer</code>.</p>
</div>
<div class="paragraph">
<p>It is possible to use exclusion and ordering together to control <code>ServletContainerInitializer</code> invocation - the exclusions will be applied before the ordering.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="using-annotations-embedded"><a class="anchor" href="#using-annotations-embedded"></a><a class="link" href="#using-annotations-embedded">Using Annotations with Jetty Embedded</a></h3>
<div class="sect3">
<h4 id="_setting-up-the-classpath"><a class="anchor" href="#_setting-up-the-classpath"></a><a class="link" href="#_setting-up-the-classpath">Setting up the Classpath</a></h4>
<div class="paragraph">
<p>You will need to place the following Jetty jar files onto the classpath of your application.
You can obtain them from the <a href="https://www.eclipse.org/jetty/download.html">Jetty distribution</a>, or the <a href="https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-annotations">Maven repository</a>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>jetty-plus.jar
jetty-annotations.jar</pre>
</div>
</div>
<div class="paragraph">
<p>You will also need the <a href="http://asm.ow2.org/">asm</a> jar, which you can obtain from <a href="http://central.maven.org/maven2/org/eclipse/jetty/orbit/org.objectweb.asm/3.3.1.v201105211655/org.objectweb.asm-3.3.1.v201105211655.jar">this link.</a></p>
</div>
</div>
<div class="sect3">
<h4 id="_example"><a class="anchor" href="#_example"></a><a class="link" href="#_example">Example</a></h4>
<div class="paragraph">
<p>Here&#8217;s an example application that sets up a Jetty server, performs some setup to ensure that annotations are scanned, and then deploys a webapp that uses annotations.
This example also uses the @Resource annotation which involves JNDI, so we would also <a href="#jndi-embedded">add the necessary JNDI jars to the classpath</a>.
The example also adds in the configuration classes that are responsible for JNDI (see line 19).</p>
</div>
<div class="paragraph">
<p>The code is as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
/**
* ServerWithAnnotations
*
*
*/
public class ServerWithAnnotations
{
public static final void main(String args[]) throws Exception
{
//Create the server
Server server = new Server(8080);
//Enable parsing of jndi-related parts of web.xml and jetty-env.xml
org.eclipse.jetty.webapp.Configuration.ClassList classlist = org.eclipse.jetty.webapp.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");
//Create a WebApp
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
webapp.setWar("../../tests/test-webapps/test-servlet-spec/test-spec-webapp/target/test-spec-webapp-9.0.4-SNAPSHOT.war");
server.setHandler(webapp);
//Register new transaction manager in JNDI
//At runtime, the webapp accesses this as java:comp/UserTransaction
org.eclipse.jetty.plus.jndi.Transaction transactionMgr = new org.eclipse.jetty.plus.jndi.Transaction(new com.acme.MockUserTransaction());
//Define an env entry with webapp scope.
org.eclipse.jetty.plus.jndi.EnvEntry maxAmount = new org.eclipse.jetty.plus.jndi.EnvEntry (webapp, "maxAmount", new Double(100), true);
// Register a mock DataSource scoped to the webapp
org.eclipse.jetty.plus.jndi.Resource mydatasource = new org.eclipse.jetty.plus.jndi.Resource(webapp, "jdbc/mydatasource", new com.acme.MockDataSource());
// Configure a LoginService
HashLoginService loginService = new HashLoginService();
loginService.setName("Test Realm");
loginService.setConfig("src/test/resources/realm.properties");
server.addBean(loginService);
server.start();
server.join();
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>On line 19 the configuration classes responsible for setting up JNDI and <code>java:comp/env</code> are added.</p>
</div>
<div class="paragraph">
<p>On line 20 we add in the configuration class that ensures annotations are inspected.</p>
</div>
<div class="paragraph">
<p>On lines 30, 33 and 37 JNDI resources that we will be able to reference with @Resource annotations are configured.</p>
</div>
<div class="paragraph">
<p>With the setup above, a servlet that uses annotations and Jetty will honour the annotations when the webapp is deployed can be created:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RunAs;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import javax.transaction.UserTransaction;
/**
* AnnotationTest
*
* Use servlet 3.0 annotations from within Jetty.
*
* Also uses servlet 2.5 resource injection and lifecycle callbacks
*/
@RunAs("special")
@WebServlet(urlPatterns = {"/","/test/*"}, name="AnnotationTest", initParams={@WebInitParam(name="fromAnnotation", value="xyz")})
@DeclareRoles({"user","client"})
public class AnnotationTest extends HttpServlet
{
private DataSource myDS;
@Resource(mappedName="UserTransaction")
private UserTransaction myUserTransaction;
@Resource(mappedName="maxAmount")
private Double maxAmount;
@Resource(mappedName="jdbc/mydatasource")
public void setMyDatasource(DataSource ds)
{
myDS=ds;
}
@PostConstruct
private void myPostConstructMethod ()
{
System.err.println("PostConstruct called");
}
@PreDestroy
private void myPreDestroyMethod()
{
System.err.println("PreDestroy called");
}
public void init(ServletConfig config) throws ServletException
{
super.init(config);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doGet(request, response);
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
{
response.setContentType("text/html");
ServletOutputStream out = response.getOutputStream();
out.println("&lt;html&gt;");
out.println("&lt;body&gt;");
out.println("&lt;h1&gt;Results&lt;/h1&gt;");
out.println(myDS.toString());
out.println("&lt;br/&gt;");
out.println(maxAmount.toString());
out.println("&lt;/body&gt;");
out.println("&lt;/html&gt;");
out.flush();
}
catch (Exception e)
{
throw new ServletException(e);
}
}
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="ant-and-jetty"><a class="anchor" href="#ant-and-jetty"></a><a class="link" href="#ant-and-jetty">Ant and Jetty</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>This chapter explains how to use Jetty with Ant and the Jetty Ant tasks.</p>
</div>
<div class="sect2">
<h3 id="jetty-ant"><a class="anchor" href="#jetty-ant"></a><a class="link" href="#jetty-ant">Ant Jetty Plugin</a></h3>
<div class="paragraph">
<p>The Ant Jetty plugin is a part of Jetty 9 under the <code>jetty-ant</code> module.
This plugin makes it possible to start a Jetty web server directly from the Ant build script, and to embed the Jetty web server inside your build process.
Its purpose is to provide almost the same functionality as the Jetty plugin for Maven: dynamic application reloading, working directly on web application sources, and tightly integrating with the build system.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-ant&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="jetty-ant-preparation"><a class="anchor" href="#jetty-ant-preparation"></a><a class="link" href="#jetty-ant-preparation">Preparing Your Project</a></h4>
<div class="paragraph">
<p>To set up your project for Ant to run Jetty, you need a Jetty distribution and the jetty-ant Jar:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p><a href="https://www.eclipse.org/jetty/download.html">Download</a> a Jetty distribution and unpack it in the local filesystem.</p>
</li>
<li>
<p><a href="https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-ant/">Get</a> the jetty-ant Jar.</p>
</li>
<li>
<p>Make a directory in your project called <code>jetty-lib/</code>.</p>
</li>
<li>
<p>Copy all of the Jars in your Jetty distribution&#8217;s <code>lib</code> directory, and all its subdirectories, into your new <code>jetty-lib</code> dir.
When copying the Jars, <em>don&#8217;t</em> preserve the Jetty distribution&#8217;s lib dir hierarchy – all the jars should be directly inside your ` jetty-lib` dir.</p>
</li>
<li>
<p>Also copy the jetty-ant Jar you downloaded earlier into the <code>jetty-lib</code> dir.</p>
</li>
<li>
<p>Make a directory in your project called <code>jetty-temp</code>.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Now you&#8217;re ready to edit or create your Ant <code>build.xml</code> file.</p>
</div>
</div>
<div class="sect3">
<h4 id="_preparing-the-build-xml-file"><a class="anchor" href="#_preparing-the-build-xml-file"></a><a class="link" href="#_preparing-the-build-xml-file">Preparing the <code>build.xml</code> file</a></h4>
<div class="paragraph">
<p>Begin with an empty <code>build.xml</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Add a <code>&lt;taskdef&gt;</code> that imports all available Jetty tasks:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now you are ready to add a new target for running Jetty:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run /&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This is the minimal configuration you need. You can now start Jetty on the default port of 8080.</p>
</div>
</div>
<div class="sect3">
<h4 id="_starting-jetty-via-ant"><a class="anchor" href="#_starting-jetty-via-ant"></a><a class="link" href="#_starting-jetty-via-ant">Starting Jetty via Ant</a></h4>
<div class="paragraph">
<p>At the command line enter:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; ant jetty.run</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_configuring-the-jetty-container"><a class="anchor" href="#_configuring-the-jetty-container"></a><a class="link" href="#_configuring-the-jetty-container">Configuring the Jetty Container</a></h4>
<div class="paragraph">
<p>A number of configuration options can help you set up the Jetty environment so that your web application has all the resources it needs:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">ports and connectors</dt>
<dd>
<p>To configure the port that Jetty starts on you need to define a connector.
First you need to configure a <code>&lt;typedef&gt;</code> for the Connector class and then define the connector in the Jetty tags:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;typedef name="connector" classname="org.eclipse.jetty.ant.types.Connector"
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run&gt;
&lt;connectors&gt;
&lt;connector port="8090"/&gt;
&lt;/connectors&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
You can set the port to 0, which starts the Jetty server connector on an arbitrary available port.
You can then access these values from system properties <code>jetty.ant.server.port</code> and <code>jetty.ant.server.host</code>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</dd>
<dt class="hdlist1">login services</dt>
<dd>
<p>If your web application requires authentication and authorization services, you can configure these on the Jetty container.
Here&#8217;s an example of how to set up an <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/security/HashLoginService.html">org.eclipse.jetty.security.HashLoginService</a>:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;typedef name="hashLoginService" classname="org.eclipse.jetty.security.HashLoginService"
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run&gt;
&lt;loginServices&gt;
&lt;hashLoginService name="Test Realm" config="${basedir}/realm.properties"/&gt;
&lt;/loginServices&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">request log</dt>
<dd>
<p>The <code>requestLog</code> option allows you to specify a request logger for the Jetty instance.
You can either use the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/NCSARequestLog.html">org.eclipse.jetty.server.NCSARequestLog</a> class, or supply the name of your custom class:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run requestLog="com.acme.MyFancyRequestLog"&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">temporary directory</dt>
<dd>
<p>You can configure a directory as a temporary file store for uses such as expanding files and compiling JSPs by supplying the <code>tempDirectory</code> option:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run tempDirectory="${basedir}/jetty-temp"&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">other context handlers</dt>
<dd>
<p>You may need to configure some other context handlers to run at the same time as your web application.
You can specify these other context handlers using the <code>&lt;contextHandlers&gt;</code> element.
You need to supply a <code>&lt;typedef&gt;</code> for it before you can use it:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath"
resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;typedef name="contextHandlers" classname="org.eclipse.jetty.ant.types.ContextHandlers"
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run&gt;
&lt;contextHandlers&gt;
&lt;contextHandler resourceBase="${basedir}/stuff" contextPath="/stuff"/&gt;
&lt;/contextHandlers&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">system properties</dt>
<dd>
<p>As a convenience, you can configure system properties by using the <code>&lt;systemProperties&gt;</code> element.
Be aware that, depending on the purpose of the system property, setting it from within the Ant execution may mean that it is evaluated too late, as the JVM evaluates some system properties on entry.</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run&gt;
&lt;systemProperties&gt;
&lt;systemProperty name="foo" value="bar"/&gt;
&lt;/systemProperties&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">jetty XML file</dt>
<dd>
<p>If you have a lot of configuration to apply to the Jetty container, it can be more convenient to put it into a standard Jetty XML configuration file and have the Ant plugin apply it before starting Jetty:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run jettyXml="${basedir}/jetty.xml"&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">scanning for changes</dt>
<dd>
<p>The most useful mode in which to run the Ant plugin is for it to continue to execute Jetty and automatically restart your web application if any part of it changes (for example, your IDE
recompiles the classes of the web application).
The <code>scanIntervalSeconds</code> option controls how frequently the <code>&lt;jetty.run&gt;</code> task scans your web application/WAR file for changes.
The default value of <code>0</code> disables scanning. Here&#8217;s an example where Jetty checks for changes every five seconds:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run scanIntervalSeconds="5"&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">stopping</dt>
<dd>
<p>In normal mode (<code>daemon="false"</code>), the <code>&lt;jetty.run&gt;</code> task runs until you <code>cntrl-c</code> it. It may be useful to script both the stop AND the start of Jetty.
For such a case, we provide the <code>&lt;jetty.stop&gt;</code> task.
+
To use it, you need to provide a port and an identifying string to both the ` &lt;jetty.run&gt;` and the <code>&lt;jetty.stop&gt;</code> tasks, where <code>&lt;jetty.run&gt;</code> listens on the given port for a stop message containing the given string, and cleanly stops Jetty when it is received.
The <code>&lt;jetty.stop&gt;</code> task sends this stop message.
You can also optionally provide a <code>stopWait</code> value (in seconds), which is the length of time the <code>&lt;jetty.stop&gt;</code> task waits for confirmation that the stop succeeded:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run stopPort="9999" stopKey="9999"&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;target name="jetty.stop"&gt;
&lt;jetty.stop stopPort="9999" stopKey="9999" stopWait="10"/&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>To stop jetty via Ant, enter:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; ant jetty.stop</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">execution without pausing ant</dt>
<dd>
<p>Usually, the <code>&lt;jetty.run&gt;</code> task runs until you <code>cntrl-c</code> it, pausing the execution of Ant as it does so. In some cases, it may be useful to let Ant continue executing.
For example, to run your unit tests you may need other tasks to execute while Jetty is running.
For this case, we provide the <code>daemon</code> option.
This defaults to <code>false</code>. For <code>true</code>, Ant continues to execute after starting Jetty.
If Ant exits, so does Jetty. Understand that this option does <em>not</em> fork a new process for Jetty.</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run daemon="true"&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="_deploying-a-web-application"><a class="anchor" href="#_deploying-a-web-application"></a><a class="link" href="#_deploying-a-web-application">Deploying a Web Application</a></h4>
<div class="paragraph">
<p>Add a <code>&lt;typedef&gt;</code> for the <code>org.eclipse.jetty.ant.AntWebAppContext</code> class with name <em>webApp</em>, then add a <code>&lt;webApp&gt;</code> element to <code>&lt;jetty.run&gt;</code> to describe your web application.
The following example deploys a web application that is expanded in the local directory <code>foo/</code> to context path ` / `:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;typedef name="webApp" classname="org.eclipse.jetty.ant.AntWebAppContext"
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run&gt;
&lt;webApp war="${basedir}/foo" contextPath="/"/&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">deploying a WAR file</dt>
<dd>
<p>It is not necessary to expand the web application into a directory.
It is fine to deploy it as a WAR file:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;typedef name="webApp" classname="org.eclipse.jetty.ant.AntWebAppContext"
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run&gt;
&lt;webApp war="${basedir}/foo.war" contextPath="/"/&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">deploying more than one web application</dt>
<dd>
<p>You can also deploy more than one web application:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;typedef name="webApp" classname="org.eclipse.jetty.ant.AntWebAppContext"
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run&gt;
&lt;webApp war="${basedir}/foo.war" contextPath="/"/&gt;
&lt;webApp war="${basedir}/other contextPath="/other"/&gt;
&lt;webApp war="${basedir}/bar.war" contextPath="/bar"/&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
</dl>
</div>
<div class="sect4">
<h5 id="_configuring-the-web-application"><a class="anchor" href="#_configuring-the-web-application"></a><a class="link" href="#_configuring-the-web-application">Configuring the Web Application</a></h5>
<div class="paragraph">
<p>As the <code>org.eclipse.jetty.ant.AntWebAppContext</code> class is an extension of
the
<a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html"><code>org.eclipse.jetty.webapp.WebAppContext</code></a>
class, you can configure it by adding attributes of the same name
(without the <code>set</code> or <code>add</code> prefix) as the setter methods.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example that specifies the location of the <code>web.xml</code> file (equivalent to method <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#setDescriptor%28java.lang.String%29"><code>AntWebAppContext.setDescriptor()</code></a>) and the web application&#8217;s temporary directory (equivalent to method <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#setTempDirectory%28java.io.File%29"><code>AntWebAppContext.setTempDirectory()</code></a>):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;typedef name="webApp" classname="org.eclipse.jetty.ant.AntWebAppContext"
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run&gt;
&lt;webApp descriptor="${basedir}/web.xml" tempDirectory="${basedir}/my-temp" war="${basedir}/foo" contextPath="/"/&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Other extra configuration options for the AntWebAppContext include:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">extra classes and Jars</dt>
<dd>
<p>If your web application&#8217;s classes and Jars do not reside inside <code>WEB-INF</code> of the resource base directory, you can use the &lt;classes&gt; and &lt;jar&gt; elements to tell Ant where to find them. Here&#8217;s an example:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;typedef name="webApp" classname="org.eclipse.jetty.ant.AntWebAppContext"
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run&gt;
&lt;webApp descriptor="${basedir}/web.xml" tempDirectory="${basedir}/my-temp" war="${basedir}/foo" contextPath="/"&gt;
&lt;classes dir="${basedir}/classes"&gt;
&lt;include name="**/*.class"/&gt;
&lt;include name="**/*.properties"/&gt;
&lt;/classes&gt;
&lt;lib dir="${basedir}/jars"&gt;
&lt;include name="**/*.jar"/&gt;
&lt;exclude name="**/*.dll"/&gt;
&lt;/lib&gt;
&lt;/webApp&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">context attributes</dt>
<dd>
<p>Jetty allows you to set up ServletContext attributes on your web application.
You configure them in a context XML file that is applied to your WebAppContext instance prior to starting it.
For convenience, the Ant plugin permits you to configure these directly in the build file.
Here&#8217;s an example:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;typedef name="webApp" classname="org.eclipse.jetty.ant.AntWebAppContext"
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run&gt;
&lt;webApp war="${basedir}/foo" contextPath="/"&gt;
&lt;attributes&gt;
&lt;attribute name="my.param" value="123"/&gt;
&lt;/attributes&gt;
&lt;/webApp&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1"><code>jetty-env.xml</code> file</dt>
<dd>
<p>If you are using features such as <a href="#configuring_jndi">JNDI</a> with your web application, you may need to configure a <a href="#using_jndi"><code>WEB-INF/jetty-env.xml</code></a> file to define resources. If the structure of your web application project is such that the source of <code>jetty-env.xml</code> file resides somewhere other than <code>WEB-INF</code>, you can use the <code>jettyEnvXml</code> attribute to tell Ant where to find it:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;typedef name="webApp" classname="org.eclipse.jetty.ant.AntWebAppContext"
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run&gt;
&lt;webApp war="${basedir}/foo" contextPath="/" jettyEnvXml="${basedir}/jetty-env.xml"&gt;
&lt;attributes&gt;
&lt;/webApp&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">context XML file</dt>
<dd>
<p>You may prefer or even require to do some advanced configuration of your web application outside of the Ant build file.
In this case, you can use a standard context XML configuration file which the Ant plugin applies to your web application before it is deployed.
Be aware that the settings from the context XML file <em>override</em> those of the attributes and nested elements you defined in the build file.</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">project name="Jetty-Ant integration test" basedir="."&gt;
&lt;path id="jetty.plugin.classpath"&gt;
&lt;fileset dir="jetty-lib" includes="*.jar"/&gt;
&lt;/path&gt;
&lt;taskdef classpathref="jetty.plugin.classpath" resource="tasks.properties" loaderref="jetty.loader" /&gt;
&lt;typedef name="webApp" classname="org.eclipse.jetty.ant.AntWebAppContext"
classpathref="jetty.plugin.classpath" loaderref="jetty.loader" /&gt;
&lt;target name="jetty.run"&gt;
&lt;jetty.run&gt;
&lt;webApp war="${basedir}/foo" contextPath="/" contextXml="${basedir}/jetty-env.xml"&gt;
&lt;attributes&gt;
&lt;/webApp&gt;
&lt;/jetty.run&gt;
&lt;/target&gt;
&lt;/project&gt;</code></pre>
</div>
</div>
</dd>
</dl>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="architecture"><a class="anchor" href="#architecture"></a><a class="link" href="#architecture">Architecture</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>General items related to the architecture of jetty and how it deals with certain design decisions.</p>
</div>
<div class="sect2">
<h3 id="jetty-classloading"><a class="anchor" href="#jetty-classloading"></a><a class="link" href="#jetty-classloading">Jetty Classloading</a></h3>
<div class="paragraph">
<p>Class loading in a web container is slightly more complex than a normal Java application.
The normal configuration is that each web context (web application or WAR file) has its own classloader, which has the system classloader as its parent.
Such a classloader hierarchy is normal in Java, however the servlet specification complicates the hierarchy because it requires the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Classes contained within <code>WEB-INF/lib</code> or <code>WEB-INF/classes</code> have priority over classes on the parent classloader.
This is the opposite of the normal behavior of a Java 2 classloader.</p>
</li>
<li>
<p>System classes such as <code>java.lang.String</code> are excluded from the webapp priority, and you may not replace them with classes in <code>WEB-INF/lib</code> or <code>WEB-INF/</code> classes.
Unfortunately the specification does not clearly state what classes are <em>System</em> classes, and it is unclear if all <code>javax</code> classes should be treated as System classes.</p>
</li>
<li>
<p>Server implementation classes like <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/Server.html">Server</a> should be hidden from the web application and should not be available in any classloader.
Unfortunately the specification does not state what classes are <em>Server</em> classes, and it is unclear if common libraries like the Xerces parser should be treated as Implementation classes.</p>
</li>
</ul>
</div>
<div class="sect3">
<h4 id="configuring-webapp-classloading"><a class="anchor" href="#configuring-webapp-classloading"></a><a class="link" href="#configuring-webapp-classloading">Configuring Webapp Classloading</a></h4>
<div class="paragraph">
<p>Jetty provides configuration options to control the three webapp class loading issues identified above.</p>
</div>
<div class="paragraph">
<p>You can configure webapp classloading by several methods on the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html">WebAppContext</a>.
You can call these methods directly if you are working with the Jetty API, or you can inject methods from a context XML file if you are using the Context Provider (<a href="#using-context-provider">[using-context-provider]</a>).
You CANNOT set these methods from a <code>jetty-web.xml</code> file, as it executes after the classloader configuration is set.
As a note, <code>jetty-web.xml</code> uses the webapp classpath and not the classpath of the server.</p>
</div>
<div class="sect4">
<h5 id="controlling-webapp-classloader-priority"><a class="anchor" href="#controlling-webapp-classloader-priority"></a><a class="link" href="#controlling-webapp-classloader-priority">Controlling Webapp Classloader Priority</a></h5>
<div class="paragraph">
<p>The method <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#isParentLoaderPriority()">org.eclipse.jett .webapp.WebAppContext.setParentLoaderPriority(boolean)</a> allows control over the priority given to webapp classes over system classes.
If you set it to false (the default), Jetty uses standard webapp classloading priority.
However, if in this mode some classes that are dependencies of other classes are loaded from the parent classloader (due to settings of system classes below), ambiguities might arise as both the webapp and system classloader versions can end up being loaded.</p>
</div>
<div class="paragraph">
<p>If set to true, Jetty uses normal JavaSE classloading priority, and gives priority to the parent/system classloader.
This avoids the issues of multiple versions of a class within a webapp, but the version the parent/system loader provides must be the right version for all webapps you configure in this way.</p>
</div>
</div>
<div class="sect4">
<h5 id="configuring-webapp-caching"><a class="anchor" href="#configuring-webapp-caching"></a><a class="link" href="#configuring-webapp-caching">Configuring Webapp Classloader Caching</a></h5>
<div class="paragraph">
<p>Introduced in Jetty 9.3.6, the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/CachingWebAppClassLoader.html">CachingWebAppClassLoader</a> can be used to cache <code>getResource(String)</code> results.
For webapps that search for classes and resources regularly, this can increase speed and performance.
This is an optional feature and it should be noted that it can conflict with several other libraries such as JSP, JSTL, JSF and CDI.
As such, this feature must be manually enabled for each webapp you want to use it in.</p>
</div>
<div class="paragraph">
<p>Below is an example of implementing this feature using Jetty IoC XML format:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id="mywebapp" class="org.eclipse.jetty.webapp.WebAppContext"&gt;
...
&lt;Set name="classLoader"&gt;
&lt;New class="org.eclipse.jetty.webapp.CachingWebAppClassLoader"&gt;
&lt;Arg&gt;&lt;Ref refid="mywebapp"/&gt;&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Set&gt;
...
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="classloading-setting-system-classes"><a class="anchor" href="#classloading-setting-system-classes"></a><a class="link" href="#classloading-setting-system-classes">Setting System Classes</a></h5>
<div class="paragraph">
<p>You can call the methods
<a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#setSystemClasses%28java.lang.String%5B%5D%29">WebAppContext.setSystemClasses(String[])</a>
or
<a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#getSystemClasspathPattern()">WebAppContext.getSystemClasspathPattern().add(String)</a>
to allow fine control over which classes are considered system classes.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A web application can see a System class.</p>
</li>
<li>
<p>A WEB-INF class cannot replace a System class.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The default system classes are:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 1. Default System Classes</caption>
<colgroup>
<col style="width: 8%;">
<col style="width: 92%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">System Classes</th>
<th class="tableblock halign-left valign-top">Note</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">java.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java SE classes (per servlet spec v2.5 / SRV.9.7.2).</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">javax.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java SE classes (per servlet spec v2.5 / SRV.9.7.2).</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.xml.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Needed by javax.xml.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.w3c.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Needed by javax.xml.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.continuation.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Webapp can see and not change continuation classes.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.jndi.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Webapp can see and not change naming classes.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.jaas.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Webapp can see and not change JAAS classes.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.websocket.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">WebSocket is a Jetty extension.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.servlet.DefaultServlet</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Webapp can see and not change default servlet.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Absolute classname can be passed, names ending with <code>.</code> are treated as packages names, and names starting with <code>-</code> are treated as negative matches and must be listed before any enclosing packages.</p>
</div>
</div>
<div class="sect4">
<h5 id="setting-server-classes"><a class="anchor" href="#setting-server-classes"></a><a class="link" href="#setting-server-classes">Setting Server Classes</a></h5>
<div class="paragraph">
<p>You can call the methods <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#setServerClasses%28java.lang.String%5B%5D%29">org.eclipse.jetty.webapp.WebAppContext.setServerClasses(String Array)</a> or
<a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#addServerClass(java.lang.String)">org.eclipse.jetty.webapp.WebAppContext.addServerClass(String)</a> to allow fine control over which classes are considered Server classes.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A web application cannot see a Server class.</p>
</li>
<li>
<p>A WEB-INF class can replace a Server class.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The default server classes are:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 2. Default Server Classes</caption>
<colgroup>
<col style="width: 8%;">
<col style="width: 92%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Server Classes</th>
<th class="tableblock halign-left valign-top">-org.eclipse.jetty.continuation.</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Don&#8217;t hide continuation classes.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-org.eclipse.jetty.jndi.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Don&#8217;t hide naming classes.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-org.eclipse.jetty.jaas.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Don&#8217;t hide jaas classes.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-org.eclipse.jetty.servlets.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Don&#8217;t hide utility servlet classes if provided.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-org.eclipse.jetty.servlet.DefaultServlet</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Don&#8217;t hide default servlet.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-org.eclipse.jetty.servlet.listener.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Don&#8217;t hide utility listeners</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-org.eclipse.jetty.websocket.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Don&#8217;t hide websocket extension.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.</p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="adding-extra-classpaths"><a class="anchor" href="#adding-extra-classpaths"></a><a class="link" href="#adding-extra-classpaths">Adding Extra Classpaths to Jetty</a></h4>
<div class="paragraph">
<p>You can add extra classpaths to Jetty in several ways.</p>
</div>
<div class="sect4">
<h5 id="classpaths-using-start-jar"><a class="anchor" href="#classpaths-using-start-jar"></a><a class="link" href="#classpaths-using-start-jar">Using <code>start.jar</code></a></h5>
<div class="paragraph">
<p>If you are using <code>start.jar</code> via the Jetty distribution, at startup the Jetty runtime automatically loads option Jars from the top level <code>$jetty.home/lib</code> directory. The default settings include:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Adding Jars under <code>$jetty.home/lib/ext</code> to the system classpath.
You can place additional Jars here.</p>
</li>
<li>
<p>Adding the directory <code>$jetty.home/resources</code> to the classpath (may contain classes or other resources).</p>
</li>
<li>
<p>Adding a single path defined by the command line parameter <em>path</em>.</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="using-extra-classpath-method"><a class="anchor" href="#using-extra-classpath-method"></a><a class="link" href="#using-extra-classpath-method">Using the extraClasspath() method</a></h5>
<div class="paragraph">
<p>You can add an additional classpath to a context classloader by calling <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#setExtraClasspath(java.lang.String)">org.eclipse.jetty.webapp.WebAppContext.setExtraClasspath(String)</a> with a comma-separated list of paths.
You can do so directly to the API via a context XML file such as the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
...
&lt;Set name="extraClasspath"&gt;../my/classes,../my/jars/special.jar,../my/jars/other.jar&lt;/Set&gt;
...</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="using-custom-webappclassloader"><a class="anchor" href="#using-custom-webappclassloader"></a><a class="link" href="#using-custom-webappclassloader">Using a Custom WebAppClassLoader</a></h4>
<div class="paragraph">
<p>If none of the alternatives already described meet your needs, you can always provide a custom classloader for your webapp.
We recommend, but do not require, that your custom loader subclasses <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppClassLoader.html">WebAppClassLoader</a>.</p>
</div>
<div class="paragraph">
<p>If you do not subclass WebAppClassLoader, we recommend that you implement the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/util/ClassVisibilityChecker.html">ClassVisibilityChecker</a> interface.
Without this interface, session persistence will be slower.</p>
</div>
<div class="paragraph">
<p>You configure the classloader for the webapp like so:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">MyCleverClassLoader myCleverClassLoader = new MyCleverClassLoader();
...
WebAppContext webapp = new WebAppContext();
...
webapp.setClassLoader(myCleverClassLoader);</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also accomplish this in a context xml file.</p>
</div>
</div>
<div class="sect3">
<h4 id="starting-jetty-custom-classloader"><a class="anchor" href="#starting-jetty-custom-classloader"></a><a class="link" href="#starting-jetty-custom-classloader">Starting Jetty with a Custom ClassLoader</a></h4>
<div class="paragraph">
<p>If you start a Jetty server using a custom class loader–consider the Jetty classes not being available to the system class loader, only your custom class loader–you may run into class loading issues when the <code>WebAppClassLoader</code> kicks in.
By default the <code>WebAppClassLoader</code> uses the system class loader as its parent, hence the problem. This is easy to fix, like so:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">context.setClassLoader(new WebAppClassLoader(this.getClass().getClassLoader(), context));</code></pre>
</div>
</div>
<div class="paragraph">
<p>or</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">context.setClassLoader(new WebAppClassLoader(new MyCustomClassLoader(), context));</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configuring-connectors"><a class="anchor" href="#configuring-connectors"></a><a class="link" href="#configuring-connectors">Configuring Jetty Connectors</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>This chapter discusses various options for configuring Jetty connectors.</p>
</div>
<div class="sect2">
<h3 id="jetty-connectors"><a class="anchor" href="#jetty-connectors"></a><a class="link" href="#jetty-connectors">Connector Configuration Overview</a></h3>
<div class="paragraph">
<p>Connectors are the mechanism through which Jetty accepts network connections for various protocols.
Configuring a connector is a combination of configuring the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Network parameters on the connector itself (for example: the listening port).</p>
</li>
<li>
<p>Services the connector uses (for example: executors, schedulers).</p>
</li>
<li>
<p>Connection factories that instantiate and configure the protocol for an accepted connection.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Typically connectors require very little configuration aside from setting the listening port, and enabling <code>X-Forwarded-For</code> customization when applicable.
Additional settings, including construction your own constructor Jetty XML files, are for expert configuration only.</p>
</div>
<div class="sect3">
<h4 id="_enabling-connectors"><a class="anchor" href="#_enabling-connectors"></a><a class="link" href="#_enabling-connectors">Enabling Connectors</a></h4>
<div class="paragraph">
<p>Out of the box, Jetty provides several <a href="#startup-modules">modules</a> for enabling different types of connectors, from HTTP to HTTPS, HTTP/2, and others.
If you startup Jetty with the <code>--list-modules=connector</code> command, you can see a list of all available connector modules:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --list-modules=connector
Available Modules:
==================
tags: [connector]
Modules for tag 'connector':
----------------------------
Module: acceptratelimit
: Enable a server wide accept rate limit
Tags: connector
Depend: server
XML: etc/jetty-acceptratelimit.xml
Module: connectionlimit
: Enable a server wide connection limit
Tags: connector
Depend: server
XML: etc/jetty-connectionlimit.xml
Module: http
: Enables a HTTP connector on the server.
: By default HTTP/1 is support, but HTTP2C can
: be added to the connector with the http2c module.
Tags: connector, http
Depend: server
XML: etc/jetty-http.xml
Module: http-forwarded
: Adds a forwarded request customizer to the HTTP Connector
: to process forwarded-for style headers from a proxy.
Tags: connector
Depend: http
XML: etc/jetty-http-forwarded.xml
Module: http2
: Enables HTTP2 protocol support on the TLS(SSL) Connector,
: using the ALPN extension to select which protocol to use.
Tags: connector, http2, http, ssl
Depend: ssl, alpn
LIB: lib/http2/*.jar
XML: etc/jetty-http2.xml
Module: http2c
: Enables the HTTP2C protocol on the HTTP Connector
: The connector will accept both HTTP/1 and HTTP/2 connections.
Tags: connector, http2, http
Depend: http
LIB: lib/http2/*.jar
XML: etc/jetty-http2c.xml
Module: https
: Adds HTTPS protocol support to the TLS(SSL) Connector
Tags: connector, https, http, ssl
Depend: ssl
Optional: http-forwarded, http2
XML: etc/jetty-https.xml
Module: proxy-protocol-ssl
: Enables the Proxy Protocol on the TLS(SSL) Connector.
: http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
: This allows a Proxy operating in TCP mode to transport
: details of the proxied connection to the server.
: Both V1 and V2 versions of the protocol are supported.
Tags: connector, ssl
Depend: ssl
XML: etc/jetty-proxy-protocol-ssl.xml
Module: ssl
: Enables a TLS(SSL) Connector on the server.
: This may be used for HTTPS and/or HTTP2 by enabling
: the associated support modules.
Tags: connector, ssl
Depend: server
XML: etc/jetty-ssl.xml
XML: etc/jetty-ssl-context.xml
Module: unixsocket
: Enables a Unix Domain Socket Connector that can receive
: requests from a local proxy and/or SSL offloader (eg haproxy) in either
: HTTP or TCP mode. Unix Domain Sockets are more efficient than
: localhost TCP/IP connections as they reduce data copies, avoid
: needless fragmentation and have better dispatch behaviours.
: When enabled with corresponding support modules, the connector can
: accept HTTP, HTTPS or HTTP2C traffic.
Tags: connector
Depend: server
LIB: lib/jetty-unixsocket-${jetty.version}.jar
LIB: lib/jnr/*.jar
XML: etc/jetty-unixsocket.xml
Module: unixsocket-forwarded
: Adds a forwarded request customizer to the HTTP configuration used
: by the Unix Domain Socket connector, for use when behind a proxy operating
: in HTTP mode that adds forwarded-for style HTTP headers. Typically this
: is an alternate to the Proxy Protocol used mostly for TCP mode.
Tags: connector
Depend: unixsocket-http
XML: etc/jetty-unixsocket-forwarded.xml
Module: unixsocket-http
: Adds a HTTP protocol support to the Unix Domain Socket connector.
: It should be used when a proxy is forwarding either HTTP or decrypted
: HTTPS traffic to the connector and may be used with the
: unix-socket-http2c modules to upgrade to HTTP/2.
Tags: connector, http
Depend: unixsocket
XML: etc/jetty-unixsocket-http.xml
Module: unixsocket-http2c
: Adds a HTTP2C connetion factory to the Unix Domain Socket Connector
: It can be used when either the proxy forwards direct
: HTTP/2C (unecrypted) or decrypted HTTP/2 traffic.
Tags: connector, http2
Depend: unixsocket-http
LIB: lib/http2/*.jar
XML: etc/jetty-unixsocket-http2c.xml
Module: unixsocket-proxy-protocol
: Enables the proxy protocol on the Unix Domain Socket Connector
: http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
: This allows information about the proxied connection to be
: efficiently forwarded as the connection is accepted.
: Both V1 and V2 versions of the protocol are supported and any
: SSL properties may be interpreted by the unixsocket-secure
: module to indicate secure HTTPS traffic. Typically this
: is an alternate to the forwarded module.
Tags: connector
Depend: unixsocket
XML: etc/jetty-unixsocket-proxy-protocol.xml
Module: unixsocket-secure
: Enable a secure request customizer on the HTTP Configuration
: used by the Unix Domain Socket Connector.
: This looks for a secure scheme transported either by the
: unixsocket-forwarded, unixsocket-proxy-protocol or in a
: HTTP2 request.
Tags: connector
Depend: unixsocket-http
XML: etc/jetty-unixsocket-secure.xml
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>To enable a connector, simply activate the associated module.
Below is an example of activating both the <code>http</code> and <code>https</code> modules in a fresh <a href="#startup-base-and-home">Jetty base</a> using the <a href="#start-vs-startd">start.d directory</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[mybase] java -jar $JETTY_HOME/start.jar --create-startd
MKDIR : ${jetty.base}/start.d
INFO : Base directory was modified
[mybase] java -jar $JETTY_HOME/start.jar --add-to-start=http,https
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : http initialized in ${jetty.base}/start.d/http.ini
INFO : https initialized in ${jetty.base}/start.d/https.ini
INFO : ssl transitively enabled, ini template available with --add-to-start=ssl
MKDIR : ${jetty.base}/etc
COPY : ${jetty.home}/modules/ssl/keystore to ${jetty.base}/etc/keystore
INFO : Base directory was modified
[mybase] tree
.
├── etc
│   └── keystore
└── start.d
├── http.ini
└── https.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>When the <code>http</code> and <code>https</code> modules were activated, so too were any modules they were dependent on, in this case <code>server</code> and <code>ssl</code>, as well as any dependencies for those modules, such as the <code>etc</code> and <code>ketystore</code> directories for <code>ssl</code>.</p>
</div>
<div class="paragraph">
<p>At this point the server has been configured with connectors for both HTTP and HTTPS and can be started:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[mybase] java -jar $JETTY_HOME/start.jar
2017-08-31 10:19:58.855:INFO::main: Logging initialized @372ms to org.eclipse.jetty.util.log.StdErrLog
2017-08-31 10:19:59.076:INFO:oejs.Server:main: jetty-10.0.0-SNAPSHOT
2017-08-31 10:19:59.125:INFO:oejs.AbstractConnector:main: Started ServerConnector@421e98e0{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2017-08-31 10:19:59.150:INFO:oejus.SslContextFactory:main: x509=X509@5315b42e(jetty,h=[jetty.eclipse.org],w=[]) for SslContextFactory@2ef9b8bc(file:///Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT/mybase/etc/keystore,file:///Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT/mybase/etc/keystore)
2017-08-31 10:19:59.151:INFO:oejus.SslContextFactory:main: x509=X509@5d624da6(mykey,h=[],w=[]) for SslContextFactory@2ef9b8bc(file:///Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT/mybase/etc/keystore,file:///Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT/mybase/etc/keystore)
2017-08-31 10:19:59.273:INFO:oejs.AbstractConnector:main: Started ServerConnector@2b98378d{SSL,[ssl, http/1.1]}{0.0.0.0:8443}
2017-08-31 10:19:59.274:INFO:oejs.Server:main: Started @791ms</code></pre>
</div>
</div>
<div class="paragraph">
<p>When modules are enabled, they are loaded with several default options.
These can be changed by editing the associated module ini file in the <code>start.d</code> directory (or the associated lines in <code>server.ini</code> if your implementation does not use <code>start.d</code>).
For example, if we examine the <code>http.ini</code> file in our <code>start.d</code> directory created above, we will see the following settings:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># ---------------------------------------
# Module: http
# Enables a HTTP connector on the server.
# By default HTTP/1 is support, but HTTP2C can
# be added to the connector with the http2c module.
# ---------------------------------------
--module=http
### HTTP Connector Configuration
## Connector host/address to bind to
# jetty.http.host=0.0.0.0
## Connector port to listen on
# jetty.http.port=8080
## Connector idle timeout in milliseconds
# jetty.http.idleTimeout=30000
## Number of acceptors (-1 picks default based on number of cores)
# jetty.http.acceptors=-1
## Number of selectors (-1 picks default based on number of cores)
# jetty.http.selectors=-1
## ServerSocketChannel backlog (0 picks platform default)
# jetty.http.acceptQueueSize=0
## Thread priority delta to give to acceptor threads
# jetty.http.acceptorPriorityDelta=0
## HTTP Compliance: RFC7230, RFC2616, LEGACY
# jetty.http.compliance=RFC7230</code></pre>
</div>
</div>
<div class="paragraph">
<p>To make a change to these settings, uncomment the line (by removing the #) and change the property to the desired value.
For example, if you wanted to change the HTTP port to 5231, you would edit the line as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">...
## Connector port to listen on
jetty.http.port=5231
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now when the server is started, HTTP connections will enter on port 5231:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar
2017-08-31 10:31:32.955:INFO::main: Logging initialized @366ms to org.eclipse.jetty.util.log.StdErrLog
2017-08-31 10:31:33.109:INFO:oejs.Server:main: jetty-10.0.0-SNAPSHOT
2017-08-31 10:31:33.146:INFO:oejs.AbstractConnector:main: Started ServerConnector@2ef9b8bc{HTTP/1.1,[http/1.1]}{0.0.0.0:5231}
...
2017-08-31 10:31:33.263:INFO:oejs.Server:main: Started @675ms</code></pre>
</div>
</div>
<div class="paragraph">
<p>Every module has their own set of configuration options, and reviewing them all is recommended.
For additional information on the module system, please refer to our documentation on <a href="#startup-modules">Startup Modules</a>.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Editing these module files is the recommended way to edit the configuration of your server.
Making changes to the associated Jetty XML file for connectors is <strong>not</strong> recommended, and is for advanced users only.
If you do wish to edit Jetty XML, please see our section on managing <a href="#">Jetty Home and Jetty Base</a> to ensure your Jetty Home remains a standard of truth for your implementation.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="_limiting-connections"><a class="anchor" href="#_limiting-connections"></a><a class="link" href="#_limiting-connections">Limiting Connections</a></h4>
<div class="paragraph">
<p>Jetty also provides the means by which to limit connections to the server and/or contexts.
This is provided by two different modules in the distribution.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>connectionlimit</code></dt>
<dd>
<p>Applies a limit to the number of connections.
If this limit is exceeded, new connections are suspended for the time specified (in milliseconds).</p>
</dd>
<dt class="hdlist1"><code>acceptratelimit</code></dt>
<dd>
<p>Limits the rate at which new connections are accepted.
If this limit is exceeded, new connections are suspended for the time specified (in milliseconds).</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>As with the modules listed above, these can be enabled by adding <code>--add-to-start=&lt;module-name&gt;</code> to the command line.</p>
</div>
</div>
<div class="sect3">
<h4 id="_advanced-configuration"><a class="anchor" href="#_advanced-configuration"></a><a class="link" href="#_advanced-configuration">Advanced Configuration</a></h4>
<div class="paragraph">
<p>Jetty primarily uses a single connector type called <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ServerConnector.html">ServerConnector</a>.</p>
</div>
<div class="paragraph">
<p>Prior to Jetty 9, the type of the connector specified both the protocol and the implementation used; for example, selector-based non blocking I/O vs blocking I/O, or SSL connector vs non-SSL connector.
Jetty 9 has a single selector-based non-blocking I/O connector, and a collection of <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ConnectionFactory.html"><code>ConnectionFactories</code></a> now configure the protocol on the connector.</p>
</div>
<div class="paragraph">
<p>The standard Jetty distribution comes with the following Jetty XML files that create and configure connectors; you should examine them as you read this section:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty-http.xml"><code>jetty-http.xml</code></a></dt>
<dd>
<p>Instantiates a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ServerConnector.html"><code>ServerConnector</code></a> that accepts HTTP connections (that may be upgraded to WebSocket connections).</p>
</dd>
<dt class="hdlist1"><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty-ssl.xml"><code>jetty-ssl.xml</code></a></dt>
<dd>
<p>Instantiates a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ServerConnector.html"><code>ServerConnector</code></a> that accepts SSL/TLS connections.
On it&#8217;s own, this connector is not functional and requires one or more of the following files to also be configured to add <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ConnectionFactory.html"><code>ConnectionFactories</code></a> to make the connector functional.</p>
</dd>
<dt class="hdlist1"><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty-https.xml"><code>jetty-https.xml</code></a></dt>
<dd>
<p>Adds a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/HttpConnectionFactory.html"><code>HttpConnectionFactory</code></a> to the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ServerConnector.html"><code>ServerConnector</code></a> configured by <code>jetty-ssl.xml</code> which combine to provide support for HTTPS.</p>
</dd>
<dt class="hdlist1"><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty-http-forwarded.xml"><code>jetty-http-forwarded.xml</code></a></dt>
<dd>
<p>Adds a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ForwardedRequestCustomizer.html"><code>ForwardedRequestCustomizer</code></a>to the HTTP Connector to process forwarded-for style headers from a proxy.</p>
</dd>
<dt class="hdlist1"><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml"><code>jetty-http2.xml</code></a></dt>
<dd>
<p>Adds a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.html"><code>Http2ServerConnectionFactory</code></a> to the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ServerConnector.html"><code>ServerConnector</code></a> configured by <code>jetty-ssl.xml</code> to support the http2 protocol.</p>
</dd>
<dt class="hdlist1"><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-alpn/jetty-alpn-server/src/main/config/etc/jetty-alpn.xml"><code>jetty-alpn.xml</code></a></dt>
<dd>
<p>Adds an <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/alpn/server/ALPNServerConnectionFactory.html"><code>ALPNServerConnectionFactory</code></a> to the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ServerConnector.html"><code>ServerConnector</code></a> configured by <code>jetty-ssl.xml</code> which allows the one SSL connector to support multiple protocols with the ALPN extension used to select the protocol to be used for each connection.</p>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="_constructing-a-serverconnector"><a class="anchor" href="#_constructing-a-serverconnector"></a><a class="link" href="#_constructing-a-serverconnector">Constructing a ServerConnector</a></h4>
<div class="paragraph">
<p>The services a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ServerConnector.html"><code>ServerConnector</code></a> instance uses are set by constructor injection and once instantiated cannot be changed.
Many of the services may be defaulted with null or 0 values so that a reasonable default is used, thus for most purposes only the Server and the connection factories need to be passed to the connector constructor. In Jetty XML (that is, in <a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty-http.xml"><code>jetty-http.xml</code></a>) you can do this by:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New class="org.eclipse.jetty.server.ServerConnector"&gt;
&lt;Arg name="server"&gt;&lt;Ref refid="Server" /&gt;&lt;/Arg&gt;
&lt;Arg name="factories"&gt;
&lt;Array type="org.eclipse.jetty.server.ConnectionFactory"&gt;
&lt;!-- insert one or more factories here --&gt;
&lt;/Array&gt;
&lt;/Arg&gt;
&lt;!-- set connector fields here --&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can see the other arguments that can be passed when constructing a <code>ServerConnector</code> in the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ServerConnector.html#ServerConnector%28org.eclipse.jetty.server.Server,%20java.util.concurrent.Executor,%20org.eclipse.jetty.util.thread.Scheduler,%20org.eclipse.jetty.io.ByteBufferPool,%20int,%20int,%20org.eclipse.jetty.server.ConnectionFactory&#8230;&#8203;%29">Javadoc</a>.
Typically the defaults are sufficient for almost all deployments.</p>
</div>
</div>
<div class="sect3">
<h4 id="jetty-connectors-network-settings"><a class="anchor" href="#jetty-connectors-network-settings"></a><a class="link" href="#jetty-connectors-network-settings">Network Settings</a></h4>
<div class="paragraph">
<p>You can configure connector network settings by calling setters on the connector before it is started.
For example, you can set the port with the Jetty XML:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New class="org.eclipse.jetty.server.ServerConnector"&gt;
&lt;Arg name="server"&gt;&lt;Ref refid="Server" /&gt;&lt;/Arg&gt;
&lt;Arg name="factories"&gt;&lt;!-- insert one or more factories here --&gt;&lt;/Arg&gt;
&lt;Set name="port"&gt;8080&lt;/Set&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Values in Jetty XML can also be parameterized so that they may be passed from property files or set on the command line.
Thus typically the port is set within Jetty XML, but uses the <code>Property</code> element to be customizable:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New class="org.eclipse.jetty.server.ServerConnector"&gt;
&lt;Arg name="server"&gt;&lt;Ref refid="Server" /&gt;&lt;/Arg&gt;
&lt;Arg name="factories"&gt;&lt;!-- insert one or more factories here --&gt;&lt;/Arg&gt;
&lt;Set name="port"&gt;&lt;Property name="jetty.http.port" default="8080"/&gt;&lt;/Set&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The network settings available for configuration on the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ServerConnector.html"><code>ServerConnector</code></a> include:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 3. Connector Configuration</caption>
<colgroup>
<col style="width: 22%;">
<col style="width: 78%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Field</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">host</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The network interface this connector binds to as an IP address or a hostname.
If null or 0.0.0.0, bind to all interfaces.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">port</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The configured port for the connector or 0 a random available port may be used (selected port available via <code>getLocalPort()</code>).</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">idleTimeout</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The time in milliseconds that the connection can be idle before it is closed.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">defaultProtocol</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The name of the default protocol used to select a <code>ConnectionFactory</code> instance. This defaults to the first <code>ConnectionFactory</code> added to the connector.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">stopTimeout</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The time in milliseconds to wait before gently stopping a connector.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">acceptQueueSize</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The size of the pending connection backlog.
The exact interpretation is JVM and operating system specific and you can ignore it.
Higher values allow more connections to wait pending an acceptor thread.
Because the exact interpretation is deployment dependent, it is best to keep this value as the default unless there is a specific connection issue for a specific OS that you need to address.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">reuseAddress</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Allow the server socket to be rebound even if in <a href="http://www.ssfnet.org/Exchange/tcp/tcpTutorialNotes.html">TIME_WAIT</a>.
For servers it is typically OK to leave this as the default true.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="jetty-connectors-http-configuration"><a class="anchor" href="#jetty-connectors-http-configuration"></a><a class="link" href="#jetty-connectors-http-configuration">HTTP Configuration</a></h4>
<div class="paragraph">
<p>The <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/HttpConfiguration.html"><code>HttpConfiguration</code></a> class holds the configuration for <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/HttpChannel.html"><code>HttpChannel</code></a>s, which you can create 1:1 with each HTTP connection or 1:n on a multiplexed HTTP/2 connection.
Thus a <code>HttpConfiguration</code> object is injected into both the HTTP and HTTP/2 connection factories.
To avoid duplicate configuration, the standard Jetty distribution creates the common <code>HttpConfiguration</code> instance in <a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty.xml"><code>jetty.xml</code></a>, which is a <code>Ref</code> element then used in <a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty-http.xml"><code>jetty-http.xml</code></a>, <a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty-https.xml"><code>jetty-https.xml</code></a> and in <a href="https://github.com/eclipse/jetty.project/tree/master/jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml"><code>jetty-http2.xml</code></a>.</p>
</div>
<div class="paragraph">
<p>A typical configuration of <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/HttpConfiguration.html">HttpConfiguration</a> is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration"&gt;
&lt;Set name="secureScheme"&gt;https&lt;/Set&gt;
&lt;Set name="securePort"&gt;&lt;Property name="jetty.ssl.port" default="8443" /&gt;&lt;/Set&gt;
&lt;Set name="outputBufferSize"&gt;32768&lt;/Set&gt;
&lt;Set name="requestHeaderSize"&gt;8192&lt;/Set&gt;
&lt;Set name="responseHeaderSize"&gt;8192&lt;/Set&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example HttpConfiguration may be used by reference to the ID &#8220;httpConfig&#8221;:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Call name="addConnector"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.server.ServerConnector"&gt;
&lt;Arg name="server"&gt;&lt;Ref refid="Server" /&gt;&lt;/Arg&gt;
&lt;Arg name="factories"&gt;
&lt;Array type="org.eclipse.jetty.server.ConnectionFactory"&gt;
&lt;Item&gt;
&lt;New class="org.eclipse.jetty.server.HttpConnectionFactory"&gt;
&lt;Arg name="config"&gt;&lt;Ref refid="httpConfig" /&gt;&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Arg&gt;
&lt;!-- ... --&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This same <code>httpConfig</code> is referenced by the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/SecuredRedirectHandler.html"><code>SecuredRedirectHandler</code></a> when redirecting secure requests.
Please note that if your <code>httpConfig</code> does not include a <code>secureScheme</code> or <code>securePort</code> or there is no <code>HttpConfiguration</code> present these types of secured requests will be returned a <code>403</code> error.</p>
</div>
<div class="paragraph">
<p>For SSL-based connectors (in <code>jetty-https.xml</code> and <code>jetty-http2.xml</code>), the common &#8220;httpConfig&#8221; instance is used as the basis to create an SSL specific configuration with ID &#8220;sslHttpConfig&#8221;:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration"&gt;
&lt;Arg&gt;&lt;Ref refid="httpConfig"/&gt;&lt;/Arg&gt;
&lt;Call name="addCustomizer"&gt;
&lt;Arg&gt;&lt;New class="org.eclipse.jetty.server.SecureRequestCustomizer"/&gt;&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This adds a <code>SecureRequestCustomizer</code> which adds SSL Session IDs and certificate information as request attributes.</p>
</div>
</div>
<div class="sect3">
<h4 id="_ssl-context-configuration"><a class="anchor" href="#_ssl-context-configuration"></a><a class="link" href="#_ssl-context-configuration">SSL Context Configuration</a></h4>
<div class="paragraph">
<p>The SSL/TLS connectors for HTTPS and HTTP/2 require a certificate to establish a secure connection.
Jetty holds certificates in standard JVM keystores and are configured as keystore and truststores on a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/util/ssl/SslContextFactory.Server.html"><code>SslContextFactory.Server</code></a> instance that is injected into an <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/SslConnectionFactory.html"><code>SslConnectionFactory</code></a> instance.
An example using the keystore distributed with Jetty (containing a self signed test certificate) is in <a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty-https.xml"><code>jetty-https.xml</code></a>.
Read more about SSL keystores in <a href="#configuring-ssl">Configuring SSL</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="_proxy-load-balancer-connection-configuration"><a class="anchor" href="#_proxy-load-balancer-connection-configuration"></a><a class="link" href="#_proxy-load-balancer-connection-configuration">Proxy / Load Balancer Connection Configuration</a></h4>
<div class="paragraph">
<p>Often a Connector needs to be configured to accept connections from an intermediary such as a Reverse Proxy and/or Load Balancer deployed in front of the server.
In such environments, the TCP/IP connection terminating on the server does not originate from the client, but from the intermediary, so that the Remote IP and port number can be reported incorrectly in logs and in some circumstances the incorrect server address and port may be used.</p>
</div>
<div class="paragraph">
<p>Thus Intermediaries typically implement one of several de facto standards to communicate to the server information about the original client connection terminating on the intermediary.
Jetty supports the <code>X-Forwarded-For</code> header and the <a href="http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt">Proxy Protocol</a> mechanisms as described below.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The XML files in the Jetty distribution contain commented out examples of both the <code>X-Forwarded-For</code> and <a href="http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt">Proxy Protocol</a> mechanisms.
When using those examples, it is recommended that the XML in the Jetty distribution is not edited.
Rather the files should be copied into a Jetty base directory and then modified.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect4">
<h5 id="_x-forward-for-configuration"><a class="anchor" href="#_x-forward-for-configuration"></a><a class="link" href="#_x-forward-for-configuration">X-Forward-for Configuration</a></h5>
<div class="paragraph">
<p>The <code>X-Forwarded-for</code> header and associated headers are a de facto standard where intermediaries add HTTP headers to each request they forward to describe the originating connection.
These headers can be interpreted by an instance of <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ForwardedRequestCustomizer.html"><code>ForwardedRequestCustomizer</code></a> which can be added to a <code>HttpConfiguration</code> as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration"&gt;
&lt;Set name="outputBufferSize"&gt;32768&lt;/Set&gt;
&lt;Set name="requestHeaderSize"&gt;8192&lt;/Set&gt;
&lt;Set name="responseHeaderSize"&gt;8192&lt;/Set&gt;
&lt;Call name="addCustomizer"&gt;
&lt;Arg&gt;&lt;New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/&gt;&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_proxy-protocol"><a class="anchor" href="#_proxy-protocol"></a><a class="link" href="#_proxy-protocol">Proxy Protocol</a></h5>
<div class="paragraph">
<p>The <a href="http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt">Proxy Protocol</a> is the <em>de facto</em> standard created by HAProxy and used by environments such as Amazon Elastic Cloud.
This mechanism is independent of any protocol, so it can be used for HTTP2, TLS etc.
The information about the client connection is sent as a small data frame on each newly established connection.
In Jetty, this protocol can be handled by the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ProxyConnectionFactory.html"><code>ProxyConnectionFactory</code></a> which parses the data frame and then instantiates the next <code>ConnectionFactory</code> on the connection with an end point that has been customized with the data obtained about the original client connection.
The connection factory can be added to any <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ServerConnector.html"><code>ServerConnector</code></a> and should be the first <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ConnectionFactory.html"><code>ConnectionFactory</code></a>.</p>
</div>
<div class="paragraph">
<p>An example of adding the factory to a HTTP connector is shown below:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Call name="addConnector"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.server.ServerConnector"&gt;
&lt;Arg name="server"&gt;&lt;Ref refid="Server" /&gt;&lt;/Arg&gt;
&lt;Arg name="factories"&gt;
&lt;Array type="org.eclipse.jetty.server.ConnectionFactory"&gt;
&lt;Item&gt;
&lt;New class="org.eclipse.jetty.server.ProxyConnectionFactory"/&gt;
&lt;/Item&gt;
&lt;Item&gt;
&lt;New class="org.eclipse.jetty.server.HttpConnectionFactory"&gt;
&lt;Arg name="config"&gt;&lt;Ref refid="httpConfig" /&gt;&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Arg&gt;
&lt;Set name="host"&gt;&lt;Property name="jetty.host" /&gt;&lt;/Set&gt;
&lt;Set name="port"&gt;&lt;Property name="jetty.http.port" default="80" /&gt;&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="configuring-ssl"><a class="anchor" href="#configuring-ssl"></a><a class="link" href="#configuring-ssl">Configuring SSL/TLS</a></h3>
<div class="paragraph">
<p>This document provides an overview of how to configure SSL and TLS for Jetty.</p>
</div>
<div class="sect3">
<h4 id="configuring-jetty-for-ssl"><a class="anchor" href="#configuring-jetty-for-ssl"></a><a class="link" href="#configuring-jetty-for-ssl">Configuring Jetty for SSL</a></h4>
<div class="paragraph">
<p>To configure Jetty for SSL, complete the tasks in the following sections:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="#generating-key-pairs-and-certificates">Generating Key Pairs and Certificates</a></p>
</li>
<li>
<p><a href="#requesting-trusted-certificate">Requesting a Trusted Certificate</a></p>
</li>
<li>
<p><a href="#loading-keys-and-certificates">Loading Keys and Certificates</a></p>
</li>
<li>
<p><a href="#configuring-sslcontextfactory">Configuring the Jetty SslContextFactory</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="tls-and-ssl-versions"><a class="anchor" href="#tls-and-ssl-versions"></a><a class="link" href="#tls-and-ssl-versions">TLS and SSL versions</a></h4>
<div class="paragraph">
<p>Which browser/OS supports which protocols can be <a href="https://en.wikipedia.org/wiki/Transport_Layer_Security#Web_browsers">found on Wikipedia</a>.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>TLS v1.2: The protocol which should be used wherever possible.
All CBC based ciphers are supported since Java 7, the new GCM modes are supported since Java 8.</p>
</li>
</ul>
</div>
<div class="sect4">
<h5 id="_older-protocols"><a class="anchor" href="#_older-protocols"></a><a class="link" href="#_older-protocols">Older Protocols</a></h5>
<div class="paragraph">
<p>TLS v1.0, v1.1 and SSL v3 are no longer supported by default. If your Jetty implementation requires these protocols for legacy support, they can be enabled manually.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Once TLS v1.3 is released, there will be no workaround available for TLS v1.0 or v1.1.
Plans for TLS v1.3 include banning ciphers with known vulnerabilities from being present at any level.
It is recommended to upgrade any clients using these ciphers as soon as possible or face being locked into a outdated version of Jetty, Java or even OS.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>By default, Jetty excludes these ciphers in the <a href="https://github.com/eclipse/jetty.project/tree/master/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java#L249-L256"><code>SslContextFactory</code>.</a>
You can re-enable these by re-declaring the ciphers you want excluded in code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setExcludeCipherSuites("^.*_(MD5|SHA|SHA1)$");</code></pre>
</div>
</div>
<div class="paragraph">
<p>If, after making these changes, you still have issues using these ciphers they are likely being blocked at the JVM level.
Locate the <code>$JAVA_HOME/jre/lib/security/</code> directory for the <code>java.security</code> file and examine it for any configuration that is excluding <em>ciphers</em> or <em>algorithms</em> (depending on the version of the JVM you are using the nomenclature may be different).</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="understanding-certificates-and-keys"><a class="anchor" href="#understanding-certificates-and-keys"></a><a class="link" href="#understanding-certificates-and-keys">Understanding Certificates and Keys</a></h4>
<div class="paragraph">
<p>Configuring SSL can be a confusing experience of keys, certificates, protocols and formats, thus it helps to have a reasonable understanding of the basics.
The following links provide some good starting points:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Certificates:</p>
<div class="ulist">
<ul>
<li>
<p><a href="http://en.tldp.org/HOWTO/SSL-Certificates-HOWTO/index.html">SSL Certificates HOWTO</a></p>
</li>
<li>
<p><a href="http://mindprod.com/jgloss/certificate.html">Mindprod Java Glossary: Certificates</a></p>
</li>
</ul>
</div>
</li>
<li>
<p>Keytool:</p>
<div class="ulist">
<ul>
<li>
<p><a href="http://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html">Keytool for Unix</a></p>
</li>
<li>
<p><a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/keytool.html">Keytool for Windows</a></p>
</li>
</ul>
</div>
</li>
<li>
<p>Other tools:</p>
<div class="ulist">
<ul>
<li>
<p><a href="https://www.ibm.com/developerworks/mydeveloperworks/groups/service/html/communityview?communityUuid=6fb00498-f6ea-4f65-bf0c-adc5bd0c5fcc">IBM Keyman</a></p>
</li>
</ul>
</div>
</li>
<li>
<p>OpenSSL:</p>
<div class="ulist">
<ul>
<li>
<p><a href="http://www.openssl.org/support/faq.html">OpenSSL FAQ</a></p>
</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="sect4">
<h5 id="openssl-vs-keytool"><a class="anchor" href="#openssl-vs-keytool"></a><a class="link" href="#openssl-vs-keytool">OpenSSL vs. Keytool</a></h5>
<div class="paragraph">
<p>For testing, the <code>keytool</code> utility bundled with the JDK provides the simplest way to generate the key and certificate you need.</p>
</div>
<div class="paragraph">
<p>You can also use the OpenSSL tools to generate keys and certificates, or to convert those that you have used with Apache or other servers.
Since Apache and other servers commonly use the OpenSSL tool suite to generate and manipulate keys and certificates, you might already have some keys and certificates created by OpenSSL, or you might also prefer the formats OpenSSL produces.</p>
</div>
<div class="paragraph">
<p>If you want the option of using the same certificate with Jetty or a web server such as Apache not written in Java, you might prefer to generate your private key and certificate with OpenSSL.</p>
</div>
</div>
<div class="sect4">
<h5 id="generating-key-pairs-and-certificates"><a class="anchor" href="#generating-key-pairs-and-certificates"></a><a class="link" href="#generating-key-pairs-and-certificates">Generating Key Pairs and Certificates</a></h5>
<div class="paragraph">
<p>The simplest way to generate keys and certificates is to use the <code>keytool</code> application that comes with the JDK, as it generates keys and certificates directly into the keystore.
See <a href="#generating-key-pairs-and-certificates-JDK-keytool">Generating Keys and Certificates with JDK&#8217;s keytool</a>.</p>
</div>
<div class="paragraph">
<p>If you already have keys and certificates, see <a href="#loading-keys-and-certificates">Loading Keys and Certificates</a> to load them into a JSSE keystore.
This section also applies if you have a renewal certificate to replace one that is expiring.</p>
</div>
<div class="paragraph">
<p>The examples below generate only basic keys and certificates.
You should read the full manuals of the tools you are using if you want to specify:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The key size</p>
</li>
<li>
<p>The certificate expiration date</p>
</li>
<li>
<p>Alternate security providers</p>
</li>
</ul>
</div>
<div class="sect5">
<h6 id="generating-key-pairs-and-certificates-JDK-keytool"><a class="anchor" href="#generating-key-pairs-and-certificates-JDK-keytool"></a><a class="link" href="#generating-key-pairs-and-certificates-JDK-keytool">Generating Keys and Certificates with JDK&#8217;s keytool</a></h6>
<div class="paragraph">
<p>The following command generates a key pair and certificate directly into file <code>keystore</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ keytool -keystore keystore -alias jetty -genkey -keyalg RSA</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The DSA key algorithm certificate produces an error after loading several pages.
In a browser, it displays a message "Could not establish an encrypted connection because certificate presented by localhost as an invalid signature."
The solution is to use RSA for the key algorithm.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>This command prompts for information about the certificate and for passwords to protect both the keystore and the keys within it.
The only mandatory response is to provide the fully qualified host name of the server at the "first and last name" prompt.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ keytool -keystore keystore -alias jetty -genkey -keyalg RSA -sigalg SHA256withRSA
Enter keystore password: password
What is your first and last name?
[Unknown]: jetty.eclipse.org
What is the name of your organizational unit?
[Unknown]: Jetty
What is the name of your organization?
[Unknown]: Mort Bay Consulting Pty. Ltd.
What is the name of your City or Locality?
[Unknown]:
What is the name of your State or Province?
[Unknown]:
What is the two-letter country code for this unit?
[Unknown]:
Is CN=jetty.eclipse.org, OU=Jetty, O=Mort Bay Consulting Pty. Ltd.,
L=Unknown, ST=Unknown, C=Unknown correct?
[no]: yes
Enter key password for &lt;jetty&gt;
(RETURN if same as keystore password):
$</code></pre>
</div>
</div>
<div class="paragraph">
<p>You now have the minimal requirements to run an SSL connection and could proceed directly to <a href="#configuring-sslcontextfactory">configure an SSL connector</a>.
However, the browser <em>will not</em> trust the certificate you have generated, and prompts the user to this effect.
While what you have at this point is often sufficient for testing, most public sites need a trusted certificate, which is demonstrated in the section <a href="#generating-csr-from-keytool">generating a CSR with keytool</a>.</p>
</div>
<div class="paragraph">
<p>If you want to use only a self signed certificate for some kind of internal admin panel add -validity &lt;days&gt; to the keytool call above, otherwise your certificate is only valid for one month.</p>
</div>
<div class="paragraph">
<p>If you are using Java 8 or later, then you may also use the SAN extension to set one or more names that the certificate applies to:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ keytool -keystore keystore -alias jetty -genkey -keyalg RSA -sigalg SHA256withRSA -ext 'SAN=dns:jetty.eclipse.org,dns:*.jetty.org'
...</code></pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="generating-keys-and-certificates-openssl"><a class="anchor" href="#generating-keys-and-certificates-openssl"></a><a class="link" href="#generating-keys-and-certificates-openssl">Generating Keys and Certificates with OpenSSL</a></h6>
<div class="paragraph">
<p>The following command generates a key pair in the file <code>jetty.key</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ openssl genrsa -aes128 -out jetty.key</code></pre>
</div>
</div>
<div class="paragraph">
<p>You might also want to use the <code>-rand</code> file argument to provide an arbitrary file that helps seed the random number generator.</p>
</div>
<div class="paragraph">
<p>The following command generates a certificate for the key into the file <code>jetty.crt</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ openssl req -new -x509 -newkey rsa:2048 -sha256 -key jetty.key -out jetty.crt</code></pre>
</div>
</div>
<div class="paragraph">
<p>Adding -sha256 ensures to get a certificate with the now recommended SHA-256 signature algorithm.
For the those with heightened security in mind, add -b4096 to get a 4069 bit key.</p>
</div>
<div class="paragraph">
<p>The next command prompts for information about the certificate and for passwords to protect both the keystore and the keys within it.
The only mandatory response is to provide the fully qualified host name of the server at the "Common Name" prompt. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ openssl genrsa -aes128 -out jetty.key
Generating RSA private key, 2048 bit long modulus
..............+++
......................................................................+++
e is 65537 (0x10001)
Enter pass phrase for jetty.key:
Verifying - Enter pass phrase for jetty.key:
$ openssl req -new -x509 -newkey rsa:2048 -sha256 -key jetty.key -out jetty.crt
Enter pass phrase for jetty.key:
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank.
For some fields there will be a default value.
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Mort Bay Consulting Pty. Ltd.
Organizational Unit Name (eg, section) []:Jetty
Common Name (e.g. server FQDN or YOUR name) []:jetty.eclipse.org
Email Address []:
$</code></pre>
</div>
</div>
<div class="paragraph">
<p>You now have the minimal requirements to run an SSL connection and could proceed directly to <a href="#loading-keys-and-certificates">Loading Keys and Certificates</a> to load these keys and certificates into a JSSE keystore.
However the browser <em>will not</em> trust the certificate you have generated, and prompts the user to this effect.
While what you have at this point is often sufficient for testing, most public sites need a trusted certificate, which is demonstrated in the section, <a href="#generating-csr-from-openssl">Generating a CSR from OpenSSL</a> to obtain a certificate.</p>
</div>
</div>
<div class="sect5">
<h6 id="using-keys-and-certificates-from-other-sources"><a class="anchor" href="#using-keys-and-certificates-from-other-sources"></a><a class="link" href="#using-keys-and-certificates-from-other-sources">Using Keys and Certificates from Other Sources</a></h6>
<div class="paragraph">
<p>If you have keys and certificates from other sources, you can proceed directly to <a href="#loading-keys-and-certificates">Loading Keys and Certificates</a>.</p>
</div>
</div>
</div>
<div class="sect4">
<h5 id="requesting-trusted-certificate"><a class="anchor" href="#requesting-trusted-certificate"></a><a class="link" href="#requesting-trusted-certificate">Requesting a Trusted Certificate</a></h5>
<div class="paragraph">
<p>The keys and certificates generated with JDK&#8217;s <code>keytool</code> and OpenSSL are sufficient to run an SSL connector.
However the browser will not trust the certificate you have generated, and it will prompt the user to this effect.</p>
</div>
<div class="paragraph">
<p>To obtain a certificate that most common browsers will trust, you need to request a well-known certificate authority (CA) to sign your key/certificate.
Such trusted CAs include: AddTrust, Entrust, GeoTrust, RSA Data Security, Thawte, VISA, ValiCert, Verisign, and beTRUSTed, among others.
Each CA has its own instructions (look for JSSE or OpenSSL sections), but all involve a step that generates a certificate signing request (CSR).</p>
</div>
<div class="sect5">
<h6 id="generating-csr-from-keytool"><a class="anchor" href="#generating-csr-from-keytool"></a><a class="link" href="#generating-csr-from-keytool">Generating a CSR with keytool</a></h6>
<div class="paragraph">
<p>The following command generates the file <code>jetty.csr</code> using <code>keytool</code> for a key/cert already in the keystore:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ keytool -certreq -alias jetty -keystore keystore -file jetty.csr</code></pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="generating-csr-from-openssl"><a class="anchor" href="#generating-csr-from-openssl"></a><a class="link" href="#generating-csr-from-openssl">Generating a CSR from OpenSSL</a></h6>
<div class="paragraph">
<p>The following command generates the file <code>jetty.csr</code> using OpenSSL for a key in the file <code>jetty.key</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ openssl req -new -key jetty.key -out jetty.csr</code></pre>
</div>
</div>
<div class="paragraph">
<p>Notice that this command uses only the existing key from <code>jetty.key</code> file, and not a certificate in <code>jetty.crt</code> as generated with OpenSSL.
You need to enter the details for the certificate again.</p>
</div>
</div>
</div>
<div class="sect4">
<h5 id="loading-keys-and-certificates"><a class="anchor" href="#loading-keys-and-certificates"></a><a class="link" href="#loading-keys-and-certificates">Loading Keys and Certificates</a></h5>
<div class="paragraph">
<p>Once a CA has sent you a certificate, or if you generated your own certificate without <code>keytool</code>, you need to load it into a JSSE keystore.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
You need both the private key and the certificate in the JSSE keystore.
You should load the certificate into the keystore used to generate the CSR with <code>keytool</code>.
If your key pair is not already in a keystore (for example, because it has been generated with OpenSSL), you need to use the PKCS12 format to load both key and certificate (see <a href="#loading-keys-and-certificates-via-pkcks12">PKCKS12 Keys &amp;Certificates</a>).
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect5">
<h6 id="loading-certificates-with-keytool"><a class="anchor" href="#loading-certificates-with-keytool"></a><a class="link" href="#loading-certificates-with-keytool">Loading Certificates with keytool</a></h6>
<div class="paragraph">
<p>You can use <code>keytool</code> to load a certificate in PEM form directly into a keystore.
The PEM format is a text encoding of certificates; it is produced by OpenSSL, and is returned by some CAs.
An example PEM file is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">jetty.crt
-----BEGIN CERTIFICATE-----
MIICSDCCAfKgAwIBAgIBADANBgkqhkiG9w0BAQQFADBUMSYwJAYDVQQKEx1Nb3J0
IEJheSBDb25zdWx0aW5nIFB0eS4gTHRkLjEOMAwGA1UECxMFSmV0dHkxGjAYBgNV
BAMTEWpldHR5Lm1vcnRiYXkub3JnMB4XDTAzMDQwNjEzMTk1MFoXDTAzMDUwNjEz
MTk1MFowVDEmMCQGA1UEChMdTW9ydCBCYXkgQ29uc3VsdGluZyBQdHkuIEx0ZC4x
DjAMBgNVBAsTBUpldHR5MRowGAYDVQQDExFqZXR0eS5tb3J0YmF5Lm9yZzBcMA0G
CSqGSIb3DQEBAQUAA0sAMEgCQQC5V4oZeVdhdhHqa9L2/ZnKySPWUqqy81riNfAJ
7uALW0kEv/LtlG34dOOcVVt/PK8/bU4dlolnJx1SpiMZbKsFAgMBAAGjga4wgasw
HQYDVR0OBBYEFFV1gbB1XRvUx1UofmifQJS/MCYwMHwGA1UdIwR1MHOAFFV1gbB1
XRvUx1UofmifQJS/MCYwoVikVjBUMSYwJAYDVQQKEx1Nb3J0IEJheSBDb25zdWx0
aW5nIFB0eS4gTHRkLjEOMAwGA1UECxMFSmV0dHkxGjAYBgNVBAMTEWpldHR5Lm1v
cnRiYXkub3JnggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADQQA6NkaV
OtXzP4ayzBcgK/qSCmF44jdcARmrXhiXUcXzjxsLjSJeYPJojhUdC2LQKy+p4ki8
Rcz6oCRvCGCe5kDB
-----END CERTIFICATE-----</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following command loads a PEM encoded certificate in the <code>jetty.crt</code> file into a JSSE keystore:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ keytool -keystore keystore -import -alias jetty -file jetty.crt -trustcacerts</code></pre>
</div>
</div>
<div class="paragraph">
<p>If the certificate you receive from the CA is not in a format that <code>keytool</code> understands, you can use the <code>openssl</code> command to convert formats:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ openssl x509 -in jetty.der -inform DER -outform PEM -out jetty.crt</code></pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="loading-keys-and-certificates-via-pkcks12"><a class="anchor" href="#loading-keys-and-certificates-via-pkcks12"></a><a class="link" href="#loading-keys-and-certificates-via-pkcks12">Loading Keys and Certificates via PKCS12</a></h6>
<div class="paragraph">
<p>If you have a key and certificate in separate files, you need to combine them into a PKCS12 format file to load into a new keystore.
The certificate can be one you generated yourself or one returned from a CA in response to your CSR.</p>
</div>
<div class="paragraph">
<p>The following OpenSSL command combines the keys in <code>jetty.key</code> and the certificate in the <code>jetty.crt</code> file into the <code>jetty.pkcs12</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ openssl pkcs12 -inkey jetty.key -in jetty.crt -export -out jetty.pkcs12</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you have a chain of certificates, because your CA is an intermediary, build the PKCS12 file as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cat example.crt intermediate.crt [intermediate2.crt] ... rootCA.crt &gt; cert-chain.txt
$ openssl pkcs12 -export -inkey example.key -in cert-chain.txt -out example.pkcs12</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The order of certificates must be from server to rootCA, as per <a href="https://www.ietf.org/rfc/rfc2246.txt">RFC2246 section 7.4.2.</a>
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>OpenSSL asks for an <em>export password</em>.
A non-empty password is required to make the next step work.
Load the resulting PKCS12 file into a JSSE keystore with <code>keytool</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ keytool -importkeystore -srckeystore jetty.pkcs12 -srcstoretype PKCS12 -destkeystore keystore</code></pre>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="renewing-certificates"><a class="anchor" href="#renewing-certificates"></a><a class="link" href="#renewing-certificates">Renewing Certificates</a></h5>
<div class="paragraph">
<p>If you are updating your configuration to use a newer certificate, as when the old one is expiring, just load the newer certificate as described in the section, <a href="#loading-keys-and-certificates">Loading Keys and Certificates</a>.
If you imported the key and certificate originally using the PKCS12 method, use an alias of "1" rather than "jetty", because that is the alias the PKCS12 process enters into the keystore.</p>
</div>
</div>
<div class="sect4">
<h5 id="layout-of-keystore-and-truststore"><a class="anchor" href="#layout-of-keystore-and-truststore"></a><a class="link" href="#layout-of-keystore-and-truststore">Layout of keystore and truststore</a></h5>
<div class="paragraph">
<p>The <code>keystore</code> only contains the server&#8217;s private key and certificate.</p>
</div>
<div id="img-certificate-chain" class="imageblock">
<div class="content">
<img src="certificate-chain.png" alt="Certificate chain">
</div>
<div class="title">Figure 1. Certificate chain</div>
</div>
<div class="literalblock">
<div class="title">The structure of KeyStore file:</div>
<div class="content">
<pre>├── PrivateKeyEntry
│   ├── PrivateKey
│   ├── Certificate chain
│   │   ├── Server certificate (end entity)
│   │   ├── Intermediary CA certificate
│   │   └── Root CA certificate
├── TrustedCertEntry
│   └── Intermediary CA certificate
└── TrustedCertEntry
   └── Root CA certificate</pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Both the <code>Intermediary CA certificate</code> and <code>Root CA certificate</code> are optional.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight nowrap"><code class="language-plain" data-lang="plain">$ cd $JETTY_BASE
$ keytool -v -list -keystore etc/keystore
Keystore type: PKCS12
Keystore provider: SUN
Your keystore contains 3 entries
Alias name: *.example.com
Creation date: Sep 20, 2016
Entry type: PrivateKeyEntry
Certificate chain length: 3
Certificate[1]:
Owner: CN=*.example.com, OU=Web Servers, O="Example.com Co.,Ltd.", C=CN
Issuer: CN="Example.com Co.,Ltd. ETP CA", OU=CA Center, O="Example.com Co.,Ltd.", C=CN
Serial number: b63af619ff0b4c368735113ba5db8997
Valid from: Mon Sep 12 15:09:49 CST 2016 until: Wed Sep 12 15:09:49 CST 2018
Certificate fingerprints:
MD5: D9:26:CC:27:77:9D:26:FE:67:4C:BE:FF:E3:95:1E:97
SHA1: AF:DC:D2:65:6A:33:42:E3:81:9E:4D:19:0D:22:20:C7:6F:2F:11:D0
SHA256: 43:E8:21:5D:C6:FB:A0:7D:5D:7B:9C:8B:8D:E9:4B:52:BF:50:0D:90:4F:61:C2:18:9E:89:AA:4C:C2:93:BD:32
Signature algorithm name: SHA256withRSA
Version: 3
Extensions:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 44 9B AD 31 E7 FE CA D5 5A 8E 17 55 F9 F0 1D 6B D..1....Z..U...k
0010: F5 A5 8F C1 ....
]
]
#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:false
PathLen: undefined
]
#3: ObjectId: 2.5.29.37 Criticality=true
ExtendedKeyUsages [
serverAuth
clientAuth
]
#4: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_Encipherment
Data_Encipherment
]
#5: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 7D 26 36 73 61 5E 08 94 AD 25 13 46 DB DB 95 25 .&amp;6sa^...%.F...%
0010: BF 82 5A CA ..Z.
]
]
Certificate[2]:
Owner: CN="Example.com Co.,Ltd. ETP CA", OU=CA Center, O="Example.com Co.,Ltd.", C=CN
Issuer: CN="Example.com Co.,Ltd. Root CA", OU=CA Center, O="Example.com Co.,Ltd.", C=CN
Serial number: f6e7b86f6fdb467f9498fb599310198f
Valid from: Wed Nov 18 00:00:00 CST 2015 until: Sun Nov 18 00:00:00 CST 2035
Certificate fingerprints:
MD5: ED:A3:91:57:D8:B8:6E:B1:01:58:55:5C:33:14:F5:99
SHA1: D9:A4:93:9D:A6:F8:A3:F9:FD:85:51:E2:C5:2E:0B:EE:80:E7:D0:22
SHA256: BF:54:7A:F6:CA:0C:FA:EF:93:B6:6B:6E:2E:D7:44:A8:40:00:EC:69:3A:2C:CC:9A:F7:FE:8E:6F:C0:FA:22:38
Signature algorithm name: SHA256withRSA
Version: 3
Extensions:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: A6 BD 5F B3 E8 7D 74 3D 20 44 66 1A 16 3B 1B DF .._...t= Df..;..
0010: E6 E6 04 46 ...F
]
]
#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen:2147483647
]
#3: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
Key_CertSign
Crl_Sign
]
#4: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 44 9B AD 31 E7 FE CA D5 5A 8E 17 55 F9 F0 1D 6B D..1....Z..U...k
0010: F5 A5 8F C1 ....
]
]
Certificate[3]:
Owner: CN="Example.com Co.,Ltd. Root CA", OU=CA Center, O="Example.com Co.,Ltd.", C=CN
Issuer: CN="Example.com Co.,Ltd. Root CA", OU=CA Center, O="Example.com Co.,Ltd.", C=CN
Serial number: f0a45bc9972c458cbeae3f723055f1ac
Valid from: Wed Nov 18 00:00:00 CST 2015 until: Sun Nov 18 00:00:00 CST 2114
Certificate fingerprints:
MD5: 50:61:62:22:71:60:F7:69:2E:27:42:6B:62:31:82:79
SHA1: 7A:6D:A6:48:B1:43:03:3B:EA:A0:29:2F:19:65:9C:9B:0E:B1:03:1A
SHA256: 05:3B:9C:5B:8E:18:61:61:D1:9C:AA:0E:8C:B1:EA:44:C2:6E:67:5D:96:30:EC:8C:F6:6F:E1:EC:AD:00:60:F1
Signature algorithm name: SHA256withRSA
Version: 3
Extensions:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: A6 BD 5F B3 E8 7D 74 3D 20 44 66 1A 16 3B 1B DF .._...t= Df..;..
0010: E6 E6 04 46 ...F
]
]
#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen:2147483647
]
#3: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
Key_CertSign
Crl_Sign
]
#4: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: A6 BD 5F B3 E8 7D 74 3D 20 44 66 1A 16 3B 1B DF .._...t= Df..;..
0010: E6 E6 04 46 ...F
]
]
*******************************************
*******************************************
Alias name: example.com co.,ltd. etp ca
Creation date: Sep 20, 2016
Entry type: trustedCertEntry
Owner: CN="Example.com Co.,Ltd. ETP CA", OU=CA Center, O="Example.com Co.,Ltd.", C=CN
Issuer: CN="Example.com Co.,Ltd. Root CA", OU=CA Center, O="Example.com Co.,Ltd.", C=CN
Serial number: f6e7b86f6fdb467f9498fb599310198f
Valid from: Wed Nov 18 00:00:00 CST 2015 until: Sun Nov 18 00:00:00 CST 2035
Certificate fingerprints:
MD5: ED:A3:91:57:D8:B8:6E:B1:01:58:55:5C:33:14:F5:99
SHA1: D9:A4:93:9D:A6:F8:A3:F9:FD:85:51:E2:C5:2E:0B:EE:80:E7:D0:22
SHA256: BF:54:7A:F6:CA:0C:FA:EF:93:B6:6B:6E:2E:D7:44:A8:40:00:EC:69:3A:2C:CC:9A:F7:FE:8E:6F:C0:FA:22:38
Signature algorithm name: SHA256withRSA
Version: 3
Extensions:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: A6 BD 5F B3 E8 7D 74 3D 20 44 66 1A 16 3B 1B DF .._...t= Df..;..
0010: E6 E6 04 46 ...F
]
]
#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen:2147483647
]
#3: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
Key_CertSign
Crl_Sign
]
#4: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 44 9B AD 31 E7 FE CA D5 5A 8E 17 55 F9 F0 1D 6B D..1....Z..U...k
0010: F5 A5 8F C1 ....
]
]
*******************************************
*******************************************
Alias name: example.com co.,ltd. root ca
Creation date: Sep 20, 2016
Entry type: trustedCertEntry
Owner: CN="Example.com Co.,Ltd. Root CA", OU=CA Center, O="Example.com Co.,Ltd.", C=CN
Issuer: CN="Example.com Co.,Ltd. Root CA", OU=CA Center, O="Example.com Co.,Ltd.", C=CN
Serial number: f0a45bc9972c458cbeae3f723055f1ac
Valid from: Wed Nov 18 00:00:00 CST 2015 until: Sun Nov 18 00:00:00 CST 2114
Certificate fingerprints:
MD5: 50:61:62:22:71:60:F7:69:2E:27:42:6B:62:31:82:79
SHA1: 7A:6D:A6:48:B1:43:03:3B:EA:A0:29:2F:19:65:9C:9B:0E:B1:03:1A
SHA256: 05:3B:9C:5B:8E:18:61:61:D1:9C:AA:0E:8C:B1:EA:44:C2:6E:67:5D:96:30:EC:8C:F6:6F:E1:EC:AD:00:60:F1
Signature algorithm name: SHA256withRSA
Version: 3
Extensions:
#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: A6 BD 5F B3 E8 7D 74 3D 20 44 66 1A 16 3B 1B DF .._...t= Df..;..
0010: E6 E6 04 46 ...F
]
]
#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen:2147483647
]
#3: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
Key_CertSign
Crl_Sign
]
#4: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: A6 BD 5F B3 E8 7D 74 3D 20 44 66 1A 16 3B 1B DF .._...t= Df..;..
0010: E6 E6 04 46 ...F
]
]
*******************************************
*******************************************</code></pre>
</div>
</div>
<div class="paragraph">
<p>In addition, you can split <code>$JETTY/etc/keystore</code> as two files.
One is <code>$JETTY/etc/keystore</code> which only contains the server’s private key and certificate,
the other is <code>$JETTY/etc/truststore</code> which contains intermediary CA and root CA.</p>
</div>
<div class="literalblock">
<div class="title">The structure of <code>$JETTY/etc/keystore</code></div>
<div class="content">
<pre>└── PrivateKeyEntry
   ├── PrivateKey
   └── Certificate chain
      └── Server certificate (end entity)</pre>
</div>
</div>
<div class="literalblock">
<div class="title">The structure of <code>$JETTY/etc/truststore</code></div>
<div class="content">
<pre>├── TrustedCertEntry
│   └── Intermediary CA certificate
└── TrustedCertEntry
   └── Root CA certificate</pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="configuring-sslcontextfactory"><a class="anchor" href="#configuring-sslcontextfactory"></a><a class="link" href="#configuring-sslcontextfactory">Configuring the Jetty SslContextFactory</a></h4>
<div class="paragraph">
<p>The generated SSL certificates from above are held in the key store are configured in an instance of <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/util/ssl/SslContextFactory.Server.html">SslContextFactory.Server</a> object.</p>
</div>
<div class="paragraph">
<p>The <code>SslContextFactory</code> is responsible for:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Creating the Java <code>SslEngine</code> used by Jetty&#8217;s Connectors and Jetty&#8217;s Clients (HTTP/1, HTTP/2, and WebSocket).</p>
</li>
<li>
<p>Managing Keystore Access</p>
</li>
<li>
<p>Managing Truststore Access</p>
</li>
<li>
<p>Managing Protocol selection via Excludes / Includes list</p>
</li>
<li>
<p>Managing Cipher Suite selection via Excludes / Includes list</p>
</li>
<li>
<p>Managing order of Ciphers offered (important for TLS/1.2 and HTTP/2 support)</p>
</li>
<li>
<p>SSL Session Caching options</p>
</li>
<li>
<p>Certificate <a href="https://en.wikipedia.org/wiki/Revocation_list">Revocation Lists</a> and Distribution Points (CRLDP)</p>
</li>
<li>
<p><a href="https://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol">OCSP</a> Support</p>
</li>
<li>
<p>Client Authentication Support</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For Jetty Connectors, the configured <code>SslContextFactory.Server</code> is injected into a specific ServerConnector <code>SslConnectionFactory</code>.</p>
</div>
<div class="paragraph">
<p>For Jetty Clients, the various constructors support using a configured <code>SslContextFactory.Client</code>.</p>
</div>
<div class="paragraph">
<p>While the <code>SslContextFactory</code> can operate without a keystore (this mode is most suitable for the various Jetty Clients) it is best practice to at least configure the keystore being used.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">setKeyStorePath</dt>
<dd>
<p>The configured keystore to use for all SSL/TLS in configured Jetty Connector (or Client).</p>
</dd>
</dl>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
As a keystore is vital security information, it can be desirable to locate the file in a directory with <strong>very</strong> restricted access.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">setKeyStorePassword</dt>
<dd>
<p>The keystore password may be set here in plain text, or as some measure of protection from casual observation, it may be obfuscated using the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/util/security/Password.html">Password</a> class.</p>
</dd>
<dt class="hdlist1">setTrustStorePath</dt>
<dd>
<p>This is used if validating client certificates and is typically set to the same path as the keystore.</p>
</dd>
<dt class="hdlist1">setKeyManagerPassword</dt>
<dd>
<p>The password that is passed to the <code>KeyManagerFactory.init(&#8230;&#8203;)</code>.
If there is no <code>keymanagerpassword</code>, then the <code>keystorepassword</code> is used instead.
If there is no <code>trustmanager</code> set, then the keystore is used as the trust store and the <code>keystorepassword</code> is used as the truststore password.</p>
</dd>
<dt class="hdlist1">setExcludeCipherSuites / setIncludeCipherSuites</dt>
<dd>
<p>This allows for the customization of the selected Cipher Suites that will be used by SSL/TLS.</p>
</dd>
<dt class="hdlist1">setExcludeProtocols / setIncludeProtocols</dt>
<dd>
<p>This allows for the customization of the selected Protocols that will be used by SSL/TLS.</p>
</dd>
</dl>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
When working with Includes / Excludes, it is important to know that <strong>Excludes will always win.</strong>
The selection process is to process the JVM list of available Cipher Suites or Protocols against the include list, then remove the excluded ones.
Be aware that each Include / Exclude list has a Set method (replace the list) or Add method (append the list).
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock caution">
<table>
<tr>
<td class="icon">
<i class="fa icon-caution" title="Caution"></i>
</td>
<td class="content">
The keystore and truststore passwords may also be set using the system properties: <code>org.eclipse.jetty.ssl.keypassword</code> <code>org.eclipse.jetty.ssl.password</code>.
This is <em>not</em> a recommended usage.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="conscrypt"><a class="anchor" href="#conscrypt"></a><a class="link" href="#conscrypt">Conscrypt SSL</a></h4>
<div class="paragraph">
<p>Jetty includes support for Google&#8217;s <a href="https://github.com/google/conscrypt/">Conscrypt SSL</a>, which is built on their fork of <a href="https://www.openssl.org/">OpenSSL</a>, <a href="https://boringssl.googlesource.com/boringssl/">BoringSSL</a>.
Implementing Conscrypt for the <a href="https://github.com/eclipse/jetty.project/tree/master/jetty-alpn/jetty-alpn-conscrypt-server/src/test/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptHTTP2Server.java">server</a> or <a href="https://github.com/eclipse/jetty.project/tree/master/jetty-alpn/jetty-alpn-conscrypt-client/src/test/java/org/eclipse/jetty/alpn/java/client/ConscryptHTTP2Client.java">client</a> is very straightforward process - simply instantiate an instance of Conscrypt&#8217;s <code>OpenSSLProvider</code> and set <code>Conscrypt</code> as a provider for Jetty&#8217;s <code>SslContextFactory</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">...
Security.addProvider(new OpenSSLProvider());
...
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStorePath("path/to/keystore");
sslContextFactory.setKeyStorePassword("CleverKeyStorePassword");
sslContextFactory.setKeyManagerPassword("OBF:VerySecretManagerPassword");
sslContextFactory.setProvider("Conscrypt");
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you are using the Jetty Distribution, please see the section on enabling the <a href="#jetty-conscrypt-distribution">Conscrypt SSL module.</a></p>
</div>
<div class="paragraph">
<p>If you are using Conscrypt with Java 8, you must exclude <code>TLSv1.3</code> protocol as it is now enabled per default with Conscrypt 2.0.0 but not supported by Java 8.</p>
</div>
</div>
<div class="sect3">
<h4 id="_configuring-sni"><a class="anchor" href="#_configuring-sni"></a><a class="link" href="#_configuring-sni">Configuring SNI</a></h4>
<div class="paragraph">
<p>From Java 8, the JVM contains support for the <a href="http://en.wikipedia.org/wiki/Server_Name_Indication">Server Name Indicator (SNI)</a> extension, which allows a SSL connection handshake to indicate one or more DNS names that it applies to.</p>
</div>
<div class="paragraph">
<p>To support this, the <code>SslContextFactory</code> is used.
The <code>SslContextFactory</code> will look for multiple X509 certificates within the keystore, each of which may have multiple DNS names (including wildcards) associated with the <a href="http://en.wikipedia.org/wiki/SubjectAltName">Subject Alternate Name</a> extension.
When using the <code>SslContextFactory</code>, the correct certificate is automatically selected if the SNI extension is present in the handshake.</p>
</div>
</div>
<div class="sect3">
<h4 id="configuring-sslcontextfactory-cipherSuites"><a class="anchor" href="#configuring-sslcontextfactory-cipherSuites"></a><a class="link" href="#configuring-sslcontextfactory-cipherSuites">Disabling/Enabling Specific Cipher Suites</a></h4>
<div class="paragraph">
<p>New cipher suites are always being developed to stay ahead of attacks.
It&#8217;s only a matter of time before the best of suites is exploited though, and making sure your server is up-to-date in this regard is paramount for any implementation.
As an example, to avoid the BEAST attack it is necessary to configure a specific set of cipher suites.This can either be done via <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/util/ssl/SslContextFactory.html#setIncludeCipherSuites(java.lang.String&#8230;&#8203;)">SslContext.setIncludeCipherSuites(java.lang.String&#8230;&#8203;)</a> or via<a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/util/ssl/SslContextFactory.html#setExcludeCipherSuites(java.lang.String&#8230;&#8203;)">SslContext.setExcludeCipherSuites(java.lang.String&#8230;&#8203;)</a>.</p>
</div>
<div class="paragraph">
<p>It&#8217;s crucial that you use the <em>exact</em> names of the cipher suites as used/known by the JDK.
You can get them by obtaining an instance of SSLEngine and call <code>getSupportedCipherSuites()</code>.
Tools like <a href="https://www.ssllabs.com/">ssllabs.com</a> might report slightly different names which will be ignored.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
It is important to stay up-to-date with the latest supported cipher suites.
Be sure to consult Oracle&#8217;s <a href="https://java.com/en/jre-jdk-cryptoroadmap.html">JRE and JDK Cryptographic Roadmap</a> frequently for recent and upcoming changes to supported ciphers.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
It&#8217;s recommended to install the Java Cryptography Extension (JCE) Unlimited Strength policy files in your JRE to get full strength ciphers such as AES-256.
The files can be found on the <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Java download page</a>.
Just overwrite the two present JAR files in <code>&lt;JRE_HOME&gt;/lib/security/</code>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Both <code>setIncludeCipherSuites</code> and <code>setExcludeCipherSuites</code> can be fed by the exact cipher suite name used in the JDK or by using regular expressions.
If you have a need to adjust the Includes or Excludes, then this is best done with a custom XML that configures the <code>SslContextFactory</code> to suit your needs.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Jetty <strong>does</strong> allow users to enable weak/deprecated cipher suites (or even no cipher suites at all).
By default, if you have these suites enabled warning messages will appear in the server logs.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>To do this, first create a new <code>${jetty.base}/etc/tweak-ssl.xml</code> file (this can be any name, just avoid prefixing it with "jetty-").</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
"https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;!-- Tweak SsslContextFactory Includes / Excludes --&gt;
&lt;Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory$Server"&gt;
&lt;!-- Mitigate SLOTH Attack --&gt;
&lt;Call name="addExcludeCipherSuites"&gt;
&lt;Arg&gt;
&lt;Array type="String"&gt;
&lt;Item&gt;.*_RSA_.*SHA1$&lt;/Item&gt;
&lt;Item&gt;.*_RSA_.*SHA$&lt;/Item&gt;
&lt;Item&gt;.*_RSA_.*MD5$&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This new XML will configure the id <code>sslContextFactory</code> further (this id is first created by the <code>ssl</code> module and its associated <code>${jetty.home}/etc/jetty-ssl-context.xml</code>).
You can do anything you want with the <code>SslContextFactory</code> in use by the Jetty Distribution from this tweaked XML.</p>
</div>
<div class="paragraph">
<p>To make sure that your <code>${jetty.base}</code> uses this new XML, add it to the end of your <code>${jetty.base}/start.ini</code> or <code>${jetty.base}/start.d/server.ini</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">$ cd /path/to/mybase
$ ls -l
drwxrwxr-x. 2 user group 4096 Feb 2 11:47 etc/
-rw-rw-r--. 1 user group 4259 Feb 2 11:47 start.ini
$ tail start.ini
# Module: https
--module=https
etc/tweak-ssl.xml
$</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The default <code>SslContextFactory</code> implementation applies the latest SSL/TLS recommendations surrounding vulnerabilities in SSL/TLS.
Check the release notes (the <code>VERSION.txt</code> found in the root of the Jetty Distribution, or the <a href="http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.eclipse.jetty%22%20AND%20a%3A%22jetty-project%22">alternate (classified 'version') artifacts for the <code>jetty-project</code> component</a> on Maven Central) for updates.
The Java JVM also applies exclusions at the JVM level and, as such, if you have a need to enable something that is generally accepted by the industry as being insecure or vulnerable you will likely have to enable it in <strong>both</strong> the Java JVM and your Jetty configuration.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
You can enable the <code>org.eclipse.jetty.util.ssl</code> named logger at <code>DEBUG</code> level to see what the list of selected Protocols and Cipher suites are at startup of Jetty.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Additional Include / Exclude examples:</p>
</div>
<div class="paragraph">
<p><strong>Example</strong>: Include all ciphers which support <a href="https://en.wikipedia.org/wiki/Forward_secrecy">Forward Secrecy</a> using regex:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;!-- Enable Forward Secrecy Ciphers.
Note: this replaces the default Include Cipher list --&gt;
&lt;Set name="IncludeCipherSuites"&gt;
&lt;Array type="String"&gt;
&lt;Item&gt;TLS_DHE_RSA.*&lt;/Item&gt;
&lt;Item&gt;TLS_ECDHE.*&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Set&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>Example</strong>: Exclude all old, insecure or anonymous cipher suites:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;!-- Eliminate Old / Insecure / Anonymous Ciphers --&gt;
&lt;Call name="addExcludeCipherSuites"&gt;
&lt;Arg&gt;
&lt;Array type="String"&gt;
&lt;Item&gt;.*NULL.*&lt;/Item&gt;
&lt;Item&gt;.*RC4.*&lt;/Item&gt;
&lt;Item&gt;.*MD5.*&lt;/Item&gt;
&lt;Item&gt;.*DES.*&lt;/Item&gt;
&lt;Item&gt;.*DSS.*&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Arg&gt;
&lt;/Call&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p><strong>Example</strong>: Since 2014 SSLv3 is considered insecure and should be disabled.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;!-- Eliminate Insecure Protocols --&gt;
&lt;Call name="addExcludeProtocols"&gt;
&lt;Arg&gt;
&lt;Array type="java.lang.String"&gt;
&lt;Item&gt;SSL&lt;/Item&gt;
&lt;Item&gt;SSLv2&lt;/Item&gt;
&lt;Item&gt;SSLv2Hello&lt;/Item&gt;
&lt;Item&gt;SSLv3&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Arg&gt;
&lt;/Call&gt;</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Note that disabling SSLv3 prevents very old browsers like Internet Explorer 6 on Windows XP from connecting.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p><strong>Example</strong>: TLS renegotiation could be disabled too to prevent an attack based on this feature.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;Set name="renegotiationAllowed"&gt;FALSE&lt;/Set&gt;</code></pre>
</div>
</div>
<div id="ssl-dump-ciphers" class="paragraph">
<p>You can view what cipher suites are enabled and disabled by performing a server dump.</p>
</div>
<div class="paragraph">
<p>To perform a server dump upon server startup, add <code>jetty.server.dumpAfterStart=true</code> to the command line when starting the server.
You can also dump the server when shutting down the server instance by adding <code>jetty.server.dumpBeforeStop</code>.</p>
</div>
<div class="paragraph">
<p>Specifically, you will want to look for the <code>SslConnectionFactory</code> portion of the dump.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar jetty.server.dumpAfterStart=true
...
| += SslConnectionFactory@18be83e4{SSL-&gt;http/1.1} - STARTED
| | += SslContextFactory@42530531(null,null) trustAll=false
| | +- Protocol Selections
| | | +- Enabled (size=3)
| | | | +- TLSv1
| | | | +- TLSv1.1
| | | | +- TLSv1.2
| | | +- Disabled (size=2)
| | | +- SSLv2Hello - ConfigExcluded:'SSLv2Hello'
| | | +- SSLv3 - JreDisabled:java.security, ConfigExcluded:'SSLv3'
| | +- Cipher Suite Selections
| | +- Enabled (size=15)
| | | +- TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
| | | +- TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
| | | +- TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
| | | +- TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
| | | +- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
| | | +- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
| | | +- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
| | | +- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
| | | +- TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
| | | +- TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
| | | +- TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
| | | +- TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
| | | +- TLS_EMPTY_RENEGOTIATION_INFO_SCSV
| | | +- TLS_RSA_WITH_AES_128_CBC_SHA256
| | | +- TLS_RSA_WITH_AES_128_GCM_SHA256
| | +- Disabled (size=42)
| | +- SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- SSL_DHE_DSS_WITH_DES_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- SSL_DHE_RSA_WITH_DES_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- SSL_DH_anon_WITH_3DES_EDE_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- SSL_DH_anon_WITH_DES_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- SSL_RSA_EXPORT_WITH_DES40_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- SSL_RSA_WITH_3DES_EDE_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- SSL_RSA_WITH_DES_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- SSL_RSA_WITH_NULL_MD5 - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- SSL_RSA_WITH_NULL_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_DHE_DSS_WITH_AES_128_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_DHE_RSA_WITH_AES_128_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_DH_anon_WITH_AES_128_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_DH_anon_WITH_AES_128_CBC_SHA256 - JreDisabled:java.security
| | +- TLS_DH_anon_WITH_AES_128_GCM_SHA256 - JreDisabled:java.security
| | +- TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDHE_ECDSA_WITH_NULL_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDHE_RSA_WITH_NULL_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDH_ECDSA_WITH_NULL_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDH_RSA_WITH_NULL_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDH_anon_WITH_AES_128_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_ECDH_anon_WITH_NULL_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_KRB5_WITH_3DES_EDE_CBC_MD5 - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_KRB5_WITH_3DES_EDE_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_KRB5_WITH_DES_CBC_MD5 - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_KRB5_WITH_DES_CBC_SHA - JreDisabled:java.security, ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_RSA_WITH_AES_128_CBC_SHA - ConfigExcluded:'^.*_(MD5|SHA|SHA1)$'
| | +- TLS_RSA_WITH_NULL_SHA256 - JreDisabled:java.security
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the example above you can see both the enabled/disabled protocols and included/excluded cipher suites.
For disabled or excluded protocols and ciphers, the reason they are disabled is given - either due to JVM restrictions, configuration or both.
As a reminder, when configuring your includes/excludes, <strong>excludes always win</strong>.</p>
</div>
<div class="paragraph">
<p>Dumps can be configured as part of the <code>jetty.xml</code> configuration for your server.
Please see the documentation on the <a href="#jetty-dump-tool">Jetty Dump Tool</a> for more information.</p>
</div>
</div>
<div class="sect3">
<h4 id="_sslcontextfactory-keystore-reload"><a class="anchor" href="#_sslcontextfactory-keystore-reload"></a><a class="link" href="#_sslcontextfactory-keystore-reload">SslContextFactory KeyStore Reload</a></h4>
<div class="paragraph">
<p>Jetty can be configured to monitor the directory of the KeyStore file specified in the SslContextFactory, and reload the
SslContextFactory if any changes are detected to the KeyStore file.</p>
</div>
<div class="paragraph">
<p>If changes need to be done to other file such as the TrustStore file, this must be done before the change to the Keystore
file which will then trigger the <code>SslContextFactory</code> reload.</p>
</div>
<div class="paragraph">
<p>With the Jetty distribution this feature can be used by simply activating the <code>ssl-reload</code> startup module.
For embedded usage the <code>KeyStoreScanner</code> should be created given the <code>SslContextFactory</code> and added as a bean on the Server.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jetty-ssl-distribution"><a class="anchor" href="#jetty-ssl-distribution"></a><a class="link" href="#jetty-ssl-distribution">SSL in the Jetty Distribution</a></h3>
<div class="paragraph">
<p>When making use of the Jetty Distribution, enabling SSL support is as easy as activating the appropriate module.
Jetty supports both the default <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html">JSSE</a>
provider and the <a href="https://github.com/google/conscrypt/">Conscrypt</a> provider as SSL implementations.</p>
</div>
<div class="sect3">
<h4 id="_default-jsse-ssl-configuration"><a class="anchor" href="#_default-jsse-ssl-configuration"></a><a class="link" href="#_default-jsse-ssl-configuration">Default JSSE SSL Configuration</a></h4>
<div class="paragraph">
<p>For the default SSL support, simply activate the <code>ssl</code> <a href="#startup-modules">module</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">$ cd /path/to/mybase
$ java -jar ${JETTY_HOME}/start.jar --add-to-startd=ssl
INFO : server initialised (transitively) in ${jetty.base}/start.d/server.ini
INFO : ssl initialised in ${jetty.base}/start.d/ssl.ini
INFO : Base directory was modified
$ tree
.
├── etc
│   └── keystore
└── start.d
├── server.ini
└── ssl.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>When you open <code>start.d/ssl.ini</code>, you will see several commented properties ready for use when configuring <code>SslContextFactory</code> basics.</p>
</div>
<div class="paragraph">
<p>To highlight some of the more commonly used properties:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">jetty.ssl.host</dt>
<dd>
<p>Configures which interfaces the SSL/TLS Connector should listen on.</p>
</dd>
<dt class="hdlist1">jetty.ssl.port</dt>
<dd>
<p>Configures which port the SSL/TLS Connector should listen on.</p>
</dd>
<dt class="hdlist1">jetty.httpConfig.securePort</dt>
<dd>
<p>If a webapp needs to redirect to a secure version of the same resource, then this is the port reported back on the response <code>location</code> line (having this be separate is useful if you have something sitting in front of Jetty, such as a Load Balancer or proxy).</p>
</dd>
<dt class="hdlist1">jetty.sslContext.keyStorePath</dt>
<dd>
<p>Sets the location of the <code>keystore</code> that you configured with your certificates.</p>
</dd>
<dt class="hdlist1">jetty.sslContext.keyStorePassword</dt>
<dd>
<p>Sets the Password for the <code>keystore</code>.</p>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="jetty-conscrypt-distribution"><a class="anchor" href="#jetty-conscrypt-distribution"></a><a class="link" href="#jetty-conscrypt-distribution">Conscrypt SSL Configuration</a></h4>
<div class="paragraph">
<p>Enabling Conscrypt SSL is just as easy as default SSL - enable both the <code>conscrypt</code> and <code>ssl</code> <a href="#startup-modules">modules</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">$ cd ${JETTY_BASE}
$ java -jar /path/to/jetty-home/start.jar --add-to-start=ssl,conscrypt
ALERT: There are enabled module(s) with licenses.
The following 1 module(s):
+ contains software not provided by the Eclipse Foundation!
+ contains software not covered by the Eclipse Public License!
+ has not been audited for compliance with its license
Module: conscrypt
+ Conscrypt is distributed under the Apache Licence 2.0
+ https://github.com/google/conscrypt/blob/master/LICENSE
Proceed (y/N)? y
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : conscrypt initialized in ${jetty.base}/start.d/conscrypt.ini
INFO : ssl initialized in ${jetty.base}/start.d/ssl.ini
MKDIR : ${jetty.base}/lib/conscrypt
DOWNLD: https://repo1.maven.org/maven2/org/conscrypt/conscrypt-openjdk-uber/1.0.0.RC11/conscrypt-openjdk-uber-1.0.0.RC11.jar to ${jetty.base}/lib/conscrypt/conscrypt-uber-1.0.0.RC11.jar
MKDIR : ${jetty.base}/etc
COPY : ${jetty.home}/modules/conscrypt/conscrypt.xml to ${jetty.base}/etc/conscrypt.xml
COPY : ${jetty.home}/modules/ssl/keystore to ${jetty.base}/etc/keystore
INFO : Base directory was modified</code></pre>
</div>
</div>
<div class="paragraph">
<p>No additional Conscrypt configuration is needed.
SSL-specific parameters, like <code>keyStorePath</code> and <code>keyStorePassword</code> can still configured as in the example above, making use of the <code>${JETTY_BASE}/start.d/ssl.ini</code> file.</p>
</div>
</div>
<div class="sect3">
<h4 id="client-certificate-authentication"><a class="anchor" href="#client-certificate-authentication"></a><a class="link" href="#client-certificate-authentication">Client Certificate Authentication</a></h4>
<div class="paragraph">
<p>To enable client certificate authentication in the Jetty Distribution, you need to enable the both the <code>ssl</code> and <code>https</code> modules.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">$ cd /path/to/mybase
$ java -jar /path/to/jetty-dist/start.jar --add-to-startd=ssl,https</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">$JETTY_BASE/start.d/ssl.ini</div>
<div class="content">
<pre class="highlight nowrap"><code class="language-ini" data-lang="ini"># Module: ssl
--module=ssl
jetty.ssl.host=0.0.0.0
jetty.ssl.port=8583
jetty.sslContext.keyStorePath=etc/keystore
jetty.sslContext.trustStorePath=etc/truststore
jetty.sslContext.keyStorePassword=OBF:
jetty.sslContext.keyManagerPassword=OBF:
jetty.sslContext.trustStorePassword=OBF:
# Enable client certificate authentication.
jetty.sslContext.needClientAuth=true</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">$JETTY_BASE/start.d/https.ini</div>
<div class="content">
<pre class="highlight nowrap"><code class="language-ini" data-lang="ini"># Module: https
--module=https</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configuring-contexts"><a class="anchor" href="#configuring-contexts"></a><a class="link" href="#configuring-contexts">Configuring Contexts</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>This chapter discusses various options for configuring Jetty contexts.</p>
</div>
<div class="sect2">
<h3 id="setting-context-path"><a class="anchor" href="#setting-context-path"></a><a class="link" href="#setting-context-path">Setting a Context Path</a></h3>
<div class="paragraph">
<p>The context path is the prefix of a URL path that is used to select the context(s) to which an incoming request is passed. Typically a URL in a Java servlet server is of the format <code><a href="http://hostname.com/contextPath/servletPath/pathInfo" class="bare">http://hostname.com/contextPath/servletPath/pathInfo</a></code>, where each of the path elements can be zero or more / separated elements.
If there is no context path, the context is referred to as the <em>root</em> context.
The root context must be configured as <code>/</code> but is reported as the empty string by the servlet API <code>getContextPath()</code> method.</p>
</div>
<div class="paragraph">
<p>How you set the context path depends on how you deploy the web application (or <code>ContextHandler</code>).</p>
</div>
<div class="sect3">
<h4 id="using-embedded-deployment"><a class="anchor" href="#using-embedded-deployment"></a><a class="link" href="#using-embedded-deployment">Using Embedded Deployment</a></h4>
<div class="paragraph">
<p>If you run Jetty from code as an embedded server (see <a href="#advanced-embedding">Embedding</a>), setting the context path is a matter of calling the <code>setContextPath</code> method on the <code>ContextHandler</code> instance (or <code>WebAppContext</code> instance).</p>
</div>
</div>
<div class="sect3">
<h4 id="usng-the-context-provider"><a class="anchor" href="#usng-the-context-provider"></a><a class="link" href="#usng-the-context-provider">By naming convention</a></h4>
<div class="paragraph">
<p>If a web application is deployed using the WebAppProvider of the DeploymentManager without an XML IoC file, then the name of the WAR file is used to set the context path:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>If the WAR file is named myapp.war, then the context will be deployed with a context path of <code>/myapp</code></p>
</li>
<li>
<p>If the WAR file is named ROOT.WAR (or any case insensitive variation), then the context will be deployed with a context path of <code>/</code></p>
</li>
<li>
<p>If the WAR file is named ROOT-foobar.war ( or any case insensitive variation), then the context will be deployed with a context path of <code>/</code> and a virtual host of "foobar"</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="using-the-webapp-provider"><a class="anchor" href="#using-the-webapp-provider"></a><a class="link" href="#using-the-webapp-provider">By Deployer configuration</a></h4>
<div class="paragraph">
<p>If a web application is deployed using the <code>WebAppProvider</code> of the <code>DeploymentManager</code> with an XML IoC file to configure the context, then the <code>setContextPath</code> method can be called within that file.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/test&lt;/Set&gt;
...
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="embedding-web-inf-jetty-web.xml-file"><a class="anchor" href="#embedding-web-inf-jetty-web.xml-file"></a><a class="link" href="#embedding-web-inf-jetty-web.xml-file">Embedding a WEB-INF/jetty-web.xml File</a></h4>
<div class="paragraph">
<p>You can also set the context path for webapps by embedding a <code>WEB-INF/jetty-web.xml</code> file in the WAR, which uses the same XML IoC format as the deployer example above.
However this is not the preferred method as it requires the web application to be modified.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ref-temporary-directories"><a class="anchor" href="#ref-temporary-directories"></a><a class="link" href="#ref-temporary-directories">Temporary Directories</a></h3>
<div class="paragraph">
<p>Jetty itself has no temporary directories, but you can assign a directory for each web application, into which the WAR is unpacked, JSPs compiled on-the-fly, etc.
If you do not assign a specific temporary directory, Jetty will create one as needed when your web application starts.
Whether you set the location of the temporary directory - or you let Jetty create one for you - you also have a choice to either keep or delete the temporary directory when the web application stops.</p>
</div>
<div class="sect3">
<h4 id="_the-default-temp-directory"><a class="anchor" href="#_the-default-temp-directory"></a><a class="link" href="#_the-default-temp-directory">The Default Temp Directory</a></h4>
<div class="paragraph">
<p>By default, Jetty will create a temporary directory for each web application. The name of the directory will be of the form:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>"jetty-"+host+"-"+port+"-"+resourceBase+"-_"+context+"-"+virtualhost+"-"+randomdigits+".dir"</pre>
</div>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>jetty-0.0.0.0-8080-test.war-_test-any-8900275691885214790.dir</pre>
</div>
</div>
<div class="paragraph">
<p>Where <code>0.0.0.0</code> is the host address, <code>8080</code> is the port, <code>test.war</code> is the resourceBase, <code>test</code> is the context path (with / converted to _), <code>any</code> is the virtual host, and <code>randomdigits</code> are a string of digits guaranteed to be unique.</p>
</div>
<div class="paragraph">
<p>Once the temp directory is created, it is retrievable as the value (as a File) of the context attribute <code>javax.servlet.context.tempdir.</code></p>
</div>
<div class="sect4">
<h5 id="_the-location-of-the-temp-directory"><a class="anchor" href="#_the-location-of-the-temp-directory"></a><a class="link" href="#_the-location-of-the-temp-directory">The location of the temp directory</a></h5>
<div class="paragraph">
<p>By default, Jetty will create this directory inside the directory named by the <code>java.io.tmpdir</code> System property.
You can instruct Jetty to use a different parent directory by setting the context attribute <code>org.eclipse.jetty.webapp.basetempdir</code> to the name of the desired parent directory.
The directory named by this attribute <em>must</em> exist and be <em>writeable</em>.</p>
</div>
<div class="paragraph">
<p>As usual with Jetty, you can either set this attribute in a context xml file, or you can do it in code.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of setting it in an xml file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/test&lt;/Set&gt;
&lt;Set name="war"&gt;foo.war&lt;/Set&gt;
&lt;Call name="setAttribute"&gt;
&lt;Arg&gt;org.eclipse.jetty.webapp.basetempdir&lt;/Arg&gt;
&lt;Arg&gt;/home/my/foo&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The equivalent in code is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">WebAppContext context = new WebAppContext();
context.setContextPath("/test");
context.setWar("foo.war");
context.setAttribute("org.eclipse.jetty.webapp.basetempdir", "/tmp/foo");</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_setting-a-specific-temp-directory"><a class="anchor" href="#_setting-a-specific-temp-directory"></a><a class="link" href="#_setting-a-specific-temp-directory">Setting a Specific Temp Directory</a></h4>
<div class="paragraph">
<p>There are several ways to use a particular directory as the temporary directory:</p>
</div>
<div class="sect4">
<h5 id="_call-webappcontext-settempdirectorystring-dir"><a class="anchor" href="#_call-webappcontext-settempdirectorystring-dir"></a><a class="link" href="#_call-webappcontext-settempdirectorystring-dir">Call WebAppContext.setTempDirectory(String dir)</a></h5>
<div class="paragraph">
<p>As before this can be accomplished with an XML file or directly in code.
Here is an example of setting the temp directory in XML:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/test&lt;/Set&gt;
&lt;Set name="war"&gt;foo.war&lt;/Set&gt;
&lt;Set name="tempDirectory"&gt;/some/dir/foo&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>And here is an example of doing it with java code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">WebAppContext context = new WebAppContext();
context.setContextPath("/test");
context.setWar("foo.war");
context.setTempDirectory(new File("/some/dir/foo"));</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_setting-the-javax-servlet-context-tempdir-context-attribute"><a class="anchor" href="#_setting-the-javax-servlet-context-tempdir-context-attribute"></a><a class="link" href="#_setting-the-javax-servlet-context-tempdir-context-attribute">Setting the javax.servlet.context.tempdir Context Attribute</a></h5>
<div class="paragraph">
<p>You should set this context attribute with the name of directory you want to use as the temp directory.
Again, you can do this in XML:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/test&lt;/Set&gt;
&lt;Set name="war"&gt;foo.war&lt;/Set&gt;
&lt;Call name="setAttribute"&gt;
&lt;Arg&gt;javax.servlet.context.tempdir&lt;/Arg&gt;
&lt;Arg&gt;/some/dir/foo&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Or in java:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">WebAppContext context = new WebAppContext();
context.setContextPath("/test");
context.setWar("foo.war");
context.setAttribute("javax.servlet.context.tempdir", "/some/dir/foo");</code></pre>
</div>
</div>
<div class="paragraph">
<p>Once a temporary directory has been created by either of these methods, a file instance for it is set as the value of the <code>javax.servlet.context.tempdir</code> attribute of the web application.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Be wary of setting an explicit temp directory if you are likely to change the jars in WEB-INF/lib between redeployments.
There is a JVM bug concerning <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4774421">caching of jar contents.</a>
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect4">
<h5 id="_setting-the-temp-directory-on-the-command-line"><a class="anchor" href="#_setting-the-temp-directory-on-the-command-line"></a><a class="link" href="#_setting-the-temp-directory-on-the-command-line">Setting the Temp Directory on the Command Line</a></h5>
<div class="paragraph">
<p>You can set the location of the temp directory on the command line when Jetty starts up in two ways.
First is the most straightforward, simply add it to your command line when starting Jetty.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar -Djava.io.tmpdir=/path/to/desired/directory</code></pre>
</div>
</div>
<div class="paragraph">
<p>Alternately, this can be defined in a <a href="#startup-modules">module.</a>
The <code>jvm</code> module packaged with Jetty is set up to add additional JVM options.
After enabling the module (using the <code>--add-to-start=jvm</code> command), edit the <code>jvm.ini</code> file and add the location to the temporary directory.
You will also need verify the line including the <code>--exec</code> command is not commented out, as this is required for Jetty to start a new, forked JVM.
Below is an example of the standard <code>jvm.ini</code> file altered to include a reference to a temp directory.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># ---------------------------------------
# Module: jvm
# A noop module that creates an ini template useful for
# setting JVM arguments (eg -Xmx )
# ---------------------------------------
--module=jvm
## JVM Configuration
## If JVM args are include in an ini file then --exec is needed
## to start a new JVM from start.jar with the extra args.
##
## If you wish to avoid an extra JVM running, place JVM args
## on the normal command line and do not use --exec
--exec
# -Xmx2000m
# -Xmn512m
# -XX:+UseConcMarkSweepGC
# -XX:ParallelCMSThreads=2
# -XX:+CMSClassUnloadingEnabled
# -XX:+UseCMSCompactAtFullCollection
# -XX:CMSInitiatingOccupancyFraction=80
# -internal:gc
# -XX:+PrintGCDateStamps
# -XX:+PrintGCTimeStamps
# -XX:+PrintGCDetails
# -XX:+PrintTenuringDistribution
# -XX:+PrintCommandLineFlags
# -XX:+DisableExplicitGC
-Djava.io.tmpdir=/path/to/desired/directory</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_the-work-directory"><a class="anchor" href="#_the-work-directory"></a><a class="link" href="#_the-work-directory">The "work" Directory</a></h4>
<div class="paragraph">
<p>It is possible to create a directory named <code>work</code> in the <code>$\{jetty.base}</code> directory.
If such a directory is found, it is assumed you want to use it as the parent directory for all of the temporary directories of the webapps in <code>$\{jetty.base}</code>.
Moreover, as has historically been the case, these temp directories inside the work directory are not cleaned up when Jetty exits (or more correctly speaking, the <code>temp</code> directory corresponding to a context is not cleaned up when that context stops).</p>
</div>
<div class="paragraph">
<p>When a <code>work</code> directory is used, the algorithm for generating the name of the context-specific temp directories omits the random digit string.
This ensures the name of the directory remains consistent across context restarts.</p>
</div>
</div>
<div class="sect3">
<h4 id="_persisting-the-temp-directory"><a class="anchor" href="#_persisting-the-temp-directory"></a><a class="link" href="#_persisting-the-temp-directory">Persisting the temp directory</a></h4>
<div class="paragraph">
<p>Sometimes it is useful to keep the contents of the temporary directory between restarts of the web application.
By default, Jetty will <strong>not</strong> persist the temp directory.
To configure Jetty to keep it, use <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html">WebAppContext.setPersistTempDirectory(true)</a>.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Be aware that if you call <code>setPersistTempDirectory(true)</code>, but let Jetty create a new temp directory each time (i.e. you do NOT set an explicit temp directory), then you will accumulate temp directories in your chosen temp directory location.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
</div>
<div class="sect2">
<h3 id="custom-error-pages"><a class="anchor" href="#custom-error-pages"></a><a class="link" href="#custom-error-pages">Creating Custom Error Pages</a></h3>
<div class="paragraph">
<p>The following sections describe several ways to create custom error pages in Jetty.</p>
</div>
<div class="sect3">
<h4 id="_defining-error-pages-in-web-xml"><a class="anchor" href="#_defining-error-pages-in-web-xml"></a><a class="link" href="#_defining-error-pages-in-web-xml">Defining error pages in web.xml</a></h4>
<div class="paragraph">
<p>You can use the standard webapp configuration file located in <code>webapp/WEB-INF/web.xml</code> to map errors to specific URLs with the <code>error-page</code> element.
This element creates a mapping between the error-code or exception-type to the location of a resource in the web application.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>error-code</code> - an integer value</p>
</li>
<li>
<p><code>exception-type</code> - a fully qualified class name of a Java Exception type</p>
</li>
<li>
<p><code>location</code> - location of the resource in the webapp relative to the root of the web application. Value should start with <code>/</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Error code example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;error-page&gt;
&lt;error-code&gt;404&lt;/error-code&gt;
&lt;location&gt;/jspsnoop/ERROR/404&lt;/location&gt;
&lt;/error-page&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Exception example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;error-page&gt;
&lt;exception-type&gt;java.io.IOException&lt;/exception-type&gt;
&lt;location&gt;/jspsnoop/IOException&lt;/location&gt;
&lt;/error-page&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The error page mappings created with the error-page element will redirect to a normal URL within the web application and will be handled as a normal request to that location and thus may be static content, a JSP or a filter and/or servlet.
When handling a request generated by an error redirection, the following request attributes are set and are available to generate dynamic content:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">javax.servlet.error.exception</dt>
<dd>
<p>The exception instance that caused the error (or null).</p>
</dd>
<dt class="hdlist1">javax.servlet.error.exception_type</dt>
<dd>
<p>The class name of the exception instance that caused the error (or null).</p>
</dd>
<dt class="hdlist1">javax.servlet.error.message</dt>
<dd>
<p>The error message.</p>
</dd>
<dt class="hdlist1">javax.servlet.error.request_uri</dt>
<dd>
<p>The URI of the request with an error.</p>
</dd>
<dt class="hdlist1">javax.servlet.error.servlet_name</dt>
<dd>
<p>The Servlet name of the servlet that the request was
dispatched to.</p>
</dd>
<dt class="hdlist1">javax.servlet.error.status_code</dt>
<dd>
<p>The status code of the error (e.g. 404, 500 etc.).</p>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="_configuring-error-pages-context-files"><a class="anchor" href="#_configuring-error-pages-context-files"></a><a class="link" href="#_configuring-error-pages-context-files">Configuring error pages context files</a></h4>
<div class="paragraph">
<p>You can use context IoC XML files to configure the default error page mappings with more flexibility than is available with <code>web.xml</code>, specifically with the support of error code ranges.
Context files are normally located in <code>${jetty.base}/webapps/</code> (see <code>DeployerManager</code> for more details) and an example of more flexible error page mapping is below:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/test&lt;/Set&gt;
&lt;Set name="war"&gt;
&lt;SystemProperty name="jetty.base" default="."/&gt;/webapps/test
&lt;/Set&gt;
&lt;!-- by Code --&gt;
&lt;Get name="errorHandler"&gt;
&lt;Call name="addErrorPage"&gt;
&lt;Arg type="int"&gt;404&lt;/Arg&gt;
&lt;Arg type="String"&gt;/jspsnoop/ERROR/404&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Get&gt;
&lt;!-- by Exception --&gt;
&lt;Get name="errorHandler"&gt;
&lt;Call name="addErrorPage"&gt;
&lt;Arg&gt;
&lt;Call class="java.lang.Class" name="forName"&gt;
&lt;Arg type="String"&gt;java.io.IOException&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Arg&gt;
&lt;Arg type="String"&gt;/jspsnoop/IOException&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Get&gt;
&lt;!-- by Code Range --&gt;
&lt;Get name="errorHandler"&gt;
&lt;Call name="addErrorPage"&gt;
&lt;Arg type="int"&gt;500&lt;/Arg&gt;
&lt;Arg type="int"&gt;599&lt;/Arg&gt;
&lt;Arg type="String"&gt;/dump/errorCodeRangeMapping&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Get&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_custom-errorhandler-class"><a class="anchor" href="#_custom-errorhandler-class"></a><a class="link" href="#_custom-errorhandler-class">Custom ErrorHandler class</a></h4>
<div class="paragraph">
<p>If no error page mapping is defined, or if the error page resource itself has an error, then the error page will be generated by an instance of <code>ErrorHandler</code> configured either the Context or the Server.
An <code>ErrorHandler</code> may extend the <code>ErrorHandler</code> class and may totally replace the handle method to generate an error page, or it can implement some or all of the following methods to partially modify the error pages:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
void handleErrorPage(HttpServletRequest request, Writer writer, int code, String message) throws IOException
void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks) throws IOException
void writeErrorPageHead(HttpServletRequest request, Writer writer, int code, String message) throws IOException
void writeErrorPageBody(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks) throws IOException
void writeErrorPageMessage(HttpServletRequest request, Writer writer, int code, String message, String uri) throws IOException
void writeErrorPageStacks(HttpServletRequest request, Writer writer) throws IOException</code></pre>
</div>
</div>
<div class="paragraph">
<p>An <code>ErrorHandler</code> instance may be set on a Context by calling the <code>ContextHandler.setErrorHandler</code> method. This can be done by embedded code or via context IoC XML.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.server.handler.ContextHandler"&gt;
...
&lt;Set name="errorHandler"&gt;
&lt;New class="com.acme.handler.MyErrorHandler"/&gt;
&lt;/Set&gt;
...
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>An <code>ErrorHandler</code> instance may be set on the entire server by setting it as a dependent bean on the Server instance.
This can be done by calling <code>Server.addBean(Object)</code> via embedded code or in <code>jetty.xml</code> IoC XML:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
...
&lt;Call name="addBean"&gt;
&lt;Arg&gt;
&lt;New class="com.acme.handler.MyErrorHandler"/&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
...
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_server-level-404-error"><a class="anchor" href="#_server-level-404-error"></a><a class="link" href="#_server-level-404-error">Server level 404 error</a></h4>
<div class="paragraph">
<p>It is possible to get a 'page not found' when a request is made to the server for a resource that is outside of any registered contexts.
As an example, you have a domain name pointing to your public server IP, yet no context is registered with Jetty to serve pages for that domain.
As a consequence, the server, by default, gives a listing of all contexts running on the server.</p>
</div>
<div class="paragraph">
<p>One of the quickest ways to avoid this behavior is to create a catch all context.
Create a "root" web app mapped to the "/" URI, and use the <code>index.html</code> redirect to whatever place with a header directive.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="setting-form-size"><a class="anchor" href="#setting-form-size"></a><a class="link" href="#setting-form-size">Setting Max Form Size</a></h3>
<div class="paragraph">
<p>When a client issues a POST request with <code>Content-Type: application/x-www-form-urlencoded</code> there are 2 configurable limits imposed to help protect the server against denial of service attacks by malicious clients sending huge amounts of data.</p>
</div>
<div class="paragraph">
<p>There is a maximum form size limit, and a maximum form keys limit.</p>
</div>
<div class="paragraph">
<p>The default maximum form size Jetty permits is 200000 bytes.
The default maximum form keys Jetty permits is 1000 keys.</p>
</div>
<div class="paragraph">
<p>You can change these defaults for a particular webapp, or all webapps within the same JVM.</p>
</div>
<div class="sect3">
<h4 id="_for-a-single-webapp"><a class="anchor" href="#_for-a-single-webapp"></a><a class="link" href="#_for-a-single-webapp">For a Single Webapp</a></h4>
<div class="paragraph">
<p>The methods to invoke are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>ContextHandler.setMaxFormContentSize(int maxSize);</code></p>
</li>
<li>
<p><code>ContextHandler.setMaxFormKeys(int max);</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>This can be done either in a context XML deployment descriptor external to the webapp, or in a <code>jetty-web.xml</code> file in the webapp&#8217;s <code>WEB-INF</code> directory.</p>
</div>
<div class="paragraph">
<p>In either case the syntax of the XML file is the same:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --&gt;
&lt;!-- Max Form Size --&gt;
&lt;!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --&gt;
&lt;Set name="maxFormContentSize"&gt;400000&lt;/Set&gt;
&lt;!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --&gt;
&lt;!-- Max Form Keys --&gt;
&lt;!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --&gt;
&lt;Set name="maxFormKeys"&gt;400&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_for-all-apps-in-the-jvm"><a class="anchor" href="#_for-all-apps-in-the-jvm"></a><a class="link" href="#_for-all-apps-in-the-jvm">For All Apps in the JVM</a></h4>
<div class="paragraph">
<p>Use the system properties:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>org.eclipse.jetty.server.Request.maxFormContentSize</code> - the maximum size of Form Content allowed</p>
</li>
<li>
<p><code>org.eclipse.jetty.server.Request.maxFormKeys</code> - the maximum number of Form Keys allowed</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>This can be set on the command line or in the <code>$JETTY_BASE\start.ini</code> or any <code>$JETTY_BASE\start.d\*.ini</code> <a href="#startup-modules">module ini file.</a>
Using <code>$JETTY_BASE\start.d\server.ini</code> as an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console"># ---------------------------------------
# Module: server
# Enables the core Jetty server on the classpath.
# ---------------------------------------
--module=server
### Common HTTP configuration
## Scheme to use to build URIs for secure redirects
# jetty.httpConfig.secureScheme=https
...
-Dorg.eclipse.jetty.server.Request.maxFormContentSize=400000
-Dorg.eclipse.jetty.server.Request.maxFormKeys=400</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="advanced-debugging"><a class="anchor" href="#advanced-debugging"></a><a class="link" href="#advanced-debugging">Debugging</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_options"><a class="anchor" href="#_options"></a><a class="link" href="#_options">Options</a></h3>
<div class="paragraph">
<p>Given how flexible Jetty is in how it can be configured and deployed into development and production, there exists a wealth of different options for debugging your application in you favorite environment.
In this section we will gather up some of these different options available and explain how you can use them.
If you would like to contribute to this section simply fork the repository and contribute the information, or open a github issue with the information and we&#8217;ll bring it over.</p>
</div>
</div>
<div class="sect2">
<h3 id="enable-remote-debugging"><a class="anchor" href="#enable-remote-debugging"></a><a class="link" href="#enable-remote-debugging">Enable remote debugging</a></h3>
<div class="sect3">
<h4 id="remote-debugging"><a class="anchor" href="#remote-debugging"></a><a class="link" href="#remote-debugging">Remote Debugging</a></h4>
<div class="paragraph">
<p>If you have a web application deployed into Jetty you can interact with it remotely from a debugging perspective easily.
The basics are that you must start up the remote JVM with additional parameters and then start up a remote debugging session in Eclipse for the webapp in question.
This is easily accomplished.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
This example assumes you are deploying your web application into the jetty-distribution.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect4">
<h5 id="_starting-jetty"><a class="anchor" href="#_starting-jetty"></a><a class="link" href="#_starting-jetty">Starting Jetty</a></h5>
<div class="paragraph">
<p>Assuming you have your webapp deployed into jetty, there are two different ways to approach this:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Via command line</dt>
<dd>
<p>Add the required parameters on the commandline like so.</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ java -Xdebug -agentlib:jdwp=transport=dt_socket,address=9999,server=y,suspend=n -jar start.jar</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">Via <code>start.ini</code></dt>
<dd>
<p>This approach is best used if you want to debug a particular jetty-distribution and not have to remember the commandline incantations.</p>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Edit the <code>start.ini</code> and uncomment the --exec line, this is required if you are adding jvm options to the start.ini file as jetty-start must generate the classpath required and fork a new jvm.</p>
</li>
<li>
<p>Add the parameters mentioned above in the Command Line option so your start.ini looks like this:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">#===========================================================
# Configure JVM arguments.
# If JVM args are include in an ini file then --exec is needed
# to start a new JVM from start.jar with the extra args.
# If you wish to avoid an extra JVM running, place JVM args
# on the normal command line and do not use --exec
#-----------------------------------------------------------
--exec
-Xdebug
-agentlib:jdwp=transport=dt_socket,address=9999,server=y,suspend=n
# -Xmx2000m
# -Xmn512m
# -XX:+UseConcMarkSweepGC
# -XX:ParallelCMSThreads=2
# -XX:+CMSClassUnloadingEnabled
# -XX:+UseCMSCompactAtFullCollection
# -XX:CMSInitiatingOccupancyFraction=80
# -verbose:gc
# -XX:+PrintGCDateStamps
# -XX:+PrintGCTimeStamps
# -XX:+PrintGCDetails
# -XX:+PrintTenuringDistribution
# -XX:+PrintCommandLineFlags
# -XX:+DisableExplicitGC</code></pre>
</div>
</div>
<div class="paragraph">
<p>Uncomment any other jvm environmental options you so desire for your debugging session.</p>
</div>
</li>
<li>
<p>Regardless of the option chosen, you should see the following lines at the top of your jetty-distribution startup.</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">Listening for transport dt_socket at address: 9999</code></pre>
</div>
</div>
</li>
</ol>
</div>
</dd>
</dl>
</div>
</div>
<div class="sect4">
<h5 id="_linking-with-your-ide"><a class="anchor" href="#_linking-with-your-ide"></a><a class="link" href="#_linking-with-your-ide">Linking with your IDE</a></h5>
<div class="paragraph">
<p>Refer to the documentation for your ide:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="#debugging-with-intellij">Debugging With IntelliJ</a></p>
</li>
<li>
<p><a href="#debugging-with-eclipse">Debugging With Eclipse</a></p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="debugging-with-intellij"><a class="anchor" href="#debugging-with-intellij"></a><a class="link" href="#debugging-with-intellij">Debugging With IntelliJ</a></h3>
<div class="paragraph">
<p>There are a number of options available to debug your application in IntelliJ.</p>
</div>
<div class="paragraph">
<p>If not done already prepare your application for remote debugging as described here: <a href="#enable-remote-debugging">Enable remote debugging</a></p>
</div>
<div class="sect3">
<h4 id="_linking-with-intellij"><a class="anchor" href="#_linking-with-intellij"></a><a class="link" href="#_linking-with-intellij">Linking with IntelliJ</a></h4>
<div class="paragraph">
<p>Next we need to link the IntelliJ project with the deployed webapp.</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Within IntelliJ, open the project containing the webapp deployed into jetty that you want to debug. Select<strong>Run &#8594; Edit Configurations</strong>.
Add a new configuration by clicking the "+" icon. Choose <strong>Remote</strong>.
Make sure the port you choose is the same as the one you added in <a href="#enable-remote-debugging">Enable remote debugging</a>.</p>
<div class="paragraph">
<p><span class="image"><img src="intellij_new_remote_config.png" alt="image" width="800"></span></p>
</div>
</li>
<li>
<p>Next in your webapp you can set a breakpoint within a servlet which when it is tripped will halt the remote jvm&#8217;s processing thread to await for debugging commands from your IntelliJ instance.
To set a breakpoint, simply open the servlet or any other class you want to debug and click left to the line you want to set the breakpoint at (where the red dot is on the next screenshot).
The red dot and red background on the line mark the breakpoint.</p>
<div class="paragraph">
<p><span class="image"><img src="intellij_set_breakpoint.png" alt="image" width="800"></span></p>
</div>
</li>
<li>
<p>Accessing that servlet within your browser, pointed at your remote debug configured jetty-distribution, should transition your IntelliJ instance to the standard debugger view.</p>
<div class="paragraph">
<p><span class="image"><img src="intellij_debug_view.png" alt="image" width="800"></span></p>
</div>
</li>
</ol>
</div>
</div>
<div class="sect3">
<h4 id="intellij-within-intellij"><a class="anchor" href="#intellij-within-intellij"></a><a class="link" href="#intellij-within-intellij">Within IntelliJ</a></h4>
<div class="paragraph">
<p>Since Jetty can be incredibly simple to embed, many people choose to create a small <code>main</code> method which they can launch directly within IntelliJ in order to more easily debug their entire application.
The best place to get started on this approach is to look through <a href="#embedding-jetty">Embedding Jetty</a> and the <a href="#embedded-examples">Embedded Examples</a> sections.</p>
</div>
<div class="paragraph">
<p>Once you have a main method defined in order to launch your application, open the source file and right-click the main method.
Select <strong>Debug</strong> or simply hit CTRL+SHIFT+D.
In your <strong>Console</strong> tab within IntelliJ you should see your application startup and once it has completed startup you should be able to configure breakpoints and hit the Jetty instance as normal via your web browser.
The same thing works for unit tests.
Instead of the main method run debug on the test method you want to debug.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="intellij_select_debug.png" alt="image" width="800"></span></p>
</div>
<div class="paragraph">
<p>Debugging in IntelliJ is extremely powerful.
For example it&#8217;s possible to have conditional breakpoints that only trigger a break if the configured conditions are met.
Have a look at the various tutorials in the internet or the <a href="http://www.jetbrains.com/idea/webhelp/getting-help.html">IntelliJ documentation</a> for further details.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
You can easily configure logging through a <code>jetty-logging.properties</code> file.
If this file is on your classpath then Jetty will use it for configuring logging, we use this approach extensively throughout Jetty development and it makes life ever so much easier.
You can see this in action in the <a href="#configuring-jetty-stderrlog">The jetty-logging.properties file</a> section.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
</div>
<div class="sect2">
<h3 id="debugging-with-eclipse"><a class="anchor" href="#debugging-with-eclipse"></a><a class="link" href="#debugging-with-eclipse">Debugging With Eclipse</a></h3>
<div class="paragraph">
<p>There are a number of options available to debug your application in Eclipse.</p>
</div>
<div class="paragraph">
<p>If not done already prepare your application for remote debugging as described here: <a href="#enable-remote-debugging">Enable remote debugging</a></p>
</div>
<div class="sect3">
<h4 id="_linking-with-eclipse"><a class="anchor" href="#_linking-with-eclipse"></a><a class="link" href="#_linking-with-eclipse">Linking with Eclipse</a></h4>
<div class="paragraph">
<p>Next we need to link the Eclipse project with the deployed webapp.</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Within Eclipse, right-click on the project containing the webapp deployed into jetty and select <strong>Debug &#8594; Debug Configurations</strong> and create a new configuration of <strong>Remote Java Application</strong>.
Make sure the port you choose is the same as the one you added in <a href="#enable-remote-debugging">Enable remote debugging</a>.</p>
<div class="paragraph">
<p><span class="image"><img src="debug-eclipse-1.png" alt="image" width="576"></span></p>
</div>
</li>
<li>
<p>Next in your webapp you can set a breakpoint within a servlet which when it is tripped will halt the remote jvm&#8217;s processing thread to await for debugging commands from your Eclipse instance.</p>
<div class="paragraph">
<p><span class="image"><img src="debug-eclipse-2.png" alt="image" width="576"></span></p>
</div>
</li>
<li>
<p>Accessing that servlet within your browser, pointed at your remote debug configurated jetty-distribution, should transition your Eclipse instance to the standard Debug view.</p>
<div class="paragraph">
<p><span class="image"><img src="debug-eclipse-3.png" alt="image" width="576"></span></p>
</div>
</li>
</ol>
</div>
</div>
<div class="sect3">
<h4 id="eclipse-within-eclipse"><a class="anchor" href="#eclipse-within-eclipse"></a><a class="link" href="#eclipse-within-eclipse">Within Eclipse</a></h4>
<div class="paragraph">
<p>Since Jetty can be incredibly simple to embed, many people choose to create a small <code>main</code> method which they can launch directly within Eclipse in order to more easily debug their entire application.
The best place to get started on this approach is to look through <a href="#embedding-jetty">Embedding Jetty</a> and the <a href="#embedded-examples">Embedded Examples</a> sections.</p>
</div>
<div class="paragraph">
<p>Once you have a main method defined in order to launch your application, right-click on the source file and select<strong>Debug As &#8594; Java Application</strong>.
In your <strong>Console</strong> tab within Eclipse you should see your application startup and once it has completed startup you should be able to configure breakpoints and hit the Jetty instance as normal via your web browser.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
You can easily configure logging through a <code>jetty-logging.properties</code>
file. If this file is on your classpath then Jetty will use it for
configuring logging, we use this approach extensively throughout Jetty
development and it makes life ever so much easier. You can see this in
action in the <a href="#configuring-jetty-stderrlog">The jetty-logging.properties file</a> section.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configuring-deployment"><a class="anchor" href="#configuring-deployment"></a><a class="link" href="#configuring-deployment">Deploying to Jetty</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>This chapter discusses various ways to deploy applications with Jetty.
Topics range from deployment bindings to deploying third party products.
It also includes information about the Deployment Manager and WebApp Provider.</p>
</div>
<div class="sect2">
<h3 id="configuring-specific-webapp-deployment"><a class="anchor" href="#configuring-specific-webapp-deployment"></a><a class="link" href="#configuring-specific-webapp-deployment">Configuring a Specific Web Application Deployment</a></h3>
<div class="paragraph">
<p>Using the Automatic Web Application Deployment model is quick and easy, but sometimes you might need to tune certain deployment properties (for example, you want to deploy with a context path that is not based on the file name, or you want to define a special database connection pool just for this web application).
You can use a <a href="#deployable-descriptor-file">Jetty Deployable Descriptor XML File</a> to accomplish such tuning.</p>
</div>
<div class="sect3">
<h4 id="deployable-descriptor-file"><a class="anchor" href="#deployable-descriptor-file"></a><a class="link" href="#deployable-descriptor-file">Jetty Deployable Descriptor XML File</a></h4>
<div class="paragraph">
<p>Jetty supports deploying Web Applications via XML files which will build an instance of a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ContextHandler.html">ContextHandler</a> that Jetty can then deploy.</p>
</div>
</div>
<div class="sect3">
<h4 id="using-basic-descriptor-files"><a class="anchor" href="#using-basic-descriptor-files"></a><a class="link" href="#using-basic-descriptor-files">Using Basic Descriptor Files</a></h4>
<div class="paragraph">
<p>In a default Jetty installation, Jetty scans its <code>$JETTY_HOME/webapps</code> directory for context deployment descriptor files.
To deploy a web application using such a file, simply place the file in that directory.</p>
</div>
<div class="paragraph">
<p>The deployment descriptor file itself is an xml file that configures a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html"><code>WebAppContext</code></a> class.
For a basic installation only two properties need configured:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">war</dt>
<dd>
<p>The filesystem path to the web application file (or directory)</p>
</dd>
<dt class="hdlist1">contextPath</dt>
<dd>
<p>The context path to use for the web application</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>For example, here is a descriptor file that deploys the file <code>/opt/myapp/myapp.war</code> to the context path <code>/wiki</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/wiki&lt;/Set&gt;
&lt;Set name="war"&gt;/opt/myapp/myapp.war&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Both <code>SystemProperty</code> and <code>Property</code> elements can be used in the descriptor file.
For example, if the system property is set to <code>myapp.home=/opt/myapp</code>, the previous example can be rewritten as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/wiki&lt;/Set&gt;
&lt;Set name="war"&gt;&lt;SystemProperty name="myapp.home"/&gt;/myapp.war&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>If the home path for an application needs altered, only the system property needs changed.
This is useful if the version of an app is frequently changed.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
To ensure your <code>web.xml</code> files are validated, you will need to set the <code>validateXml</code> attribute to true as described <a href="#jetty-xml-dtd">here.</a>
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="configuring-advanced-descriptor-files"><a class="anchor" href="#configuring-advanced-descriptor-files"></a><a class="link" href="#configuring-advanced-descriptor-files">Configuring Advanced Descriptor Files</a></h4>
<div class="paragraph">
<p>Official documentation for the for the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html"><code>WebAppContext</code></a> class lists all the properties that can be set.
Here are some examples that configure advanced options in the descriptor file.</p>
</div>
<div class="paragraph">
<p>This first example tells Jetty not to expand the WAR file when deploying it.
This can help make it clear that users should not make changes to the temporary unpacked WAR because such changes do not persist, and therefore do not apply the next time the web application deploys.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/wiki&lt;/Set&gt;
&lt;Set name="war"&gt;&lt;SystemProperty name="myapp.home"/&gt;/myapp.war&lt;/Set&gt;
&lt;Set name="extractWAR"&gt;false&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The next example retrieves the JavaEE Servlet context and sets an initialization parameter on it.
The <code>setAttribute</code> method can also be used to set a Servlet context attribute.
However, since the <code>web.xml</code> for the web application is processed after the deployment descriptor, the <code>web.xml</code> values overwrite identically named attributes from the deployment descriptor.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/wiki&lt;/Set&gt;
&lt;Set name="war"&gt;&lt;SystemProperty name="myapp.home"/&gt;/myapp.war&lt;/Set&gt;
&lt;Get name="ServletContext"&gt;
&lt;Call name="setInitParameter"&gt;
&lt;Arg&gt;myapp.config&lt;/Arg&gt;
&lt;Arg&gt;&lt;SystemProperty name="myapp.home"&gt;/config/app-config.xml&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Get&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following example sets a special <code>web.xml</code> override descriptor.
This descriptor is processed after the web application&#8217;s <code>web.xml</code>, so it may override identically named attributes.
This feature is useful when adding parameters or additional Servlet mappings without breaking open a packed WAR file.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/wiki&lt;/Set&gt;
&lt;Set name="war"&gt;&lt;SystemProperty name="myapp.home"/&gt;/myapp.war&lt;/Set&gt;
&lt;Set name="overrideDescriptor"&gt;/opt/myapp/overlay-web.xml&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The next example configures not only the web application context, but also a database connection pool (see <a href="#jndi-datasource-examples">Datasource Examples</a>) that the application can then use.
If the <code>web.xml</code> does not include a reference to this data source, an override descriptor mechanism (as shown in the previous example) can be used to include it.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/wiki&lt;/Set&gt;
&lt;Set name="war"&gt;&lt;SystemProperty name="myapp.home"/&gt;/myapp.war&lt;/Set&gt;
&lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="org.apache.commons.dbcp.BasicDataSource"&gt;
&lt;Set name="driverClassName"&gt;org.some.Driver&lt;/Set&gt;
&lt;Set name="url"&gt;jdbc.url&lt;/Set&gt;
&lt;Set name="username"&gt;jdbc.user&lt;/Set&gt;
&lt;Set name="password"&gt;jdbc.pass&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>There are many other settings that can be changed in a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html"><code>WebAppContext</code></a>.
The <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html">javadoc</a> for <code>WebAppContext</code> is a good source of information.
Also see the documentation on <a href="#troubleshooting-zip-exceptions">avoiding zip file exceptions</a> for a description of <code>WebAppContext</code> settings that determine such things as whether or not the war is automatically unpacked during deployment, or whether certain sections of a webapp are copied to a temporary location.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="configuring-webapps"><a class="anchor" href="#configuring-webapps"></a><a class="link" href="#configuring-webapps">Deployment Processing of WebAppContexts</a></h3>
<div class="paragraph">
<p>Web applications require a certain amount of processing before they can go into service: they may need to be unpacked, a special classloader created for their jar files, <code>web.xml</code> and <code>web-fragment.xml</code> descriptors processed, and classes scanned for annotations amongst other things.
As web applications have become more complex, Jetty has added ways to assist with customization by either broadening or lessening the amount of processing that is done at deployment time.
This section will examine this processing and it can be tailored to fit individual needs.</p>
</div>
<div class="paragraph">
<p>If instead you&#8217;re looking for information on how to configure a specific <code>WebAppContext</code> - such as its context path, whether it should be unpacked or not - then you can find that in the section entitled <a href="#configuring-specific-webapp-deployment">Configuring a Specific WebApp Deployment</a>.</p>
</div>
<div class="sect3">
<h4 id="webapp-configurations"><a class="anchor" href="#webapp-configurations"></a><a class="link" href="#webapp-configurations">Configuration Classes</a></h4>
<div class="paragraph">
<p>As a webapp is being deployed, a series of <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/Configuration.html">org.eclipse.jetty.webapp.Configuration</a> classes are applied to it, each one performing a specific function.
The ordering of these Configurations is significant as subsequent Configurations tend to build on information extracted or setup in foregoing Configurations.
These are the default list, in order, of Configurations that are applied to each <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html">org.eclipse.jetty.webapp.WebAppContex</a>t:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 4. Default Configuration classes</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebInfConfiguration.html">org.eclipse.jetty.webapp.WebInfConfiguration</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Extracts war, orders jars and defines classpath</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebXmlConfiguration.html">org.eclipse.jetty.webapp.WebXmlConfiguration</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Processes a WEB-INF/web.xml file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/MetaInfConfiguration.html">org.eclipse.jetty.webapp.MetaInfConfiguration</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Looks in container and webapp jars for META-INF/resources and
META-INF/web-fragment.xml</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/FragmentConfiguration.html">org.eclipse.jetty.webapp.FragmentConfiguration</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Processes all discovered META-INF/web-fragment.xml files</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.html">org.eclipse.jetty.webapp.JettyWebXmlConfiguration</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Processes a WEB-INF/jetty-web.xml file</p></td>
</tr>
</tbody>
</table>
<div class="sect4">
<h5 id="_anatomy-of-a-configuration-class"><a class="anchor" href="#_anatomy-of-a-configuration-class"></a><a class="link" href="#_anatomy-of-a-configuration-class">Anatomy of a Configuration Class</a></h5>
<div class="paragraph">
<p>A Configuration class is called 5 times in different phases of the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html"><code>WebAppContext&#8217;s</code></a> lifecycle:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">preConfigure</dt>
<dd>
<p>As the <code>WebAppContext</code> is starting up this phase is executed.
The <code>Configuration</code> should discover any of the resources it will need during the subsequent phases.</p>
</dd>
<dt class="hdlist1">configure</dt>
<dd>
<p>This phase is where the work of the class is done, usually using the resources discovered during the <code>preConfigure</code> phase.</p>
</dd>
<dt class="hdlist1">postConfigure</dt>
<dd>
<p>This phase allows the <code>Configuration</code> to clear down any resources that may have been created during the previous 2 phases that are not needed for the lifetime of the <code>WebAppContext</code>.</p>
</dd>
<dt class="hdlist1">deconfigure</dt>
<dd>
<p>This phase occurs whenever a <code>WebAppContext</code> is being stopped and allows the Configuration to undo any resources/metadata that it created.
A <code>WebAppContext</code> should be able to be cleanly start/stopped multiple times without resources being held.</p>
</dd>
<dt class="hdlist1">destroy</dt>
<dd>
<p>This phase is called when a <code>WebAppContext</code> is actually removed from service.
For example, the war file associated with it is deleted from the $JETTY_HOME/webapps directory.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Each phase is called on each <code>Configuration</code> class in the order in which the <code>Configuration</code> class is listed.
Using the default <code>Configuration</code> classes as an example, <code>preConfigure()</code> will be called on <code>WebInfConfiguration</code>, <code>WebXmlConfiguration</code>, <code>MetaInfConfiguration</code>, <code>FragmentConfiguration</code> and then <code>JettyWebXmlConfiguration</code>.
The cycle begins again for the <code>configure()</code> phase and again for the <code>postConfigure()</code> phases.
The cycle is repeated <em>in reverse order</em> for the <code>deconfigure()</code> and eventually the <code>destroy()</code> phases.</p>
</div>
</div>
<div class="sect4">
<h5 id="_extending-container-support-by-creating-extra-configurations"><a class="anchor" href="#_extending-container-support-by-creating-extra-configurations"></a><a class="link" href="#_extending-container-support-by-creating-extra-configurations">Extending Container Support by Creating Extra Configurations</a></h5>
<div class="paragraph">
<p>As shown, there is a default set of Configurations that support basic deployment of a webapp.
JavaEE features such as JNDI and advanced servlet spec features such as annotations have not been mentioned.
Jetty&#8217;s philosophy is to allow the user to tailor the container exactly to their needs.
If these features are not needed, then Jetty does not pay the price for them - an important consideration because features such as annotations require extensive and time-consuming scanning of <code>WEB-INF/lib</code> jars.
As modern webapps may have scores of these jars, it can be a source of significant deployment delay.
We will see in the section <a href="#webapp-context-attributes">Other Configuration</a> another helpful webapp facility that Jetty provides for cutting down the time spent analyzing jars.</p>
</div>
<div class="paragraph">
<p>Jetty makes use of the flexibility of Configurations to make JNDI and annotation support pluggable.</p>
</div>
<div class="paragraph">
<p>Firstly, lets look at how Configurations help enable JNDI.</p>
</div>
<div class="sect5">
<h6 id="jndi-configuration-classes"><a class="anchor" href="#jndi-configuration-classes"></a><a class="link" href="#jndi-configuration-classes">Example: JNDI Configurations</a></h6>
<div class="paragraph">
<p>JNDI lookups within web applications require the container to hookup resources defined in the container&#8217;s environment to that of the web application.
To achieve that, we use 2 extra Configurations:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 5. JNDI Configuration classes</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/plus/webapp/EnvConfiguration.html">org.eclipse.jetty.plus.webapp.EnvConfiguration</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Creates <code>java:comp/env</code> for the webapp, applies a <code>WEB-INF/jetty-env.xml</code> file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/plus/webapp/PlusConfiguration.html">org.eclipse.jetty.plus.webapp.PlusConfiguration</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Processes JNDI related aspects of <code>WEB-INF/web.xml</code> and hooks up naming entries</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>These configurations must be added in <em>exactly</em> the order shown above and should be inserted <em>immediately before</em> the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.html">org.eclipse.jetty.webapp.JettyWebXmlConfiguration</a> class in the list of configurations.
To fully support JNDI additional configuration is required, full details of which can be found <a href="#jndi">here</a>.</p>
</div>
</div>
<div class="sect5">
<h6 id="_example-annotation-configurations"><a class="anchor" href="#_example-annotation-configurations"></a><a class="link" href="#_example-annotation-configurations">Example: Annotation Configurations</a></h6>
<div class="paragraph">
<p>We need just one extra Configuration class to help provide servlet annotation scanning:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 6. Annotation Configuration classes</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/annotations.AnnotationConfiguration.html">org.eclipse.jetty.annotations.AnnotationConfiguration</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Scan container and web app jars looking for @WebServlet, @WebFilter,
@WebListener etc</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The above configuration class must be <em>inserted immediately before</em> the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/JettyWebXmlConfiguration.html">org.eclipse.jetty.webapp.JettyWebXmlConfiguration</a> class in the list of configurations.
To fully support annotations additional configuration is require, details of which can be found <a href="#webapp-context-attributes">below.</a></p>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_how-to-set-the-list-of-configurations"><a class="anchor" href="#_how-to-set-the-list-of-configurations"></a><a class="link" href="#_how-to-set-the-list-of-configurations">How to Set the List of Configurations</a></h5>
<div class="paragraph">
<p>You have a number of options for how to make Jetty use a different list of Configurations.</p>
</div>
<div class="sect5">
<h6 id="_setting-the-list-directly-on-the-webappcontext"><a class="anchor" href="#_setting-the-list-directly-on-the-webappcontext"></a><a class="link" href="#_setting-the-list-directly-on-the-webappcontext">Setting the list directly on the WebAppContext</a></h6>
<div class="paragraph">
<p>If you have only one webapp that you wish to affect, this may be the easiest option.
You will, however, either need to have a context xml file that represents your web app, or you need to call the equivalent in code.
Let&#8217;s see an example of how we would add in the Configurations for both JNDI <em>and</em> annotations:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="war"&gt;&lt;SystemProperty name="jetty.base" default="."/&gt;/webapps/my-cool-webapp&lt;/Set&gt;
&lt;Set name="configurationClasses"&gt;
&lt;Array type="java.lang.String"&gt;
&lt;Item&gt;org.eclipse.jetty.webapp.WebInfConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.webapp.WebXmlConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.webapp.MetaInfConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.webapp.FragmentConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.plus.webapp.EnvConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.plus.webapp.PlusConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.annotations.AnnotationConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.webapp.JettyWebXmlConfiguration&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Of course, you can also use this method to reduce the Configurations applied to a specific <code>WebAppContext</code>.</p>
</div>
</div>
<div class="sect5">
<h6 id="_setting-the-list-for-all-webapps-via-the-deployer"><a class="anchor" href="#_setting-the-list-for-all-webapps-via-the-deployer"></a><a class="link" href="#_setting-the-list-for-all-webapps-via-the-deployer">Setting the list for all webapps via the Deployer</a></h6>
<div class="paragraph">
<p>If you use the <a href="#deployment-architecture">deployer</a>, you can set up the list of Configuration classes on the <a href="#default-web-app-provider">WebAppProvider</a>.
They will then be applied to each <code>WebAppContext</code> deployed by the deployer:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;Call name="addBean"&gt;
&lt;Arg&gt;
&lt;New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager"&gt;
&lt;Set name="contexts"&gt;
&lt;Ref refid="Contexts" /&gt;
&lt;/Set&gt;
&lt;Call id="webappprovider" name="addAppProvider"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.deploy.providers.WebAppProvider"&gt;
&lt;Set name="monitoredDirName"&gt;&lt;Property name="jetty.base" default="." /&gt;/webapps&lt;/Set&gt;
&lt;Set name="configurationClasses"&gt;
&lt;Array type="java.lang.String"&gt;
&lt;Item&gt;org.eclipse.jetty.webapp.WebInfConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.webapp.WebXmlConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.webapp.MetaInfConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.webapp.FragmentConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.plus.webapp.EnvConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.plus.webapp.PlusConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.annotations.AnnotationConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.webapp.JettyWebXmlConfiguration&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="_adding-or-inserting-to-an-existing-list"><a class="anchor" href="#_adding-or-inserting-to-an-existing-list"></a><a class="link" href="#_adding-or-inserting-to-an-existing-list">Adding or inserting to an existing list</a></h6>
<div class="paragraph">
<p>Instead of having to enumerate the list in its entirety, you can simply nominate classes that you want to add, and indicate whereabouts in the list you want them inserted.
Let&#8217;s look at an example of using this method to add in Configuration support for JNDI - as usual you can either do this in an xml file, or via equivalent code.
This example uses an xml file, in fact it is the <code>$JETTY_HOME/etc/jetty-plus.xml</code> file from the Jetty distribution:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;!-- =========================================================== --&gt;
&lt;!-- Add plus Configuring classes to all webapps for this Server --&gt;
&lt;!-- =========================================================== --&gt;
&lt;Call class="org.eclipse.jetty.webapp.Configuration$ClassList" name="setServerDefault"&gt;
&lt;Arg&gt;&lt;Ref refid="Server" /&gt;&lt;/Arg&gt;
&lt;Call name="addAfter"&gt;
&lt;Arg name="afterClass"&gt;org.eclipse.jetty.webapp.FragmentConfiguration&lt;/Arg&gt;
&lt;Arg&gt;
&lt;Array type="String"&gt;
&lt;Item&gt;org.eclipse.jetty.plus.webapp.EnvConfiguration&lt;/Item&gt;
&lt;Item&gt;org.eclipse.jetty.plus.webapp.PlusConfiguration&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/Configuration.html">org.eclipse.jetty.webapp.Configuration.ClassList</a> class provides these methods for insertion:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">addAfter</dt>
<dd>
<p>Inserts the supplied list of <code>Configuration</code> class names after the given Configuration class name.</p>
</dd>
<dt class="hdlist1">addBefore</dt>
<dd>
<p>Inserts the supplied list of <code>Configuration</code> class names before the given Configuration class name.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="webapp-context-attributes"><a class="anchor" href="#webapp-context-attributes"></a><a class="link" href="#webapp-context-attributes">Other Configuration</a></h4>
<div class="sect4">
<h5 id="container-include-jar-pattern"><a class="anchor" href="#container-include-jar-pattern"></a><a class="link" href="#container-include-jar-pattern">org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</a></h5>
<div class="paragraph">
<p>This is a <a href="#context_attributes">context attribute</a> that can be set on <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html">an org.eclipse.jetty.webapp.WebAppContext</a> to control which parts of the <em>container&#8217;s</em> classpath should be processed for things like annotations, <code>META-INF/resources</code>, <code>META-INF/web-fragment.xml</code> and <code>tlds</code> inside <code>META-INF</code>.</p>
</div>
<div class="paragraph">
<p>Normally, nothing from the container classpath will be included for processing.
However, sometimes you will need to include some.
For example, you may have some libraries that are shared amongst your webapps and thus you have put them into a <code>$JETTY_HOME/lib</code> directory.
The libraries contain annotations and therefore must be scanned.</p>
</div>
<div class="paragraph">
<p>The value of this attribute is a regexp that defines which <em>jars</em> and <em>class directories</em> from the container&#8217;s classpath should be examined.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example from a context xml file (although as always, you could have accomplished the same in code), which would match any jar whose name starts with "foo-" or "bar-", or a directory named "classes":</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Call name="setAttribute"&gt;
&lt;Arg&gt;org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern&lt;/Arg&gt;
&lt;Arg&gt;.*/foo-[^/]*\.jar$|.*/bar-[^/]*\.jar$|.*/classes/.*&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that the order of the patterns defines the ordering of the scanning of the jars or class directories.</p>
</div>
</div>
<div class="sect4">
<h5 id="web-inf-include-jar-pattern"><a class="anchor" href="#web-inf-include-jar-pattern"></a><a class="link" href="#web-inf-include-jar-pattern">org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</a></h5>
<div class="paragraph">
<p>Similarly to the previous <a href="#context_attributes">context attribute</a>, this attribute controls which jars are processed for things like annotations, <code>META-INF/resources</code>, <code>META-INF/web-fragment.xml</code> and <code>tlds</code> in <code>META-INF</code>.
However, this attribute controls which jars from the <em>webapp&#8217;s</em> classpath (usually <code>WEB-INF/lib</code>) are processed.
This can be particularly useful when you have dozens of jars in <code>WEB-INF/lib</code>, but you know that only a few need to be scanned.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example in a xml file of a pattern that matches any jar that starts with <code>spring-</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Call name="setAttribute"&gt;
&lt;Arg&gt;org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern&lt;/Arg&gt;
&lt;Arg&gt;.*/spring-[^/]*\.jar$&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that the order of the patterns defines the ordering of the scanning of jar files.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="static-content-deployment"><a class="anchor" href="#static-content-deployment"></a><a class="link" href="#static-content-deployment">Configuring Static Content Deployment</a></h3>
<div class="paragraph">
<p>To serve purely static content, the Jetty Deployment Descriptor XML concepts and the internal <code>ResourceHandler</code> can be used.
Create a file called <code>scratch.xml</code> in the <code>${jetty.base}/webapps</code> directory and paste the following file contents in it.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.server.handler.ContextHandler"&gt;
&lt;Set name="contextPath"&gt;/scratch&lt;/Set&gt;
&lt;Set name="handler"&gt;
&lt;New class="org.eclipse.jetty.server.handler.ResourceHandler"&gt;
   &lt;Set name="resourceBase"&gt;/home/scratch&lt;/Set&gt;
&lt;Set name="directoriesListed"&gt;true&lt;/Set&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This is a very basic setup for serving static files.
For advanced static file serving, use the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlet/DefaultServlet.html">DefaultServlet</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="deployment-architecture"><a class="anchor" href="#deployment-architecture"></a><a class="link" href="#deployment-architecture">Deployment Architecture</a></h3>
<div class="paragraph">
<p>Jetty is built around an extensible Deployment Manager architecture complete with formal LifeCycle for Web Applications going through it.</p>
</div>
<div class="paragraph">
<p>For Jetty to serve content (static or dynamic), a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ContextHandler.html">ContextHandler</a> needs to be configured and added to Jetty in the appropriate location.
A pluggable <code>DeploymentManager</code> exists to make this process easier.
The Jetty distribution contains example <code>DeploymentManager</code> configurations to deploy WAR files found in a directory to Jetty, and to deploy Jetty context xml files into Jetty as well.</p>
</div>
<div class="paragraph">
<p>The <code>DeploymentManager</code> is the heart of the typical webapp deployment mechanism; it operates as a combination of an Application LifeCycle Graph, Application Providers that find and provide Applications into the Application LifeCycle Graph, and a set of bindings in the graph that control the deployment process.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="Jetty_DeployManager_DeploymentManager_Roles.png" alt="image" width="195"></span></p>
</div>
<div class="sect3">
<h4 id="udm-application-providers"><a class="anchor" href="#udm-application-providers"></a><a class="link" href="#udm-application-providers">Application Providers</a></h4>
<div class="paragraph">
<p>Before Jetty deploys an application, an <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/deploy/AppProvider.html"><code>AppProvider</code></a> identifies the App and then provides it to the <code>DeploymentManager</code>.
The main <code>AppProvider</code> with the Jetty distribution is the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/deploy/providers/WebAppProvider.html"><code>WebAppProvider</code>.</a></p>
</div>
</div>
<div class="sect3">
<h4 id="udm-application-lifecycle-graph"><a class="anchor" href="#udm-application-lifecycle-graph"></a><a class="link" href="#udm-application-lifecycle-graph">Application LifeCycle Graph</a></h4>
<div class="paragraph">
<p>The core feature of the <code>DeploymentManager</code> is the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/deploy/AppLifeCycle.html">Application LifeCycle Graph</a>.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="Jetty_DeployManager_AppLifeCycle-1.png" alt="image" width="340"></span></p>
</div>
<div class="paragraph">
<p>The nodes and edges of this graph are pre-defined in Jetty along the most common actions and states found.
These nodes and edges are not hardcoded; they can be adjusted and added to depending on need (for example, any complex requirements for added workflow, approvals, staging, distribution, coordinated deploys for a cluster or cloud, etc.).</p>
</div>
<div class="paragraph">
<p>New applications enter this graph at the Undeployed node, and the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/deploy/DeploymentManager.html#requestAppGoal(org.eclipse.jetty.deploy.App"><code>java.lang.String DeploymentManager.requestAppGoal(App,String)</code></a> method pushes them through the graph.</p>
</div>
</div>
<div class="sect3">
<h4 id="udm-lifecycle-bindings"><a class="anchor" href="#udm-lifecycle-bindings"></a><a class="link" href="#udm-lifecycle-bindings">LifeCycle Bindings</a></h4>
<div class="paragraph">
<p>A set of default <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/deploy/AppLifeCycle.Binding.html"><code>AppLifeCycle.Bindings</code></a> defines standard behavior, and handles deploying, starting, stopping, and undeploying applications.
If desired, custom <code>AppLifeCycle.Bindings</code> can be written and assigned anywhere on the Application LifeCycle graph.</p>
</div>
<div class="paragraph">
<p>Examples of new <code>AppLifeCycle.Binding</code> implementations that can be developed include:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Validating the incoming application.</p>
</li>
<li>
<p>Preventing the deployment of known forbidden applications.</p>
</li>
<li>
<p>Submitting the installation to an application auditing service in a corporate environment.</p>
</li>
<li>
<p>Distributing the application to other nodes in the cluster or cloud.</p>
</li>
<li>
<p>Emailing owner/admin of change of state of the application.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>There are four default bindings:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/deploy/bindings/StandardDeployer.html"><code>StandardDeployer</code></a> — Deploys the ContextHandler into Jetty in the appropriate place.</p>
</li>
<li>
<p><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/deploy/bindings/StandardStarter.html"><code>StandardStarter</code></a> — Sets the ContextHandler to started and start accepting incoming requests.</p>
</li>
<li>
<p><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/deploy/bindings/StandardStopper.html"><code>StandardStopper</code></a> — Stops the ContextHandler and stops accepting incoming requests.</p>
</li>
<li>
<p><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/deploy/bindings/StandardUndeployer.html"><code>StandardUndeployer</code></a> — Removes the ContextHandler from Jetty.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p><span class="image"><img src="Jetty_DeployManager_DefaultAppLifeCycleBindings.png" alt="image" width="851"></span></p>
</div>
<div class="paragraph">
<p>A fifth, non-standard binding, called <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/deploy/bindings/DebugBinding.html">DebugBinding</a>, is also available for debugging reasons; it logs the various transitions through the Application LifeCycle.</p>
</div>
<div class="sect4">
<h5 id="_using-globalwebappconfigbinding"><a class="anchor" href="#_using-globalwebappconfigbinding"></a><a class="link" href="#_using-globalwebappconfigbinding">Using GlobalWebappConfigBinding</a></h5>
<div class="paragraph">
<p>In addition to the LifeCycle bindings discussed above, there is also the <a href="https://www.eclipse.org/jetty/javadoc/current/org/eclipse/jetty/deploy/bindings/GlobalWebappConfigBinding.html"><code>GlobalWebappConfigBinding</code></a> which, when added to the <code>DeploymentManager</code> will apply an additional configuration XML file to each webapp that it deploys.
This can useful when setting server or system classes, or when defining <a href="#override-web-xml">override descriptors.</a>
This configuration XML file will be <em>in addition to</em> any context XML file that exists for the webapp; it will be applied <em>after</em> any context XML files but <em>before</em> the webapp is started.
The format for the XML file is the same as any context XML file and can be used to same parameters for a webapp.</p>
</div>
<div class="paragraph">
<p>To use this binding, you can either modify the existing <code>jetty-deploy.xml</code> which comes with the Jetty distribution (be sure to <a href="#startup-base-and-home">copy it to your $JETTY_BASE/etc directory first</a>), or by <a href="#custom-modules">creating a new module</a> file which calls to an additional XML file.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;Call name="addLifeCycleBinding"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.deploy.bindings.GlobalWebappConfigBinding" &gt;
&lt;Set name="jettyXml"&gt;&lt;Property name="jetty.home" default="." /&gt;/etc/global-webapp-config.xml&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="default-web-app-provider"><a class="anchor" href="#default-web-app-provider"></a><a class="link" href="#default-web-app-provider">Understanding the Default WebAppProvider</a></h4>
<div class="paragraph">
<p>The <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/deploy/providers/WebAppProvider.html">WebAppProvider</a> is used for the deployment of Web Applications packaged as WAR files, expanded as a directory, or declared in a <a href="#deployable-descriptor-file">Jetty Deployable Descriptor XML File</a>.
It supports hot (re)deployment.</p>
</div>
<div class="paragraph">
<p>The basic operation of the <code>WebAppProvider</code> is to periodically scan a directory for deployables.
In the standard Jetty Distribution, this is configured in the <code>${jetty.home}/etc/jetty-deploy.xml</code> file.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;Call name="addBean"&gt;
&lt;Arg&gt;
&lt;New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager"&gt;
&lt;Set name="contexts"&gt;
&lt;Ref refid="Contexts" /&gt;
&lt;/Set&gt;
&lt;Call id="webappprovider" name="addAppProvider"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.deploy.providers.WebAppProvider"&gt;
&lt;Set name="monitoredDirName"&gt;&lt;Property name="jetty.home" default="." /&gt;/webapps&lt;/Set&gt;
&lt;Set name="defaultsDescriptor"&gt;&lt;Property name="jetty.home" default="." /&gt;/etc/webdefault.xml&lt;/Set&gt;
&lt;Set name="scanInterval"&gt;1&lt;/Set&gt;
&lt;Set name="extractWars"&gt;true&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above configuration will create a <code>DeploymentManager</code> tracked as a Server LifeCycle Bean, with the following configuration.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">contexts</dt>
<dd>
<p>A passed in reference to the HandlerContainer into which the discovered webapps are deployed.
This is normally a reference that points to the <code>id="Contexts"</code> found in the <code>${jetty.home}/etc/jetty.xml</code> file, which itself is an instance of <code>ContextHandlerCollection</code>.</p>
</dd>
<dt class="hdlist1">monitoredDirName</dt>
<dd>
<p>The file path or URL to the directory to scan for web applications.</p>
<div class="literalblock">
<div class="content">
<pre>Scanning follows these rules:</pre>
</div>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>A base directory must exist.</p>
</li>
<li>
<p>Hidden Files (starting with <code>"."</code>) are ignored.</p>
</li>
<li>
<p>Directories with names ending in <code>".d"</code> are ignored.</p>
</li>
<li>
<p>Common CVS directories <code>"CVS"</code> and <code>"CVSROOT"</code> are ignored.</p>
</li>
<li>
<p>Any <code>*.war</code> files are considered <a href="#automatic-webapp-deployment">automatic deployables</a>.</p>
</li>
<li>
<p>Any <code>*.xml</code> files are considered <a href="#deployable-descriptor-file">context descriptor deployables</a>.</p>
</li>
<li>
<p>In the special case where both a WAR file and XML file exists for same base name, the XML file is assumed to configure and reference the WAR file (see <a href="#configuring-specific-webapp-deployment">Configuring a Specific Web Application Deployment</a>).
Since jetty-9.2.7, if either the WAR file or its corresponding XML file changes, the webapp will be redeployed.</p>
</li>
<li>
<p>A directory is considered to be deployable.</p>
</li>
<li>
<p>In the special case where both a Directory and WAR file of the same name exists, the WAR file is assumed to be an automatic deployable.</p>
</li>
<li>
<p>In the special case where both a Directory and XML file of the same name exists, the XML file is assumed to configure and reference the Directory.</p>
</li>
<li>
<p>All other directories are subject to automatic deployment.</p>
</li>
<li>
<p>If automatic deployment is used, and the special filename <code>root.war/ROOT.war</code> or directory name <code>root/ROOT</code> will result in a deployment to the <code>"/"</code> context path.</p>
</li>
</ol>
</div>
</dd>
<dt class="hdlist1">defaultsDescriptor</dt>
<dd>
<p>Specifies the default Servlet web descriptor to use for all Web Applications.
The intent of this descriptor is to include common configuration for the Web Application before the Web Application&#8217;s own <code>/WEB-INF/web.xml</code> is applied.
The <code>${jetty.home}/etc/webdefault.xml</code> that comes with the Jetty distribution controls the configuration of the JSP and Default servlets, along with MIME-types and other basic metadata.</p>
</dd>
<dt class="hdlist1">scanInterval</dt>
<dd>
<p>The period in seconds between sweeps of the <code>monitoredDirName</code> for changes: new contexts to deploy, changed contexts to redeploy, or removed contexts to undeploy.</p>
</dd>
<dt class="hdlist1">extractWars</dt>
<dd>
<p>If parameter is true, any packed WAR or zip files are first extracted to a temporary directory before being deployed.
This is advisable if there are uncompiled JSPs in the web apps.</p>
</dd>
<dt class="hdlist1">parentLoaderPriority</dt>
<dd>
<p>Parameter is a boolean that selects whether the standard Java <a href="#jetty-classloading">parent first delegation</a> is used or the <a href="#jetty-classloading">servlet specification webapp classloading priority</a>.
The latter is the default.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect2">
<h3 id="quickstart-webapp"><a class="anchor" href="#quickstart-webapp"></a><a class="link" href="#quickstart-webapp">Quickstart Webapps</a></h3>
<div class="paragraph">
<p>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 of a webapp as it allows new features and frameworks to be enabled simply by dropping in a jar file.
However, for deployment, the need to scan the contents of many jars can have a significant impact of the start time of a webapp.</p>
</div>
<div class="paragraph">
<p>With the release of Jetty 9.2, a quickstart module was included which allows a webapp to be pre-scanned and preconfigured.
This means that all the scanning is done prior to deployment and all configuration is encoded into an effective <code>web.xml</code>, called <code>WEB-INF/quickstart-web.xml</code>, which can be inspected to understand what will be deployed before deploying.
Not only does the <code>quickstart-web.xml</code> contain all the discovered Servlets, Filters and Constraints, but it also encodes as context parameters all discovered:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>ServletContainerInitializers</p>
</li>
<li>
<p>HandlesTypes classes</p>
</li>
<li>
<p>Taglib Descriptors</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>With the quickstart mechanism, Jetty is able to entirely bypass all scanning and discovery modes and start a webapp in a predictable and fast way.
Tests have shown that webapps that took many seconds to scan and deploy can now be deployed in a few hundred milliseconds.</p>
</div>
<div class="sect3">
<h4 id="_setting-up-quickstart"><a class="anchor" href="#_setting-up-quickstart"></a><a class="link" href="#_setting-up-quickstart">Setting up Quickstart</a></h4>
<div class="sect4">
<h5 id="_prerequisites"><a class="anchor" href="#_prerequisites"></a><a class="link" href="#_prerequisites">Prerequisites</a></h5>
<div class="sect5">
<h6 id="_jetty-distribution-2"><a class="anchor" href="#_jetty-distribution-2"></a><a class="link" href="#_jetty-distribution-2">Jetty Distribution</a></h6>
<div class="paragraph">
<p>In a standard Jetty distribution the quickstart module can be configured with the following command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ java -jar $JETTY_HOME/start.jar --add-to-start=quickstart</code></pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="_embedded"><a class="anchor" href="#_embedded"></a><a class="link" href="#_embedded">Embedded</a></h6>
<div class="paragraph">
<p>In a Maven project you add a dependency on the artifact <code>jetty-quickstart</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-quickstart&lt;/artifactId&gt;
&lt;version&gt;10.0.0-SNAPSHOT&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_configuration"><a class="anchor" href="#_configuration"></a><a class="link" href="#_configuration">Configuration</a></h5>
<div class="paragraph">
<p>Webapps need to be instances of <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/quickstart/QuickStartWebApp.html"><code>org.eclipse.jetty.quickstart.QuickStartWebApp</code></a> rather than the normal <code>org.eclipse.jetty.webapp.WebAppContext</code>.</p>
</div>
<div class="paragraph">
<p><code>org.eclipse.jetty.quickstart.QuickStartWebApp</code> instances offer the same setters as the familiar <code>org.eclipse.jetty.webapp.WebAppContext</code>, with the addition of:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">autoPreconfigure</dt>
<dd>
<p>(true/false).
If true, the first time the webapp is run, the WEB-INF/quickstart-web.xml is generated BEFORE the webapp is deployed.
Subsequent runs use the previously generated quickstart file.</p>
</dd>
<dt class="hdlist1">originAttribute</dt>
<dd>
<p>The name of an attribute to insert into the generated elements in quickstart-web.xml that gives the origin of the element.
By default it is <code>origin</code>.</p>
</dd>
<dt class="hdlist1">generateOrigin</dt>
<dd>
<p>(true/false).
By default it is <code>false</code>.
If true, the origin attribute will be inserted into each element in quickstart-web.xml.
Note that origin attributes will also be generated if debug log level is enabled.</p>
</dd>
</dl>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If you are using Spring-Boot you must set <code>generateOrigin</code> to true.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>The origin is either a descriptor eg web.xml,web-fragment.xml,override-web.xml file, or an annotation eg @WebServlet.
For xml validation each attribute must be unique, and therefore an integer counter is appended to each value.
Some examples of elements with origin attribute information are:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;listener origin="DefaultsDescriptor(file:///path/to/distro/etc/webdefault.xml):21"&gt;
&lt;listener origin="WebDescriptor(file:///path/to/base/webapps/test-spec/WEB-INF/web.xml):22"&gt;
&lt;servlet-class origin="FragmentDescriptor(jar:file:///path/to/base/webapps/test-spec/WEB-INF/lib/test-web-fragment.jar!/META-INF/web-fragment.xml):23"&gt;
&lt;servlet-class origin="@WebServlet(com.acme.test.TestServlet):24"&gt;</code></pre>
</div>
</div>
<div class="sect5">
<h6 id="_in-xml"><a class="anchor" href="#_in-xml"></a><a class="link" href="#_in-xml">In XML</a></h6>
<div class="paragraph">
<p>If a web application already has a context xml file, eg <code>webapps/myapp.xml</code> file, simply change the class in the <code>Configure</code> element.
Otherwise, create a context xml file with the following information (in addition to the usual setting of contextPath, war etc):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.quickstart.QuickStartWebApp"&gt;
&lt;Set name="autoPreconfigure"&gt;true&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="_in-code"><a class="anchor" href="#_in-code"></a><a class="link" href="#_in-code">In Code</a></h6>
<div class="paragraph">
<p>Create an instance of <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/quickstart/QuickStartWebApp.html"><code>org.eclipse.jetty.quickstart.QuickStartWebApp</code></a> rather than the normal <code>org.eclipse.jetty.webapp.WebAppContext</code>. You then use the QuickStartWebApp instance in exactly the same way that you would a WebAppContext.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s a snippet:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java"> QuickStartWebApp webapp = new QuickStartWebApp();
webapp.setAutoPreconfigure(true);</code></pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="_pre-generating-the-quickstart-web-xml-file"><a class="anchor" href="#_pre-generating-the-quickstart-web-xml-file"></a><a class="link" href="#_pre-generating-the-quickstart-web-xml-file">Pre-generating the quickstart-web.xml file</a></h6>
<div class="paragraph">
<p>Rather than use the <code>autoPreconfigure</code> feature of the QuickStartWebApp - which lazily generates the <code>quickstart-web.xml</code> file - you can eagerly pre-generate it for an existing war by invoking as a main class <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/quickstart/PreconfigureQuickStartWar.html"><code>org.eclipse.jetty.quickstart.PreconfigureQuickStartWar</code></a>.
Note that you will need to provide all necessary jetty jars on the command line classpath.
This will unpack the war if necessary, and create the <code>quickstart-web.xml</code> before the first deployment:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ java -cp [jetty classpath] org.eclipse.jetty.quickstart.PreconfigureQuickStartWar myapp.war</code></pre>
</div>
</div>
<div class="paragraph">
<p>Run the class with no arguments to see other runtime options.</p>
</div>
<div class="paragraph">
<p>Alternatively, you could use the <a href="#get-up-and-running">Jetty Maven Plugin</a> goal <a href="#jetty-effective-web-xml"><code>jetty:effective-web-xml</code></a>: this will generate quickstart information, but print it to stderr.
The goal provides a configuration option to save the output to a file, which you can then copy into your webapp&#8217;s WEB-INF dir.
Note that as the Jetty Maven Plugin is a general tool for running webapps, it may have more jars on its classpath than are needed by your application, and thus may generate extra quickstart information: we recommend that you use this goal only as a quick guide to the type of information that quickstart generates.</p>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_avoiding-tld-scans-with-precompiled-jsps"><a class="anchor" href="#_avoiding-tld-scans-with-precompiled-jsps"></a><a class="link" href="#_avoiding-tld-scans-with-precompiled-jsps">Avoiding TLD Scans with precompiled JSPs</a></h4>
<div class="paragraph">
<p>Of course precompiling JSPs is an excellent way to improve the start time of a web application.
As of Jetty 9.2 the Apache Jasper JSP implementation has been used and has been augmented to allow the TLD scan to be skipped.
This can be done by adding a <code>context-param</code> to the <code>web.xml</code> file (this is done automatically by the Jetty Maven JSPC plugin):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;context-param&gt;
&lt;param-name&gt;org.eclipse.jetty.jsp.precompiled&lt;/param-name&gt;
&lt;param-value&gt;true&lt;/param-value&gt;
&lt;/context-param&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_bypassing-start-jar"><a class="anchor" href="#_bypassing-start-jar"></a><a class="link" href="#_bypassing-start-jar">Bypassing start.jar</a></h4>
<div class="paragraph">
<p>The Jetty <code>start.jar</code> mechanism is a very powerful and flexible mechanism for constructing a <code>classpath</code> and executing a configuration encoded in Jetty XML format.
However, this mechanism does take some time to build the <code>classpath</code>.
The start.jar mechanism can be bypassed by using the <code>–dry-run</code> option to generate and reuse a complete command line to start Jetty at a later time:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ RUN=$(java -jar $JETTY_HOME/start.jar --dry-run)
$ eval $RUN</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that <code>--dry-run</code> may create a properties file in the temp directory and include it on the generated command line.
If so, then a copy of the temporary properties file should be taken and the command line updated with it&#8217;s new persistent location.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="advanced-embedding"><a class="anchor" href="#advanced-embedding"></a><a class="link" href="#advanced-embedding">Embedding</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="jetty-helloworld"><a class="anchor" href="#jetty-helloworld"></a><a class="link" href="#jetty-helloworld">Jetty Embedded HelloWorld</a></h3>
<div class="paragraph">
<p>This section provides a tutorial that shows how you can quickly develop embedded code against the Jetty API.</p>
</div>
<div class="sect3">
<h4 id="downloading-jars"><a class="anchor" href="#downloading-jars"></a><a class="link" href="#downloading-jars">Downloading the Jars</a></h4>
<div class="paragraph">
<p>Jetty is decomposed into many jars and dependencies to achieve a minimal footprint by selecting the minimal set of jars.
Typically it is best to use something like <a href="#jetty-maven-helloworld">Maven</a> to manage jars, however this tutorial uses an aggregate Jar that contains all of the required Jetty classes in one Jar.
You can manually download the aggregate <a href="https://repo1.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all/10.0.0-SNAPSHOT/jetty-all-10.0.0-SNAPSHOT-uber.jar"><code>jetty-all.jar</code></a> using <code>curl</code> or a browser.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The central Maven repository has started to aggressively reject/deny access to the repository from the <code>wget</code> command line tool (due to abusive use of the tool by some groups).
The administrators of the central maven repository have stated that the recommended command line download tool is now curl.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
The <code>jetty-all</code> jar referenced in this section is for example purposes only and should not be used outside of this context.
Please consider using <a href="#jetty-maven-helloworld">Maven</a> to manage your project dependencies.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Use curl as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; mkdir Demo
&gt; cd Demo
&gt; curl -o jetty-all-uber.jar https://repo1.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all/10.0.0-SNAPSHOT/jetty-all-10.0.0-SNAPSHOT-uber.jar</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="writing-helloworld-example"><a class="anchor" href="#writing-helloworld-example"></a><a class="link" href="#writing-helloworld-example">Writing a HelloWorld Example</a></h4>
<div class="paragraph">
<p>The <a href="#embedding">Embedding Jetty</a> section contains many examples of writing against the Jetty API.
This tutorial uses a simple HelloWorld handler with a main method to run the server.
You can either <a href="https://github.com/eclipse/jetty.project/tree/master/examples/embedded/src/main/java/org/eclipse/jetty/embedded/HelloWorld.java">download</a> or create in an editor the file <code>HelloWorld.java</code> with the following content:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/jetty-helloworld.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/HelloWorld.java[]</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="compiling-helloworld-example"><a class="anchor" href="#compiling-helloworld-example"></a><a class="link" href="#compiling-helloworld-example">Compiling the HelloWord example</a></h4>
<div class="paragraph">
<p>The following command compiles the HelloWorld class:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; mkdir classes
&gt; javac -d classes -cp jetty-all-uber.jar HelloWorld.java</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="running-handler-and-server"><a class="anchor" href="#running-handler-and-server"></a><a class="link" href="#running-handler-and-server">Running the Handler and Server</a></h4>
<div class="paragraph">
<p>The following command runs the HelloWorld example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -cp classes:jetty-all-uber.jar org.eclipse.jetty.demos.HelloWorld</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can now point your browser at <a href="http://localhost:8080/">http://localhost:8080</a> to see your hello world page.</p>
</div>
</div>
<div class="sect3">
<h4 id="next-steps"><a class="anchor" href="#next-steps"></a><a class="link" href="#next-steps">Next Steps</a></h4>
<div class="paragraph">
<p>To learn more about Jetty, take these next steps:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Follow the examples in <a href="#embedding-jetty">Embedding Jetty</a> to better understand the jetty APIs.</p>
</li>
<li>
<p>Explore the complete <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/">Jetty javadoc</a></p>
</li>
<li>
<p>Consider using <a href="#maven-and-jetty">Jetty and Maven</a> to manage your Jars and dependencies.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="embedding-jetty"><a class="anchor" href="#embedding-jetty"></a><a class="link" href="#embedding-jetty">Embedding Jetty</a></h3>
<div class="paragraph">
<p>Jetty has a slogan, "<em>Don&#8217;t deploy your application in Jetty, deploy Jetty in your application!</em>"
What this means is that as an alternative to bundling your application as a standard WAR to be deployed in Jetty, Jetty is designed to be a software component that can be instantiated and used in a Java program just like any POJO.
Put another way, running Jetty in embedded mode means putting an HTTP module into your application, rather than putting your application into an HTTP server.</p>
</div>
<div class="paragraph">
<p>This tutorial takes you step-by-step from the simplest Jetty server instantiation to running multiple web applications with standards-based deployment descriptors.
The source for most of these examples is part of the standard Jetty project.</p>
</div>
<div class="sect3">
<h4 id="_overview"><a class="anchor" href="#_overview"></a><a class="link" href="#_overview">Overview</a></h4>
<div class="paragraph">
<p>To embed a Jetty server the following steps are typical and are illustrated by the examples in this tutorial:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Create a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/Server.html">Server</a> instance.</p>
</li>
<li>
<p>Add/Configure <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/Connector.html">Connectors</a>.</p>
</li>
<li>
<p>Add/Configure <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/Handler.html">Handlers</a> and/or <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ContextHandler.html">Contexts</a> and/or <a href="http://docs.oracle.com/javaee/6/api/javax/servlet/Servlet.html">Servlets</a>.</p>
</li>
<li>
<p>Start the Server.</p>
</li>
<li>
<p>Wait on the server or do something else with your thread.</p>
</li>
</ol>
</div>
</div>
<div class="sect3">
<h4 id="_creating-the-server"><a class="anchor" href="#_creating-the-server"></a><a class="link" href="#_creating-the-server">Creating the Server</a></h4>
<div class="paragraph">
<p>The following code from SimplestServer.java instantiates and runs the simplest possible Jetty server:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/embedding-jetty.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/SimplestServer.java[]</code></pre>
</div>
</div>
<div class="paragraph">
<p>This runs an HTTP server on port 8080. It is not a very useful server as it has no handlers, and thus returns a 404 error for every request.</p>
</div>
</div>
<div class="sect3">
<h4 id="_using-handlers"><a class="anchor" href="#_using-handlers"></a><a class="link" href="#_using-handlers">Using Handlers</a></h4>
<div class="paragraph">
<p>To produce a response to a request, Jetty requires that you set a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/Handler.html">Handler</a> on the server.
A handler may:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Examine/modify the HTTP request.</p>
</li>
<li>
<p>Generate the complete HTTP response.</p>
</li>
<li>
<p>Call another Handler (see <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/HandlerWrapper.html"><code>HandlerWrapper</code></a>).</p>
</li>
<li>
<p>Select one or many Handlers to call (see <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/HandlerCollection.html"><code>HandlerCollection</code></a>).</p>
</li>
</ul>
</div>
<div class="sect4">
<h5 id="_helloworld-handler"><a class="anchor" href="#_helloworld-handler"></a><a class="link" href="#_helloworld-handler">HelloWorld Handler</a></h5>
<div class="paragraph">
<p>The following code based on HelloHandler.java shows a simple hello world handler:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/embedding-jetty.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/HelloHandler.java[]</code></pre>
</div>
</div>
<div class="paragraph">
<p>The parameters passed to the handle method are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>target</code> – the target of the request, which is either a URI or a name from a named dispatcher.</p>
</li>
<li>
<p><code>baseRequest</code> – the Jetty mutable request object, which is always unwrapped.</p>
</li>
<li>
<p><code>request</code> – the immutable request object, which may have been wrapped by a filter or servlet.</p>
</li>
<li>
<p><code>response</code> – the response, which may have been wrapped by a filter or servlet.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The handler sets the response status, content-type, and marks the request as handled before it generates the body of the response using a writer.</p>
</div>
</div>
<div class="sect4">
<h5 id="_running-helloworldhandler"><a class="anchor" href="#_running-helloworldhandler"></a><a class="link" href="#_running-helloworldhandler">Running HelloWorldHandler</a></h5>
<div class="paragraph">
<p>To allow a Handler to handle HTTP requests, you must add it to a Server instance.
The following code from OneHandler.java shows how a Jetty server can use the HelloWorld handler:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/embedding-jetty.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneHandler.java[]</code></pre>
</div>
</div>
<div class="paragraph">
<p>One or more handlers do all request handling in Jetty.
Some handlers select other specific handlers (for example, a <code>ContextHandlerCollection</code> uses the context path to select a <code>ContextHandler</code>); others use application logic to generate a response (for example, the <code>ServletHandler</code> passes the request to an application Servlet), while others do tasks unrelated to generating the response (for example, <code>RequestLogHandler</code> or <code>StatisticsHandler</code>).</p>
</div>
<div class="paragraph">
<p>Later sections describe how you can combine handlers like aspects.
You can see some of the handlers available in Jetty in the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/package-summary.html">org.eclipse.jetty.server.handler</a> package.</p>
</div>
</div>
<div class="sect4">
<h5 id="_handler-collections-and-wrappers"><a class="anchor" href="#_handler-collections-and-wrappers"></a><a class="link" href="#_handler-collections-and-wrappers">Handler Collections and Wrappers</a></h5>
<div class="paragraph">
<p>Complex request handling is typically built from multiple Handlers that you can combine in various ways.
Jetty has several implementations of the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/HandlerContainer.html"><code>HandlerContainer</code></a> interface:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/HandlerCollection.html"><code>HandlerCollection</code></a></dt>
<dd>
<p>Holds a collection of other handlers and calls each handler in order.
This is useful for combining statistics and logging handlers with the handler that generates the response.</p>
</dd>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/HandlerList.html"><code>HandlerList</code></a></dt>
<dd>
<p>A Handler Collection that calls each handler in turn until either an exception is thrown, the response is committed or the <code>request.isHandled()</code> returns true.
You can use it to combine handlers that conditionally handle a request, such as calling multiple contexts until one matches a virtual host.</p>
</dd>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/HandlerWrapper.html"><code>HandlerWrapper</code></a></dt>
<dd>
<p>A Handler base class that you can use to daisy chain handlers together in the style of aspect-oriented programming.
For example, a standard web application is implemented by a chain of a context, session, security and servlet handlers.</p>
</dd>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ContextHandlerCollection.html"><code>ContextHandlerCollection</code></a></dt>
<dd>
<p>A specialized <code>HandlerCollection</code> that uses the longest prefix of the request URI (the <code>contextPath</code>) to select a contained <code>ContextHandler</code> to handle the request.</p>
</dd>
</dl>
</div>
</div>
<div class="sect4">
<h5 id="_scoped-handlers"><a class="anchor" href="#_scoped-handlers"></a><a class="link" href="#_scoped-handlers">Scoped Handlers</a></h5>
<div class="paragraph">
<p>Much of the standard Servlet container in Jetty is implemented with <code>HandlerWrappers</code> that daisy chain handlers together: <code>ContextHandler</code> to <code>SessionHandler</code> to <code>SecurityHandler</code> to <code>ServletHandler</code>.
However, because of the nature of the servlet specification, this chaining cannot be a pure nesting of handlers as the outer handlers sometimes need information that the inner handlers process.
For example, when a <code>ContextHandler</code> calls some application listeners to inform them of a request entering the context, it must already know which servlet the <code>ServletHandler</code> will dispatch the request to so that the <code>servletPath</code> method returns the correct value.</p>
</div>
<div class="paragraph">
<p>The <code>HandlerWrapper</code> is specialized to the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ScopedHandler.html"><code>ScopedHandler</code></a> abstract class, which supports a daisy chain of scopes.
For example if a <code>ServletHandler</code> is nested within a <code>ContextHandler</code>, the order and nesting of execution of methods is:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>Server.handle(...)
ContextHandler.doScope(...)
ServletHandler.doScope(...)
ContextHandler.doHandle(...)
ServletHandler.doHandle(...)
SomeServlet.service(...)</pre>
</div>
</div>
<div class="paragraph">
<p>Thus when the <code>ContextHandler</code> handles the request, it does so within the scope the <code>ServletHandler</code> has established.</p>
</div>
</div>
<div class="sect4">
<h5 id="_resource-handler"><a class="anchor" href="#_resource-handler"></a><a class="link" href="#_resource-handler">Resource Handler</a></h5>
<div class="paragraph">
<p>The <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/embedded/FileServer.html">FileServer example</a> shows how you can use a <code>ResourceHandler</code> to serve static content from the current working directory:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/embedding-jetty.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/FileServer.java[]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Notice that a <code>HandlerList</code> is used with the <code>ResourceHandler</code> and a <code>DefaultHandler</code>, so that the <code>DefaultHandler</code> generates a good 404 response for any requests that do not match a static resource.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_embedding-connectors"><a class="anchor" href="#_embedding-connectors"></a><a class="link" href="#_embedding-connectors">Embedding Connectors</a></h4>
<div class="paragraph">
<p>In the previous examples, the Server instance is passed a port number and it internally creates a default instance of a Connector that listens for requests on that port.
However, often when embedding Jetty it is desirable to explicitly instantiate and configure one or more Connectors for a Server instance.</p>
</div>
<div class="sect4">
<h5 id="_one-connector"><a class="anchor" href="#_one-connector"></a><a class="link" href="#_one-connector">One Connector</a></h5>
<div class="paragraph">
<p>The following example, <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/embedded/OneConnector.html">OneConnector.java</a>,
instantiates, configures, and adds a single HTTP connector instance to the server:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/embedding-jetty.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneConnector.java[]</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example the connector handles the HTTP protocol, as that is the default for the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/ServerConnector.html"><code>ServerConnector</code></a> class.</p>
</div>
</div>
<div class="sect4">
<h5 id="_many-connectors"><a class="anchor" href="#_many-connectors"></a><a class="link" href="#_many-connectors">Many Connectors</a></h5>
<div class="paragraph">
<p>When configuring multiple connectors (for example, HTTP and HTTPS), it may be desirable to share configuration of common parameters for HTTP.
To achieve this you need to explicitly configure the <code>ServerConnector</code> class with <code>ConnectionFactory</code> instances, and provide them with common HTTP configuration.</p>
</div>
<div class="paragraph">
<p>The <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/embedded/ManyConnectors.html">ManyConnectors example</a>, configures a server with two <code>ServerConnector</code> instances: the http connector has a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/HttpConnectionFactory.html"><code>HTTPConnectionFactory</code></a> instance; the https connector has a <code>SslConnectionFactory</code> chained to a <code>HttpConnectionFactory</code>.
Both <code>HttpConnectionFactory</code> are configured based on the same <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/HttpConfiguration.html"><code>HttpConfiguration</code></a> instance, however the HTTPS factory uses a wrapped configuration so that a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/SecureRequestCustomizer.html"><code>SecureRequestCustomizer</code></a> can be added.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_embedding-servlets"><a class="anchor" href="#_embedding-servlets"></a><a class="link" href="#_embedding-servlets">Embedding Servlets</a></h4>
<div class="paragraph">
<p><a href="http://en.wikipedia.org/wiki/Java_Servlet">Servlets</a> are the standard way to provide application logic that handles HTTP requests.
Servlets are similar to a Jetty Handler except that the request object is not mutable and thus cannot be modified.
Servlets are handled in Jetty by a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/embedded/MinimalServlets.html"><code>ServletHandler</code></a>.
It uses standard path mappings to match a Servlet to a request; sets the requests <code>servletPath</code> and <code>pathInfo</code>; passes the request to the servlet, possibly via Filters to produce a response.</p>
</div>
<div class="paragraph">
<p>The <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/embedded/MinimalServlets.html">MinimalServlets example</a> creates a <code>ServletHandler</code> instance and configures a single HelloServlet:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/embedding-jetty.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/MinimalServlets.java[]</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_embedding-contexts"><a class="anchor" href="#_embedding-contexts"></a><a class="link" href="#_embedding-contexts">Embedding Contexts</a></h4>
<div class="paragraph">
<p>A <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/embedded/OneContext.html"><code>ContextHandler</code></a> is a <code>ScopedHandler</code> that responds only to requests that have a URI prefix that matches the configured context path.
Requests that match the context path have their path methods updated accordingly and the contexts scope is available, which optionally may include:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A <code>Classloader</code> that is set as the Thread context <code>classloader</code> while request handling is in scope.</p>
</li>
<li>
<p>A set of attributes that is available via the <a href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html"><code>ServletContext</code></a> API.</p>
</li>
<li>
<p>A set of init parameters that is available via the <a href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html"><code>ServletContext</code></a> API.</p>
</li>
<li>
<p>A base Resource which is used as the document root for static resource requests via the <a href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html"><code>ServletContext</code></a> API.</p>
</li>
<li>
<p>A set of virtual host names.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The following <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/embedded/OneContext.html">OneContext example</a> shows a context being established that wraps the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/embedded/HelloHandler.html">HelloHandler</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/embedding-jetty.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneContext.java[]</code></pre>
</div>
</div>
<div class="paragraph">
<p>When many contexts are present, you can embed a <code>ContextHandlerCollection</code> to efficiently examine a request URI to then select the matching <code>ContextHandler</code>(s) for the request.
The <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/embedded/ManyContexts.html">ManyContexts example</a> shows how many such contexts you can configure:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/embedding-jetty.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyContexts.java[]</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_embedding-servletcontexts"><a class="anchor" href="#_embedding-servletcontexts"></a><a class="link" href="#_embedding-servletcontexts">Embedding ServletContexts</a></h4>
<div class="paragraph">
<p>A <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlet/ServletContextHandler.html"><code>ServletContextHandler</code></a> is a specialization of <code>ContextHandler</code> with support for standard sessions and Servlets.
The following <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/embedded/OneServletContext.html">OneServletContext example</a> instantiates a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlet/DefaultServlet.html"><code>DefaultServlet</code></a> to server static content from /tmp/ and a <code>DumpServlet</code> that creates a session and dumps basic details about the request:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/embedding-jetty.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneServletContext.java[]</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_embedding-web-applications"><a class="anchor" href="#_embedding-web-applications"></a><a class="link" href="#_embedding-web-applications">Embedding Web Applications</a></h4>
<div class="paragraph">
<p>A <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html"><code>WebAppContext</code></a> is an extension of a <code>ServletContextHandler</code> that uses the <a href="http://en.wikipedia.org/wiki/WAR_%28Sun_file_format%29">standard layout</a> and web.xml to configure the servlets, filters and other features from a web.xml and/or annotations.
The following <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/embedded/OneWebApp.html">OneWebApp example</a> configures the Jetty test webapp.
Web applications can use resources the container provides, and in this case a <code>LoginService</code> is needed and also configured:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/embedding-jetty.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneWebApp.java[]</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_like-jetty-xml"><a class="anchor" href="#_like-jetty-xml"></a><a class="link" href="#_like-jetty-xml">Like Jetty XML</a></h4>
<div class="paragraph">
<p>The typical way to configure an instance of the Jetty server is via <code>jetty.xml</code> and associated configuration files.
However the Jetty XML configuration format is just a simple rendering of what you can do in code; it is very simple to write embedded code that does precisely what the jetty.xml configuration does.
The <a href="https://github.com/eclipse/jetty.project/tree/master/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java">LikeJettyXml example</a> following renders in code the behavior obtained from the configuration files:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty.xml">jetty.xml</a></p>
</li>
<li>
<p><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-jmx/src/main/config/etc/jetty-jmx.xml">jetty-jmx.xml</a></p>
</li>
<li>
<p><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty-http.xml">jetty-http.xml</a></p>
</li>
<li>
<p><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty-https.xml">jetty-https.xml</a></p>
</li>
<li>
<p><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-deploy/src/main/config/etc/jetty-deploy.xml">jetty-deploy.xml</a></p>
</li>
<li>
<p><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty-stats.xml">jetty-stats.xml</a></p>
</li>
<li>
<p><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty-requestlog.xml">jetty-requestlog.xml</a></p>
</li>
<li>
<p><a href="https://github.com/eclipse/jetty.project/tree/master/jetty-server/src/main/config/etc/jetty-lowresources.xml">jetty-lowresources.xml</a></p>
</li>
<li>
<p><a href="https://github.com/eclipse/jetty.project/tree/master/tests/test-webapps/test-jetty-webapp/src/main/config/etc/test-realm.xml">test-realm.xml</a></p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/embedding-jetty.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java[]</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="embedded-examples"><a class="anchor" href="#embedded-examples"></a><a class="link" href="#embedded-examples">Embedded Examples</a></h3>
<div class="paragraph">
<p>Jetty has a rich history of being embedded into a wide variety of applications.
In this section we will walk you through a number of our simple examples under our embedded-jetty-examples project in our git repository.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
These files are pulled directly from our git repository when this document is generated.
If the line numbers do not line up feel free to fix this documentation in github and give us a pull request, or at least open an issue to notify us of the discrepancy.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect3">
<h4 id="embedded-file-server"><a class="anchor" href="#embedded-file-server"></a><a class="link" href="#embedded-file-server">Simple File Server</a></h4>
<div class="paragraph">
<p>This example shows how to create a simple file server in Jetty.
It is perfectly suitable for test cases where you need an actual web server to obtain a file from, it could easily be configured to serve files from a directory under <code>src/test/resources</code>.
Note that this does not have any logic for caching of files, either within the server or setting the appropriate headers on the response.
It is simply a few lines that illustrate how easy it is to serve out some files.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/examples/embedded-file-server.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/FileServer.java[]</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_run-it"><a class="anchor" href="#_run-it"></a><a class="link" href="#_run-it">Run it!</a></h5>
<div class="paragraph">
<p>After you have started things up you should be able to navigate to <a href="http://localhost:8080/index.html" class="bare">http://localhost:8080/index.html</a> (assuming one is in the resource base directory) and you are good to go.</p>
</div>
</div>
<div class="sect4">
<h5 id="_maven-coordinates"><a class="anchor" href="#_maven-coordinates"></a><a class="link" href="#_maven-coordinates">Maven Coordinates</a></h5>
<div class="paragraph">
<p>To use this example in your project you will need the following Maven dependencies declared.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-server&lt;/artifactId&gt;
&lt;version&gt;${project.version}&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="embedded-split-file-server"><a class="anchor" href="#embedded-split-file-server"></a><a class="link" href="#embedded-split-file-server">Split File Server</a></h4>
<div class="paragraph">
<p>This example builds on the <a href="#emebedded-file-server">Simple File Server</a> to show how chaining multiple <code>ResourceHandlers</code> together can let you aggregate multiple directories to serve content on a single path and how you can link these together with <code>ContextHandlers</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/examples/embedded-split-file-server.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/SplitFileServer.java[]</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_run-it-2"><a class="anchor" href="#_run-it-2"></a><a class="link" href="#_run-it-2">Run it!</a></h5>
<div class="paragraph">
<p>After you have started things up you should be able to navigate to <a href="http://localhost:8090/index.html" class="bare">http://localhost:8090/index.html</a> (assuming one is in the resource base directory) and you are good to go.
Any requests for files will be looked for in the first resource handler, then the second, and so on and so forth.</p>
</div>
</div>
<div class="sect4">
<h5 id="_maven-coordinates-2"><a class="anchor" href="#_maven-coordinates-2"></a><a class="link" href="#_maven-coordinates-2">Maven Coordinates</a></h5>
<div class="paragraph">
<p>To use this example as is in your project you will need the following maven dependencies declared.
We would recommend not using the toolchain dependency in your actual application.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-server&lt;/artifactId&gt;
&lt;version&gt;${project.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty.toolchain&lt;/groupId&gt;
&lt;artifactId&gt;jetty-test-helper&lt;/artifactId&gt;
&lt;version&gt;2.2&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="embedded-many-connectors"><a class="anchor" href="#embedded-many-connectors"></a><a class="link" href="#embedded-many-connectors">Multiple Connectors</a></h4>
<div class="paragraph">
<p>This example shows how to configure Jetty to use multiple connectors, specifically so it can process both http and https requests.
Since the meat of this example is the server and connector configuration it only uses a simple HelloHandler but this example should be easily merged with other examples like those deploying servlets or webapps.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/examples/embedded-many-connectors.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java[]</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_walkthrough"><a class="anchor" href="#_walkthrough"></a><a class="link" href="#_walkthrough">Walkthrough</a></h5>
<div class="paragraph">
<p>Start things up!
By using the <code>server.join()</code> the server thread will join with the current thread.
See <a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()"><code>Thread.join()</code></a> for more details.</p>
</div>
</div>
<div class="sect4">
<h5 id="_maven-coordinates-3"><a class="anchor" href="#_maven-coordinates-3"></a><a class="link" href="#_maven-coordinates-3">Maven Coordinates</a></h5>
<div class="paragraph">
<p>To use this example in your project you will need the following Maven dependencies declared.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-server&lt;/artifactId&gt;
&lt;version&gt;${project.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-security&lt;/artifactId&gt;
&lt;version&gt;${project.version}&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="embedded-secured-hello-handler"><a class="anchor" href="#embedded-secured-hello-handler"></a><a class="link" href="#embedded-secured-hello-handler">Secured Hello Handler</a></h4>
<div class="paragraph">
<p>This example shows how to wrap one handler with another one that handles security.
We have a simple Hello Handler that just return a greeting but add on the restriction that to get this greeting you must authenticate.
Another thing to remember is that this example uses the <code>ConstraintSecurityHandler</code> which is what supports the security mappings inside of the servlet api, it could be easier to show just the <code>SecurityHandler</code> usage, but the constraint provides more configuration power.
If you don&#8217;t need that you can drop the Constraint bits and use just the <code>SecurityHandler</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/examples/embedded-secured-hello-handler.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java[]</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_run-it-3"><a class="anchor" href="#_run-it-3"></a><a class="link" href="#_run-it-3">Run it!</a></h5>
<div class="paragraph">
<p>After you have started things up you should be able to navigate to <a href="http://localhost:8080/index.html" class="bare">http://localhost:8080/index.html</a> (assuming one is in the resource base directory) and you are good to go.</p>
</div>
</div>
<div class="sect4">
<h5 id="_the-realm-properties-file"><a class="anchor" href="#_the-realm-properties-file"></a><a class="link" href="#_the-realm-properties-file">The Realm Properties File</a></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-properties" data-lang="properties">Unresolved directive in embedding/examples/embedded-secured-hello-handler.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/test/resources/realm.properties[]</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_maven-coordinates-4"><a class="anchor" href="#_maven-coordinates-4"></a><a class="link" href="#_maven-coordinates-4">Maven Coordinates</a></h5>
<div class="paragraph">
<p>To use this example in your project you will need the following Maven dependencies declared.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-server&lt;/artifactId&gt;
&lt;version&gt;${project.version}&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="embedded-minimal-servlet"><a class="anchor" href="#embedded-minimal-servlet"></a><a class="link" href="#embedded-minimal-servlet">Minimal Servlet</a></h4>
<div class="paragraph">
<p>This example shows the bare minimum required for deploying a servlet into Jetty.
Note that this is strictly a servlet, not a servlet in the context of a web application, that example comes later.
This is purely just a servlet deployed and mounted on a context and able to process requests.
This example is excellent for situations where you have a simple servlet that you need to unit test, just mount it on a context and issue requests using your favorite http client library (like our Jetty client found in <a href="#client-http">[client-http]</a>).</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/examples/embedded-minimal-servlet.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/MinimalServlets.java[]</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_walkthrough-2"><a class="anchor" href="#_walkthrough-2"></a><a class="link" href="#_walkthrough-2">Walkthrough</a></h5>
<div class="paragraph">
<p>Start things up! By using the <code>server.join()</code> the server thread will join with the current thread.
See <a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()"><code>Thread.join()</code></a> for more details.</p>
</div>
<div class="paragraph">
<p>It is really simple to create useful servlets for testing behaviors. Sometimes you need a http server to run a unit test against that will return test content and wiring up a servlet like this makes it trivial.</p>
</div>
<div class="paragraph">
<p>After you have started things up you should be able to navigate to <a href="http://localhost:8080/" class="bare">http://localhost:8080/</a> and you are good to go.</p>
</div>
</div>
<div class="sect4">
<h5 id="_maven-coordinates-5"><a class="anchor" href="#_maven-coordinates-5"></a><a class="link" href="#_maven-coordinates-5">Maven Coordinates</a></h5>
<div class="paragraph">
<p>To use this example in your project you will need the following Maven dependencies declared.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-servlet&lt;/artifactId&gt;
&lt;version&gt;${project.version}&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="embedded-one-webapp"><a class="anchor" href="#embedded-one-webapp"></a><a class="link" href="#embedded-one-webapp">Web Application</a></h4>
<div class="paragraph">
<p>This example shows how to deploy a simple webapp with an embedded instance of Jetty.
This is useful when you want to manage the lifecycle of a server programmatically, either within a production application or as a simple way to deploying and debugging a full scale application deployment.
In many ways it is easier then traditional deployment since you control the classpath yourself, making this easy to wire up in a test case in Maven and issue requests using your favorite http client library (like our Jetty client found in <a href="#client-http">[client-http]</a>).</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/examples/embedded-one-webapp.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneWebApp.java[]</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_run-it-4"><a class="anchor" href="#_run-it-4"></a><a class="link" href="#_run-it-4">Run it!</a></h5>
<div class="paragraph">
<p>After you have started things up you should be able to navigate to <a href="http://localhost:8080/" class="bare">http://localhost:8080/</a> and you are good to go.</p>
</div>
</div>
<div class="sect4">
<h5 id="_maven-coordinates-6"><a class="anchor" href="#_maven-coordinates-6"></a><a class="link" href="#_maven-coordinates-6">Maven Coordinates</a></h5>
<div class="paragraph">
<p>To use this example in your project you will need the following Maven dependencies declared.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-webapp&lt;/artifactId&gt;
&lt;version&gt;${project.version}&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="embedded-webapp-jsp"><a class="anchor" href="#embedded-webapp-jsp"></a><a class="link" href="#embedded-webapp-jsp">Web Application with JSP</a></h4>
<div class="paragraph">
<p>This example is very similar to the one in the previous section, although it enables the embedded webapp to use JSPs.
As of jetty-9.2, we use the JSP engine from Apache, which relies on a Servlet Specification 3.1 style <code>ServletContainerInitializer</code> to initialize itself.
To get this to work with Jetty, you need to enable annotations processing, as shown in this example code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in embedding/embedded-examples.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneWebAppWithJsp.java[]</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_run-it-5"><a class="anchor" href="#_run-it-5"></a><a class="link" href="#_run-it-5">Run it!</a></h5>
<div class="paragraph">
<p>After you have started things up you should be able to navigate to <a href="http://localhost:8080/jsp/" class="bare">http://localhost:8080/jsp/</a> and click on any of the links to jsps.</p>
</div>
</div>
<div class="sect4">
<h5 id="_maven-coordinates-7"><a class="anchor" href="#_maven-coordinates-7"></a><a class="link" href="#_maven-coordinates-7">Maven Coordinates</a></h5>
<div class="paragraph">
<p>To use this example in your project, you will need the following Maven dependencies declared, in addition to those from the previous section:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-annotations&lt;/artifactId&gt;
&lt;version&gt;${project.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;apache-jsp&lt;/artifactId&gt;
&lt;version&gt;${project.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;apache-jstl&lt;/artifactId&gt;
&lt;version&gt;${project.version}&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="adding-embedded-examples"><a class="anchor" href="#adding-embedded-examples"></a><a class="link" href="#adding-embedded-examples">Adding Examples</a></h4>
<div class="paragraph">
<p>If you would like to add an example to this list, fork the documentation project from github (see the blue bar at the bottom of this page) and add the new page.
Feel free to add the example contents directly as a <code>[source.java]</code> and we will take it from there.</p>
</div>
<div class="paragraph">
<p>If you feel and example is missing, feel free to open a bug to ask for it.
No guarantees, but the more helpful and demonstrative it is the better.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="advanced-extras"><a class="anchor" href="#advanced-extras"></a><a class="link" href="#advanced-extras">Provided Servlets, Filters, and Handlers</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Jetty ships with a bundle of servlets that interact with the key classes.
Most are in the org.eclipse.jetty.servlets package.
These servlets and filters are among the principle elements of Jetty as a component-based infrastructure that holds and runs J2EE applications.
As described, they play a major role in running and maintaining the Jetty server.</p>
</div>
<div class="paragraph">
<p>Also included are a number of Jetty specific handlers that allow access to internals of jetty that would not normally be exposed and are very useful testing environments and many production scenarios.</p>
</div>
<div class="sect2">
<h3 id="default-servlet"><a class="anchor" href="#default-servlet"></a><a class="link" href="#default-servlet">Default Servlet</a></h3>
<div class="sect3">
<h4 id="default-servlet-metadata"><a class="anchor" href="#default-servlet-metadata"></a><a class="link" href="#default-servlet-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.servlet.DefaultServlet</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-servlet</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlet/DefaultServlet.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlet/DefaultServlet.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="default-servlet-usage"><a class="anchor" href="#default-servlet-usage"></a><a class="link" href="#default-servlet-usage">Usage</a></h4>
<div class="paragraph">
<p>The <code>DefaultServlet</code> implements the <code>ResourceFactory</code> interface and extends the <code>HttpServlet</code> abstract class.
It is usually mapped to "/" and provides handling for static content, <code>OPTION</code> and <code>TRACE</code> methods for the context.
The <code>MOVE</code> method is allowed if <code>PUT</code> and <code>DELETE</code> are allowed.
See the <code>DefaultServlet</code> <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlet/DefaultServlet.html">javadoc</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="default-servlet-init"><a class="anchor" href="#default-servlet-init"></a><a class="link" href="#default-servlet-init">Init Parameters</a></h4>
<div class="paragraph">
<p>Jetty supports the following <code>initParameters</code>:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">acceptRanges</dt>
<dd>
<p>If <code>true</code>, range requests and responses are supported.</p>
</dd>
<dt class="hdlist1">dirAllowed</dt>
<dd>
<p>If <code>true</code>, directory listings are returned if no welcome file is found.
Otherwise 403 Forbidden displays.</p>
</dd>
<dt class="hdlist1">redirectWelcome</dt>
<dd>
<p>If <code>true</code>, welcome files are redirected rather that forwarded.</p>
</dd>
<dt class="hdlist1">welcomeServlets</dt>
<dd>
<p>If <code>true</code>, attempt to dispatch to welcome files that are servlets, but only after no matching static
resources could be found. If <code>false</code>, then a welcome file must exist on disk. If <code>exact</code>, then exact
servlet matches are supported without an existing file. Default is <code>false</code>. This must be <code>false</code> if you want directory listings,
but have index.jsp in your welcome file list.</p>
</dd>
<dt class="hdlist1">precompressed</dt>
<dd>
<p>If set to a comma separated list of encoding types (that may be listed in a requests Accept-Encoding header) to file extension mappings to look for and serve.
For example: <code>br=.br,gzip=.gz,bzip2=.bz</code>.
If set to a boolean <code>true</code>, then a default set of compressed formats will be used, otherwise no precompressed formats supported.</p>
</dd>
<dt class="hdlist1">gzip</dt>
<dd>
<p>Deprecated. Use <code>precompressed</code> instead. If set to <code>true</code>, then static content is served as gzip content encoded if a matching resource is found ending with ".gz".</p>
</dd>
<dt class="hdlist1">resourceBase</dt>
<dd>
<p>Set to replace the context resource base.</p>
</dd>
<dt class="hdlist1">resourceCache</dt>
<dd>
<p>If set, this is a context attribute name, which the servlet will use to look for a shared ResourceCache instance.</p>
</dd>
<dt class="hdlist1">relativeResourceBase</dt>
<dd>
<p>Set with a pathname relative to the base of the servlet context root. Useful for only serving static content out of only specific subdirectories.</p>
</dd>
<dt class="hdlist1">cacheControl</dt>
<dd>
<p>If set, all static content will have this value set as the cache-control header.</p>
</dd>
<dt class="hdlist1">pathInfoOnly</dt>
<dd>
<p>If <code>true</code>, only the path info will be applied to the resourceBase</p>
</dd>
<dt class="hdlist1">stylesheet</dt>
<dd>
<p>Set with the location of an optional stylesheet that will be used to decorate the directory listing html.</p>
</dd>
<dt class="hdlist1">etags</dt>
<dd>
<p>If <code>true</code>, weak etags will be generated and handled.</p>
</dd>
<dt class="hdlist1">maxCacheSize</dt>
<dd>
<p>Maximum total size of the cache or 0 for no cache.</p>
</dd>
<dt class="hdlist1">maxCachedFileSize</dt>
<dd>
<p>Maximum size of a file to cache.</p>
</dd>
<dt class="hdlist1">maxCachedFiles</dt>
<dd>
<p>Maximum number of files to cache.</p>
</dd>
<dt class="hdlist1">useFileMappedBuffer</dt>
<dd>
<p>If set to <code>true</code>, mapped file buffer serves static content.
Setting this value to <code>false</code> means that a direct buffer is used instead of a mapped file buffer.
By default, this is set to <code>true</code>.</p>
</dd>
<dt class="hdlist1">otherGzipFileExtensions</dt>
<dd>
<p>A comma separated list of other file extensions that signify that a file is gzip compressed.
If you don&#8217;t explicitly set this, it defaults to <code>.svgz</code>.</p>
</dd>
<dt class="hdlist1">encodingHeaderCacheSize</dt>
<dd>
<p>Max entries in a cache of ACCEPT-ENCODING headers</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect2">
<h3 id="proxy-servlet"><a class="anchor" href="#proxy-servlet"></a><a class="link" href="#proxy-servlet">Proxy Servlet</a></h3>
<div class="sect3">
<h4 id="proxy-servlet-metadata"><a class="anchor" href="#proxy-servlet-metadata"></a><a class="link" href="#proxy-servlet-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.proxy.ProxyServlet</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-proxy</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/proxy/ProxyServlet.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/proxy/ProxyServlet.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="proxy-servlet-usage"><a class="anchor" href="#proxy-servlet-usage"></a><a class="link" href="#proxy-servlet-usage">Usage</a></h4>
<div class="paragraph">
<p>An asynchronous servlet that forwards requests to another server either as a standard web reverse proxy (as defined by RFC2616) or as a transparent reverse proxy.
Internally it uses the async jetty-client.</p>
</div>
<div class="paragraph">
<p>To facilitate JMX monitoring, the <code>HttpClient</code> instance is set as context attribute, prefixed with the servlet&#8217;s name and exposed by the mechanism provided by <code>ContextHandler.MANAGED_ATTRIBUTES</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="proxy-servlet-init"><a class="anchor" href="#proxy-servlet-init"></a><a class="link" href="#proxy-servlet-init">Init Parameters</a></h4>
<div class="paragraph">
<p>The following init parameters may be used to configure the servlet:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">hostHeader</dt>
<dd>
<p>forces the host header to a particular value</p>
</dd>
<dt class="hdlist1">viaHost</dt>
<dd>
<p>the name to use in the Via header: Via: http/1.1 &lt;viaHost&gt;</p>
</dd>
<dt class="hdlist1">whiteList</dt>
<dd>
<p>comma-separated list of allowed proxy hosts</p>
</dd>
<dt class="hdlist1">blackList</dt>
<dd>
<p>comma-separated list of forbidden proxy hosts</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>In addition, there are a number of init parameters that can be used to configure the <code>HttpClient</code> instance used internally for the proxy.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">maxThreads</dt>
<dd>
<p>Default Value: 256
The max number of threads of HttpClient&#8217;s Executor</p>
</dd>
<dt class="hdlist1">maxConnections</dt>
<dd>
<p>Default Value: 32768
The max number of connections per destination.
RFC 2616 suggests that 2 connections should be opened per each destination, but browsers commonly open 6 or more.
If this <code>HttpClient</code> is used for load testing, it is common to have only one destination (the server to load test), and it is recommended to set this value to a high value (at least as much as the threads present in the executor).</p>
</dd>
<dt class="hdlist1">idleTimeout</dt>
<dd>
<p>Default Value: 30000
The idle timeout in milliseconds that a connection can be idle, that is without traffic of bytes in either direction.</p>
</dd>
<dt class="hdlist1">timeout</dt>
<dd>
<p>Default Value: 60000
The total timeout in milliseconds for the request/response conversation.</p>
</dd>
<dt class="hdlist1">requestBufferSize</dt>
<dd>
<p>Default Value: 4096
The size of the request buffer the request is written into.</p>
</dd>
<dt class="hdlist1">responseBufferSize</dt>
<dd>
<p>Default Value: 4096
The size of the response buffer the response is written into.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect2">
<h3 id="balancer-servlet"><a class="anchor" href="#balancer-servlet"></a><a class="link" href="#balancer-servlet">Balancer Servlet</a></h3>
<div class="sect3">
<h4 id="balancer-servlet-metadata"><a class="anchor" href="#balancer-servlet-metadata"></a><a class="link" href="#balancer-servlet-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.proxy.BalancerServlet</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-proxy</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/proxy/BalancerServlet.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/proxy/BalancerServlet.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="balancer-servlet-usage"><a class="anchor" href="#balancer-servlet-usage"></a><a class="link" href="#balancer-servlet-usage">Usage</a></h4>
<div class="paragraph">
<p>The Balancer servlet allows for simple, sticky round robin load balancing leveraging the <code>ProxyServlet</code> that is distributed with Jetty.</p>
</div>
<div class="paragraph">
<p>In addition to the parameters for <code>ProxyServlet</code>, the following are available for the balancer servlet:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">stickySessions</dt>
<dd>
<p>True if sessions should be sticky for subsequent requests</p>
</dd>
<dt class="hdlist1">balancerMember.&lt;name&gt;.proxyTo</dt>
<dd>
<p>One of more of these are required and will be the locations that are used to proxy traffic to.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect2">
<h3 id="cgi-servlet"><a class="anchor" href="#cgi-servlet"></a><a class="link" href="#cgi-servlet">CGI Servlet</a></h3>
<div class="sect3">
<h4 id="cgi-servlet-metadata"><a class="anchor" href="#cgi-servlet-metadata"></a><a class="link" href="#cgi-servlet-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.servlets.CGI</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-servlets</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlets/CGI.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlets/CGI.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="cgi-servlet-usage"><a class="anchor" href="#cgi-servlet-usage"></a><a class="link" href="#cgi-servlet-usage">Usage</a></h4>
<div class="paragraph">
<p>The CGI servlet class extends the abstract HttpServlet class.
When the init parameter is called, the cgi bin directory is set with the <code>cgibinResourceBase</code>.
Otherwise, it defaults to the resource base of the context.</p>
</div>
<div class="paragraph">
<p>The cgi bin uses three parameters:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">commandPrefix</dt>
<dd>
<p>The init parameter obtained when there is a prefix set to all commands directed to the method exec.</p>
</dd>
<dt class="hdlist1">Path</dt>
<dd>
<p>An init parameter passed to the exec environment as a PATH.
This must be run unpacked somewhere in the filesystem.</p>
</dd>
<dt class="hdlist1">ENV_</dt>
<dd>
<p>An init parameter that points to an environment variable with the name stripped of the leading ENV_ and using the init parameter value.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect2">
<h3 id="qos-filter"><a class="anchor" href="#qos-filter"></a><a class="link" href="#qos-filter">Quality of Service Filter</a></h3>
<div class="sect3">
<h4 id="qos-filter-metadata"><a class="anchor" href="#qos-filter-metadata"></a><a class="link" href="#qos-filter-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.servlets.QoSFilter</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-servlets</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlets/QoSFilter.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlets/QoSFilter.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="qos-filter-usage"><a class="anchor" href="#qos-filter-usage"></a><a class="link" href="#qos-filter-usage">Usage</a></h4>
<div class="paragraph">
<p>Jetty supports Continuations, which allow non-blocking handling of HTTP requests, so that threads can be allocated in a managed way to provide application specific Quality of Service (QoS).
The <code>QoSFilter</code> is a utility servlet filter that implements some QoS features.</p>
</div>
</div>
<div class="sect3">
<h4 id="qos-understanding"><a class="anchor" href="#qos-understanding"></a><a class="link" href="#qos-understanding">Understanding the Problem</a></h4>
<div class="sect4">
<h5 id="_waiting-for-resources"><a class="anchor" href="#_waiting-for-resources"></a><a class="link" href="#_waiting-for-resources">Waiting for Resources</a></h5>
<div class="paragraph">
<p>Web applications frequently use JDBC Connection pools to limit the simultaneous load on the database.
This protects the database from peak loads, but makes the web application vulnerable to thread starvation.
Consider a thread pool with 20 connections, being used by a web application that that typically receives 200 requests per second and each request holds a JDBC connection for 50ms.
Such a pool can service on average 200*20*1000/50 = 400 requests per second.</p>
</div>
<div class="paragraph">
<p>However, if the request rate rises above 400 per second, or if the database slows down (due to a large query) or becomes momentarily unavailable, the thread pool can very quickly accumulate many waiting requests.
If, for example, the website is "slashdotted" or experiences some other temporary burst of traffic and the request rate rises from 400 to 500 requests per second, then 100 requests per second join those waiting for a JDBC connection.
Typically, a web server&#8217;s thread pool contains only a few hundred threads, so a burst or slow DB need only persist for a few seconds to consume the entire web server&#8217;s thread pool; this is called thread starvation.
The key issue with thread starvation is that it effects the entire web application, and potentially the entire web server.
Even if the requests using the database are only a small proportion of the total requests on the web server, all requests are blocked because all the available threads are waiting on the JDBC connection pool.
This represents non-graceful degradation under load and provides a very poor quality of service.</p>
</div>
</div>
<div class="sect4">
<h5 id="_prioritizing-resources"><a class="anchor" href="#_prioritizing-resources"></a><a class="link" href="#_prioritizing-resources">Prioritizing Resources</a></h5>
<div class="paragraph">
<p>Consider a web application that is under extreme load.
This load might be due to a popularity spike (slashdot), usage burst (Christmas or close of business), or even a denial of service attack.
During such periods of load, it is often desirable not to treat all requests as equals, and to give priority to high value customers or administrative users.</p>
</div>
<div class="paragraph">
<p>The typical behavior of a web server under extreme load is to use all its threads to service requests and to build up a backlog of unserviced requests.
If the backlog grows deep enough, then requests start to timeout and users experience failures as well as delays.</p>
</div>
<div class="paragraph">
<p>Ideally, the web application should be able to examine the requests in the backlog, and give priority to high value customers and administrative users.
But with the standard blocking servlet API, it is not possible to examine a request without allocating a thread to that request for the duration of its handling.
There is no way to delay the handling of low priority requests, so if the resources are to be reallocated, then the low priority requests must all be failed.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="qos-applying"><a class="anchor" href="#qos-applying"></a><a class="link" href="#qos-applying">Applying the QoSFilter</a></h4>
<div class="paragraph">
<p>The Quality of Service Filter (QoSFilter) uses Continuations to avoid thread starvation, prioritize requests and give graceful degradation under load, to provide a high quality of service.
When you apply the filter to specific URLs within a web application, it limits the number of active requests being handled for those URLs.
Any requests in excess of the limit are suspended. When a request completes handling the limited URL, one of the waiting requests resumes and can be handled.
You can assign priorities to each suspended request, so that high priority requests resume before lower priority requests.</p>
</div>
<div class="sect4">
<h5 id="_required-jars"><a class="anchor" href="#_required-jars"></a><a class="link" href="#_required-jars">Required JARs</a></h5>
<div class="paragraph">
<p>To use the QoS Filter, these JAR files must be available in <code>WEB-INF/lib</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>$JETTY_HOME/lib/jetty-util.jar</p>
</li>
<li>
<p>$JETTY_HOME/lib/jetty-servlets.jar – contains QoSFilter</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="_sample-configuration"><a class="anchor" href="#_sample-configuration"></a><a class="link" href="#_sample-configuration">Sample Configuration</a></h5>
<div class="paragraph">
<p>Place the configuration in a webapp&#8217;s <code>web.xml</code> or <code>jetty-web.xml</code>.
The default configuration processes ten requests at a time, servicing more important requests first and queuing up the rest.
This example processes fifty requests at a time:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;filter&gt;
&lt;filter-name&gt;QoSFilter&lt;/filter-name&gt;
&lt;filter-class&gt;org.eclipse.jetty.servlets.QoSFilter&lt;/filter-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;maxRequests&lt;/param-name&gt;
&lt;param-value&gt;50&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;/filter&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="qos-filter-init"><a class="anchor" href="#qos-filter-init"></a><a class="link" href="#qos-filter-init">Configuring QoS Filter Parameters</a></h5>
<div class="paragraph">
<p>A semaphore polices the <code>maxRequests</code> limit.
The filter waits a short time while attempting to acquire the semaphore.
The <code>waitMs</code> init parameter controls the wait, avoiding the expense of a suspend if the semaphore is shortly available.
If the semaphore cannot be obtained, Jetty suspends the request for the default suspend period of the container or the value set as the <code>suspendMs</code> init parameter.</p>
</div>
<div class="paragraph">
<p>The QoS filter uses the following init parameters:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">maxRequests</dt>
<dd>
<p>The maximum number of requests to be serviced at a time. The default is 10.</p>
</dd>
<dt class="hdlist1">maxPriority</dt>
<dd>
<p>The maximum valid priority that can be assigned to a request.
A request with a high priority value is more important than a request with a low priority value. The default is 10.</p>
</dd>
<dt class="hdlist1">waitMs</dt>
<dd>
<p>The length of time, in milliseconds, to wait while trying to accept a new request.
Used when the maxRequests limit is reached.
Default is 50 ms.</p>
</dd>
<dt class="hdlist1">suspendMs</dt>
<dd>
<p>Length of time, in milliseconds, that the request will be suspended if it is not accepted immediately.
If not set, the container&#8217;s default suspend period applies. Default is -1 ms.</p>
</dd>
<dt class="hdlist1">managedAttr</dt>
<dd>
<p>If set to true, then this servlet is set as a <code>ServletContext</code> attribute with the filter name as the attribute name.
This allows a context external mechanism (for example, JMX via <code>ContextHandler.MANAGED_ATTRIBUTES</code>) to manage the configuration of the filter.</p>
</dd>
</dl>
</div>
</div>
<div class="sect4">
<h5 id="_mapping-to-urls"><a class="anchor" href="#_mapping-to-urls"></a><a class="link" href="#_mapping-to-urls">Mapping to URLs</a></h5>
<div class="paragraph">
<p>You can use the <code>&lt;filter-mapping&gt;</code> syntax to map the QoSFilter to a servlet, either by using the servlet name, or by using a URL pattern.
In this example, a URL pattern applies the QoSFilter to every request within the web application context:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;filter-mapping&gt;
&lt;filter-name&gt;QoSFilter&lt;/filter-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_setting-the-request-priority"><a class="anchor" href="#_setting-the-request-priority"></a><a class="link" href="#_setting-the-request-priority">Setting the Request Priority</a></h5>
<div class="paragraph">
<p>Requests with higher values have a higher priority.
The default request priorities assigned by the QoSFilter are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>2&#8201;&#8212;&#8201;For any authenticated request</p>
</li>
<li>
<p>1&#8201;&#8212;&#8201;For any request with a non-new valid session</p>
</li>
<li>
<p>0&#8201;&#8212;&#8201;For all other requests</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>To customize the priority, subclass QoSFilter and then override the <code>getPriority(ServletRequest request)</code> method to return an appropriate priority for the request.
You can then use this subclass as your QoS filter.
Here&#8217;s an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public class ParsePriorityQoSFilter extends QoSFilter
{
protected int getPriority(ServletRequest request)
{
String p = ((HttpServletRequest)request).getParameter("priority");
if (p!=null)
return Integer.parseInt(p);
return 0;
}
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="dos-filter"><a class="anchor" href="#dos-filter"></a><a class="link" href="#dos-filter">Denial of Service Filter</a></h3>
<div class="sect3">
<h4 id="dos-filter-metadata"><a class="anchor" href="#dos-filter-metadata"></a><a class="link" href="#dos-filter-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.servlets.DoSFilter</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-servlets</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlets/DoSFilter.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlets/DoSFilter.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="dos-filter-usage"><a class="anchor" href="#dos-filter-usage"></a><a class="link" href="#dos-filter-usage">Usage</a></h4>
<div class="paragraph">
<p>The Denial of Service (DoS) filter limits exposure to request flooding, whether malicious, or as a result of a misconfigured client.
The DoS filter keeps track of the number of requests from a connection per second.
If the requests exceed the limit, Jetty rejects, delays, or throttles the request, and sends a warning message.
The filter works on the assumption that the attacker might be written in simple blocking style, so by suspending requests you are hopefully consuming the attacker&#8217;s resources.</p>
</div>
</div>
<div class="sect3">
<h4 id="dos-filter-using"><a class="anchor" href="#dos-filter-using"></a><a class="link" href="#dos-filter-using">Using the DoS Filter</a></h4>
<div class="paragraph">
<p>Jetty places throttled requests in a priority queue, giving priority first to authenticated users and users with an HttpSession, then to connections identified by their IP addresses.
Connections with no way to identify them have lowest priority.
To uniquely identify authenticated users, you should implement the The extractUserId(ServletRequest request) function.</p>
</div>
<div class="sect4">
<h5 id="_required-jars-2"><a class="anchor" href="#_required-jars-2"></a><a class="link" href="#_required-jars-2">Required JARs</a></h5>
<div class="paragraph">
<p>To use the DoS Filter, these JAR files must be available in WEB-INF/lib:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>$JETTY_HOME/lib/jetty-util.jar</p>
</li>
<li>
<p>$JETTY_HOME/lib/jetty-servlets.jar</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="_sample-configuration-2"><a class="anchor" href="#_sample-configuration-2"></a><a class="link" href="#_sample-configuration-2">Sample Configuration</a></h5>
<div class="paragraph">
<p>Place the configuration in a webapp&#8217;s <code>web.xml</code> or <code>jetty-web.xml</code>.
The default configuration allows 25 requests per connection at a time, servicing more important requests first, and queuing up the rest.
This example allow 30 requests at a time:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;filter&gt;
&lt;filter-name&gt;DoSFilter&lt;/filter-name&gt;
&lt;filter-class&gt;org.eclipse.jetty.servlets.DoSFilter&lt;/filter-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;maxRequestsPerSec&lt;/param-name&gt;
&lt;param-value&gt;30&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;/filter&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="dos-filter-init"><a class="anchor" href="#dos-filter-init"></a><a class="link" href="#dos-filter-init">Configuring DoS Filter Parameters</a></h5>
<div class="paragraph">
<p>The following <code>init</code> parameters control the behavior of the filter:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">maxRequestsPerSec</dt>
<dd>
<p>Maximum number of requests from a connection per second.
Requests in excess of this are first delayed, then throttled.
Default is 25.</p>
</dd>
<dt class="hdlist1">delayMs</dt>
<dd>
<p>Delay imposed on all requests over the rate limit, before they are considered at all:</p>
<div class="ulist">
<ul>
<li>
<p>100 (ms) = Default</p>
</li>
<li>
<p>-1 = Reject request</p>
</li>
<li>
<p>0 = No delay</p>
</li>
<li>
<p>any other value = Delay in ms</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1">maxWaitMs</dt>
<dd>
<p>Length of time, in ms, to blocking wait for the throttle semaphore.
Default is 50 ms.</p>
</dd>
<dt class="hdlist1">throttledRequests</dt>
<dd>
<p>Number of requests over the rate limit able to be considered at once.
Default is 5.</p>
</dd>
<dt class="hdlist1">throttleMs</dt>
<dd>
<p>Length of time, in ms, to async wait for semaphore. Default is 30000L.</p>
</dd>
<dt class="hdlist1">maxRequestMs</dt>
<dd>
<p>Length of time, in ms, to allow the request to run. Default is 30000L.</p>
</dd>
<dt class="hdlist1">maxIdleTrackerMs</dt>
<dd>
<p>Length of time, in ms, to keep track of request rates for a connection, before deciding that the user has gone away, and discarding it.
Default is 30000L.</p>
</dd>
<dt class="hdlist1">insertHeaders</dt>
<dd>
<p>If true, insert the DoSFilter headers into the response.
Defaults to true.</p>
</dd>
<dt class="hdlist1">trackSessions</dt>
<dd>
<p>If true, usage rate is tracked by session if a session exists.
Defaults to true.</p>
</dd>
<dt class="hdlist1">remotePort</dt>
<dd>
<p>If true and session tracking is not used, then rate is tracked by IP and port (effectively connection).
Defaults to false.</p>
</dd>
<dt class="hdlist1">ipWhitelist</dt>
<dd>
<p>A comma-separated list of IP addresses that will not be rate limited.</p>
</dd>
<dt class="hdlist1">managedAttr</dt>
<dd>
<p>If set to true, then this servlet is set as a ServletContext attribute with the filter name as the attribute name.
This allows a context external mechanism (for example, JMX via <code>ContextHandler.MANAGED_ATTRIBUTES</code>) to manage the configuration of the filter.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="header-filter"><a class="anchor" href="#header-filter"></a><a class="link" href="#header-filter">Header Filter</a></h3>
<div class="sect3">
<h4 id="header-filter-metadata"><a class="anchor" href="#header-filter-metadata"></a><a class="link" href="#header-filter-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.servlets.HeaderFilter</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-servlets</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlets/HeaderFilter.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlets/HeaderFilter.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="header-filter-usage"><a class="anchor" href="#header-filter-usage"></a><a class="link" href="#header-filter-usage">Usage</a></h4>
<div class="paragraph">
<p>The header filter sets or adds headers to each response based on an optionally included/excluded list of path specs, mime types, and/or HTTP methods.
This filter processes its configured headers before calling <code>doFilter</code> in the filter chain. Some of the headers configured in this filter may get overwritten by other filters and/or the servlet processing the request.</p>
</div>
<div class="sect4">
<h5 id="_required-jars-3"><a class="anchor" href="#_required-jars-3"></a><a class="link" href="#_required-jars-3">Required JARs</a></h5>
<div class="paragraph">
<p>To use the Header Filter, these JAR files must be available in WEB-INF/lib:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>$JETTY_HOME/lib/jetty-http.jar</p>
</li>
<li>
<p>$JETTY_HOME/lib/jetty-servlets.jar</p>
</li>
<li>
<p>$JETTY_HOME/lib/jetty-util.jar</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="_sample-configuration-3"><a class="anchor" href="#_sample-configuration-3"></a><a class="link" href="#_sample-configuration-3">Sample Configuration</a></h5>
<div class="paragraph">
<p>Place the configuration in a webapp&#8217;s <code>web.xml</code> or <code>jetty-web.xml</code>.
This filter will perform the following actions on each response:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Set the X-Frame-Options header to DENY.</p>
</li>
<li>
<p>Add a Cache-Control header containing no-cache, no-store, must-revalidate</p>
</li>
<li>
<p>Set the Expires header to approximately one year in the future.</p>
</li>
<li>
<p>Add a Date header with the current system time.</p>
</li>
</ul>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Each action must be separated by a comma.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;filter&gt;
&lt;filter-name&gt;HeaderFilter&lt;/filter-name&gt;
&lt;filter-class&gt;org.eclipse.jetty.servlets.HeaderFilter&lt;/filter-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;headerConfig&lt;/param-name&gt;
&lt;param-value&gt;
set X-Frame-Options: DENY,
"add Cache-Control: no-cache, no-store, must-revalidate",
setDate Expires: 31540000000,
addDate Date: 0
&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;/filter&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="header-filter-init"><a class="anchor" href="#header-filter-init"></a><a class="link" href="#header-filter-init">Configuring Header Filter Parameters</a></h5>
<div class="paragraph">
<p>The following <code>init</code> parameters control the behavior of the filter:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">includedPaths</dt>
<dd>
<p>Optional. Comma separated values of included path specs.</p>
</dd>
<dt class="hdlist1">excludedPaths</dt>
<dd>
<p>Optional. Comma separated values of excluded path specs.</p>
</dd>
<dt class="hdlist1">includedMimeTypes</dt>
<dd>
<p>Optional. Comma separated values of included mime types. The mime type will be guessed from the extension at the end of the request URL if the content type has not been set on the response.</p>
</dd>
<dt class="hdlist1">excludedMimeTypes</dt>
<dd>
<p>Optional. Comma separated values of excluded mime types. The mime type will be guessed from the extension at the end of the request URL if the content type has not been set on the response.</p>
</dd>
<dt class="hdlist1">includedHttpMethods</dt>
<dd>
<p>Optional. Comma separated values of included http methods.</p>
</dd>
<dt class="hdlist1">excludedHttpMethods</dt>
<dd>
<p>Optional. Comma separated values of excluded http methods.</p>
</dd>
<dt class="hdlist1">headerConfig</dt>
<dd>
<p>Comma separated values of actions to perform on headers. The syntax for each action is <code>action headerName: headerValue</code>.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Supported header actions:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>set</code> - causes set <code>setHeader</code> to be called on the response</p>
</li>
<li>
<p><code>add</code> - causes set <code>addHeader</code> to be called on the response</p>
</li>
<li>
<p><code>setDate</code> - causes <code>setDateHeader</code> to be called on the response.</p>
</li>
<li>
<p><code>addDate</code> - causes <code>addDateHeader</code> to be called on the response.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If <code>setDate</code> or <code>addDate</code> is used, <code>headerValue</code> should be the number of milliseconds to add to the current system time before writing the header value.</p>
</div>
<div class="paragraph">
<p>If a property is both included and excluded by the filter configuration, then it will be considered excluded.</p>
</div>
<div class="paragraph">
<p>Path spec rules:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>If the spec starts with <code>^</code>, the spec is assumed to be a regex based path spec and will match with normal Java regex rules.</p>
</li>
<li>
<p>If the spec starts with <code>/</code>, the spec is assumed to be a Servlet url-pattern rules path spec for either an exact match or prefix based match.</p>
</li>
<li>
<p>If the spec starts with <code>*.</code>, the spec is assumed to be a Servlet url-pattern rules path spec for a suffix based match.</p>
</li>
<li>
<p>All other syntaxes are unsupported.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="gzip-filter"><a class="anchor" href="#gzip-filter"></a><a class="link" href="#gzip-filter">Gzip Handler</a></h3>
<div class="sect3">
<h4 id="gzip-filter-metadata"><a class="anchor" href="#gzip-filter-metadata"></a><a class="link" href="#gzip-filter-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.server.handler.gzip.GzipHandler</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-servlets</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/gzip/GzipHandler.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/gzip/GzipHandler.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="gzip-filter-usage"><a class="anchor" href="#gzip-filter-usage"></a><a class="link" href="#gzip-filter-usage">Usage</a></h4>
<div class="paragraph">
<p>The Jetty <code>GzipHandler</code> is a compression handler that you can apply to any dynamic resource (servlet).
It fixes many of the bugs in commonly available compression filters: it works with asynchronous servlets; it handles all ways to set content length.
Some user-agents might be excluded from compression to avoid common browser bugs (yes, this means IE!).</p>
</div>
<div class="paragraph">
<p>The <code>GzipHandler</code> can be added to the entire server by enabling the <code>gzip.mod</code> module.
It may also be added to individual contexts in a context xml file.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Jetty 9 only compresses using GZip.
Using deflate HTTP compression is not supported and will not function.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="gzip-filter-rules"><a class="anchor" href="#gzip-filter-rules"></a><a class="link" href="#gzip-filter-rules">Gzip Rules</a></h4>
<div class="paragraph">
<p><code>GzipHandler</code> will gzip the content of a response if:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>It is mapped to a matching path</p>
</li>
<li>
<p>The request method is configured to support gzip</p>
</li>
<li>
<p>The request is not from an excluded User-Agent</p>
</li>
<li>
<p>accept-encoding header is set to gzip</p>
</li>
<li>
<p>The response status code is &gt;=200 and &lt;300</p>
</li>
<li>
<p>The content length is unknown or more than the minGzipSize initParameter or the minGzipSize is 0(default)</p>
</li>
<li>
<p>The content-type does not match an excluded mime-type</p>
</li>
<li>
<p>No content-encoding is specified by the resource</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Compressing the content can greatly improve the network bandwidth usage, but at the cost of memory and CPU cycles.
The <a href="#default-servlet">DefaultServlet</a> is capable of serving pre-compressed static content, which saves memory and CPU.</p>
</div>
<div class="paragraph">
<p>The <code>GzipHandler</code> installs an output interceptor which passes through to the <code>DefaultServlet</code>.
If the content served by <code>DefaultServlet</code> is already compressed, the <code>GzipHandler</code> does nothing; if it is not compressed, the content is compressed on-the-fly.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Automatic precompression by the <code>DefaultServlet</code> can be configured.
Read more about the <code>DefaultServlet</code> <a href="#default-servlet">here.</a>
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="gzip-filter-init"><a class="anchor" href="#gzip-filter-init"></a><a class="link" href="#gzip-filter-init">Gzip Configuration</a></h4>
<div class="dlist">
<dl>
<dt class="hdlist1">minGzipSize</dt>
<dd>
<p>Content will only be compressed if content length is either unknown or greater than <code>minGzipSize</code>.</p>
</dd>
<dt class="hdlist1">checkGzExists (Deprecated)</dt>
<dd>
<p>False by default.
If set to true, the handler will check for pre-compressed content.</p>
</dd>
<dt class="hdlist1">includedMethods</dt>
<dd>
<p>List of HTTP methods to compress.
If not set, only <code>GET</code> requests are compressed.</p>
</dd>
<dt class="hdlist1">includedMimeTypes</dt>
<dd>
<p>List of MIME types to compress.</p>
</dd>
<dt class="hdlist1">excludedMimeTypes</dt>
<dd>
<p>List of MIME types not to compress.</p>
</dd>
<dt class="hdlist1">excludedAgentPatterns</dt>
<dd>
<p>A list of regex patterns for User-Agent names from which requests should not be compressed.</p>
</dd>
<dt class="hdlist1">excludedPaths</dt>
<dd>
<p>List of paths to exclude from compression.
Performs a <code>String.startsWith(String)</code> comparison to check if the path matches.
If it does match then there is no compression.
To match subpaths use excludePathPatterns instead.</p>
</dd>
<dt class="hdlist1">includedPaths</dt>
<dd>
<p>List of paths to consider for compression.</p>
</dd>
<dt class="hdlist1">includePaths</dt>
<dd>
<p>List of paths to definitely consider for compression.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect2">
<h3 id="cross-origin-filter"><a class="anchor" href="#cross-origin-filter"></a><a class="link" href="#cross-origin-filter">Cross Origin Filter</a></h3>
<div class="sect3">
<h4 id="cross-origin-filter-metadata"><a class="anchor" href="#cross-origin-filter-metadata"></a><a class="link" href="#cross-origin-filter-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.servlets.CrossOriginFilter</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-servlets</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlets/CrossOriginFilter.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlets/CrossOriginFilter.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="cross-origin-filter-usage"><a class="anchor" href="#cross-origin-filter-usage"></a><a class="link" href="#cross-origin-filter-usage">Usage</a></h4>
<div class="paragraph">
<p>HTTP requests made from a script are subject to well known restrictions, the most prominent being the same domain policy.</p>
</div>
<div class="paragraph">
<p>Firefox 3.5 introduced support for W3C&#8217;s Access Control for Cross-Site Requests specification, which requires a compliant client (for example, Firefox 3.5) and a compliant server (via this servlet filter).</p>
</div>
<div class="paragraph">
<p>This filter implements the required bits to support the server-side contract of the specification, and will allow a compliant client to perform cross-domain requests via the standard XMLHttpRequest object.
If the client does not issue a compliant cross-domain request, this filter does nothing, and its overhead is the check of the presence of the cross-domain HTTP header.</p>
</div>
<div class="paragraph">
<p>This is extremely useful in CometD web applications where it is now possible to perform cross-domain long polling without using script injection (also known as the JSONP transport), and therefore removing all the downsides that the JSONP transport has (it&#8217;s chattier, does not react quickly to failures, has a message size limit, uses GET instead of POST, etc.).</p>
</div>
</div>
<div class="sect3">
<h4 id="cross-origin-setup"><a class="anchor" href="#cross-origin-setup"></a><a class="link" href="#cross-origin-setup">Setup</a></h4>
<div class="paragraph">
<p>You will need to put the <code>jetty-servlets.jar</code> file onto your classpath.
If you are creating a webapp, ensure that this jar is included in your webapp&#8217;s <code>WEB-INF/lib</code>.
Or, if you are running Jetty embedded you will need to ensure that <code>jetty-servlets.jar</code> is on the execution classpath.
You can download the <code>jetty-servlets.jar</code> from the Maven Central Repository at <a href="https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-servlets/" class="bare">https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-servlets/</a>.
It is also available as part of the Jetty distribution in the <code>$JETTY_HOME/lib</code> directory.</p>
</div>
</div>
<div class="sect3">
<h4 id="cross-origin-config"><a class="anchor" href="#cross-origin-config"></a><a class="link" href="#cross-origin-config">Configuration</a></h4>
<div class="paragraph">
<p>This is a regular servlet filter that must be configured in <code>web.xml</code>.</p>
</div>
<div class="paragraph">
<p>It supports the following configuration parameters:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">allowedOrigins</dt>
<dd>
<p>A comma separated list of origins that are allowed to access the resources.
Default value is: * (all origins)</p>
</dd>
<dt class="hdlist1">allowedMethods</dt>
<dd>
<p>A comma separated list of HTTP methods that are allowed to be used when accessing the resources.
Default value is: GET,POST,HEAD</p>
</dd>
<dt class="hdlist1">allowedHeaders</dt>
<dd>
<p>A comma separated list of HTTP headers that are allowed to be specified when accessing the resources.
Default value is: X-Requested-With,Content-Type,Accept,Origin</p>
</dd>
<dt class="hdlist1">allowCredentials</dt>
<dd>
<p>A boolean indicating if the resource allows requests with credentials.
Default value is: true</p>
</dd>
<dt class="hdlist1">preflightMaxAge</dt>
<dd>
<p>The number of seconds that preflight requests can be cached by the client.
Default value is 1800 seconds (30 minutes)</p>
</dd>
<dt class="hdlist1">chainPreflight</dt>
<dd>
<p>If true preflight requests are chained to their target resource for normal handling (as an OPTION request).
Otherwise the filter will response to the preflight.
Default is true.</p>
</dd>
<dt class="hdlist1">exposedHeaders</dt>
<dd>
<p>A comma separated list of HTTP headers that are allowed to be exposed on the client.
Default value is the empty list.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>A typical configuration could be:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;web-app&gt;
&lt;filter&gt;
&lt;filter-name&gt;cross-origin&lt;/filter-name&gt;
&lt;filter-class&gt;org.eclipse.jetty.servlets.CrossOriginFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;cross-origin&lt;/filter-name&gt;
&lt;url-pattern&gt;/cometd/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
&lt;/web-app&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="resource-handler"><a class="anchor" href="#resource-handler"></a><a class="link" href="#resource-handler">Resource Handler</a></h3>
<div class="sect3">
<h4 id="resource-handler-metadata"><a class="anchor" href="#resource-handler-metadata"></a><a class="link" href="#resource-handler-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.server.handler.ResourceHandler</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-server</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ResourceHandler.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ResourceHandler.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="resource-handler-usage"><a class="anchor" href="#resource-handler-usage"></a><a class="link" href="#resource-handler-usage">Usage</a></h4>
<div class="paragraph">
<p>This handler will serve static content and handle If-Modified-Since headers and is suitable for simple serving of static content.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
There is no caching done with this handler, so if you are looking for a more fully featured way of serving static content look to the <a href="#default-servlet">Default Servlet</a>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Requests for resources that do not exist are let pass (Eg no 404&#8217;s).
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="_improving-the-look-and-feel"><a class="anchor" href="#_improving-the-look-and-feel"></a><a class="link" href="#_improving-the-look-and-feel">Improving the Look and Feel</a></h4>
<div class="paragraph">
<p>The resource handler has a default stylesheet which you can change by calling <code>setStyleSheet(String location)</code> with the location of a file on the system that it can locate through the resource loading system.
The default css is called <code>jetty-dir.css</code> and is located in the <code>jetty-util</code> package, pulled as a classpath resource from the <code>jetty-util</code> jar when requested through the <code>ResourceHandler</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="_embedded-example"><a class="anchor" href="#_embedded-example"></a><a class="link" href="#_embedded-example">Embedded Example</a></h4>
<div class="paragraph">
<p>The following is an example of a split fileserver, able to serve static content from multiple directory locations.
Since this handler does not return 404&#8217;s on content you are able to iteratively try multiple resource handlers to resolve content.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in extras/resource-handler.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/SplitFileServer.java[]</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="debug-handler"><a class="anchor" href="#debug-handler"></a><a class="link" href="#debug-handler">Debug Handler</a></h3>
<div class="sect3">
<h4 id="debug-handler-metadata"><a class="anchor" href="#debug-handler-metadata"></a><a class="link" href="#debug-handler-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.server.handler.DebugHandler</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-server</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/DebugHandler.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/DebugHandler.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="debug-handler-usage"><a class="anchor" href="#debug-handler-usage"></a><a class="link" href="#debug-handler-usage">Usage</a></h4>
<div class="paragraph">
<p>A simple handler that is useful to debug incoming traffic.
It will log entry and exit points of HTTP requests as well as the response code.</p>
</div>
</div>
<div class="sect3">
<h4 id="_usage-in-standard-distribution"><a class="anchor" href="#_usage-in-standard-distribution"></a><a class="link" href="#_usage-in-standard-distribution">Usage in Standard Distribution</a></h4>
<div class="paragraph">
<p>The debug handler can be added to Jetty by activating the <code>debug</code> module.</p>
</div>
</div>
<div class="sect3">
<h4 id="_embedded-usage"><a class="anchor" href="#_embedded-usage"></a><a class="link" href="#_embedded-usage">Embedded usage</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Server server = new Server(8080);
RolloverFileOutputStream outputStream = new RolloverFileOutputStream("MeinLogPfad/yyyy_mm_dd.request.log", true,10);
DebugHandler debugHandler = new DebugHandler();
debugHandler.setOutputStream(outputStream);
debugHandler.setHandler(server.getHandler());
server.setHandler(debugHandler);
server.start();</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_example-output"><a class="anchor" href="#_example-output"></a><a class="link" href="#_example-output">Example output</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">15:14:05.838:qtp551889550-13-selector-0 OPENED HttpConnection@e910ee4{IDLE},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of 0}
15:14:05.846:qtp551889550-57:http://0:0:0:0:0:0:0:1:8080/ REQUEST 0:0:0:0:0:0:0:1 GET __utma=111872281.10102721.1321534299.1369833564.1370447492.35; __utmz=111872281.1321534299.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _opt_vi_RPY720HZ=75E12E63-0CD0-4D6F-8383-C90D5C8397C7; Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:22.0) Gecko/20100101 Firefox/22.0
15:14:05.894:qtp551889550-57:http://0:0:0:0:0:0:0:1:8080/ RESPONSE 200 null
15:14:05.959:qtp551889550-59:http://0:0:0:0:0:0:0:1:8080/jetty.css REQUEST 0:0:0:0:0:0:0:1 GET __utma=111872281.10102721.1321534299.1369833564.1370447492.35; __utmz=111872281.1321534299.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _opt_vi_RPY720HZ=75E12E63-0CD0-4D6F-8383-C90D5C8397C7; visited=yes; Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:22.0) Gecko/20100101 Firefox/22.0
15:14:05.962:qtp551889550-59:http://0:0:0:0:0:0:0:1:8080/jetty.css RESPONSE 200 null
15:14:06.052:qtp551889550-57:http://0:0:0:0:0:0:0:1:8080/images/jetty-header.jpg REQUEST 0:0:0:0:0:0:0:1 GET __utma=111872281.10102721.1321534299.1369833564.1370447492.35; __utmz=111872281.1321534299.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _opt_vi_RPY720HZ=75E12E63-0CD0-4D6F-8383-C90D5C8397C7; visited=yes; Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:22.0) Gecko/20100101 Firefox/22.0
15:14:06.055:qtp551889550-57:http://0:0:0:0:0:0:0:1:8080/images/jetty-header.jpg RESPONSE 200 null
15:14:07.248:qtp551889550-59:http://0:0:0:0:0:0:0:1:8080/favicon.ico REQUEST 0:0:0:0:0:0:0:1 GET __utma=111872281.10102721.1321534299.1369833564.1370447492.35; __utmz=111872281.1321534299.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _opt_vi_RPY720HZ=75E12E63-0CD0-4D6F-8383-C90D5C8397C7; visited=yes; Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:22.0) Gecko/20100101 Firefox/22.0
15:14:07.251:qtp551889550-59:http://0:0:0:0:0:0:0:1:8080/favicon.ico RESPONSE 404 text/html;charset=ISO-8859-1
15:14:09.330:qtp551889550-57 CLOSED HttpConnection@e910ee4{INTERESTED},g=HttpGenerator{s=START},p=HttpParser{s=START,0 of -1}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="statistics-handler"><a class="anchor" href="#statistics-handler"></a><a class="link" href="#statistics-handler">Statistics Handler</a></h3>
<div class="sect3">
<h4 id="statistics-handler-metadata"><a class="anchor" href="#statistics-handler-metadata"></a><a class="link" href="#statistics-handler-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.server.handler.StatisticsHandler</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-server</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/StatisticsHandler.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/StatisticsHandler.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="statistics-handler-usage"><a class="anchor" href="#statistics-handler-usage"></a><a class="link" href="#statistics-handler-usage">Usage</a></h4>
<div class="paragraph">
<p>Jetty currently has two main statistics collection mechanisms:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Instances of <code>ConnectionStatistics</code> can collect statistics for each connection of a connector.</p>
</li>
<li>
<p>The <code>StatisticsHandler</code> class may be used to collect statistics for HTTP requests.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code>StatisticsHandler</code> and <code>ConnectionStatistics</code> are not included in the default Jetty configuration, these need to be configured manually or enabled using the Jetty <code>stats</code> module on the command line.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ java -jar {$jetty.home}/start.jar --add-to-start=stats</code></pre>
</div>
</div>
<div class="paragraph">
<p>In addition to these, the <code>SessionHandler</code> and <code>DefaultSessionCache</code> classes collect statistics for sessions.
These statistics are enabled by default and are accessible via JMX interface.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
To view statistics, you have to be able to connect to Jetty using either JConsole or some other JMX agent. See <a href="#using-jmx">Using JMX with Jetty</a> for more information.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="request-statistics"><a class="anchor" href="#request-statistics"></a><a class="link" href="#request-statistics">Request Statistics</a></h4>
<div class="paragraph">
<p>To collect request statistics a <code>StatisticsHandler</code> must be configured as one of the handlers of the server.
Typically this can be done as the top level handler, but you may choose to configure a statistics handler for just one context by creating a context configuration file.
You can enable the <code>StatisticsHandler</code> by activating the <code>stats</code> modules on the command line.</p>
</div>
<div class="paragraph">
<p>Alternately, if you are making multiple changes to the Jetty configuration, you could include statistics handler configuration into your own Jetty xml configuration.
The following fragment shows how to configure a top level statistics handler:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;Call name="insertHandler"&gt;
&lt;Arg&gt;
&lt;New id="StatsHandler" class="org.eclipse.jetty.server.handler.StatisticsHandler"/&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="connection-statistics"><a class="anchor" href="#connection-statistics"></a><a class="link" href="#connection-statistics">Connection Statistics</a></h4>
<div class="paragraph">
<p>Detailed statistics on connection duration and number of messages are only collated when a connection is closed.
The current and maximum number of connections are the only "live" statistics.</p>
</div>
<div class="paragraph">
<p>The following example shows how to turn on connection statistics in the Jetty XML format.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;Call name="addBeanToAllConnectors"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.io.ConnectionStatistics"/&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>A special variant of <code>ConnectionStatistics</code> called <code>IncludeExcludeConnectionStatistics</code> allows you to refine which types of connection you want to collect statistics for.</p>
</div>
<div class="paragraph">
<p>The following example shows how this can be used to record statistics only for WebSocket connections.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;Call name="addBeanToAllConnectors"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.io.IncludeExcludeConnectionStatistics"&gt;
&lt;Call name="include" arg="org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection"/&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="session-statistics"><a class="anchor" href="#session-statistics"></a><a class="link" href="#session-statistics">Session Statistics</a></h4>
<div class="paragraph">
<p>Session handling is built into Jetty for any servlet or webapp context.
Detailed statistics on session duration are only collated when a session is closed.
The current, minimum, and maximum number of sessions are the only "live" statistics.
The session statistics are enabled by default and do not need to be configured.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="inetaccess-handler"><a class="anchor" href="#inetaccess-handler"></a><a class="link" href="#inetaccess-handler">InetAccess Handler</a></h3>
<div class="sect3">
<h4 id="inetaccess-handler-metadata"><a class="anchor" href="#inetaccess-handler-metadata"></a><a class="link" href="#inetaccess-handler-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.server.handler.InetAccessHandler</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-server</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/InetAccessHandler.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/InetAccessHandler.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="inetaccess-handler-usage"><a class="anchor" href="#inetaccess-handler-usage"></a><a class="link" href="#inetaccess-handler-usage">Usage</a></h4>
<div class="paragraph">
<p>Controls access to the wrapped handler using the real remote IP. Control is provided by and <code>IncludeExcludeSet</code> over a <code>InetAddressSet</code>.
This handler uses the real internet address of the connection, not one reported in the forwarded for headers, as this cannot be as easily forged.</p>
</div>
</div>
<div class="sect3">
<h4 id="_usage-in-standard-distribution-2"><a class="anchor" href="#_usage-in-standard-distribution-2"></a><a class="link" href="#_usage-in-standard-distribution-2">Usage in Standard Distribution</a></h4>
<div class="paragraph">
<p>The InetAccess handler can be added to Jetty by activating the <code>inetaccess</code> module.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="moved-context-handler"><a class="anchor" href="#moved-context-handler"></a><a class="link" href="#moved-context-handler">Moved Context Handler</a></h3>
<div class="sect3">
<h4 id="moved-context-handler-metadata"><a class="anchor" href="#moved-context-handler-metadata"></a><a class="link" href="#moved-context-handler-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.server.handler.MovedContextHandler</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-server</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/MovedContextHandler.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/MovedContextHandler.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="moved-context-handler-usage"><a class="anchor" href="#moved-context-handler-usage"></a><a class="link" href="#moved-context-handler-usage">Usage</a></h4>
<div class="paragraph">
<p>You can use the <code>MovedContextHandler</code> to relocate or redirect a context that has changed context path and/or virtual hosts.</p>
</div>
<div class="paragraph">
<p>You can configure it to <em>permanently</em> redirect the old URL to the new URL, in which case Jetty sends a Http Status code of 301 to the browser with the new URL.
Alternatively, you can make it non-permanent, in which case Jetty sends a 302 Http Status code along with the new URL.</p>
</div>
<div class="paragraph">
<p>In addition, as with any other context, you can configure a list of virtual hosts, meaning that this context responds only to requests to one of the listed host names.</p>
</div>
<div class="paragraph">
<p>Suppose you have a context deployed at <code>/foo</code>, but that now you want to deploy at the root context <code>/</code> instead.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>First you reconfigure and redeploy the context on Jetty.</p>
</li>
<li>
<p>Next you need a way to redirect all the browsers who have bookmarked <code>/foo</code> to the new path.
You create a new <a href="#configuring-contexts">context xml</a> file in <code>{$jetty/.base}/webapps</code> and configure the <code>MovedContextHandler</code> to do the redirection from <code>/foo</code> to <code>/</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Below is an example.
This is a permanent redirection, which also preserves <code>pathinfo</code> and query strings on the redirect:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.server.handler.MovedContextHandler"&gt;
&lt;Set name="contextPath"&gt;/foo&lt;/Set&gt;
&lt;Set name="newContextURL"&gt;/&lt;/Set&gt;
&lt;Set name="permanent"&gt;true&lt;/Set&gt;
&lt;Set name="discardPathInfo"&gt;false&lt;/Set&gt;
&lt;Set name="discardQuery"&gt;false&lt;/Set&gt;
&lt;Set name="virtualHosts"&gt;
&lt;Array type="String"&gt;
&lt;Item&gt;209.235.245.73&lt;/Item&gt;
&lt;Item&gt;127.0.0.73&lt;/Item&gt;
&lt;Item&gt;acme.org&lt;/Item&gt;
&lt;Item&gt;www.acme.org&lt;/Item&gt;
&lt;Item&gt;server.acme.org&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="shutdown-handler"><a class="anchor" href="#shutdown-handler"></a><a class="link" href="#shutdown-handler">Shutdown Handler</a></h3>
<div class="sect3">
<h4 id="shutdown-handler-metadata"><a class="anchor" href="#shutdown-handler-metadata"></a><a class="link" href="#shutdown-handler-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.server.handler.ShutdownHandler</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-server</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ShutdownHandler.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ShutdownHandler.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="shutdown-handler-usage"><a class="anchor" href="#shutdown-handler-usage"></a><a class="link" href="#shutdown-handler-usage">Usage</a></h4>
<div class="paragraph">
<p>A handler that shuts the server down on a valid request.
This is used to perform "soft" restarts from Java.
If <code>_exitJvm</code> is set to true a hard <code>System.exit()</code> call is being made.</p>
</div>
<div class="paragraph">
<p>This is an example of how you can setup this handler directly with the Server.
It can also be added as a part of handler chain or collection.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java"> Server server = new Server(8080);
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]
{ someOtherHandler, new ShutdownHandler(server,"secret password") });
server.setHandler(handlers);
server.start();</code></pre>
</div>
</div>
<div class="paragraph">
<p>This is an example that you can use to call the shutdown handler from within java.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java"> public static void attemptShutdown(int port, String shutdownCookie) {
try {
URL url = new URL("http://localhost:" + port + "/shutdown?token=" + shutdownCookie);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.getResponseCode();
logger.info("Shutting down " + url + ": " + connection.getResponseMessage());
} catch (SocketException e) {
logger.debug("Not running");
// Okay - the server is not running
} catch (IOException e) {
throw new RuntimeException(e);
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="default-handler"><a class="anchor" href="#default-handler"></a><a class="link" href="#default-handler">Default Handler</a></h3>
<div class="sect3">
<h4 id="default-handler-metadata"><a class="anchor" href="#default-handler-metadata"></a><a class="link" href="#default-handler-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.server.handler.DefaultHandler</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-server</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/DefaultHandler.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/DefaultHandler.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="default-handler-usage"><a class="anchor" href="#default-handler-usage"></a><a class="link" href="#default-handler-usage">Usage</a></h4>
<div class="paragraph">
<p>A simple handler that is useful to terminate handler chains with a clean fashion.
As in the example below, if a resource to be served is not matched within the resource handler the <code>DefaultHandler</code> will take care of producing a 404 page.
This class is a useful template to either extend and embrace or simply provide a similar implementation for customizing to your needs.
There is also an <a href="#error-handler">Error Handler</a> that services errors related to the servlet api specification, so it is best to not get the two confused.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The <code>DefaultHandler</code> will also handle serving out the <code>flav.ico</code> file should a request make it through all of the other handlers without being resolved.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java"> Server server = new Server(8080);
HandlerList handlers = new HandlerList();
ResourceHandler resourceHandler = new ResourceHandler();
resourceHandler.setBaseResource(Resource.newResource("."));
handlers.setHandlers(new Handler[]
{ resourceHandler, new DefaultHandler() });
server.setHandler(handlers);
server.start();</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="error-handler"><a class="anchor" href="#error-handler"></a><a class="link" href="#error-handler">Error Handler</a></h3>
<div class="sect3">
<h4 id="error-handler-metadata"><a class="anchor" href="#error-handler-metadata"></a><a class="link" href="#error-handler-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: <code>org.eclipse.jetty.server.handler.ErrorHandler</code></p>
</li>
<li>
<p>Maven Artifact: org.eclipse.jetty:jetty-server</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ErrorHandler.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ErrorHandler.html</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="error-handler-usage"><a class="anchor" href="#error-handler-usage"></a><a class="link" href="#error-handler-usage">Usage</a></h4>
<div class="paragraph">
<p>A handler that is used to report errors from servlet contexts and webapp contexts to report error conditions.
Primarily handles setting the various servlet spec specific response headers for error conditions.
Can be customized by extending; for more information on this see <a href="#custom-error-pages">Creating Custom Error Pages</a>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="rewrite-handler"><a class="anchor" href="#rewrite-handler"></a><a class="link" href="#rewrite-handler">Rewrite Handler</a></h3>
<div class="paragraph">
<p>The <code>RewriteHandler</code> matches a request against a set of rules, and modifies the request accordingly for any rules that match.
The most common use is to rewrite request URIs, but it is capable of much more: rules can also be configured to redirect the response, set a cookie or response code on the response, modify the header, etc.</p>
</div>
<div class="sect3">
<h4 id="rewrite-handler-metadata"><a class="anchor" href="#rewrite-handler-metadata"></a><a class="link" href="#rewrite-handler-metadata">Info</a></h4>
<div class="ulist">
<ul>
<li>
<p>Classname: org.eclipse.jetty.rewrite.handler.RewriteHandler</p>
</li>
<li>
<p>Maven artifact: org.eclipse.jetty:jetty-rewrite</p>
</li>
<li>
<p>Javadoc: <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/rewrite/handler/RewriteHandler.html" class="bare">http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/rewrite/handler/RewriteHandler.html</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The standard Jetty distribution bundle contains the <code>jetty-rewrite</code> <a href="#startup-modules">module</a>, so all you need to do is to enable it using one of the <a href="#start-jar">module commands</a>, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ java -jar start.jar --add-to-start=rewrite</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If you are running the standard Jetty distribution with the sample test webapp, there will be a demo of the rewrite module at <a href="http://localhost:8080/test/rewrite/" class="bare">http://localhost:8080/test/rewrite/</a>
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="_usage"><a class="anchor" href="#_usage"></a><a class="link" href="#_usage">Usage</a></h4>
<div class="paragraph">
<p>The rewrite module enables the following Jetty xml config file on the execution path:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0"?&gt;&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd"&gt;
&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;!-- =========================================================== --&gt;
&lt;!-- configure rewrite handler --&gt;
&lt;!-- =========================================================== --&gt;
&lt;Call name="insertHandler"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.rewrite.handler.RewriteHandler"&gt;
&lt;Set name="rewriteRequestURI" property="jetty.rewrite.rewriteRequestURI" /&gt;
&lt;Set name="rewritePathInfo" property="jetty.rewrite.rewritePathInfo" /&gt;
&lt;Set name="originalPathAttribute" property="jetty.rewrite.originalPathAttribute" /&gt;
&lt;!-- Set DispatcherTypes --&gt;
&lt;Set name="dispatcherTypes"&gt;
&lt;Array type="javax.servlet.DispatcherType"&gt;
&lt;Item&gt;
&lt;Call class="javax.servlet.DispatcherType" name="valueOf"&gt;
&lt;Arg&gt;REQUEST&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Item&gt;
&lt;Item&gt;
&lt;Call class="javax.servlet.DispatcherType" name="valueOf"&gt;
&lt;Arg&gt;ASYNC&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Set&gt;
&lt;Get id="Rewrite" name="ruleContainer" /&gt;
&lt;!-- see rewrite-rules.xml in $JETTY_BASE for how to add a rule(s) --&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>As the commented out code shows, you configure the <code>RewriteHandler</code> by adding various rules.</p>
</div>
<div class="paragraph">
<p>There is an example of <a href="#rewrite-rules">rules</a> configuration in the standard distribution in the <code>demo-base/etc/demo-rewrite-rules.xml</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd"&gt;
&lt;!-- =============================================================== --&gt;
&lt;!-- Configure the demos --&gt;
&lt;!-- =============================================================== --&gt;
&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;!-- ============================================================= --&gt;
&lt;!-- Add rewrite rules --&gt;
&lt;!-- ============================================================= --&gt;
&lt;Ref refid="Rewrite"&gt;
&lt;!-- Add rule to protect against IE ssl bug --&gt;
&lt;Call name="addRule"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.rewrite.handler.MsieSslRule"/&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;!-- protect favicon handling --&gt;
&lt;Call name="addRule"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule"&gt;
&lt;Set name="pattern"&gt;/favicon.ico&lt;/Set&gt;
&lt;Set name="name"&gt;Cache-Control&lt;/Set&gt;
&lt;Set name="value"&gt;Max-Age=3600,public&lt;/Set&gt;
&lt;Set name="terminating"&gt;true&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;!-- redirect from the welcome page to a specific page --&gt;
&lt;Call name="addRule"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule"&gt;
&lt;Set name="pattern"&gt;/test/rewrite/&lt;/Set&gt;
&lt;Set name="replacement"&gt;/test/rewrite/info.html&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;!-- replace the entire request URI --&gt;
&lt;Call name="addRule"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule"&gt;
&lt;Set name="pattern"&gt;/test/some/old/context&lt;/Set&gt;
&lt;Set name="replacement"&gt;/test/rewritten/newcontext&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;!-- replace the beginning of the request URI --&gt;
&lt;Call name="addRule"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule"&gt;
&lt;Set name="pattern"&gt;/test/rewrite/for/*&lt;/Set&gt;
&lt;Set name="replacement"&gt;/test/rewritten/&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;!-- reverse the order of the path sections --&gt;
&lt;Call name="addRule"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.rewrite.handler.RewriteRegexRule"&gt;
&lt;Set name="regex"&gt;(.*?)/reverse/([^/]*)/(.*)&lt;/Set&gt;
&lt;Set name="replacement"&gt;$1/reverse/$3/$2&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;!-- add a cookie to each path visited --&gt;
&lt;Call name="addRule"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.rewrite.handler.CookiePatternRule"&gt;
&lt;Set name="pattern"&gt;/*&lt;/Set&gt;
&lt;Set name="name"&gt;visited&lt;/Set&gt;
&lt;Set name="value"&gt;yes&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;!-- actual redirect, instead of internal rewrite --&gt;
&lt;Call name="addRule"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.rewrite.handler.RedirectPatternRule"&gt;
&lt;Set name="pattern"&gt;/test/redirect/*&lt;/Set&gt;
&lt;Set name="location"&gt;/test/redirected&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;!-- add a response rule --&gt;
&lt;Call name="addRule"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.rewrite.handler.ResponsePatternRule"&gt;
&lt;Set name="pattern"&gt;/400Error&lt;/Set&gt;
&lt;Set name="code"&gt;400&lt;/Set&gt;
&lt;Set name="message"&gt;ResponsePatternRule Demo&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Ref&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_embedded-example-2"><a class="anchor" href="#_embedded-example-2"></a><a class="link" href="#_embedded-example-2">Embedded Example</a></h5>
<div class="paragraph">
<p>This is an example for embedded Jetty, which does something similar to the configuration file example above:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java"> Server server = new Server();
RewriteHandler rewrite = new RewriteHandler();
rewrite.setRewriteRequestURI(true);
rewrite.setRewritePathInfo(false);
rewrite.originalPathAttribute("requestedPath");
RedirectPatternRule redirect = new RedirectPatternRule();
redirect.setPattern("/redirect/*");
redirect.setReplacement("/redirected");
rewrite.addRule(redirect);
RewritePatternRule oldToNew = new RewritePatternRule();
oldToNew.setPattern("/some/old/context");
oldToNew.setReplacement("/some/new/context");
rewrite.addRule(oldToNew);
RewriteRegexRule reverse = new RewriteRegexRule();
reverse.setRegex("/reverse/([^/]*)/(.*)");
reverse.setReplacement("/reverse/$2/$1");
rewrite.addRule(reverse);
server.setHandler(rewrite);</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="rewrite-rules"><a class="anchor" href="#rewrite-rules"></a><a class="link" href="#rewrite-rules">Rules</a></h4>
<div class="paragraph">
<p>There are several types of rules that are written extending useful base rule classes.</p>
</div>
<div class="sect4">
<h5 id="_patternrule"><a class="anchor" href="#_patternrule"></a><a class="link" href="#_patternrule">PatternRule</a></h5>
<div class="paragraph">
<p>Matches against the request URI using the servlet pattern syntax.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/rewrite/handler/CookiePatternRule.html">CookiePatternRule</a></dt>
<dd>
<p>Adds a cookie to the response.</p>
</dd>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.html">HeaderPatternRule</a></dt>
<dd>
<p>Adds/modifies a header in the response.</p>
</dd>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/rewrite/handler/RedirectPatternRule.html">RedirectPatternRule</a></dt>
<dd>
<p>Redirects the response.</p>
</dd>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/rewrite/handler/ResponsePatternRule.html">ResponsePatternRule</a></dt>
<dd>
<p>Sends the response code (status or error).</p>
</dd>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/rewrite/handler/RewritePatternRule.html">RewritePatternRule</a></dt>
<dd>
<p>Rewrite the URI by replacing the matched request path with a fixed string.</p>
</dd>
</dl>
</div>
</div>
<div class="sect4">
<h5 id="_regexrule"><a class="anchor" href="#_regexrule"></a><a class="link" href="#_regexrule">RegexRule</a></h5>
<div class="paragraph">
<p>Matches against the request URI using regular expressions.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/rewrite/handler/RedirectRegexRule.html">RedirectRegexRule</a></dt>
<dd>
<p>Redirect the response.</p>
</dd>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.html">RewriteRegexRule</a></dt>
<dd>
<p>Rewrite the URI by matching with a regular expression.
(The replacement string may use <code>Template:$n</code> to replace the nth capture group.)</p>
</dd>
</dl>
</div>
</div>
<div class="sect4">
<h5 id="_headerrule"><a class="anchor" href="#_headerrule"></a><a class="link" href="#_headerrule">HeaderRule</a></h5>
<div class="paragraph">
<p>Match against request headers. Match either on a header name and specific value, or on the presence of a header (with any value).</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRule.html">ForwardedSchemaHeaderRule</a></dt>
<dd>
<p>Set the scheme on the request (defaulting to HTTPS).</p>
</dd>
</dl>
</div>
</div>
<div class="sect4">
<h5 id="_others"><a class="anchor" href="#_others"></a><a class="link" href="#_others">Others</a></h5>
<div class="paragraph">
<p>Extra rules that defy standard classification.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/rewrite/handler/MsieSslRule.html">MsieSslRule</a></dt>
<dd>
<p>Disables the keep alive for SSL from IE5 or IE6.</p>
</dd>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/rewrite/handler/LegacyRule.html">LegacyRule</a></dt>
<dd>
<p>Implements the legacy API of RewriteHandler</p>
</dd>
</dl>
</div>
</div>
<div class="sect4">
<h5 id="_rulecontainer"><a class="anchor" href="#_rulecontainer"></a><a class="link" href="#_rulecontainer">RuleContainer</a></h5>
<div class="paragraph">
<p>Groups rules together.
The contained rules will only be processed if the conditions for the <code>RuleContainer</code> evaluate to true.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.html">VirtualHostRuleContainer</a></dt>
<dd>
<p>Groups rules that apply only to a specific virtual host or a set of virtual hosts</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="fastcgi"><a class="anchor" href="#fastcgi"></a><a class="link" href="#fastcgi">FastCGI Support</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="fastcgi-intro"><a class="anchor" href="#fastcgi-intro"></a><a class="link" href="#fastcgi-intro">FastCGI Introduction</a></h3>
<div class="paragraph">
<p>FastCGI is a network protocol primarily used by a <em>web server</em> to communicate to a <em>FastCGI server</em>.
FastCGI servers are typically used to serve web content generated by dynamic web languages, primarily <a href="http://www.php.net/">PHP</a>, but also Python, Ruby, Perl and others.</p>
</div>
<div class="paragraph">
<p>Web servers that supports FastCGI are, among others, <a href="http://httpd.apache.org/">Apache</a>, <a href="http://nginx.org/">Nginx</a>, and Jetty.
Web servers typically act as proxies, converting HTTP requests that they receive from clients (browsers) to FastCGI requests that are forwarded to the FastCGI server.
The FastCGI server spawns the dynamic web language interpreter, passing it the information contained in the FastCGI request and a dynamic web language script is executed, producing web content, typically HTML.
The web content is then formatted into a FastCGI response that is returned to the web server, which converts it to a HTTP response that is then returned to the client.</p>
</div>
<div class="paragraph">
<p>The most well known FastCGI server is the <a href="http://php-fpm.org/">PHP FastCGI Process Manager</a>, or <code>php-fpm</code>.
In the following we will assume that <code>php-fpm</code> is used as FastCGI server.</p>
</div>
<div class="paragraph">
<p>Jetty can be configured to act as a web server that supports FastCGI, replacing the functionality that is normally provided by Apache or Nginx.
This allows users to leverage Jetty features such as HTTP/2, the unique support that Jetty provides for HTTP/2 Push, Jetty&#8217;s scalability, and of course Jetty&#8217;s native support for Java Web Standards such as Servlets, JSPs, etc.</p>
</div>
<div class="paragraph">
<p>With such configuration, users can not only deploy their Java Web Applications in Jetty, but also serve their <a href="http://wordpress.com/">WordPress</a> site or blog or their <a href="https://drupal.org/">Drupal</a> site without having to install and manage multiple web servers.</p>
</div>
</div>
<div class="sect2">
<h3 id="configuring-fastcgi"><a class="anchor" href="#configuring-fastcgi"></a><a class="link" href="#configuring-fastcgi">Configuring Jetty for FastCGI</a></h3>
<div class="paragraph">
<p>In this section you will see how to configure Jetty to serve WordPress via FastCGI.</p>
</div>
<div class="paragraph">
<p>The first step is to have WordPress installed on your server machine, for example under <code>/var/www/wordpress</code>.
For more information about how to install WordPress, please refer to the <a href="https://codex.wordpress.org/Installing_WordPress">WordPress Installation Guide</a>.</p>
</div>
<div class="paragraph">
<p>The second step is to install <code>php-fpm</code> and make sure it is configured to listen on a TCP socket; typically it is configured to listen to <code>localhost:9000</code>.</p>
</div>
<div class="paragraph">
<p>The third step is to install Jetty, for example under <code>/opt/jetty</code>, called in the following <code>$JETTY_HOME</code>.
Refer to <a href="#jetty-downloading">Downloading Jetty</a> for more information about how to install Jetty.</p>
</div>
<div class="paragraph">
<p>The fourth step is to create a Jetty base directory (see <a href="#startup-base-and-home">Managing Jetty Base and Jetty Home</a>), called in the following <code>$JETTY_BASE</code>, where you setup the configuration needed to support FastCGI in Jetty, and configure the <code>fcgi</code>, <code>http</code> and <code>deploy</code> modules, so that Jetty will be able to accept HTTP requests from browsers, convert them in FastCGI, and proxy them to <code>php-fpm</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ mkdir -p /usr/jetty/wordpress
$ cd /usr/jetty/wordpress
$ java -jar $JETTY_HOME/start.jar --add-to-start=fcgi,http,deploy</code></pre>
</div>
</div>
<div class="paragraph">
<p>Therefore <code>$JETTY_BASE=/usr/jetty/wordpress</code>.</p>
</div>
<div class="paragraph">
<p>The fifth step is to deploy the web application that provides the proxying of client requests to the FastCGI server, <code>php-fpm</code>.
Typically this is done by deploying a <code>*.war</code> file in the <code>$JETTY_BASE/webapps</code> directory.
For FastCGI there is no web application that needs developed - all the work has already been done for you by Jetty.
As such you only need to deploy a Jetty context XML file that configures the web application directly.
Copy and paste the following content as <code>$JETTY_BASE/webapps/jetty-wordpress.xml</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.servlet.ServletContextHandler"&gt;
&lt;New id="root" class="java.lang.String"&gt;
&lt;Arg&gt;/var/www/wordpress&lt;/Arg&gt;
&lt;/New&gt;
&lt;Set name="contextPath"&gt;/&lt;/Set&gt;
&lt;Set name="resourceBase"&gt;&lt;Ref refid="root" /&gt;&lt;/Set&gt;
&lt;Set name="welcomeFiles"&gt;
&lt;Array type="string"&gt;&lt;Item&gt;index.php&lt;/Item&gt;&lt;/Array&gt;
&lt;/Set&gt;
&lt;Call name="addFilter"&gt;
&lt;Arg&gt;org.eclipse.jetty.fcgi.server.proxy.TryFilesFilter&lt;/Arg&gt;
&lt;Arg&gt;/*&lt;/Arg&gt;
&lt;Arg&gt;
&lt;Call name="of" class="java.util.EnumSet"&gt;
&lt;Arg&gt;&lt;Get name="REQUEST" class="javax.servlet.DispatcherType" /&gt;&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Arg&gt;
&lt;Call name="setInitParameter"&gt;
&lt;Arg&gt;files&lt;/Arg&gt;
&lt;Arg&gt;$path /index.php?p=$path&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Call&gt;
&lt;Call name="addServlet"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.servlet.ServletHolder"&gt;
&lt;Arg&gt;default&lt;/Arg&gt;
&lt;Arg&gt;
&lt;Call name="forName" class="java.lang.Class"&gt;
&lt;Arg&gt;org.eclipse.jetty.servlet.DefaultServlet&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Arg&gt;
&lt;Call name="setInitParameter"&gt;
&lt;Arg&gt;dirAllowed&lt;/Arg&gt;
&lt;Arg&gt;false&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;Arg&gt;/&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Call name="addServlet"&gt;
&lt;Arg&gt;org.eclipse.jetty.fcgi.server.proxy.FastCGIProxyServlet&lt;/Arg&gt;
&lt;Arg&gt;*.php&lt;/Arg&gt;
&lt;Call name="setInitParameter"&gt;
&lt;Arg&gt;proxyTo&lt;/Arg&gt;
&lt;Arg&gt;http://localhost:9000&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Call name="setInitParameter"&gt;
&lt;Arg&gt;prefix&lt;/Arg&gt;
&lt;Arg&gt;/&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Call name="setInitParameter"&gt;
&lt;Arg&gt;scriptRoot&lt;/Arg&gt;
&lt;Arg&gt;&lt;Ref refid="root" /&gt;&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Call name="setInitParameter"&gt;
&lt;Arg&gt;scriptPattern&lt;/Arg&gt;
&lt;Arg&gt;(.+?\\.php)&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>An explanation of the above contents:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Linne 6 specifies the WordPress installation directory, in this example <code>/var/www/wordpress</code> (as defined in the first step).</p>
</li>
<li>
<p>Line 9 it is specified the context path at which WordPress will be served, in this example at the root context path <code>/</code>.</p>
</li>
<li>
<p>Line 10 specifies the resource base of the context, also set to the WordPress installation directory.
This allows Jetty to serve static resources directly from the WordPress installation directory.</p>
</li>
<li>
<p>Line 12 specifies the welcome file as <code>index.php</code>, so that Jetty can perform the proper redirects in case of URIs ending with the <code>/</code> character.</p>
</li>
<li>
<p>Line 15 specifies the <code>TryFilesFilter</code>, a Servlet Filter that has been inspired by the <a href="http://wiki.nginx.org/HttpCoreModule#try_files">try_files</a> functionality offered by Nginx.
This filter tries to serve the resource from the file system first, and if the resource is not found it forwards the request as <code>index.php?p=$path</code>, which will match the proxy servlet defined below.
Refer to the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilter.html">TryFilesFilter</a> documentation for further information.</p>
</li>
<li>
<p>Line 29specifies Jetty&#8217;s <code>DefaultServlet</code> to serve static content such as CSS files, JavaScript files, etc. <code>DefaultServlet</code> will serve these files by looking in the resource base of the context, defined at line 10 (see above).</p>
</li>
<li>
<p>Line 47 specifies the <code>FastCGIProxyServlet</code>, a Servlet that proxies HTTP requests arriving from clients to FastCGI requests to the FastCGI server.</p>
</li>
<li>
<p>Line 52 specifies the TCP address of the FastCGI server (<code>php-fpm</code>), where HTTP requests are forwarded as FastCGI requests.</p>
</li>
<li>
<p>Line 60 specifies once again the WordPress installation directory, so that the <code>FastCGIProxyServlet</code> can pass this information to the FastCGI server.</p>
</li>
<li>
<p>Line 64 specifies a regular expression that matches request URIs performed to this servlet, in addition to the standard URL mapping defined by Servlet at line 49.
Refer to the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.html">FastCGIProxyServlet</a> documentation for further information.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The last step is to start Jetty (see <a href="#startup">Starting Jetty</a>) and navigate to <code><a href="http://localhost:8080" class="bare">http://localhost:8080</a></code> with your browser and enjoy WordPress:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cd $JETTY_BASE
$ java -jar /opt/jetty/start.jar</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="configuring-fastcgi-http2"><a class="anchor" href="#configuring-fastcgi-http2"></a><a class="link" href="#configuring-fastcgi-http2">Configuring Jetty to Proxy HTTP/2 to FastCGI</a></h4>
<div class="paragraph">
<p>In order to configure Jetty to listen for HTTP/2 requests from clients that are HTTP/2 enabled and forward them to the FastCGI server as FastCGI requests, you need to enable the <code>http2</code> module, which in turn will require a TLS connector and consequently a keystore to read the key material required by TLS.</p>
</div>
<div class="paragraph">
<p>Enabling the <code>http2</code> is easy; in additions to the modules you have enabled above, add the <code>http2</code> module:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cd $JETTY_BASE
$ java -jar $JETTY_HOME/start.jar --add-to-start=http2</code></pre>
</div>
</div>
<div class="paragraph">
<p>The command above adds the <code>http2</code> module (and its dependencies) to the existing modules and uses the default Jetty keystore to provide the key material required by TLS.
You will want to use your own keystore with your own private key and certificate for your own domain.</p>
</div>
<div class="paragraph">
<p>Remember that by adding the <code>http2</code> module, you will start two JVMs: one that reads the configuration, and one that has the ALPN boot boot jar in the boot classpath, as explained in <a href="#http2-configuring">[http2-configuring]</a>.</p>
</div>
<div class="paragraph">
<p>Since now your site will run over TLS, you need to make sure that the WordPress URL is also configured so.
If you have followed the steps of the <a href="#configuring-fastcgi">previous section</a>, your WordPress site is served at <code><a href="http://localhost:8080" class="bare">http://localhost:8080</a></code>.
You will need to change that to be <code><a href="https://localhost:8443" class="bare">https://localhost:8443</a></code> from the WordPress administration web interface, or follow the <a href="http://codex.wordpress.org/Changing_The_Site_URL">WordPress instructions</a> to do so without using the administration web interface.</p>
</div>
<div class="paragraph">
<p>The minimal modules required to run WordPress with Jetty on HTTP/2 are therefore: <code>http2</code>, <code>http</code>, <code>fcgi</code> and <code>deploy</code>.
These will setup a clear text connector on port 8080 for HTTP/1.1 and a TLS connector on port 8443 for HTTP/2 and HTTP/1.1.</p>
</div>
<div class="paragraph">
<p>At this point, you can start Jetty (see <a href="#startup">Starting Jetty</a>), hit <code><a href="http://localhost:8080" class="bare">http://localhost:8080</a></code> with your browser and enjoy WordPress via HTTP/2 using a HTTP/2 enabled browser:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cd $JETTY_BASE
$ java -jar $JETTY_HOME/start.jar</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you don&#8217;t have a HTTP/2 enabled browser, WordPress will still be available over HTTP/1.1.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="frameworks"><a class="anchor" href="#frameworks"></a><a class="link" href="#frameworks">Frameworks</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="framework-cdi"><a class="anchor" href="#framework-cdi"></a><a class="link" href="#framework-cdi">CDI</a></h3>
<div class="paragraph">
<p>Contexts and Dependency Injection for Java EE (<a href="http://www.cdi-spec.org/">CDI</a>) is a standard implemented by frameworks such as <a href="http://seamframework.org/Weld">Weld</a> and <a href="https://openwebbeans.apache.org/">Apache OpenWebBeans</a>.
This is a common way to assemble and configure webapplications by a process often referred to as 'decoration'.</p>
</div>
<div class="paragraph">
<p>Jetty integration of CDI frameworks allows CDI to be used to inject the Filters, Servlets and Listeners created within a Servlet Context.
There are two approaches to integration:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>CDI implementation can integrate with Jetty.
This requires the CDI implementation to have Jetty specific code.
Since Jetty-9.4.20 a loosely bound mechanism has been available for CDI implementations to extends the Jetty <code>DecoratedObjectFactory</code> without hard API dependencies.
Prior to that, CDI implementations directly called jetty APIs that need to be explicitly exposed to the webapp.</p>
</li>
<li>
<p>Alternately, Jetty can integrate with CDI implementations by using standard CDI SPIs.</p>
</li>
</ul>
</div>
<div class="sect3">
<h4 id="_jetty-cdi-modules"><a class="anchor" href="#_jetty-cdi-modules"></a><a class="link" href="#_jetty-cdi-modules">Jetty CDI Modules</a></h4>
<div class="paragraph">
<p>The Jetty distribution come with several CDI modules.
These modules do not provide CDI, but instead enable one of more integration mechanisms.</p>
</div>
<div class="sect4">
<h5 id="_jetty-cdi-module"><a class="anchor" href="#_jetty-cdi-module"></a><a class="link" href="#_jetty-cdi-module">Jetty <code>cdi</code> Module</a></h5>
<div class="paragraph">
<p>The <code>cdi</code> module supports either two modes of CDI integration which can be selected either by the "org.eclipse.jetty.cdi" context init parameter or the "org.eclipse.jetty.cdi" server attribute (which is initialised from the "jetty.cdi.mode" start property).
Supported modes are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>CdiSpiDecorator</code> Jetty will call the CDI SPI within the webapp to decorate objects (default).</p>
</li>
<li>
<p><code>CdiDecoratingLister</code> The webapp may register a decorator on the context attribute "org.eclipse.jetty.cdi.decorator".</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre>cd $JETTY_BASE
java -jar $JETTY_HOME/start.jar --add-to-start=cdi</pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_jetty-cdi-decorate-module"><a class="anchor" href="#_jetty-cdi-decorate-module"></a><a class="link" href="#_jetty-cdi-decorate-module">Jetty <code>cdi-decorate</code> Module</a></h5>
<div class="paragraph">
<p>This module depends on the <code>cdi</code> module and sets the default mode to <code>CdiDecoratingListener</code>.
This is the preferred mode for Weld integration.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>cd $JETTY_BASE
java -jar $JETTY_HOME/start.jar --add-to-start=cdi-decorate</pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_jetty-cdi-spi-module"><a class="anchor" href="#_jetty-cdi-spi-module"></a><a class="link" href="#_jetty-cdi-spi-module">Jetty <code>cdi-spi</code> Module</a></h5>
<div class="paragraph">
<p>This module depends on the <code>cdi</code> module and sets the default mode to <code>CdiSpiDecorator</code>.
This is the preferred mode for Open Web Beans integration.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>cd $JETTY_BASE
java -jar $JETTY_HOME/start.jar --add-to-start=cdi-spi</pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_jetty-cdi2-module"><a class="anchor" href="#_jetty-cdi2-module"></a><a class="link" href="#_jetty-cdi2-module">Jetty <code>cdi2</code> Module</a></h5>
<div class="paragraph">
<p>This module supports the <strong>deprecated</strong> technique of exposing private Jetty decorate APIs to the CDI implementation in the webapp.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>cd $JETTY_BASE
java -jar $JETTY_HOME/start.jar --add-to-start=cdi2</pre>
</div>
</div>
<div class="paragraph">
<p>This module is equivalent to directly modifying the class path configuration with a <code>jetty-web.xml</code> like:</p>
</div>
<div class="listingblock XML">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Call name="prependServerClass"&gt;
&lt;Arg&gt;-org.eclipse.jetty.util.Decorator&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Call name="prependServerClass"&gt;
&lt;Arg&gt;-org.eclipse.jetty.util.DecoratedObjectFactory&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Call name="prependServerClass"&gt;
&lt;Arg&gt;-org.eclipse.jetty.server.handler.ContextHandler.&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Call name="prependServerClass"&gt;
&lt;Arg&gt;-org.eclipse.jetty.server.handler.ContextHandler&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Call name="prependServerClass"&gt;
&lt;Arg&gt;-org.eclipse.jetty.servlet.ServletContextHandler&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
The <code>cdi2</code> module or directly modifying the web application classpath will not work for Jetty 10.0.0 and later.
It should only be used for versions prior to Jetty 9.4.20 and/or Weld 3.1.2.Final
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
</div>
<div class="sect3">
<h4 id="cdi-embedded"><a class="anchor" href="#cdi-embedded"></a><a class="link" href="#cdi-embedded">Embedded Jetty with CDI</a></h4>
<div class="paragraph">
<p>When starting embedded Jetty programmatically from the <code>main</code> method, to use CDI it may be
necessary:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>enable a Jetty CDI integration mode</p>
</li>
<li>
<p>and/or enable a CDI frame integration.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>However, depending on the exact configuration of the embedded server, either or both steps may not be required as `ServletContainerInitializer`s may be discovered.</p>
</div>
<div class="paragraph">
<p>The details for embedding CDI is explained in the <a href="#weld-embedded">Embedded Jetty with Weld</a> section, which can also be adapted to other CDI frameworks.
Unresolved directive in frameworks/chapter.adoc - include::weld.adoc[]</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="framework-jetty-spring"><a class="anchor" href="#framework-jetty-spring"></a><a class="link" href="#framework-jetty-spring">Spring Setup</a></h3>
<div class="paragraph">
<p>You can assemble and configure Jetty in code or with almost any IoC style framework including Spring.
If all you want to do is setup a Jetty server in your stock Spring usage, simply look at the xml snippet below as an example.
If you want to replace the jetty-xml being used to start the normal Jetty distribution with spring, you may do so however currently it will not leverage the rest of the module system.</p>
</div>
<div class="sect3">
<h4 id="_jetty-spring-module"><a class="anchor" href="#_jetty-spring-module"></a><a class="link" href="#_jetty-spring-module">Jetty-Spring Module</a></h4>
<div class="paragraph">
<p>The skeleton of a jetty spring module can be enabled from the jetty-distribution via the <a href="#startup-modules">module mechanism</a>.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ java -jar start.jar --add-to-start=spring</code></pre>
</div>
</div>
<div class="paragraph">
<p>This (or the alternative <a href="#start-jar">--add-to-start</a>=spring command) creates a <code>${jetty.home}/lib/spring</code> directory and populates it with the jetty-spring integration jar.
It does NOT supply the spring jars and their dependencies.
You will need to download these and place them into jetty&#8217;s classpath - you can use the <code>${jetty.home}/lib/spring</code> directory created by spring.mod for this purpose.</p>
</div>
</div>
<div class="sect3">
<h4 id="_using-spring-to-configure-jetty"><a class="anchor" href="#_using-spring-to-configure-jetty"></a><a class="link" href="#_using-spring-to-configure-jetty">Using Spring to Configure Jetty</a></h4>
<div class="paragraph">
<p>Configuring Jetty via Spring is simply a matter of calling the API as Spring beans.
The following is an example mimicking the default jetty startup configuration.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt;
&lt;!-- =============================================================== --&gt;
&lt;!-- Configure the Jetty Server with Spring --&gt;
&lt;!-- This file is the similar to jetty.xml, but written in spring --&gt;
&lt;!-- XmlBeanFactory format. --&gt;
&lt;!-- =============================================================== --&gt;
&lt;beans&gt;
&lt;bean id="contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/&gt;
&lt;bean id="server" name="Main" class="org.eclipse.jetty.server.Server" init-method="start" destroy-method="stop"&gt;
&lt;constructor-arg&gt;
&lt;bean id="threadPool" class="org.eclipse.jetty.util.thread.QueuedThreadPool"&gt;
&lt;property name="minThreads" value="10"/&gt;
&lt;property name="maxThreads" value="50"/&gt;
&lt;/bean&gt;
&lt;/constructor-arg&gt;
&lt;property name="connectors"&gt;
&lt;list&gt;
&lt;bean id="connector" class="org.eclipse.jetty.server.ServerConnector"&gt;
&lt;constructor-arg ref="server"/&gt;
&lt;property name="port" value="8080"/&gt;
&lt;/bean&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;property name="handler"&gt;
&lt;bean id="handlers" class="org.eclipse.jetty.server.handler.HandlerCollection"&gt;
&lt;property name="handlers"&gt;
&lt;list&gt;
&lt;ref bean="contexts"/&gt;
&lt;bean id="defaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/property&gt;
&lt;property name="beans"&gt;
&lt;list&gt;
&lt;bean id="deploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager"&gt;
&lt;property name="contexts" ref="contexts"/&gt;
&lt;property name="appProviders"&gt;
&lt;list&gt;
&lt;bean id="webAppProvider" class="org.eclipse.jetty.deploy.providers.WebAppProvider"&gt;
&lt;property name="monitoredDirName" value="webapps"/&gt;
&lt;property name="scanInterval" value="1"/&gt;
&lt;property name="extractWars" value="true"/&gt;
&lt;/bean&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/beans&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="framework-jetty-osgi"><a class="anchor" href="#framework-jetty-osgi"></a><a class="link" href="#framework-jetty-osgi">OSGI</a></h3>
<div class="sect3">
<h4 id="_introduction"><a class="anchor" href="#_introduction"></a><a class="link" href="#_introduction">Introduction</a></h4>
<div class="paragraph">
<p>The Jetty OSGi infrastructure provides a Jetty container inside an OSGi container.
Traditional JavaEE webapps can be deployed, in addition to Jetty <code>ContextHandlers</code>, along with OSGi web bundles.
In addition, the infrastructure also supports the OSGi <code>HttpService</code> interface.</p>
</div>
</div>
<div class="sect3">
<h4 id="_general-setup"><a class="anchor" href="#_general-setup"></a><a class="link" href="#_general-setup">General Setup</a></h4>
<div class="paragraph">
<p>All of the Jetty jars contain manifest entries appropriate to ensure that they can be deployed into an OSGi container as bundles.
You will need to install some jetty jars into your OSGi container.
You can always find the Jetty jars either in the Maven Central repository, or you can <a href="https://www.eclipse.org/jetty/download.html">download</a> a distribution of Jetty.
Here&#8217;s the absolute minimal set of Jetty jars:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 7. Minimal Bundles</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Jar</th>
<th class="tableblock halign-left valign-top">Bundle Symbolic Name</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-util</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.util</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-http</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.http</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-io</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.io</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-security</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.security</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-server</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.server</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-servlet</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.servlet</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-webapp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.webapp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-deploy</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.deploy</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-xml</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.xml</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-servlet-api</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.servlet-api</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>You <strong>must also install the Apache Aries SPI Fly bundles</strong> as many parts of Jetty - for example ALPN, websocket, annotations - use the <code>ServiceLoader</code> mechanism, which requires an OSGi Service Loader Mediator like SPI Fly:</p>
</div>
<table id="spifly" class="tableblock frame-all grid-all stretch">
<caption class="title">Table 8. SPI Fly Bundles</caption>
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Jar</th>
<th class="tableblock halign-left valign-top">Bundle Symbolic Name</th>
<th class="tableblock halign-left valign-top">Location</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.aries.spifly:org.apache.aries.spifly.dynamic.bundle-1.2.4.jar</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.aries.spifly.dynamic.bundle</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://repo1.maven.org/maven2/org/apache/aries/spifly/org.apache.aries.spifly.dynamic.bundle/">Maven central</a></p></td>
</tr>
</tbody>
</table>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
We strongly recommend that you also deploy the <a href="#osgi-annotations">annotation-related</a> jars also, as the Servlet Specification increasingly relies on annotations for functionality.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>You will also need the <strong>OSGi Event Management service</strong> and the <strong>OSGi Configuration Management service</strong>.
If your OSGi container does not automatically make these available, you will need to add them in a way appropriate to your container.</p>
</div>
</div>
<div class="sect3">
<h4 id="_the-jetty-osgi-container"><a class="anchor" href="#_the-jetty-osgi-container"></a><a class="link" href="#_the-jetty-osgi-container">The Jetty OSGi Container</a></h4>
<div class="sect4">
<h5 id="_the-jetty-osgi-boot-jar"><a class="anchor" href="#_the-jetty-osgi-boot-jar"></a><a class="link" href="#_the-jetty-osgi-boot-jar">The jetty-osgi-boot jar</a></h5>
<div class="paragraph">
<p>Now that you have the basic set of Jetty jars installed, you can install the <a href="https://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot/">jetty-osgi-boot.jar</a> bundle, downloadable from the maven central repo <a href="https://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot/">here.</a></p>
</div>
<div class="paragraph">
<p>This bundle will instantiate and make available the Jetty OSGi container when it is started.
If this bundle is not auto-started upon installation into your OSGi container, you should start it manually using a command appropriate for your container.</p>
</div>
</div>
<div class="sect4">
<h5 id="customize-jetty-container"><a class="anchor" href="#customize-jetty-container"></a><a class="link" href="#customize-jetty-container">Customizing the Jetty Container</a></h5>
<div class="paragraph">
<p>Before going ahead with the install, you may want to customize the Jetty container.
In general this is done by a combination of System properties and the usual Jetty xml configuration files.
The way you define the System properties will depend on which OSGi container you are using, so ensure that you are familiar with how to set them for your environment.
In the following examples, we will assume that the OSGi container allows us to set System properties as simple <code>name=value</code> pairs.</p>
</div>
<div class="paragraph">
<p>The available System properties are:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">jetty.http.port</dt>
<dd>
<p>If not specified, this defaults to the usual jetty port of 8080.</p>
</dd>
<dt class="hdlist1">jetty.home</dt>
<dd>
<p>Either this property <em>or</em> the <strong>jetty.home.bundle</strong> <em>must</em> be specified.
This property should point to a file system location that has an <code>etc/</code> directory containing xml files to configure the Jetty container on startup.
For example:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">jetty.home=/opt/custom/jetty</code></pre>
</div>
</div>
<div class="paragraph">
<p>Where <code>/opt/custom/jetty</code> contains:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">etc/jetty.xml
etc/jetty-selector.xml
etc/jetty-deployer.xml
etc/jetty-special.xml</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">jetty.home.bundle</dt>
<dd>
<p>Either this property <em>or</em> the <strong>jetty.home</strong> property must be specified.
This property should specify the symbolic name of a bundle which contains a directory called <code>jettyhome/</code>.
The <code>jettyhome/</code> directory should have a subdirectory called <code>etc/</code> that contains the xml files to be applied to Jetty on startup.
The jetty-osgi-boot.jar contains a <code>jettyhome/</code> directory with a default set of xml configuration files.
Here&#8217;s how you would specify it:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">jetty.home.bundle=org.eclipse.jetty.osgi.boot</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here&#8217;s a partial listing of that jar that shows you the names of the xml files contained within it:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">META-INF/MANIFEST.MF
jettyhome/etc/jetty.xml
jettyhome/etc/jetty-deployer.xml
jettyhome/etc/jetty-http.xml</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">jetty.etc.config.urls</dt>
<dd>
<p>This specifies the paths of the xml files that are to be used.
If not specified, they default to:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">etc/jetty.xml,etc/jetty-http.xml,etc/jetty-deployer.xml</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that the paths can either be relative or absolute, or a mixture.
If the path is relative, it is resolved against either <strong>jetty.home</strong> or <strong>jetty.home.bundle</strong>, whichever was specified.
You can use this ability to mix and match jetty configuration files to add functionality, such as adding in a https connector.
Here&#8217;s an example of adding a HTTPS connector, using the relevant files from the jetty-distribution:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>etc/jetty.xml, etc/jetty-http.xml, /opt/jetty/etc/jetty-ssl.xml, /opt/jetty/etc/jetty-https.xml, etc/jetty-deployer.xml</pre>
</div>
</div>
<div class="paragraph">
<p>Note that regardless of whether you set the <strong>jetty.home</strong> or <strong>jetty.home.bundle</strong> property, when Jetty executes the configuration files, it will set an appropriate value for <strong>jetty.home</strong> so that references in xml files to <code>&lt;property name="jetty.home"&gt;</code> will work.
Be careful, however, if you are mixing and matching relative and absolute configuration file paths: the value of <strong>jetty.home</strong> is determined from the resolved location of the <em>relative</em> files only.</p>
</div>
</dd>
</dl>
</div>
</div>
<div class="sect4">
<h5 id="_the-jetty-container-as-an-osgi-service"><a class="anchor" href="#_the-jetty-container-as-an-osgi-service"></a><a class="link" href="#_the-jetty-container-as-an-osgi-service">The Jetty Container as an OSGi Service</a></h5>
<div class="paragraph">
<p>You can now go ahead and deploy the jetty-osgi-boot.jar into your OSGi container.
A Jetty server instance will be created, the xml config files applied to it, and then published as an OSGi service.
Normally, you will not need to interact with this service instance, however you can retrieve a reference to it using the usual OSGi API:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">org.osgi.framework.BundleContext bc;
org.osgi.framework.ServiceReference ref = bc.getServiceReference("org.eclipse.jetty.server.Server");</code></pre>
</div>
</div>
<div class="paragraph">
<p>The Server service has a couple of properties associated with it that you can retrieve using the <code>org.osgi.framework.ServiceReference.getProperty(String)</code> method:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">managedServerName</dt>
<dd>
<p>The Jetty Server instance created by the jetty-osgi-boot.jar will be called "defaultJettyServer"</p>
</dd>
<dt class="hdlist1">jetty.etc.config.urls</dt>
<dd>
<p>The list of xml files resolved from either <strong>jetty.home</strong> or <strong>jetty.home.bundle</strong>/jettyhome</p>
</dd>
</dl>
</div>
</div>
<div class="sect4">
<h5 id="_adding-more-jetty-servers"><a class="anchor" href="#_adding-more-jetty-servers"></a><a class="link" href="#_adding-more-jetty-servers">Adding More Jetty Servers</a></h5>
<div class="paragraph">
<p>As we have seen in the previous section, the jetty-osgi-boot code will create an <code>org.eclipse.jetty.server.Server</code> instance, apply the xml configuration files specified by <strong>jetty.etc.config.urls</strong> System property to it, and then register it as an OSGi Service.
The name associated with this default instance is <code>defaultJettyServer</code>.</p>
</div>
<div class="paragraph">
<p>You can create other Server instances, register them as OSGi Services, and the jetty-osgi-boot code will notice them, and configure them so that they can deploy <code>ContextHandlers</code> and webapp bundles.
When you deploy webapps or <code>ContextHandlers</code> as bundles or Services (see sections below) you can target them to be deployed to a particular server instance via
the Server&#8217;s name.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of how to create a new Server instance and register it with OSGi so that the jetty-osgi-boot code will find it and configure it so it can be a deployment target:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public class Activator implements BundleActivator
{
public void start(BundleContext context) throws Exception
{
Server server = new Server();
//do any setup on Server in here
String serverName = "fooServer";
Dictionary serverProps = new Hashtable();
//define the unique name of the server instance
serverProps.put("managedServerName", serverName);
serverProps.put("jetty.http.port", "9999");
//let Jetty apply some configuration files to the Server instance
serverProps.put("jetty.etc.config.urls", "file:/opt/jetty/etc/jetty.xml,file:/opt/jetty/etc/jetty-selector.xml,file:/opt/jetty/etc/jetty-deployer.xml");
//register as an OSGi Service for Jetty to find
context.registerService(Server.class.getName(), server, serverProps);
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now that we have created a new Server called "fooServer", we can deploy webapps and <code>ContextHandlers</code> as Bundles or Services to it (see below for more information on this). Here&#8217;s an example of deploying a webapp as a Service and targeting it to the "fooServer" Server we created above:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public class Activator implements BundleActivator
{
public void start(BundleContext context) throws Exception
{
//Create a webapp context as a Service and target it at the "fooServer" Server instance
WebAppContext webapp = new WebAppContext();
Dictionary props = new Hashtable();
props.put("war",".");
props.put("contextPath","/acme");
props.put("managedServerName", "fooServer");
context.registerService(ContextHandler.class.getName(),webapp,props);
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_deploying-bundles-as-webapps"><a class="anchor" href="#_deploying-bundles-as-webapps"></a><a class="link" href="#_deploying-bundles-as-webapps">Deploying Bundles as Webapps</a></h4>
<div class="paragraph">
<p>The Jetty OSGi container listens for the installation of bundles, and will automatically attempt to deploy any that appear to be webapps.</p>
</div>
<div class="paragraph">
<p>Any of the following criteria are sufficient for Jetty to deploy the bundle as a webapp:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Bundle contains a WEB-INF/web.xml file</dt>
<dd>
<p>If the bundle contains a web descriptor, then it is automatically deployed.
This is an easy way to deploy classic JavaEE webapps.</p>
</dd>
<dt class="hdlist1">Bundle MANIFEST contains Jetty-WarFolderPath (for releases prior tojetty-9.3) or Jetty-WarResourcePath</dt>
<dd>
<p>This is the location within the bundle of the webapp resources.
Typically this would be used if the bundle is not a pure webapp, but rather the webapp is a component of the bundle.
Here&#8217;s an example of a bundle where the resources of the webapp are not located at the root of the bundle, but rather inside the subdirectory <code>web/</code> :</p>
<div class="paragraph">
<p><code>MANIFEST</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">Bundle-Name: Web
Jetty-WarResourcePath: web
Import-Package: javax.servlet;version="3.1",
javax.servlet.resources;version="3.1"
Bundle-SymbolicName: com.acme.sample.web</code></pre>
</div>
</div>
<div class="paragraph">
<p>Bundle contents:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">META-INF/MANIFEST.MF
web/index.html
web/foo.html
web/WEB-INF/web.xml
com/acme/sample/web/MyStuff.class
com/acme/sample/web/MyOtherStuff.class</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">Bundle MANIFEST contains Web-ContextPath</dt>
<dd>
<p>This header can be used in conjunction with either of the two preceding headers to control the context path to which the webapp is deployed, or alone to identify that the bundle&#8217;s contents should be published as a webapp.
This header is part of the RFC-66 specification for using webapps with OSGi.
Here&#8217;s an example based on the previous one where we use the <code>Web-ContextPath</code> header to set its deployment context path to be "/sample" :</p>
<div class="paragraph">
<p><code>MANIFEST</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">Bundle-Name: Web
Jetty-WarResourcePath: web
Web-ContextPath: /sample
Import-Package: javax.servlet;version="3.1",
javax.servlet.resources;version="3.1"
Bundle-SymbolicName: com.acme.sample.web</code></pre>
</div>
</div>
</dd>
</dl>
</div>
<div class="paragraph">
<p>You can also define extra headers in your bundle MANIFEST that help
customize the web app to be deployed:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Jetty-defaultWebXmlFilePath</dt>
<dd>
<p>The location of a <code>webdefault.xml</code> file to apply to the webapp.
The location can be either absolute (either absolute path or file: url), or relative (in which case it is interpreted as relative to the bundle root).
Defaults to the <code>webdefault.xml</code> file built into the Jetty OSGi container.</p>
</dd>
<dt class="hdlist1">Jetty-WebXmlFilePath</dt>
<dd>
<p>The location of the <code>web.xml</code> file.
The location can be either absolute (either absolute path or file: url), or relative (in which case it is interpreted as relative to the bundle root).
Defaults to <code>WEB-INF/web.xml</code></p>
</dd>
<dt class="hdlist1">Jetty-extraClassPath</dt>
<dd>
<p>A classpath of additional items to add to the webapp&#8217;s classloader.</p>
</dd>
<dt class="hdlist1">Jetty-bundleInstall</dt>
<dd>
<p>The path to the base folder that overrides the computed bundle installation - mostly useful for those OSGi frameworks that unpack bundles by default.</p>
</dd>
<dt class="hdlist1">Require-TldBundle</dt>
<dd>
<p>A comma separated list of bundle symbolic names of bundles containing TLDs that this webapp depends upon.</p>
</dd>
<dt class="hdlist1">managedServerName</dt>
<dd>
<p>The name of the Server instance to which to deploy this webapp bundle.
If not specified, defaults to the default Server instance called "defaultJettyServer".</p>
</dd>
<dt class="hdlist1">Jetty-WarFragmentResourcePath</dt>
<dd>
<p>The path within a fragment hosted by the web-bundle that contains static resources for the webapp.
The path is appended to the base resource for the webapp (see Jetty-WarResourcePath).</p>
</dd>
<dt class="hdlist1">Jetty-WarPrependFragmentResourcePath</dt>
<dd>
<p>The path within a fragment hosted by the web-bundle that contains static resources for the webapp.
The path is prepended to the base resource for the webapp (see Jetty-WarResourcePath).</p>
</dd>
<dt class="hdlist1">Jetty-ContextFilePath</dt>
<dd>
<p>A comma separated list of paths within the webapp bundle to Jetty context files that will be applied to the webapp.
Alternatively you may include a single Jetty context file called <code>jetty-webapp-context.xml</code> in the webapp bundle&#8217;s META-INF directory and it will be automatically applied to the webapp.</p>
</dd>
</dl>
</div>
<div class="sect4">
<h5 id="_determining-the-context-path-for-a-webapp-bundle"><a class="anchor" href="#_determining-the-context-path-for-a-webapp-bundle"></a><a class="link" href="#_determining-the-context-path-for-a-webapp-bundle">Determining the Context Path for a Webapp Bundle</a></h5>
<div class="paragraph">
<p>As we have seen in the previous section, if the bundle <code>MANIFEST</code> contains the RFC-66 header <strong>Web-ContextPath</strong>, Jetty will use that as the context path.
If the <code>MANIFEST</code> does not contain that header, then Jetty will concoct a context path based on the last element of the bundle&#8217;s location (by calling <code>Bundle.getLocation()</code>) after stripping off any file extensions.</p>
</div>
<div class="paragraph">
<p>For example, suppose we have a bundle whose location is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">file://some/where/over/the/rainbow/oz.war</code></pre>
</div>
</div>
<div class="paragraph">
<p>The corresponding synthesized context path would be:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">/oz</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_extra-properties-available-for-webapp-bundles"><a class="anchor" href="#_extra-properties-available-for-webapp-bundles"></a><a class="link" href="#_extra-properties-available-for-webapp-bundles">Extra Properties Available for Webapp Bundles</a></h5>
<div class="paragraph">
<p>You can further customize your webapp by including a Jetty context xml file that is applied to the webapp.
This xml file must be placed in <code>META-INF</code> of the bundle, and must be called <code>jetty-webapp-context.xml</code>.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of a webapp bundle listing containing such a file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">META-INF/MANIFEST.MF
META-INF/jetty-webapp-context.xml
web/index.html
web/foo.html
web/WEB-INF/web.xml
com/acme/sample/web/MyStuff.class
com/acme/sample/web/MyOtherStuff.class</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of the contents of a <code>META-INF/jetty-webapp-context.xml</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="defaultsDescriptor"&gt;&lt;Property name="bundle.root"/&gt;META-INF/webdefault.xml&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>As you can see, it is a normal context xml file used to set up a webapp.
There are, however, some additional useful properties that can be referenced</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Server</dt>
<dd>
<p>This is a reference to the Jetty <code>org.eclipse.jetty.server.Server</code> instance to which the webapp being configured in the context xml file will be deployed.</p>
</dd>
<dt class="hdlist1">bundle.root</dt>
<dd>
<p>This is a reference to the <code>org.eclipse.jetty.util.resource.Resource</code> that represents the location of the Bundle.
Note that this could be either a directory in the file system if the OSGi container automatically unpacks bundles, or it may be a jar:file: url if the bundle remains packed.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_deploying-bundles-as-jetty-contexthandlers"><a class="anchor" href="#_deploying-bundles-as-jetty-contexthandlers"></a><a class="link" href="#_deploying-bundles-as-jetty-contexthandlers">Deploying Bundles as Jetty ContextHandlers</a></h4>
<div class="paragraph">
<p>In addition to deploying webapps, the Jetty OSGi container listens for the installation of bundles that are not heavyweight webapps, but rather use the flexible Jetty-specific concept of <code>ContextHandlers</code>.</p>
</div>
<div class="paragraph">
<p>The following is the criteria used to decide if a bundle can be deployed as a <code>ContextHandler</code>:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Bundle MANIFEST contains Jetty-ContextFilePath</dt>
<dd>
<p>A comma separated list of names of context files - each one of which represents a ContextHandler that should be deployed by Jetty.
The context files can be inside the bundle, external to the bundle somewhere on the file system, or external to the bundle in the <strong>jetty.home</strong> directory.</p>
<div class="paragraph">
<p>A context file that is inside the bundle:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">Jetty-ContextFilePath: ./a/b/c/d/foo.xml</code></pre>
</div>
</div>
<div class="paragraph">
<p>A context file that is on the file system:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">Jetty-ContextFilePath: /opt/app/contexts/foo.xml</code></pre>
</div>
</div>
<div class="paragraph">
<p>A context file that is relative to jetty.home:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">Jetty-ContextFilePath: contexts/foo.xml</code></pre>
</div>
</div>
<div class="paragraph">
<p>A number of different context files:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">Jetty-ContextFilePath: ./a/b/c/d/foo.xml,/opt/app/contexts/foo.xml,contexts/foo.xml</code></pre>
</div>
</div>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Other <code>MANIFEST</code> properties that can be used to configure the deployment of the <code>ContextHandler</code>:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">managedServerName</dt>
<dd>
<p>The name of the Server instance to which to deploy this webapp bundle.
If not specified, defaults to the default Server instance called "defaultJettyServer".</p>
</dd>
</dl>
</div>
<div class="sect4">
<h5 id="_determining-the-context-path-for-a-contexthandler-bundle"><a class="anchor" href="#_determining-the-context-path-for-a-contexthandler-bundle"></a><a class="link" href="#_determining-the-context-path-for-a-contexthandler-bundle">Determining the Context Path for a ContextHandler Bundle</a></h5>
<div class="paragraph">
<p>Usually, the context path for the ContextHandler will be set by the context xml file.
However, you can override any path set in the context xml file by using the <strong>Web-ContextPath</strong> header in the <code>MANIFEST</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="_extra-properties-available-for-context-xml-files"><a class="anchor" href="#_extra-properties-available-for-context-xml-files"></a><a class="link" href="#_extra-properties-available-for-context-xml-files">Extra Properties Available for Context Xml Files</a></h5>
<div class="paragraph">
<p>Before the Jetty OSGi container applies a context xml file found in a <strong>Jetty-ContextFilePath</strong> <code>MANIFEST</code> header, it sets a few useful propertiesthat can be referred to within the xml file:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Server</dt>
<dd>
<p>This is a reference to the Jetty <code>org.eclipse.jetty.server.Server</code> instance to which the <code>ContextHandler</code> being configured in the context xml file will be deployed.</p>
</dd>
<dt class="hdlist1">bundle.root</dt>
<dd>
<p>This is a reference to the <code>org.eclipse.jetty.util.resource.Resource</code> that represents the location of the Bundle (obtained by calling <code>Bundle.getLocation()</code>).
Note that this could be either a directory in the file system if the OSGi container automatically unpacks bundles, or it may be a jar:file: url if the bundle remains packed.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of a context xml file that makes use of these properties:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.server.handler.ContextHandler"&gt;
&lt;!-- Get root for static content, could be on file system or this bundle --&gt;
&lt;Call id="res" class="org.eclipse.jetty.util.resource.Resource" name="newResource"&gt;
&lt;Arg&gt;&lt;Property name="bundle.root"/&gt;&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Ref refid="res"&gt;
&lt;Call id="base" name="addPath"&gt;
&lt;Arg&gt;/static/&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Ref&gt;
&lt;Set name="contextPath"&gt;/unset&lt;/Set&gt;
&lt;!-- Set up the base resource for static files relative to inside bundle --&gt;
&lt;Set name="baseResource"&gt;
&lt;Ref refid="base"/&gt;
&lt;/Set&gt;
&lt;Set name="handler"&gt;
&lt;New class="org.eclipse.jetty.server.handler.ResourceHandler"&gt;
&lt;Set name="welcomeFiles"&gt;
&lt;Array type="String"&gt;
&lt;Item&gt;index.html&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Set&gt;
&lt;Set name="cacheControl"&gt;max-age=3600,public&lt;/Set&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="services-as-webapps"><a class="anchor" href="#services-as-webapps"></a><a class="link" href="#services-as-webapps">Deploying Services as Webapps</a></h4>
<div class="paragraph">
<p>In addition to listening for bundles whose format or <code>MANIFEST</code> entries define a webapp or <code>ContextHandler</code> for to be deployed, the Jetty OSGi container also listens for the registration of OSGi services that are instances of <code>org.eclipse.jetty.webapp.WebAppContext</code>.
So you may programmatically create a <code>WebAppContext</code>, register it as a service, and have Jetty pick it up and deploy it.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of doing that with a simple bundle that serves static content, and an <code>org.osgi.framework.BundleActivator</code> that instantiates the <code>WebAppContext</code>:</p>
</div>
<div class="paragraph">
<p>The bundle contents:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">META-INF/MANIFEST.MF
index.html
com/acme/osgi/Activator.class</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>MANIFEST.MF</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">Bundle-Classpath: .
Bundle-Name: Jetty OSGi Test WebApp
DynamicImport-Package: org.eclipse.jetty.*;version="[9.0,10.0)"
Bundle-Activator: com.acme.osgi.Activator
Import-Package: org.eclipse.jetty.server.handler;version="[9.0,10)",
org.eclipse.jetty.webapp;version="[9.0,10)",
org.osgi.framework;version= "[1.5,2)",
org.osgi.service.cm;version="1.2.0",
org.osgi.service.packag eadmin;version="[1.2,2)",
org.osgi.service.startlevel;version="1.0.0",
org.osgi.service.url;version="1.0.0",
org.osgi.util.tracker;version= "1.3.0",
org.xml.sax,org.xml.sax.helpers
Bundle-SymbolicName: com.acme.testwebapp</code></pre>
</div>
</div>
<div class="paragraph">
<p>The Activator code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public void start(BundleContext context) throws Exception
{
WebAppContext webapp = new WebAppContext();
Dictionary props = new Hashtable();
props.put("Jetty-WarResourcePath",".");
props.put("contextPath","/acme");
context.registerService(WebAppContext.class.getName(),webapp,props);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above setup is sufficient for Jetty to recognize and deploy the <code>WebAppContext</code> at /acme.</p>
</div>
<div class="paragraph">
<p>As the example shows, you can use OSGi Service properties in order to communicate extra configuration information to Jetty:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Jetty-WarFolderPath (for releases prior to 9.3) or Jetty-WarResourcePath</dt>
<dd>
<p>The location within the bundle of the root of the static resources for the webapp</p>
</dd>
<dt class="hdlist1">Web-ContextPath</dt>
<dd>
<p>The context path at which to deploy the webapp.</p>
</dd>
<dt class="hdlist1">Jetty-defaultWebXmlFilePath</dt>
<dd>
<p>The location within the bundle of a <code>webdefault.xml</code> file to apply to the webapp.
Defaults to that of the Jetty OSGi container.</p>
</dd>
<dt class="hdlist1">Jetty-WebXmlFilePath</dt>
<dd>
<p>The location within the bundle of the <code>web.xml</code> file.
Defaults to <code>WEB-INF/web.xml</code></p>
</dd>
<dt class="hdlist1">Jetty-extraClassPath</dt>
<dd>
<p>A classpath of additional items to add to the webapp&#8217;s classloader.</p>
</dd>
<dt class="hdlist1">Jetty-bundleInstall</dt>
<dd>
<p>The path to the base folder that overrides the computed bundle installation - mostly useful for those OSGi frameworks that unpack bundles by default.</p>
</dd>
<dt class="hdlist1">Require-TldBundle</dt>
<dd>
<p>A comma separated list of bundle symbolic names of bundles containing TLDs that this webapp depends upon.</p>
</dd>
<dt class="hdlist1">managedServerName</dt>
<dd>
<p>The name of the Server instance to which to deploy this webapp.
If not specified, defaults to the default Server instance called "defaultJettyServer".</p>
</dd>
<dt class="hdlist1">Jetty-WarFragmentResourcePath</dt>
<dd>
<p>The path within a fragment hosted by the web-bundle that contains static resources for the webapp.
The path is appended to the base resource for the webapp (see Jetty-WarResourcePath).</p>
</dd>
<dt class="hdlist1">Jetty-WarPrependFragmentResourcePath</dt>
<dd>
<p>The path within a fragment hosted by the web-bundle that contains static resources for the webapp.
The path is prepended to the base resource for the webapp (see Jetty-WarResourcePath).</p>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="_deploying-services-as-contexthandlers"><a class="anchor" href="#_deploying-services-as-contexthandlers"></a><a class="link" href="#_deploying-services-as-contexthandlers">Deploying Services as ContextHandlers</a></h4>
<div class="paragraph">
<p>Similarly to WebApp`Contexts, the Jetty OSGi container can detect the registration of an OSGi Service that represents a <code>ContextHandler</code> and ensure that it is deployed.
The <code>ContextHandler</code> can either be fully configured before it is registered as an OSGi service - in which case the Jetty OSGi container will merely deploy it - or the <code>ContextHandler</code> can be partially configured, with the Jetty OSGi container completing the configuration via a context xml file and properties associated with the Service.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of doing that with a simple bundle that serves static content with an <code>org.osgi.framework.BundleActivator</code> that instantiates a <code>ContextHandler</code> and registers it as an OSGi Service, passing in properties that define a context xml file and context path for Jetty to apply upon deployment:</p>
</div>
<div class="paragraph">
<p>The bundle contents:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">META-INF/MANIFEST.MF
static/index.html
acme.xml
com/acme/osgi/Activator.class
com/acme/osgi/Activator$1.class</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>MANIFEST</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">Bundle-Classpath: .
Bundle-Name: Jetty OSGi Test Context
DynamicImport-Package: org.eclipse.jetty.*;version="[9.0,10.0)"
Bundle-Activator: com.acme.osgi.Activator
Import-Package: javax.servlet;version="2.6.0",
javax.servlet.resources;version="2.6.0",
org.eclipse.jetty.server.handler;version="[9.0,10)",
org.osgi.framework;version="[1.5,2)",
org.osgi.service.cm;version="1.2.0",
org.osgi.service.packageadmin;version="[1.2,2)",
org.osgi.service.startlevel;version="1.0.0.o",
org.osgi.service.url;version="1.0.0",
org.osgi.util.tracker;version="1.3.0",
org.xml.sax,org.xml.sax.helpers
Bundle-SymbolicName: com.acme.testcontext</code></pre>
</div>
</div>
<div class="paragraph">
<p>The Activator code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public void start(final BundleContext context) throws Exception
{
ContextHandler ch = new ContextHandler();
ch.addEventListener(new ServletContextListener () {
@Override
public void contextInitialized(ServletContextEvent sce)
{
System.err.println("Context is initialized");
}
@Override
public void contextDestroyed(ServletContextEvent sce)
{
System.err.println("Context is destroyed!");
}
});
Dictionary props = new Hashtable();
props.put("Web-ContextPath","/acme");
props.put("Jetty-ContextFilePath", "acme.xml");
context.registerService(ContextHandler.class.getName(),ch,props);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The contents of the <code>acme.xml</code> context file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.server.handler.ContextHandler"&gt;
&lt;!-- Get root for static content, could be on file system or this bundle --&gt;
&lt;Call id="res" class="org.eclipse.jetty.util.resource.Resource" name="newResource"&gt;
&lt;Arg&gt;&lt;Property name="bundle.root"/&gt;&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Ref refid="res"&gt;
&lt;Call id="base" name="addPath"&gt;
&lt;Arg&gt;/static/&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Ref&gt;
&lt;Set name="contextPath"&gt;/unset&lt;/Set&gt;
&lt;!-- Set up the base resource for static files relative to inside bundle --&gt;
&lt;Set name="baseResource"&gt;
&lt;Ref refid="base"/&gt;
&lt;/Set&gt;
&lt;Set name="handler"&gt;
&lt;New class="org.eclipse.jetty.server.handler.ResourceHandler"&gt;
&lt;Set name="welcomeFiles"&gt;
&lt;Array type="String"&gt;
&lt;Item&gt;index.html&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Set&gt;
&lt;Set name="cacheControl"&gt;max-age=3600,public&lt;/Set&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>You may also use the following OSGi Service properties:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">managedServerName</dt>
<dd>
<p>The name of the Server instance to which to deploy this webapp.
If not specified, defaults to the default Server instance called "defaultJettyServer".</p>
</dd>
</dl>
</div>
<div class="sect4">
<h5 id="_extra-properties-available-for-context-xml-files-2"><a class="anchor" href="#_extra-properties-available-for-context-xml-files-2"></a><a class="link" href="#_extra-properties-available-for-context-xml-files-2">Extra Properties Available for Context Xml Files</a></h5>
<div class="paragraph">
<p>Before the Jetty OSGi container applies a context xml file found in a <code>Jetty-ContextFilePath</code> property, it sets a few useful properties that can be referred to within the xml file:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Server</dt>
<dd>
<p>This is a reference to the Jetty <code>org.eclipse.jetty.server.Server</code> instance to which the <code>ContextHandler</code> being configured in the context xml file will be deployed.</p>
</dd>
<dt class="hdlist1">bundle.root</dt>
<dd>
<p>This is a reference to the <code>org.eclipse.jetty.util.resource.Resource</code> that represents the location of the Bundle publishing the <code>ContextHandler</code> as a Service (obtained by calling <code>Bundle.getLocation()</code>).
Note that this could be either a directory in the file system if the OSGi container automatically unpacks bundles, or it may be a jar:file: url if the bundle remains packed.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>In the example above, you can see both of these properties being used in the context xml file.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_support-for-the-osgi-service-platform-enterprise-specification"><a class="anchor" href="#_support-for-the-osgi-service-platform-enterprise-specification"></a><a class="link" href="#_support-for-the-osgi-service-platform-enterprise-specification">Support for the OSGi Service Platform Enterprise Specification</a></h4>
<div class="paragraph">
<p>The Jetty OSGi container implements several aspects of the Enterprise Specification v4.2 for the <code>WebAppContexts</code> and <code>ContextHandlers</code> that it deploys from either bundles or OSGi services as outlined in foregoing sections.</p>
</div>
<div class="sect4">
<h5 id="_context-attributes"><a class="anchor" href="#_context-attributes"></a><a class="link" href="#_context-attributes">Context Attributes</a></h5>
<div class="paragraph">
<p>For each <code>WebAppContext</code> or <code>ContextHandler</code>, the following context attribute is set, as required by section <em>128.6.1 Bundle Context</em> page 427:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">osgi-bundleContext</dt>
<dd>
<p>The value of this attribute is the <code>BundleContext</code> representing the Bundle associated with the <code>WebAppContext</code> or <code>ContextHandler</code>.</p>
</dd>
</dl>
</div>
</div>
<div class="sect4">
<h5 id="_service-attributes"><a class="anchor" href="#_service-attributes"></a><a class="link" href="#_service-attributes">Service Attributes</a></h5>
<div class="paragraph">
<p>As required by the specification section <em>128.3.4 Publishing the Servlet Context</em> page 421, each <code>WebAppContext</code> and <code>ContextHandler</code> deployed by the Jetty OSGi container is also published as an OSGi service (unless it has been already - see sections 1.6 and 1.7).
The following properties are associated with these services:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">osgi.web.symbolicname</dt>
<dd>
<p>The symbolic name of the Bundle associated with the <code>WebAppContext</code> or <code>ContextHandler</code></p>
</dd>
<dt class="hdlist1">osgi.web.version</dt>
<dd>
<p>The Bundle-Version header from the Bundle associated with the <code>WebAppContext</code> or <code>ContextHandler</code></p>
</dd>
<dt class="hdlist1">osgi.web.contextpath</dt>
<dd>
<p>The context path of the <code>WebAppContext</code> or <code>ContextHandler</code></p>
</dd>
</dl>
</div>
</div>
<div class="sect4">
<h5 id="_osgi-events"><a class="anchor" href="#_osgi-events"></a><a class="link" href="#_osgi-events">OSGi Events</a></h5>
<div class="paragraph">
<p>As required by the specification section <em>128.5 Events</em> pg 426, the
following OSGi Event Admin events will be posted:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">org/osgi/service/web/DEPLOYING</dt>
<dd>
<p>The Jetty OSGi container is about to deploy a <code>WebAppContext</code> or <code>ContextHandler</code></p>
</dd>
<dt class="hdlist1">org/osgi/service/web/DEPLOYED</dt>
<dd>
<p>The Jetty OSGi container has finished deploying a <code>WebAppContext</code> or <code>ContextHandler</code> and it is in service</p>
</dd>
<dt class="hdlist1">org/osgi/service/web/UNDEPLOYING</dt>
<dd>
<p>The Jetty OSGi container is about to undeploy a <code>WebAppContext</code> or <code>ContextHandler</code></p>
</dd>
<dt class="hdlist1">org/osgi/service/web/UNDEPLOYED</dt>
<dd>
<p>The Jetty OSGi container has finished undeploying a <code>WebAppContext</code> or <code>ContextHandler</code> and it is no longer in service</p>
</dd>
<dt class="hdlist1">org/osgi/service/web/FAILED</dt>
<dd>
<p>The Jetty OSGi container failed to deploy a <code>WebAppContext</code> or <code>ContextHandler</code></p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_using-jsps"><a class="anchor" href="#_using-jsps"></a><a class="link" href="#_using-jsps">Using JSPs</a></h4>
<div class="sect4">
<h5 id="_setup"><a class="anchor" href="#_setup"></a><a class="link" href="#_setup">Setup</a></h5>
<div class="paragraph">
<p>In order to use JSPs with your webapps and bundles you will need to install the JSP and JSTL jars and their dependencies into your OSGi container.
Some you will find in the Jetty distribution, whereas others you will need to download from <a href="https://repo1.maven.org/maven2/org/eclipse/jetty/orbit/">Maven central</a>.
Here is the list of recommended jars (NOTE the version numbers may change in future):</p>
</div>
<table id="osgi-jsp" class="tableblock frame-all grid-all stretch">
<caption class="title">Table 9. Jars Required for JSP</caption>
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Jar</th>
<th class="tableblock halign-left valign-top">Bundle Symbolic Name</th>
<th class="tableblock halign-left valign-top">Location</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">The <a href="#osgi-annotations">annotation jars</a></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.mortbay.jasper:apache-el</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.mortbay.jasper.apache-el</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Distribution lib/apache-jsp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.mortbay.jasper:apache-jsp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.mortbay.jasper.apache-jsp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Distribution lib/apache-jsp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty:apache-jsp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.apache-jsp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Distribution lib/apache-jsp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jdt.core-3.8.2.v20130121.jar</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jdt.core.compiler.batch</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Distribution lib/apache-jsp</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.osgi:jetty-osgi-boot-jsp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.osgi.boot.jsp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot-jsp">Maven central</a></p></td>
</tr>
</tbody>
</table>
<div class="quoteblock">
<blockquote>
<div class="olist NOTE">
<ol class="NOTE">
<li>
<p>As of Jetty 9.2.3 the jetty-osgi-boot-jsp bundle changed to using Apache Jasper as the JSP implementation.
Prior to this the Glassfish Jasper implementation was used, which had a different set of dependencies - pay careful attention to the jars listed both at the top of this page and in this section, as deployment of other jars can cause incomplete or incorrect package resolution in the OSGi container.</p>
</li>
<li>
<p>The order of deployment is important.
Deploy these bundles in the order shown or you may experience strange failures in the compilation of jsps.
This can be hard to diagnose but is almost always caused by the <code>ServletContainerInitializer</code> in the <code>org.eclipse.jetty.apache-jsp</code> bundle for the jsp container not being invoked due to incorrect startup of the annotation jars.</p>
</li>
</ol>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>For the JSTL library, we recommend the use of the implementation from Glassfish, as it has fewer dependencies:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 10. Jars Required for Glassfish JSTL</caption>
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Jar</th>
<th class="tableblock halign-left valign-top">Bundle Symbolic Name</th>
<th class="tableblock halign-left valign-top">The <a href="#osgi-jsp">jsp jars</a></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.orbit:javax.servlet.jsp.jstl-1.2.0.v201105211821.jar</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">javax.servlet.jsp.jstl</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>However, if you wish, you may use the JSTL implementation from Apache instead, although you will need to source some dependency jars with suitable OSGi manifests:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 11. Jars Required for Apache JSTL</caption>
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Jar</th>
<th class="tableblock halign-left valign-top">Bundle Symbolic Name</th>
<th class="tableblock halign-left valign-top">Location</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">The <a href="#osgi-jsp">jsp jars</a></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.taglibs:taglibs-standard-spec:jar:1.2.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.taglibs.taglibs-standard-spec</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Distribution lib/apache-jstl</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.taglibs:taglibs-standard-spec:jar:1.2.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.taglibs.standard-impl</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Distribution lib/apache-jstl</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.xalan 2.7.1</p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Try
<a href="http://download.eclipse.org/tools/orbit/downloads/drops/R20140525021250/repository/plugins/org.apache.xalan_2.7.1.v201005080400.jar">Eclipse
Orbit</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.xml.serializer 2.7.1</p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Try
<a href="http://download.eclipse.org/tools/orbit/downloads/drops/R20140525021250/repository/plugins/org.apache.xml.serializer_2.7.1.v201005080400.jar">Eclipse
Orbit</a></p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect4">
<h5 id="_the-jetty-osgi-boot-jsp-jar"><a class="anchor" href="#_the-jetty-osgi-boot-jsp-jar"></a><a class="link" href="#_the-jetty-osgi-boot-jsp-jar">The jetty-osgi-boot-jsp jar</a></h5>
<div class="paragraph">
<p>To be able to use JSPs you will need to also install the <a href="https://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot-jsp/">jetty-osgi-boot-jsp.jar</a> into your OSGi container.
This jar can be obtained from maven central <a href="https://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-boot-jsp/">here</a>.</p>
</div>
<div class="paragraph">
<p>This bundle acts as a fragment extension to the jetty-osgi-boot.jar and adds in support for using JSP.</p>
</div>
<div class="sect5">
<h6 id="_using-taglibs"><a class="anchor" href="#_using-taglibs"></a><a class="link" href="#_using-taglibs">Using TagLibs</a></h6>
<div class="paragraph">
<p>The Jetty JSP OSGi container will make available the JSTL tag library to all webapps.
If you only use this tag library, then your webapp will work without any further modification.</p>
</div>
<div class="paragraph">
<p>However, if you make use of other taglibs, you will need to ensure that they are installed into the OSGi container, and also define some System properties and/or <code>MANIFEST</code> headers in your webapp.
This is necessary because the classloading regime used by the OSGi container is very different than that used by JSP containers, and the <code>MANIFEST</code> of a normal webapp does not contain enough information for the OSGi environment to allow a JSP container to find and resolve TLDs referenced in the webapp&#8217;s .jsp files.</p>
</div>
<div class="paragraph">
<p>Firstly, lets look at an example of a web bundle&#8217;s modified <code>MANIFEST</code> file so you get an idea of what is required.
This example is a web bundle that uses the Spring servlet framework:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">Bundle-SymbolicName: com.acme.sample
Bundle-Name: WebSample
Web-ContextPath: taglibs
Import-Bundle: org.springframework.web.servlet
Require-TldBundle: org.springframework.web.servlet
Bundle-Version: 1.0.0
Import-Package: org.eclipse.virgo.web.dm;version="[3.0.0,4.0.0)",org.s
pringframework.context.config;version="[2.5.6,4.0.0)",org.springframe
work.stereotype;version="[2.5.6,4.0.0)",org.springframework.web.bind.
annotation;version="[2.5.6,4.0.0)",org.springframework.web.context;ve
rsion="[2.5.6,4.0.0)",org.springframework.web.servlet;version="[2.5.6
,4.0.0)",org.springframework.web.servlet.view;version="[2.5.6,4.0.0)"</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <strong>Require-TldBundle</strong> header tells the Jetty OSGi container that this bundle contains TLDs that need to be passed over to the JSP container for processing.
The <strong>Import-Bundle</strong> header ensures that the implementation classes for these TLDs will be available to the webapp on the OSGi classpath.</p>
</div>
<div class="paragraph">
<p>The format of the <strong>Require-TldBundle</strong> header is a comma separated list of one or more symbolic names of bundles containing TLDs.</p>
</div>
</div>
<div class="sect5">
<h6 id="_container-path-taglibs"><a class="anchor" href="#_container-path-taglibs"></a><a class="link" href="#_container-path-taglibs">Container Path Taglibs</a></h6>
<div class="paragraph">
<p>Some TLD jars are required to be found on the Jetty OSGi container&#8217;s classpath, rather than considered part of the web bundle&#8217;s classpath.
For example, this is true of JSTL and Java Server Faces.
The Jetty OSGi container takes care of JSTL for you, but you can control which other jars are considered as part of the container&#8217;s classpath by using the System property <strong>org.eclipse.jetty.osgi.tldbundles</strong>:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">org.eclipse.jetty.osgi.tldbundles</dt>
<dd>
<p>System property defined on the OSGi environment that is a comma separated list of symbolic names of bundles containing taglibs that will be treated as if they are on the container&#8217;s classpath for web bundles.
For example:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">org.eclipse.jetty.osgi.tldbundles=com.acme.special.tags,com.foo.web,org.bar.web.framework</code></pre>
</div>
</div>
<div class="paragraph">
<p>You will still need to define the <strong>Import-Bundle</strong> header in the <code>MANIFEST</code> file for the web bundle to ensure that the TLD bundles are on the OSGi classpath.</p>
</div>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Alternatively or additionally, you can define a pattern as a context attribute that will match symbolic bundle names in the OSGi environment containing TLDs that should be considered as discovered from the container&#8217;s classpath.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">org.eclipse.jetty.server.webapp.containerIncludeBundlePattern</dt>
<dd>
<p>This pattern must be specified as a context attribute of the <code>WebAppContext</code> representing the web bundle.
Unless you are deploying your own <code>WebAppContext</code> (see <a href="#services-as-webapps">Deploying Services as Webapps</a>), you won&#8217;t have a reference to the <code>WebAppContext</code> to do this.
In that case, it can be specified on the <code>org.eclipse.jetty.deploy.DeploymentManager</code>, where it will be applied to <em>every</em> webapp deployed by the Jetty OSGi container.
The <code>jetty-osgi-boot.jar</code> contains the default <code>jettyhome/etc/jetty-deploy.xml</code> file where the <code>DeploymentManager</code> is defined.
To set the pattern, you will need to provide your own etc files - see the section on <a href="#customize-jetty-container">customizing the jetty container</a> for how to do this. Here&#8217;s how the <code>jetty-deploy.xml</code> file would look if we defined a pattern that matched all bundle symbolic names ending in "tag" and "web":</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;Call name="addBean"&gt;
&lt;Arg&gt;
&lt;New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager"&gt;
&lt;Set name="contexts"&gt;
&lt;Ref refid="Contexts" /&gt;
&lt;/Set&gt;
&lt;Call name="setContextAttribute"&gt;
&lt;Arg&gt;org.eclipse.jetty.server.webapp.ContainerIncludeBundlePattern&lt;/Arg&gt;
&lt;Arg&gt;.*\.tag$|.*\.web$&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Again, you will still need to define suitable <strong>Import-Bundle</strong> headers in your web bundle <code>MANIFEST</code> to ensure that bundles matching the pattern are available on the OSGi class path.</p>
</div>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="osgi-annotations"><a class="anchor" href="#osgi-annotations"></a><a class="link" href="#osgi-annotations">Using Annotations/ServletContainerInitializers</a></h4>
<div class="paragraph">
<p>Annotations are very much part of the Servlet 3.0 and 3.1 specifications.
In order to use them with Jetty in OSGi, you will need to deploy some extra jars into your OSGi container:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 12. Jars Required for Annotations</caption>
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Jar</th>
<th class="tableblock halign-left valign-top">Bundle Symbolic Name</th>
<th class="tableblock halign-left valign-top">Location</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">The <a href="#spifly">spifly jars</a></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.ow2.asm:asm-7.0.jar</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.objectweb.asm</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://repo1.maven.org/maven2/org/ow2/asm/asm">Maven central</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.ow2.asm:asm-commons-7.0.jar</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.objectweb.asm.commons</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://repo1.maven.org/maven2/org/ow2/asm/asm-commons">Maven central</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.ow2.asm:asm-tree-7.0.jar</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.objectweb.asm.tree</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://repo1.maven.org/maven2/org/ow2/asm/asm-tree">Maven central</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">javax.annotation:javax.annotation-api-1.2.jar</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">javax.annotation-api</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://repo1.maven.org/maven2/javax/annotation/javax.annotation-api/">Maven
central</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jta api version 1.1.1 (eg
org.apache.geronimo.specs:geronimo-jta_1.1_spec-1.1.1.jar)<sup>*</sup></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Maven
central</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">javax mail api version 1.4.1 (eg
org.eclipse.jetty.orbit:javax.mail.glassfish-1.4.1.v201005082020.jar)<sup>*</sup></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Maven central</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-jndi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.jndi</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Distribution lib/</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-plus</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.plus</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Distribution lib/</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-annotations</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">org.eclipse.jetty.annotations</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Distribution lib/</p></td>
</tr>
</tbody>
</table>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
If you wish to use JSPs you will need to deploy these annotation-related jars.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
You may be able to deploy later versions or other providers of these specifications, however these particular versions are known to have correct manifests and have been tested and known to work with OSGi.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Even if your webapp itself does not not use annotations, you may need to deploy these jars because your webapp depends on a Jetty module or a 3rd party library that uses a <a href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html">javax.servlet.ServletContainerInitializer</a>.
This interface requires annotation support.
It is implemented by providers of code that extend the capabilities of the container.
An example of this is the Jetty JSR356 Websocket implementation, although it is being used increasingly commonly in popular libraries like <a href="http://projects.spring.io/spring-framework/">Spring</a>, <a href="https://jersey.java.net/">Jersey</a> and JSP containers.</p>
</div>
<div class="paragraph">
<p>To find <code>ServletContainerInitializers</code> on the classpath, Jetty uses the Java <a href="http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html"><code>ServiceLoader</code></a>
mechanism.
For this to function in OSGi, you will need an OSGi R5 compatible container, and have support for the <a href="http://blog.osgi.org/2013/02/javautilserviceloader-in-osgi.html">Service Loader Mediator</a>.
Jetty has been tested with the <a href="http://aries.apache.org/modules/spi-fly.html">Aries SpiFly</a> module, which is the reference implementation of the Service Loader Mediator, and is listed in the jars above.</p>
</div>
</div>
<div class="sect3">
<h4 id="_osgi-containers"><a class="anchor" href="#_osgi-containers"></a><a class="link" href="#_osgi-containers">OSGi Containers</a></h4>
<div class="sect4">
<h5 id="_felix"><a class="anchor" href="#_felix"></a><a class="link" href="#_felix">Felix</a></h5>
<div class="paragraph">
<p>The Jetty OSGi integration has been successfully tested against <a href="http://felix.apache.org/">Felix</a> 5.0.0.</p>
</div>
<div class="paragraph">
<p>You will require the following extra Felix services, available as separately downloadable jars:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="http://felix.apache.org/documentation/subprojects/apache-felix-config-admin.html">Felix Configuration Admin Service</a></p>
</li>
<li>
<p><a href="http://felix.apache.org/documentation/subprojects/apache-felix-event-admin.html">Felix Event Admin Service</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Unfortunately, as of Felix 4.x there is a difficultly with the resolution of the <code>javax.transaction</code> package.
A <a href="http://mail-archives.apache.org/mod_mbox/felix-users/201211.mbox/%3CCAPr=90M+5vYjPqAvyTU+gYHr64y_FosBYELeUYcU_rFEJF3Cxw&#64;mail.gmail.com%3E">description of the problem</a> and hint to solving it is described [<a href="http://mail-archives.apache.org/mod_mbox/felix-users/201211.mbox/%3CCAPr=90M+5vYjPqAvyTU+gYHr64y_FosBYELeUYcU_rFEJF3Cxw&#64;mail.gmail.com%3E">here</a>].</p>
</div>
<div class="paragraph">
<p>The simplest solution for this is to extract the <code>default.properties</code> file from the <code>felix.jar</code>, change the declaration of the <code>javax.sql</code> and <code>javax.transaction</code> packages and set the changed lines as the value of the <code>org.osgi.framework.system.packages</code> property in the <code>conf/config.properties</code> file.</p>
</div>
<div class="paragraph">
<p>The <code>default.properties</code> file defines the default <code>org.osgi.framework.system.packages</code> property like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-properties" data-lang="properties"># Default packages exported by system bundle.
org.osgi.framework.system.packages=org.osgi.framework; version=1.7.0, \
org.osgi.framework.hooks.bundle; version=1.1.0, \
org.osgi.framework.hooks.resolver; version=1.0.0, \
org.osgi.framework.hooks.service; version=1.1.0, \
org.osgi.framework.hooks.weaving; version=1.0.0, \
org.osgi.framework.launch; version=1.1.0, \
org.osgi.framework.namespace; version=1.0.0, \
org.osgi.framework.startlevel; version=1.0.0, \
org.osgi.framework.wiring; version=1.1.0, \
org.osgi.resource; version=1.0.0, \
org.osgi.service.packageadmin; version=1.2.0, \
org.osgi.service.startlevel; version=1.1.0, \
org.osgi.service.url; version=1.0.0, \
org.osgi.util.tracker; version=1.5.1 \
${jre-${java.specification.version}}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The last line must be substituted for one of the definitions further down in the file that is suitable for the jvm you are using.</p>
</div>
<div class="paragraph">
<p>You will take these lines and copy them into the <code>conf/config.properties</code> file, after having replaced the line <code>$\{jre-$\{java.specification.version}}</code> with all of the lines relevant to your version of the jvm.</p>
</div>
<div class="paragraph">
<p>For example, for a 1.7 jvm, you will find this property definition:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-properties" data-lang="properties">jre-1.7=, \
javax.accessibility;uses:="javax.swing.text";version="0.0.0.1_007_JavaSE", \
javax.activation;version="0.0.0.1_007_JavaSE", \
javax.activity;version="0.0.0.1_007_JavaSE", \
javax.annotation.processing;uses:="javax.tools,javax.lang.model,javax.lang.model.element,javax.lang.model.util";version="0.0.0.1_007_JavaSE", \
javax.annotation;version="0.0.0.1_007_JavaSE", \
javax.crypto.interfaces;uses:="javax.crypto.spec,javax.crypto";version="0.0.0.1_007_JavaSE", \
javax.crypto.spec;uses:="javax.crypto";version="0.0.0.1_007_JavaSE", \
javax.crypto;uses:="javax.crypto.spec";version="0.0.0.1_007_JavaSE", \
javax.imageio.event;uses:="javax.imageio";version="0.0.0.1_007_JavaSE", \
javax.imageio.metadata;uses:="org.w3c.dom,javax.imageio";version="0.0.0.1_007_JavaSE", \
javax.imageio.plugins.bmp;uses:="javax.imageio";version="0.0.0.1_007_JavaSE", \
javax.imageio.plugins.jpeg;uses:="javax.imageio";version="0.0.0.1_007_JavaSE", \
javax.imageio.spi;uses:="javax.imageio.stream,javax.imageio,javax.imageio.metadata";version="0.0.0.1_007_JavaSE", \
javax.imageio.stream;uses:="javax.imageio";version="0.0.0.1_007_JavaSE", \
javax.imageio;uses:="javax.imageio.metadata,javax.imageio.stream,javax.imageio.spi,javax.imageio.event";version="0.0.0.1_007_JavaSE", \
javax.jws.soap;version="0.0.0.1_007_JavaSE", \
javax.jws;version="0.0.0.1_007_JavaSE", \
javax.lang.model.element;uses:="javax.lang.model.type,javax.lang.model";version="0.0.0.1_007_JavaSE", \
javax.lang.model.type;uses:="javax.lang.model.element,javax.lang.model";version="0.0.0.1_007_JavaSE", \
javax.lang.model.util;uses:="javax.lang.model,javax.lang.model.element,javax.annotation.processing,javax.lang.model.type";version="0.0.0.1_007_JavaSE", \
javax.lang.model;version="0.0.0.1_007_JavaSE", \
javax.management.loading;uses:="javax.management";version="0.0.0.1_007_JavaSE", \
javax.management.modelmbean;uses:="javax.management,javax.management.loading";version="0.0.0.1_007_JavaSE", \
javax.management.monitor;uses:="javax.management";version="0.0.0.1_007_JavaSE", \
javax.management.openmbean;uses:="javax.management";version="0.0.0.1_007_JavaSE", \
javax.management.relation;uses:="javax.management";version="0.0.0.1_007_JavaSE", \
javax.management.remote.rmi;uses:="javax.management.remote,javax.security.auth,javax.management,javax.management.loading,javax.naming,javax.rmi.ssl,org.omg.CORBA,org.omg.CORBA_2_3.portable,org.omg.CORBA.portable,javax.rmi.CORBA,javax.rmi";version="0.0.0.1_007_JavaSE", \
javax.management.remote;uses:="javax.security.auth,javax.management";version="0.0.0.1_007_JavaSE", \
javax.management.timer;uses:="javax.management";version="0.0.0.1_007_JavaSE", \
javax.management;uses:="javax.management.loading,javax.management.openmbean";version="0.0.0.1_007_JavaSE", \
javax.naming.directory;uses:="javax.naming";version="0.0.0.1_007_JavaSE", \
javax.naming.event;uses:="javax.naming,javax.naming.directory";version="0.0.0.1_007_JavaSE", \
javax.naming.ldap;uses:="javax.naming,javax.naming.directory,javax.net.ssl,javax.naming.event";version="0.0.0.1_007_JavaSE", \
javax.naming.spi;uses:="javax.naming,javax.naming.directory";version="0.0.0.1_007_JavaSE", \
javax.naming;uses:="javax.naming.spi";version="0.0.0.1_007_JavaSE", \
javax.net.ssl;uses:="javax.security.cert,javax.security.auth.x500,javax.net";version="0.0.0.1_007_JavaSE", \
javax.net;version="0.0.0.1_007_JavaSE", \
javax.print.attribute.standard;uses:="javax.print.attribute";version="0.0.0.1_007_JavaSE", \
javax.print.attribute;version="0.0.0.1_007_JavaSE", \
javax.print.event;uses:="javax.print,javax.print.attribute";version="0.0.0.1_007_JavaSE", \
javax.print;uses:="javax.print.attribute,javax.print.event,javax.print.attribute.standard";version="0.0.0.1_007_JavaSE", \
javax.rmi.CORBA;uses:="org.omg.CORBA,org.omg.CORBA_2_3.portable,org.omg.CORBA.portable,org.omg.SendingContext";version="0.0.0.1_007_JavaSE", \
javax.rmi.ssl;uses:="javax.net,javax.net.ssl";version="0.0.0.1_007_JavaSE", \
javax.rmi;uses:="org.omg.CORBA,javax.rmi.CORBA";version="0.0.0.1_007_JavaSE", \
javax.script;version="0.0.0.1_007_JavaSE", \
javax.security.auth.callback;version="0.0.0.1_007_JavaSE", \
javax.security.auth.kerberos;uses:="javax.security.auth,javax.crypto";version="0.0.0.1_007_JavaSE", \
javax.security.auth.login;uses:="javax.security.auth,javax.security.auth.callback";version="0.0.0.1_007_JavaSE", \
javax.security.auth.spi;uses:="javax.security.auth.callback,javax.security.auth.login,javax.security.auth";version="0.0.0.1_007_JavaSE", \
javax.security.auth.x500;uses:="javax.security.auth";version="0.0.0.1_007_JavaSE", \
javax.security.auth;version="0.0.0.1_007_JavaSE", \
javax.security.cert;version="0.0.0.1_007_JavaSE", \
javax.security.sasl;uses:="javax.security.auth.callback";version="0.0.0.1_007_JavaSE", \
javax.sound.midi.spi;uses:="javax.sound.midi";version="0.0.0.1_007_JavaSE", \
javax.sound.midi;uses:="javax.sound.midi.spi";version="0.0.0.1_007_JavaSE", \
javax.sound.sampled.spi;uses:="javax.sound.sampled";version="0.0.0.1_007_JavaSE", \
javax.sound.sampled;uses:="javax.sound.sampled.spi";version="0.0.0.1_007_JavaSE", \
javax.sql.rowset.serial;uses:="javax.sql.rowset";version="0.0.0.1_007_JavaSE", \
javax.sql.rowset.spi;uses:="javax.sql,javax.naming,javax.sql.rowset";version="0.0.0.1_007_JavaSE", \
javax.sql.rowset;uses:="javax.sql,javax.sql.rowset.serial,javax.sql.rowset.spi";version="0.0.0.1_007_JavaSE", \
javax.sql;uses:="javax.transaction.xa";version="0.0.0.1_007_JavaSE", \
javax.swing.border;uses:="javax.swing";version="0.0.0.1_007_JavaSE", \
javax.swing.colorchooser;uses:="javax.swing,javax.swing.border,javax.swing.event,javax.swing.text";version="0.0.0.1_007_JavaSE", \
javax.swing.event;uses:="javax.swing,javax.swing.text,javax.swing.table,javax.swing.tree,javax.swing.undo";version="0.0.0.1_007_JavaSE", \
javax.swing.filechooser;uses:="javax.swing";version="0.0.0.1_007_JavaSE", \
javax.swing.plaf.basic;uses:="javax.swing.border,javax.swing,javax.swing.plaf,javax.swing.text,javax.swing.event,javax.swing.colorchooser,javax.accessibility,javax.swing.filechooser,javax.swing.text.html,javax.sound.sampled,javax.swing.table,javax.swing.plaf.synth,javax.swing.tree";version="0.0.0.1_007_JavaSE", \
javax.swing.plaf.metal;uses:="javax.swing.plaf,javax.swing,javax.swing.border,javax.swing.text,javax.swing.plaf.basic,javax.swing.filechooser,javax.swing.event,javax.swing.tree";version="0.0.0.1_007_JavaSE", \
javax.swing.plaf.multi;uses:="javax.accessibility,javax.swing,javax.swing.plaf,javax.swing.filechooser,javax.swing.text,javax.swing.tree";version="0.0.0.1_007_JavaSE", \
javax.swing.plaf.nimbus;uses:="javax.swing,javax.swing.plaf,javax.swing.border,javax.swing.plaf.synth";version="0.0.0.1_007_JavaSE", \
javax.swing.plaf.synth;uses:="javax.swing,javax.swing.plaf,javax.swing.text,javax.swing.border,javax.swing.plaf.basic,javax.swing.colorchooser,javax.swing.event,javax.xml.parsers,org.xml.sax,org.xml.sax.helpers,javax.swing.table,javax.swing.tree";version="0.0.0.1_007_JavaSE", \
javax.swing.plaf;uses:="javax.swing,javax.swing.border,javax.accessibility,javax.swing.filechooser,javax.swing.text,javax.swing.tree";version="0.0.0.1_007_JavaSE", \
javax.swing.table;uses:="javax.swing.event,javax.swing.plaf,javax.swing.border,javax.swing,javax.accessibility";version="0.0.0.1_007_JavaSE", \
javax.swing.text.html.parser;uses:="javax.swing.text,javax.swing.text.html";version="0.0.0.1_007_JavaSE", \
javax.swing.text.html;uses:="javax.swing.event,javax.swing.text,javax.accessibility,javax.swing,javax.swing.plaf,javax.swing.border,javax.swing.undo";version="0.0.0.1_007_JavaSE", \
javax.swing.text.rtf;uses:="javax.swing.text";version="0.0.0.1_007_JavaSE", \
javax.swing.text;uses:="javax.swing.event,javax.swing.tree,javax.swing.undo,javax.swing,javax.swing.plaf,javax.swing.plaf.basic,javax.print,javax.print.attribute,javax.accessibility,javax.swing.text.html";version="0.0.0.1_007_JavaSE", \
javax.swing.tree;uses:="javax.swing.event,javax.swing,javax.swing.border,javax.swing.plaf,javax.swing.plaf.basic";version="0.0.0.1_007_JavaSE", \
javax.swing.undo;uses:="javax.swing,javax.swing.event";version="0.0.0.1_007_JavaSE", \
javax.swing;uses:="javax.swing.event,javax.accessibility,javax.swing.text,javax.swing.plaf,javax.swing.border,javax.swing.tree,javax.swing.table,javax.swing.colorchooser,javax.swing.plaf.basic,javax.swing.text.html,javax.swing.filechooser,javax.print,javax.print.attribute,javax.swing.plaf.metal";version="0.0.0.1_007_JavaSE", \
javax.tools;uses:="javax.lang.model.element,javax.annotation.processing,javax.lang.model";version="0.0.0.1_007_JavaSE", \
javax.transaction.xa;version="0.0.0.1_007_JavaSE", \
javax.transaction;version="0.0.0.1_007_JavaSE", \
javax.xml.bind.annotation.adapters;uses:="javax.xml.bind";version="0.0.0.1_007_JavaSE", \
javax.xml.bind.annotation;uses:="javax.xml.transform,javax.xml.bind,javax.xml.parsers,javax.xml.transform.dom,org.w3c.dom";version="0.0.0.1_007_JavaSE", \
javax.xml.bind.attachment;uses:="javax.activation";version="0.0.0.1_007_JavaSE", \
javax.xml.bind.helpers;uses:="javax.xml.bind.annotation.adapters,javax.xml.transform.dom,org.w3c.dom,org.xml.sax,javax.xml.bind.attachment,javax.xml.stream,javax.xml.transform,javax.xml.transform.stream,javax.xml.validation,javax.xml.transform.sax,javax.xml.bind,javax.xml.parsers";version="0.0.0.1_007_JavaSE", \
javax.xml.bind.util;uses:="javax.xml.transform.sax,javax.xml.bind,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers";version="0.0.0.1_007_JavaSE", \
javax.xml.bind;uses:="javax.xml.validation,javax.xml.namespace,javax.xml.datatype,javax.xml.transform,javax.xml.bind.annotation,javax.xml.transform.stream,org.w3c.dom,javax.xml.bind.attachment,javax.xml.stream,javax.xml.bind.annotation.adapters,org.xml.sax";version="0.0.0.1_007_JavaSE", \
javax.xml.crypto.dom;uses:="javax.xml.crypto,org.w3c.dom";version="0.0.0.1_007_JavaSE", \
javax.xml.crypto.dsig.dom;uses:="javax.xml.crypto.dsig,javax.xml.crypto,org.w3c.dom,javax.xml.crypto.dom";version="0.0.0.1_007_JavaSE", \
javax.xml.crypto.dsig.keyinfo;uses:="javax.xml.crypto";version="0.0.0.1_007_JavaSE", \
javax.xml.crypto.dsig.spec;uses:="javax.xml.crypto";version="0.0.0.1_007_JavaSE", \
javax.xml.crypto.dsig;uses:="javax.xml.crypto,javax.xml.crypto.dsig.spec,javax.xml.crypto.dsig.keyinfo";version="0.0.0.1_007_JavaSE", \
javax.xml.crypto;uses:="javax.xml.crypto.dsig.keyinfo";version="0.0.0.1_007_JavaSE", \
javax.xml.datatype;uses:="javax.xml.namespace";version="0.0.0.1_007_JavaSE", \
javax.xml.namespace;version="0.0.0.1_007_JavaSE", \
javax.xml.parsers;uses:="javax.xml.validation,org.w3c.dom,org.xml.sax,org.xml.sax.helpers";version="0.0.0.1_007_JavaSE", \
javax.xml.soap;uses:="javax.activation,javax.xml.namespace,org.w3c.dom,javax.xml.transform.dom,javax.xml.transform";version="0.0.0.1_007_JavaSE", \
javax.xml.stream.events;uses:="javax.xml.namespace,javax.xml.stream";version="0.0.0.1_007_JavaSE", \
javax.xml.stream.util;uses:="javax.xml.stream,javax.xml.stream.events,javax.xml.namespace";version="0.0.0.1_007_JavaSE", \
javax.xml.stream;uses:="javax.xml.stream.events,javax.xml.namespace,javax.xml.stream.util,javax.xml.transform";version="0.0.0.1_007_JavaSE", \
javax.xml.transform.dom;uses:="javax.xml.transform,org.w3c.dom";version="0.0.0.1_007_JavaSE", \
javax.xml.transform.sax;uses:="org.xml.sax.ext,javax.xml.transform,org.xml.sax,javax.xml.transform.stream";version="0.0.0.1_007_JavaSE", \
javax.xml.transform.stax;uses:="javax.xml.stream,javax.xml.transform,javax.xml.stream.events";version="0.0.0.1_007_JavaSE", \
javax.xml.transform.stream;uses:="javax.xml.transform";version="0.0.0.1_007_JavaSE", \
javax.xml.transform;version="0.0.0.1_007_JavaSE", \
javax.xml.validation;uses:="org.w3c.dom.ls,javax.xml.transform,javax.xml.transform.stream,org.xml.sax,org.w3c.dom";version="0.0.0.1_007_JavaSE", \
javax.xml.ws.handler.soap;uses:="javax.xml.ws.handler,javax.xml.namespace,javax.xml.soap,javax.xml.bind";version="0.0.0.1_007_JavaSE", \
javax.xml.ws.handler;uses:="javax.xml.ws,javax.xml.namespace";version="0.0.0.1_007_JavaSE", \
javax.xml.ws.http;uses:="javax.xml.ws";version="0.0.0.1_007_JavaSE", \
javax.xml.ws.soap;uses:="javax.xml.ws.spi,javax.xml.ws,javax.xml.soap";version="0.0.0.1_007_JavaSE", \
javax.xml.ws.spi.http;version="0.0.0.1_007_JavaSE", \
javax.xml.ws.spi;uses:="javax.xml.ws,javax.xml.ws.wsaddressing,javax.xml.transform,org.w3c.dom,javax.xml.namespace,javax.xml.ws.handler,javax.xml.bind";version="0.0.0.1_007_JavaSE", \
javax.xml.ws.wsaddressing;uses:="javax.xml.bind.annotation,javax.xml.namespace,org.w3c.dom,javax.xml.transform,javax.xml.bind,javax.xml.ws,javax.xml.ws.spi";version="0.0.0.1_007_JavaSE", \
javax.xml.ws;uses:="javax.xml.ws.handler,javax.xml.ws.spi,javax.xml.ws.spi.http,javax.xml.transform,org.w3c.dom,javax.xml.bind.annotation,javax.xml.transform.stream,javax.xml.bind,javax.xml.namespace";version="0.0.0.1_007_JavaSE", \
javax.xml.xpath;uses:="org.xml.sax,javax.xml.namespace";version="0.0.0.1_007_JavaSE", \
javax.xml;version="0.0.0.1_007_JavaSE", \
org.ietf.jgss;version="0.0.0.1_007_JavaSE", \
org.omg.CORBA.DynAnyPackage;uses:="org.omg.CORBA";version="0.0.0.1_007_JavaSE", \
org.omg.CORBA.ORBPackage;uses:="org.omg.CORBA";version="0.0.0.1_007_JavaSE", \
org.omg.CORBA.TypeCodePackage;uses:="org.omg.CORBA";version="0.0.0.1_007_JavaSE", \
org.omg.CORBA.portable;uses:="org.omg.CORBA,org.omg.CORBA_2_3.portable";version="0.0.0.1_007_JavaSE", \
org.omg.CORBA;uses:="org.omg.CORBA.portable,org.omg.CORBA.DynAnyPackage,org.omg.CORBA.ORBPackage,org.omg.CORBA_2_3.portable,org.omg.CORBA.TypeCodePackage";version="0.0.0.1_007_JavaSE", \
org.omg.CORBA_2_3.portable;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.CORBA_2_3;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.CosNaming.NamingContextExtPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.CosNaming.NamingContextPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.CosNaming";version="0.0.0.1_007_JavaSE", \
org.omg.CosNaming;uses:="org.omg.CORBA.portable,org.omg.CORBA,org.omg.PortableServer,org.omg.CosNaming.NamingContextPackage,org.omg.CosNaming.NamingContextExtPackage";version="0.0.0.1_007_JavaSE", \
org.omg.Dynamic;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.DynamicAny.DynAnyFactoryPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.DynamicAny.DynAnyPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.DynamicAny;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.DynamicAny.DynAnyFactoryPackage,org.omg.DynamicAny.DynAnyPackage";version="0.0.0.1_007_JavaSE", \
org.omg.IOP.CodecFactoryPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.IOP.CodecPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.IOP;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.IOP.CodecFactoryPackage,org.omg.IOP.CodecPackage";version="0.0.0.1_007_JavaSE", \
org.omg.Messaging;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.PortableInterceptor.ORBInitInfoPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.PortableInterceptor;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.IOP,org.omg.PortableInterceptor.ORBInitInfoPackage,org.omg.CORBA_2_3.portable,org.omg.Dynamic";version="0.0.0.1_007_JavaSE", \
org.omg.PortableServer.CurrentPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.PortableServer.POAManagerPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.PortableServer.POAPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.PortableServer.ServantLocatorPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.PortableServer.portable;uses:="org.omg.CORBA,org.omg.PortableServer";version="0.0.0.1_007_JavaSE", \
org.omg.PortableServer;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.PortableServer.CurrentPackage,org.omg.PortableServer.POAManagerPackage,org.omg.PortableServer.POAPackage,org.omg.PortableServer.portable,org.omg.CORBA_2_3,org.omg.PortableServer.ServantLocatorPackage";version="0.0.0.1_007_JavaSE", \
org.omg.SendingContext;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", \
org.omg.stub.java.rmi;uses:="javax.rmi.CORBA";version="0.0.0.1_007_JavaSE", \
org.w3c.dom.bootstrap;uses:="org.w3c.dom";version="0.0.0.1_007_JavaSE", \
org.w3c.dom.events;uses:="org.w3c.dom,org.w3c.dom.views";version="0.0.0.1_007_JavaSE", \
org.w3c.dom.ls;uses:="org.w3c.dom,org.w3c.dom.events,org.w3c.dom.traversal";version="0.0.0.1_007_JavaSE", \
org.w3c.dom;version="0.0.0.1_007_JavaSE", \
org.xml.sax.ext;uses:="org.xml.sax,org.xml.sax.helpers";version="0.0.0.1_007_JavaSE", \
org.xml.sax.helpers;uses:="org.xml.sax";version="0.0.0.1_007_JavaSE", \
org.xml.sax;version="0.0.0.1_007_JavaSE"</code></pre>
</div>
</div>
<div class="paragraph">
<p>Remove the definition for the <code>javax.transaction</code> packages, and remove the <code>uses:=</code> clause for the <code>javax.sql</code> packages (but leaving the <code>version</code> clause). Concatenate all the lines together.
You&#8217;ll wind up with something like this in your <code>conf/config.properties</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-properties" data-lang="properties">org.osgi.framework.system.packages=org.osgi.framework;version=1.7.0, org.osgi.framework.hooks.bundle;version=1.1.0, org.osgi.framework.hooks.resolver;version=1.0.0, org.osgi.framework.hooks.service;version=1.1.0, org.osgi.framework.hooks.weaving;version=1.0.0, org.osgi.framework.launch;version=1.1.0, org.osgi.framework.namespace;version=1.0.0, org.osgi.framework.startlevel;version=1.0.0, org.osgi.framework.wiring;version=1.1.0, org.osgi.resource;version=1.0.0, org.osgi.service.packageadmin; version=1.2.0, org.osgi.service.startlevel; version=1.1.0, org.osgi.service.url;version=1.0.0, org.osgi.util.tracker;version=1.5.1 javax.accessibility;uses:="javax.swing.text";version="0.0.0.1_007_JavaSE", javax.activation;version="0.0.0.1_007_JavaSE", javax.activity;version="0.0.0.1_007_JavaSE", javax.annotation.processing;uses:="javax.tools,javax.lang.model,javax.lang.model.element,javax.lang.model.util";version="0.0.0.1_007_JavaSE", javax.annotation;version="0.0.0.1_007_JavaSE", javax.crypto.interfaces;uses:="javax.crypto.spec,javax.crypto";version="0.0.0.1_007_JavaSE", javax.crypto.spec;uses:="javax.crypto";version="0.0.0.1_007_JavaSE", javax.crypto;uses:="javax.crypto.spec";version="0.0.0.1_007_JavaSE", javax.imageio.event;uses:="javax.imageio";version="0.0.0.1_007_JavaSE", javax.imageio.metadata;uses:="org.w3c.dom,javax.imageio";version="0.0.0.1_007_JavaSE", javax.imageio.plugins.bmp;uses:="javax.imageio";version="0.0.0.1_007_JavaSE", javax.imageio.plugins.jpeg;uses:="javax.imageio";version="0.0.0.1_007_JavaSE", javax.imageio.spi;uses:="javax.imageio.stream,javax.imageio,javax.imageio.metadata";version="0.0.0.1_007_JavaSE", javax.imageio.stream;uses:="javax.imageio";version="0.0.0.1_007_JavaSE", javax.imageio;uses:="javax.imageio.metadata,javax.imageio.stream,javax.imageio.spi,javax.imageio.event";version="0.0.0.1_007_JavaSE", javax.jws.soap;version="0.0.0.1_007_JavaSE", javax.jws;version="0.0.0.1_007_JavaSE", javax.lang.model.element;uses:="javax.lang.model.type,javax.lang.model";version="0.0.0.1_007_JavaSE", javax.lang.model.type;uses:="javax.lang.model.element,javax.lang.model";version="0.0.0.1_007_JavaSE", javax.lang.model.util;uses:="javax.lang.model,javax.lang.model.element,javax.annotation.processing,javax.lang.model.type";version="0.0.0.1_007_JavaSE", javax.lang.model;version="0.0.0.1_007_JavaSE", javax.management.loading;uses:="javax.management";version="0.0.0.1_007_JavaSE", javax.management.modelmbean;uses:="javax.management,javax.management.loading";version="0.0.0.1_007_JavaSE", javax.management.monitor;uses:="javax.management";version="0.0.0.1_007_JavaSE", javax.management.openmbean;uses:="javax.management";version="0.0.0.1_007_JavaSE", javax.management.relation;uses:="javax.management";version="0.0.0.1_007_JavaSE", javax.management.remote.rmi;uses:="javax.management.remote,javax.security.auth,javax.management,javax.management.loading,javax.naming,javax.rmi.ssl,org.omg.CORBA,org.omg.CORBA_2_3.portable,org.omg.CORBA.portable,javax.rmi.CORBA,javax.rmi";version="0.0.0.1_007_JavaSE", javax.management.remote;uses:="javax.security.auth,javax.management";version="0.0.0.1_007_JavaSE", javax.management.timer;uses:="javax.management";version="0.0.0.1_007_JavaSE", javax.management;uses:="javax.management.loading,javax.management.openmbean";version="0.0.0.1_007_JavaSE", javax.naming.directory;uses:="javax.naming";version="0.0.0.1_007_JavaSE", javax.naming.event;uses:="javax.naming,javax.naming.directory";version="0.0.0.1_007_JavaSE", javax.naming.ldap;uses:="javax.naming,javax.naming.directory,javax.net.ssl,javax.naming.event";version="0.0.0.1_007_JavaSE", javax.naming.spi;uses:="javax.naming,javax.naming.directory";version="0.0.0.1_007_JavaSE", javax.naming;uses:="javax.naming.spi";version="0.0.0.1_007_JavaSE", javax.net.ssl;uses:="javax.security.cert,javax.security.auth.x500,javax.net";version="0.0.0.1_007_JavaSE", javax.net;version="0.0.0.1_007_JavaSE", javax.print.attribute.standard;uses:="javax.print.attribute";version="0.0.0.1_007_JavaSE", javax.print.attribute;version="0.0.0.1_007_JavaSE", javax.print.event;uses:="javax.print,javax.print.attribute";version="0.0.0.1_007_JavaSE", javax.print;uses:="javax.print.attribute,javax.print.event,javax.print.attribute.standard";version="0.0.0.1_007_JavaSE", javax.rmi.CORBA;uses:="org.omg.CORBA,org.omg.CORBA_2_3.portable,org.omg.CORBA.portable,org.omg.SendingContext";version="0.0.0.1_007_JavaSE", javax.rmi.ssl;uses:="javax.net,javax.net.ssl";version="0.0.0.1_007_JavaSE", javax.rmi;uses:="org.omg.CORBA,javax.rmi.CORBA";version="0.0.0.1_007_JavaSE", javax.script;version="0.0.0.1_007_JavaSE", javax.security.auth.callback;version="0.0.0.1_007_JavaSE", javax.security.auth.kerberos;uses:="javax.security.auth,javax.crypto";version="0.0.0.1_007_JavaSE", javax.security.auth.login;uses:="javax.security.auth,javax.security.auth.callback";version="0.0.0.1_007_JavaSE", javax.security.auth.spi;uses:="javax.security.auth.callback,javax.security.auth.login,javax.security.auth";version="0.0.0.1_007_JavaSE", javax.security.auth.x500;uses:="javax.security.auth";version="0.0.0.1_007_JavaSE", javax.security.auth;version="0.0.0.1_007_JavaSE", javax.security.cert;version="0.0.0.1_007_JavaSE", javax.security.sasl;uses:="javax.security.auth.callback";version="0.0.0.1_007_JavaSE", javax.sound.midi.spi;uses:="javax.sound.midi";version="0.0.0.1_007_JavaSE", javax.sound.midi;uses:="javax.sound.midi.spi";version="0.0.0.1_007_JavaSE", javax.sound.sampled.spi;uses:="javax.sound.sampled";version="0.0.0.1_007_JavaSE", javax.sound.sampled;uses:="javax.sound.sampled.spi";version="0.0.0.1_007_JavaSE", javax.sql.rowset.serial;version="0.0.0.1_007_JavaSE", javax.sql.rowset.spi;version="0.0.0.1_007_JavaSE", javax.sql.rowset;version="0.0.0.1_007_JavaSE", javax.sql;version="0.0.0.1_007_JavaSE", javax.swing.border;uses:="javax.swing";version="0.0.0.1_007_JavaSE", javax.swing.colorchooser;uses:="javax.swing,javax.swing.border,javax.swing.event,javax.swing.text";version="0.0.0.1_007_JavaSE", javax.swing.event;uses:="javax.swing,javax.swing.text,javax.swing.table,javax.swing.tree,javax.swing.undo";version="0.0.0.1_007_JavaSE", javax.swing.filechooser;uses:="javax.swing";version="0.0.0.1_007_JavaSE", javax.swing.plaf.basic;uses:="javax.swing.border,javax.swing,javax.swing.plaf,javax.swing.text,javax.swing.event,javax.swing.colorchooser,javax.accessibility,javax.swing.filechooser,javax.swing.text.html,javax.sound.sampled,javax.swing.table,javax.swing.plaf.synth,javax.swing.tree";version="0.0.0.1_007_JavaSE", javax.swing.plaf.metal;uses:="javax.swing.plaf,javax.swing,javax.swing.border,javax.swing.text,javax.swing.plaf.basic,javax.swing.filechooser,javax.swing.event,javax.swing.tree";version="0.0.0.1_007_JavaSE", javax.swing.plaf.multi;uses:="javax.accessibility,javax.swing,javax.swing.plaf,javax.swing.filechooser,javax.swing.text,javax.swing.tree";version="0.0.0.1_007_JavaSE", javax.swing.plaf.nimbus;uses:="javax.swing,javax.swing.plaf,javax.swing.border,javax.swing.plaf.synth";version="0.0.0.1_007_JavaSE", javax.swing.plaf.synth;uses:="javax.swing,javax.swing.plaf,javax.swing.text,javax.swing.border,javax.swing.plaf.basic,javax.swing.colorchooser,javax.swing.event,javax.xml.parsers,org.xml.sax,org.xml.sax.helpers,javax.swing.table,javax.swing.tree";version="0.0.0.1_007_JavaSE", javax.swing.plaf;uses:="javax.swing,javax.swing.border,javax.accessibility,javax.swing.filechooser,javax.swing.text,javax.swing.tree";version="0.0.0.1_007_JavaSE", javax.swing.table;uses:="javax.swing.event,javax.swing.plaf,javax.swing.border,javax.swing,javax.accessibility";version="0.0.0.1_007_JavaSE", javax.swing.text.html.parser;uses:="javax.swing.text,javax.swing.text.html";version="0.0.0.1_007_JavaSE", javax.swing.text.html;uses:="javax.swing.event,javax.swing.text,javax.accessibility,javax.swing,javax.swing.plaf,javax.swing.border,javax.swing.undo";version="0.0.0.1_007_JavaSE", javax.swing.text.rtf;uses:="javax.swing.text";version="0.0.0.1_007_JavaSE", javax.swing.text;uses:="javax.swing.event,javax.swing.tree,javax.swing.undo,javax.swing,javax.swing.plaf,javax.swing.plaf.basic,javax.print,javax.print.attribute,javax.accessibility,javax.swing.text.html";version="0.0.0.1_007_JavaSE", javax.swing.tree;uses:="javax.swing.event,javax.swing,javax.swing.border,javax.swing.plaf,javax.swing.plaf.basic";version="0.0.0.1_007_JavaSE", javax.swing.undo;uses:="javax.swing,javax.swing.event";version="0.0.0.1_007_JavaSE", javax.swing;uses:="javax.swing.event,javax.accessibility,javax.swing.text,javax.swing.plaf,javax.swing.border,javax.swing.tree,javax.swing.table,javax.swing.colorchooser,javax.swing.plaf.basic,javax.swing.text.html,javax.swing.filechooser,javax.print,javax.print.attribute,javax.swing.plaf.metal";version="0.0.0.1_007_JavaSE", javax.tools;uses:="javax.lang.model.element,javax.annotation.processing,javax.lang.model";version="0.0.0.1_007_JavaSE", javax.xml.bind.annotation.adapters;uses:="javax.xml.bind";version="0.0.0.1_007_JavaSE", javax.xml.bind.annotation;uses:="javax.xml.transform,javax.xml.bind,javax.xml.parsers,javax.xml.transform.dom,org.w3c.dom";version="0.0.0.1_007_JavaSE", javax.xml.bind.attachment;uses:="javax.activation";version="0.0.0.1_007_JavaSE", javax.xml.bind.helpers;uses:="javax.xml.bind.annotation.adapters,javax.xml.transform.dom,org.w3c.dom,org.xml.sax,javax.xml.bind.attachment,javax.xml.stream,javax.xml.transform,javax.xml.transform.stream,javax.xml.validation,javax.xml.transform.sax,javax.xml.bind,javax.xml.parsers";version="0.0.0.1_007_JavaSE", javax.xml.bind.util;uses:="javax.xml.transform.sax,javax.xml.bind,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers";version="0.0.0.1_007_JavaSE", javax.xml.bind;uses:="javax.xml.validation,javax.xml.namespace,javax.xml.datatype,javax.xml.transform,javax.xml.bind.annotation,javax.xml.transform.stream,org.w3c.dom,javax.xml.bind.attachment,javax.xml.stream,javax.xml.bind.annotation.adapters,org.xml.sax";version="0.0.0.1_007_JavaSE", javax.xml.crypto.dom;uses:="javax.xml.crypto,org.w3c.dom";version="0.0.0.1_007_JavaSE", javax.xml.crypto.dsig.dom;uses:="javax.xml.crypto.dsig,javax.xml.crypto,org.w3c.dom,javax.xml.crypto.dom";version="0.0.0.1_007_JavaSE", javax.xml.crypto.dsig.keyinfo;uses:="javax.xml.crypto";version="0.0.0.1_007_JavaSE", javax.xml.crypto.dsig.spec;uses:="javax.xml.crypto";version="0.0.0.1_007_JavaSE", javax.xml.crypto.dsig;uses:="javax.xml.crypto,javax.xml.crypto.dsig.spec,javax.xml.crypto.dsig.keyinfo";version="0.0.0.1_007_JavaSE", javax.xml.crypto;uses:="javax.xml.crypto.dsig.keyinfo";version="0.0.0.1_007_JavaSE", javax.xml.datatype;uses:="javax.xml.namespace";version="0.0.0.1_007_JavaSE", javax.xml.namespace;version="0.0.0.1_007_JavaSE", javax.xml.parsers;uses:="javax.xml.validation,org.w3c.dom,org.xml.sax,org.xml.sax.helpers";version="0.0.0.1_007_JavaSE", javax.xml.soap;uses:="javax.activation,javax.xml.namespace,org.w3c.dom,javax.xml.transform.dom,javax.xml.transform";version="0.0.0.1_007_JavaSE", javax.xml.stream.events;uses:="javax.xml.namespace,javax.xml.stream";version="0.0.0.1_007_JavaSE", javax.xml.stream.util;uses:="javax.xml.stream,javax.xml.stream.events,javax.xml.namespace";version="0.0.0.1_007_JavaSE", javax.xml.stream;uses:="javax.xml.stream.events,javax.xml.namespace,javax.xml.stream.util,javax.xml.transform";version="0.0.0.1_007_JavaSE", javax.xml.transform.dom;uses:="javax.xml.transform,org.w3c.dom";version="0.0.0.1_007_JavaSE", javax.xml.transform.sax;uses:="org.xml.sax.ext,javax.xml.transform,org.xml.sax,javax.xml.transform.stream";version="0.0.0.1_007_JavaSE", javax.xml.transform.stax;uses:="javax.xml.stream,javax.xml.transform,javax.xml.stream.events";version="0.0.0.1_007_JavaSE", javax.xml.transform.stream;uses:="javax.xml.transform";version="0.0.0.1_007_JavaSE", javax.xml.transform;version="0.0.0.1_007_JavaSE", javax.xml.validation;uses:="org.w3c.dom.ls,javax.xml.transform,javax.xml.transform.stream,org.xml.sax,org.w3c.dom";version="0.0.0.1_007_JavaSE", javax.xml.ws.handler.soap;uses:="javax.xml.ws.handler,javax.xml.namespace,javax.xml.soap,javax.xml.bind";version="0.0.0.1_007_JavaSE", javax.xml.ws.handler;uses:="javax.xml.ws,javax.xml.namespace";version="0.0.0.1_007_JavaSE", javax.xml.ws.http;uses:="javax.xml.ws";version="0.0.0.1_007_JavaSE", javax.xml.ws.soap;uses:="javax.xml.ws.spi,javax.xml.ws,javax.xml.soap";version="0.0.0.1_007_JavaSE", javax.xml.ws.spi.http;version="0.0.0.1_007_JavaSE", javax.xml.ws.spi;uses:="javax.xml.ws,javax.xml.ws.wsaddressing,javax.xml.transform,org.w3c.dom,javax.xml.namespace,javax.xml.ws.handler,javax.xml.bind";version="0.0.0.1_007_JavaSE", javax.xml.ws.wsaddressing;uses:="javax.xml.bind.annotation,javax.xml.namespace,org.w3c.dom,javax.xml.transform,javax.xml.bind,javax.xml.ws,javax.xml.ws.spi";version="0.0.0.1_007_JavaSE", javax.xml.ws;uses:="javax.xml.ws.handler,javax.xml.ws.spi,javax.xml.ws.spi.http,javax.xml.transform,org.w3c.dom,javax.xml.bind.annotation,javax.xml.transform.stream,javax.xml.bind,javax.xml.namespace";version="0.0.0.1_007_JavaSE", javax.xml.xpath;uses:="org.xml.sax,javax.xml.namespace";version="0.0.0.1_007_JavaSE", javax.xml;version="0.0.0.1_007_JavaSE", org.ietf.jgss;version="0.0.0.1_007_JavaSE", org.omg.CORBA.DynAnyPackage;uses:="org.omg.CORBA";version="0.0.0.1_007_JavaSE", org.omg.CORBA.ORBPackage;uses:="org.omg.CORBA";version="0.0.0.1_007_JavaSE", org.omg.CORBA.TypeCodePackage;uses:="org.omg.CORBA";version="0.0.0.1_007_JavaSE", org.omg.CORBA.portable;uses:="org.omg.CORBA,org.omg.CORBA_2_3.portable";version="0.0.0.1_007_JavaSE", org.omg.CORBA;uses:="org.omg.CORBA.portable,org.omg.CORBA.DynAnyPackage,org.omg.CORBA.ORBPackage,org.omg.CORBA_2_3.portable,org.omg.CORBA.TypeCodePackage";version="0.0.0.1_007_JavaSE", org.omg.CORBA_2_3.portable;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.CORBA_2_3;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.CosNaming.NamingContextExtPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.CosNaming.NamingContextPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.CosNaming";version="0.0.0.1_007_JavaSE", org.omg.CosNaming;uses:="org.omg.CORBA.portable,org.omg.CORBA,org.omg.PortableServer,org.omg.CosNaming.NamingContextPackage,org.omg.CosNaming.NamingContextExtPackage";version="0.0.0.1_007_JavaSE", org.omg.Dynamic;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.DynamicAny.DynAnyFactoryPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.DynamicAny.DynAnyPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.DynamicAny;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.DynamicAny.DynAnyFactoryPackage,org.omg.DynamicAny.DynAnyPackage";version="0.0.0.1_007_JavaSE", org.omg.IOP.CodecFactoryPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.IOP.CodecPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.IOP;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.IOP.CodecFactoryPackage,org.omg.IOP.CodecPackage";version="0.0.0.1_007_JavaSE", org.omg.Messaging;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.PortableInterceptor.ORBInitInfoPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.PortableInterceptor;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.IOP,org.omg.PortableInterceptor.ORBInitInfoPackage,org.omg.CORBA_2_3.portable,org.omg.Dynamic";version="0.0.0.1_007_JavaSE", org.omg.PortableServer.CurrentPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.PortableServer.POAManagerPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.PortableServer.POAPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.PortableServer.ServantLocatorPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.PortableServer.portable;uses:="org.omg.CORBA,org.omg.PortableServer";version="0.0.0.1_007_JavaSE", org.omg.PortableServer;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.PortableServer.CurrentPackage,org.omg.PortableServer.POAManagerPackage,org.omg.PortableServer.POAPackage,org.omg.PortableServer.portable,org.omg.CORBA_2_3,org.omg.PortableServer.ServantLocatorPackage";version="0.0.0.1_007_JavaSE", org.omg.SendingContext;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_007_JavaSE", org.omg.stub.java.rmi;uses:="javax.rmi.CORBA";version="0.0.0.1_007_JavaSE", org.w3c.dom.bootstrap;uses:="org.w3c.dom";version="0.0.0.1_007_JavaSE", org.w3c.dom.events;uses:="org.w3c.dom,org.w3c.dom.views";version="0.0.0.1_007_JavaSE", org.w3c.dom.ls;uses:="org.w3c.dom,org.w3c.dom.events,org.w3c.dom.traversal";version="0.0.0.1_007_JavaSE", org.w3c.dom;version="0.0.0.1_007_JavaSE", org.xml.sax.ext;uses:="org.xml.sax,org.xml.sax.helpers";version="0.0.0.1_007_JavaSE", org.xml.sax.helpers;uses:="org.xml.sax";version="0.0.0.1_007_JavaSE", org.xml.sax;version="0.0.0.1_007_JavaSE"</code></pre>
</div>
</div>
<div class="paragraph">
<p>You should now be able to start Felix, and deploy all the jars listed on this page.
You should see output similar to this on the console, using the <code>felix:lb</code> command:</p>
</div>
<div class="literalblock">
<div class="content">
<pre> ID|State |Level|Name
0|Active | 0|System Bundle (4.4.1)
1|Active | 1|ASM (7.0)
2|Active | 1|ASM commons classes (7.0)
3|Active | 1|ASM Tree class visitor (7.0)
4|Active | 1|geronimo-jta_1.1_spec (1.1.1)
5|Active | 1|javax.annotation API (1.2.0)
6|Active | 1|javax.mail bundle from Glassfish (1.4.1.v201005082020)
7|Active | 1|Java Server Pages Standard Tag Library API Bundle (1.2.0.v201105211821)
8|Active | 1|JavaServer Pages (TM) TagLib Implementation (1.2.2)
9|Active | 1|Jetty :: Servlet Annotations ({VERSION})
10|Active | 1|Jetty :: Deployers ({VERSION})
11|Active | 1|Jetty :: Http Utility ({VERSION})
12|Active | 1|Jetty :: IO Utility ({VERSION})
13|Active | 1|Jetty :: JNDI Naming ({VERSION})
14|Active | 1|Jetty :: OSGi :: Boot ({VERSION})
15|Resolved | 1|Jetty-OSGi-Jasper Integration ({VERSION})
16|Active | 1|Jetty Servlet API and Schemas for OSGi (3.1.0)
17|Active | 1|Jetty :: Plus ({VERSION})
18|Active | 1|Jetty :: Security ({VERSION})
19|Active | 1|Jetty :: Server Core ({VERSION})
20|Active | 1|Jetty :: Servlet Handling ({VERSION})
21|Active | 1|Jetty :: Utility Servlets and Filters ({VERSION})
22|Active | 1|Jetty :: Utilities ({VERSION})
23|Active | 1|Jetty :: Webapp Application Support ({VERSION})
24|Active | 1|Jetty :: XML utilities ({VERSION})
25|Active | 1|Apache Aries SPI Fly Dynamic Weaving Bundle (1.2)
27|Active | 1|Apache Felix Bundle Repository (2.0.2)
28|Active | 1|Apache Felix Configuration Admin Service (1.8.0)
29|Active | 1|Apache Felix EventAdmin (1.3.2)
30|Active | 1|Apache Felix Gogo Command (0.14.0)
31|Active | 1|Apache Felix Gogo Runtime (0.12.1)
32|Active | 1|Apache Felix Gogo Shell (0.10.0)
33|Active | 1|Apache Felix Log Service (1.0.1)
34|Active | 1|Jetty :: Apache JSP ({VERSION})
35|Active | 1|Eclipse Compiler for Java(TM) (3.8.2.v20130121-145325)
36|Active | 1|Mortbay EL API and Implementation (8.5.33.1)
37|Active | 1|Mortbay Jasper (8.5.33.1)</pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_eclipse"><a class="anchor" href="#_eclipse"></a><a class="link" href="#_eclipse">Eclipse</a></h5>
<div class="paragraph">
<p>The Jetty OSGi integration has been successfully tested against <a href="https://www.eclipse.org/equinox/">Equinox</a> Mars RC1.</p>
</div>
<div class="paragraph">
<p>Ensure that these services are present:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://www.eclipse.org/equinox/bundles/">Configuration Admin</a></p>
</li>
<li>
<p><a href="https://www.eclipse.org/equinox/bundles/">Event Admin</a></p>
</li>
</ul>
</div>
<div class="sect5">
<h6 id="_eclipse-update-site"><a class="anchor" href="#_eclipse-update-site"></a><a class="link" href="#_eclipse-update-site">Eclipse Update Site</a></h6>
<div class="paragraph">
<p>There is a list of Eclipse P2 sites for the jetty releases maintained at <a href="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/" class="bare">http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/</a></p>
</div>
<div class="paragraph">
<p>Each P2 repo has one big feature group that defines most of the Jetty jars.
<strong>Beware: No 3rd party dependency jars are included, so you will need to have installed the dependencies listed previously in this document.</strong></p>
</div>
<div class="paragraph">
<p>In addition, as the feature group includes websocket, you will need to download and have installed the <code>javax.websocket-api</code> jar:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 13. Extra Jars Required for Websocket</caption>
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Jar</th>
<th class="tableblock halign-left valign-top">Bundle Symbolic Name</th>
<th class="tableblock halign-left valign-top">Location</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">javax.websocket-api</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">javax.websocket-api</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://repo1.maven.org/maven2/javax/websocket/websocket-api">Maven
central</a></p></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="framework-metro"><a class="anchor" href="#framework-metro"></a><a class="link" href="#framework-metro">Metro</a></h3>
<div class="paragraph">
<p><a href="https://metro.java.net/">Metro</a> is the reference implementation for <a href="http://jcp.org/en/jsr/detail?id=109">web services</a>.
You can easily use Metro with Jetty to integrate web services with your web applications.</p>
</div>
<div class="sect3">
<h4 id="metro-setup-distro"><a class="anchor" href="#metro-setup-distro"></a><a class="link" href="#metro-setup-distro">Metro Setup</a></h4>
<div class="olist arabic">
<ol class="arabic">
<li>
<p><a href="https://metro.java.net/latest/download.html">Download</a> the Metro distribution and unpack it to your disk.
We&#8217;ll refer to the unpacked location as <code>$metro.home</code>.</p>
</li>
<li>
<p>Create the directory <code>$jetty.home/lib/metro</code></p>
</li>
<li>
<p>Copy the jars from $metro.home/lib to <code>$jetty.home/lib/metro</code></p>
</li>
<li>
<p>Edit the start.ini file and add an OPTION line for metro near the end.</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">OPTIONS=metro</code></pre>
</div>
</div>
</li>
</ol>
</div>
<div class="paragraph">
<p>That&#8217;s all the setup you need to do to integrate Jetty and Metro.</p>
</div>
<div class="paragraph">
<p>Now read the <a href="https://metro.java.net/discover/">Metro documentation</a> on <a href="https://metro.java.net/getting-started/">how to create web services</a>.
The Metro distribution you downloaded should also contain several example web applications in the $metro.home/samples directory that you can build and deploy to Jetty (simply by copying the war file produced by the build).</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of the log output from Jetty when one of the sample Metro wars (from <code>$metro.home/samples/async</code>) is deployed to Jetty:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[2093] java -jar start.jar
2013-07-26 15:47:53.480:INFO:oejs.Server:main: jetty-9.0.4.v20130625
2013-07-26 15:47:53.549:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/home/user/jetty-distribution-10.0.0-SNAPSHOT/webapps/] at interval 1
Jul 26, 2013 3:47:53 PM com.sun.xml.ws.transport.http.servlet.WSServletContextListener contextInitialized
INFO: WSSERVLET12: JAX-WS context listener initializing
Jul 26, 2013 3:47:56 PM com.sun.xml.ws.server.MonitorBase createRoot
INFO: Metro monitoring rootname successfully set to: com.sun.metro:pp=/,type=WSEndpoint,name=/metro-async-AddNumbersService-AddNumbersImplPort
Jul 26, 2013 3:47:56 PM com.sun.xml.ws.transport.http.servlet.WSServletDelegate &lt;init&gt;
INFO: WSSERVLET14: JAX-WS servlet initializing
2013-07-26 15:47:56.800:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@75707c77{/metro-async,file:/tmp/jetty-0.0.0.0-8080-metro-async.war-_metro-async-any-/webapp/,AVAILABLE}{/metro-async.war}
2013-07-26 15:47:56.853:INFO:oejs.ServerConnector:main: Started ServerConnector@47dce809{HTTP/1.1}{0.0.0.0:8080}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="introduction"><a class="anchor" href="#introduction"></a><a class="link" href="#introduction">Introducing Jetty</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="what-is-jetty"><a class="anchor" href="#what-is-jetty"></a><a class="link" href="#what-is-jetty">What is Jetty?</a></h3>
<div class="paragraph">
<p>Eclipse Jetty is an open-source project providing an HTTP server, HTTP client, and servlet container.</p>
</div>
<div class="paragraph">
<p>The Jetty documentation is broken up in to four parts:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The <a href="{GSTARTEDGUIDE}">Getting Started Guide</a> emphasizes beginning to use Jetty.
It provides information about what Jetty is and where you can download it, and where to find Jetty in repositories like Central Maven.
It also provides a Quick Start guide on how to get Jetty up and running as well as an overview of how and what to configure in Jetty.</p>
</li>
<li>
<p>The <a href="../operations-guide/index.html">Operations Guide</a> details configuring Jetty as a distributed package at a more granular level.
From server startup to session management, logging, HTTP/2 support and Jetty optimization, these chapters will help administrators get the most out of their distributed Jetty server instances.
This section also covers configuring many of the most common servlet container features such as JNDI and JMX.</p>
</li>
<li>
<p>Aimed at advanced users of Jetty, the <a href="../programming-guide/index.html">Programming Guide</a> focuses on Jetty development.
A large portion of this section is focused on using Jetty as an embedded server in existing applications.
It contains several examples and how-to guides for making the most out of the Jetty framework.
This section also includes a guide on using the Jetty Maven plugin as well as information on debugging Jetty.</p>
</li>
<li>
<p>The <a href="#../contribution-guide/index.html">Contribution Guide</a> is aimed at those who want to contribute to the Jetty open source project.
It includes instructions on interacting with the community, how to raise bugs, and how to report security issues.
In addition, it also details source control and build information for the project.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="what-jetty-version"><a class="anchor" href="#what-jetty-version"></a><a class="link" href="#what-jetty-version">What Version Do I Use?</a></h3>
<div class="paragraph">
<p>Jetty 10 and 11 are the most recent versions of Jetty and has a great many improvements over previous versions.
This documentation which focuses on Jetty 10.
While many people continue to use older versions of Jetty, we generally recommend using Jetty 10 or 11 (more on the differences later) as they represent the version of Jetty that we will actively maintain and improve over the next few years.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
It is important that only stable releases are used in production environments.
Versions that have been deprecated or are released as Milestones (M) or Release Candidates (RC) are not suitable for production as they may contain security flaws or incomplete/non-functioning feature sets.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 14. Jetty Versions</caption>
<colgroup>
<col style="width: 12%;">
<col style="width: 9%;">
<col style="width: 15%;">
<col style="width: 6%;">
<col style="width: 21%;">
<col style="width: 10%;">
<col style="width: 6%;">
<col style="width: 21%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Version</th>
<th class="tableblock halign-left valign-top">Year</th>
<th class="tableblock halign-left valign-top">Home</th>
<th class="tableblock halign-left valign-top">Min JVM</th>
<th class="tableblock halign-left valign-top">Protocols</th>
<th class="tableblock halign-left valign-top">Servlet</th>
<th class="tableblock halign-left valign-top">JSP</th>
<th class="tableblock halign-left valign-top">Status</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">11</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2020-</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Eclipse</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">11 <sup>(2)</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.1 (RFC 7230), HTTP/2 (RFC 7540), WebSocket (RFC 6455, JSR 356), FastCGI, <strong>JakartaEE Namespace</strong><sup>(1)</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4.0.2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>UNSTABLE / Beta</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2019-</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Eclipse</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">11 <sup>(2)</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.1 (RFC 7230), HTTP/2 (RFC 7540), WebSocket (RFC 6455, JSR 356), FastCGI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4.0.2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>UNSTABLE / Beta</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.4</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2016-</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Eclipse</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.1 (RFC 7230), HTTP/2 (RFC 7540), WebSocket (RFC 6455, JSR 356), FastCGI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Stable</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2015-</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Eclipse</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.8 <sup>(3)</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.1 (RFC 7230), HTTP/2 (RFC 7540), WebSocket (RFC 6455, JSR 356), FastCGI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Deprecated</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2014-2018</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Eclipse</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.7 <sup>(3)</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.1 RFC2616, javax.websocket, SPDY v3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Deprecated / <strong>End of Life January 2018</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2013-2014</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Eclipse</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.7 <sup>(3)</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.1 RFC2616</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Deprecated / <strong>End of Life May 2014</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2013-2013</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Eclipse</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.7 <sup>(3)</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.1 RFC2616</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.1-beta</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Deprecated / <strong>End of Life November 2013</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2009-2014</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Eclipse/Codehaus</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.6 <sup>(3)</sup></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.1 RFC2616, WebSocket RFC 6455, SPDY v3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Deprecated / <strong>End of Life November 2014</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">7</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2008-2014</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Eclipse/Codehaus</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.5</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.1 RFC2616, WebSocket RFC 6455, SPDY v3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.5</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Deprecated / <strong>End of Life November 2014</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">6</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2006-2010</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Codehaus</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.4-1.5</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.1 RFC2616</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.5</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Deprecated / <strong>End of Life November 2010</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">5</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2003-2009</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Sourceforge</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.2-1.5</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.1 RFC2616</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.4</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Antique</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2001-2006</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Sourceforge</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.2, J2ME</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.1 RFC2616</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Ancient</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1999-2002</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Sourceforge</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.1 RFC2068</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Fossilized</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1998-2000</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Mortbay</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.0 RFC1945</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">2.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Legendary</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1995-1998</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Mortbay</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">HTTP/1.0 RFC1945</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Mythical</p></td>
</tr>
</tbody>
</table>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Due to Oracle&#8217;s ownership of the "Java" trademark, usage of the javax.* namespace has been restricted and the jakarta.* namespace <a href="https://www.eclipse.org/lists/jakartaee-platform-dev/msg00029.html">was adopted</a> by the Eclipse Foundation.</p>
</li>
<li>
<p>JPMS module support is optional</p>
</li>
<li>
<p>JDK9 and newer is not supported if using MultiRelease JAR Files, or Bytecode / Annotation scanning.</p>
</li>
</ol>
</div>
</div>
<div class="sect2">
<h3 id="jetty-javaee"><a class="anchor" href="#jetty-javaee"></a><a class="link" href="#jetty-javaee">Jetty and Java EE Web Profile</a></h3>
<div class="paragraph">
<p>Jetty implements aspects of the Java EE specification, primarily the Servlet Specification.
Recent releases of the Java EE platform have introduced a Web Profile, recognizing that many developers need only a subset of the many technologies under the Java EE umbrella.</p>
</div>
<div class="paragraph">
<p>While Jetty itself does not ship all of the Web Profile technologies, Jetty architecture is such that you can plug in third party implementations to produce a container customized to your exact needs.</p>
</div>
<div class="sect3">
<h4 id="jetty-javaee-7"><a class="anchor" href="#jetty-javaee-7"></a><a class="link" href="#jetty-javaee-7">Java EE 7 Web Profile</a></h4>
<div class="paragraph">
<p>In the forthcoming Java EE-7 specification, the Web Profile reflects updates in its component specifications and adds some new ones:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 15. JavaEE7 Web Profile</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">JSR</th>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Included with jetty-9.1.x</th>
<th class="tableblock halign-left valign-top">Pluggable</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=340">JSR 340</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Servlet Specification API 3.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=344">JSR 344</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java Server Faces 2.2 (JSF)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes, <a href="https://javaserverfaces.java.net/">Mojarra</a> or <a href="http://myfaces.apache.org/">MyFaces</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=245">JSR 245</a> / <a href="http://jcp.org/en/jsr/detail?id=341">JSR 341</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java Server Pages 2.3/Java Expression Language 3.0 (JSP/EL)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=52">JSR 52</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java Standard Tag Library 1.2 (JSTL)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=45">JSR 45</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Debugging Support for Other Languages 1.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes (via JSP)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes (via JSP)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=346">JSR 346</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Contexts and Dependency Injection for the JavaEE Platform 1.1 (Web Beans)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes, <a href="http://seamframework.org/Weld">Weld</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=330">JSR 330</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Dependency Injection for Java 1.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes as part of a CDI implementation, <a href="http://seamframework.org/Weld">Weld</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=316">JSR 316</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Managed Beans 1.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes, as part of another technology</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=345">JSR 345</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Enterprise JavaBeans 3.2 Lite</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=338">JSR 338</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java Persistence 2.1 (JPA)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes, eg <a href="http://www.hibernate.org/">Hibernate</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=250">JSR 250</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Common Annotations for the Java Platform 1.2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Partially (for non-core Servlet Spec annotations)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=907">JSR 907</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java Transaction API 1.2 (JTA)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=349">JSR 349</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Bean Validation 1.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes as part of another technology eg JSF, or a stand-alone implementation such as <a href="http://www.hibernate.org/subprojects/validator/docs.html">Hiberate
Validator</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=339">JSR 339</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java API for RESTful Web Services 2.0 (JAX-RS)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=356">JSR 356</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java API for Websocket 1.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=353">JSR 353</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java API for JSON Processing 1.0 (JSON-P)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes, eg JSON-P <a href="https://java.net/projects/jsonp/">reference implementation</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="jcp.org/en/jsr/detail?id=318">JSR 318</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Interceptors 1.2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes as part of a CDI implementation</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="jetty-javaee-6"><a class="anchor" href="#jetty-javaee-6"></a><a class="link" href="#jetty-javaee-6">Jetty EE 6 Web Profile</a></h4>
<div class="paragraph">
<p>Here is the matrix of JSRs for Java EE 6 Web Profile, and how they relate to Jetty:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 16. Java EE 6 Web Profile</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">JSR</th>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Included with jetty-9.0.x</th>
<th class="tableblock halign-left valign-top">Pluggable</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=315">JSR 315</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Servlet Specification API 3.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=314">JSR 314</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">JavaServer Faces 2.0 (JSF)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes, for example, <a href="https://javaserverfaces.java.net/">Mojarra</a> or <a href="http://myfaces.apache.org/">MyFaces</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=245">JSR 245</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">JavaServer Pages 2.2/Java Expression Language 2.2 (JSP/EL)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=52">JSR 52</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java Standard Tag Library 1.2 (JSTL)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=45">JSR 45</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Debugging Support for Other Languages 1.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes (via JSP)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes (via JSP)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=299">JSR 299</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Contexts and Dependency Injection for the Java EE Platform 1.0 (Web Beans)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes, <a href="http://seamframework.org/Weld">Weld</a> or <a href="http://openwebbeans.apache.org/">OpenWebBeans</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=330">JSR 330</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Dependency Injection for Java 1.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes as part of a CDI implementation, <a href="http://seamframework.org/Weld">Weld</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=316">JSR 316</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Managed Beans 1.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes, as part of another technology.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=318">JSR 318</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Enterprise JavaBeans 3.1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes, OpenEJB</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=317">JSR 317</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java Persistence 2.0 (JPA)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes, <a href="http://www.hibernate.org/">Hibernate</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=250">JSR 250</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Common Annotations for the Java Platform</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Partially (for non-core Servlet Spec annotations)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=907">JSR 907</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java Transaction API (JTA)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Implementations are pluggable, such as <a href="http://www.atomikos.com/">Atomikos</a>, <a href="http://jotm.ow2.org/xwiki/bin/view/Main/WebHome">JOTM</a>, <a href="http://jencks.codehaus.org/Transaction+Manager">Jencks (Geronimo Transaction Manager)</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://jcp.org/en/jsr/detail?id=303">JSR 303</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Bean Validation 1.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes as part of another technology (JSF), or a stand-alone implementation such as <a href="http://www.hibernate.org/subprojects/validator/docs.html">Hiberate
Validator</a></p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="quickstart-jetty-coordinates"><a class="anchor" href="#quickstart-jetty-coordinates"></a><a class="link" href="#quickstart-jetty-coordinates">Finding Jetty in Maven</a></h3>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
It is important that only stable releases are used in production environments.
Versions that have been deprecated or are released as Milestones (M) or Release Candidates (RC) are not suitable for production as they may contain security flaws or incomplete/non-functioning feature sets.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect3">
<h4 id="_maven-coordinates-8"><a class="anchor" href="#_maven-coordinates-8"></a><a class="link" href="#_maven-coordinates-8">Maven Coordinates</a></h4>
<div class="paragraph">
<p>Jetty has existed in Maven Central almost since its inception, though the coordinates have changed over the years.
When Jetty was based at SourceForge and then The Codehaus it was located under the <code>groupId</code> of <code>org.mortbay.jetty</code>.
With Jetty 7 the project moved to the Eclipse foundation and to a new <code>groupId</code> at that time to reflect its new home.</p>
</div>
<div class="paragraph">
<p>The top level Project Object Model (POM) for the Jetty project is located under the following coordinates.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-project&lt;/artifactId&gt;
&lt;version&gt;${project.version}&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_changelogs-in-maven-central"><a class="anchor" href="#_changelogs-in-maven-central"></a><a class="link" href="#_changelogs-in-maven-central">Changelogs in Maven Central</a></h4>
<div class="paragraph">
<p>The changes between versions of Jetty are tracked in a file called VERSIONS.txt, which is under source control and is generated on release.
Those generated files are also uploaded into Maven Central during the release of the top level POM. You can find them as a classifier marked artifact.</p>
</div>
<div class="paragraph">
<p><a href="https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-project/" class="bare">https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-project/</a></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-project&lt;/artifactId&gt;
&lt;version&gt;${project.version}&lt;/version&gt;
&lt;classifier&gt;version&lt;/classifier&gt;
&lt;type&gt;txt&lt;/type&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="quick-start-getting-started"><a class="anchor" href="#quick-start-getting-started"></a><a class="link" href="#quick-start-getting-started">Using Jetty</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can use Jetty in many different ways ranging from embedding Jetty in applications, launching it from different build systems, from different JVM-based languages, or as a standalone distribution.
This guide covers the latter, a standalone distribution suitable for deploying web applications.</p>
</div>
<div class="sect2">
<h3 id="jetty-downloading"><a class="anchor" href="#jetty-downloading"></a><a class="link" href="#jetty-downloading">Downloading Jetty</a></h3>
<div class="sect3">
<h4 id="_downloading-the-jetty-distribution"><a class="anchor" href="#_downloading-the-jetty-distribution"></a><a class="link" href="#_downloading-the-jetty-distribution">Downloading the Jetty Distribution</a></h4>
<div class="paragraph">
<p>The standalone Jetty distribution is available for download from the Eclipse Foundation:</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="paragraph">
<p><strong>Jetty</strong>
<a href="https://www.eclipse.org/jetty/download.html" class="bare">https://www.eclipse.org/jetty/download.html</a></p>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>It is available in both zip and gzip formats; download the one most appropriate for your system.
When you download and unpack the binary, it is extracted into a directory called <code>jetty-distribution-VERSION.</code>
Put this directory in a convenient location.
The rest of the instructions in this documentation refer to this location as either <code>$JETTY_HOME</code> or as <code>$(jetty.home).</code></p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
It is important that <strong>only</strong> stable releases are used in production environments.
Versions that have been deprecated or are released as Milestones (M) or Release Candidates (RC) are <strong>not</strong> suitable for production as they may contain security flaws or incomplete/non-functioning feature sets.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect4">
<h5 id="distribution-content"><a class="anchor" href="#distribution-content"></a><a class="link" href="#distribution-content">Distribution Content</a></h5>
<div class="paragraph">
<p>A summary of the distribution&#8217;s contents follows.
The top-level directory contains:</p>
</div>
<table class="tableblock frame-all grid-all" style="width: 80%;">
<caption class="title">Table 17. Contents</caption>
<colgroup>
<col style="width: 40%;">
<col style="width: 60%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Location</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">license-eplv10-aslv20.html</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">License file for Jetty</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">README.txt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Useful getting started information</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">VERSION.txt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Release information</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">bin/</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Utility shell scripts to help run Jetty on Unix systems</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">demo-base/</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A Jetty base directory to run a Jetty server with demonstration webapps</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">etc/</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Directory for Jetty XML configuration files</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">lib/</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All the JAR files necessary to run Jetty</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">logs/</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Directory for request logs</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">modules/</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Directory of module definitions</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">notice.html</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">License information and exceptions</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">resources/</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Directory containing additional resources for classpath, activated via configuration</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">start.ini</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">File containing the arguments that are added to the effective command line (modules, properties and XML configuration files)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">start.jar</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Jar that invokes Jetty (see also <a href="#quickstart-running-jetty">Running Jetty</a>)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">webapps/</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Directory containing webapps that run under the default configuration of Jetty</p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="jetty-home-downloading"><a class="anchor" href="#jetty-home-downloading"></a><a class="link" href="#jetty-home-downloading">Downloading the Jetty-Home Distribution</a></h4>
<div class="paragraph">
<p>Jetty-Home is an alternate version of the distribution that contains only the necessary items to host a Jetty distribution.
It is intended for advanced users who are already familiar with Jetty and want to download a smaller distribution package.
Jetty-Home can be downloaded from the Maven Central repository:</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="paragraph">
<p><strong>Jetty-Home</strong>
<a href="https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/" class="bare">https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/</a></p>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Like the main Jetty distribution, Jetty-Home is available in both zip and gzip formats; download the one most appropriate for your system.
Notice that there are a number of other files with extensions of .sha or .md5 which are checksum files.
When you download and unpack the binary, it is extracted into a directory called <code>jetty-home-VERSION.</code>
Put this directory in a convenient location.</p>
</div>
<div class="sect4">
<h5 id="jetty-home-distribution-content"><a class="anchor" href="#jetty-home-distribution-content"></a><a class="link" href="#jetty-home-distribution-content">Distribution Content</a></h5>
<div class="paragraph">
<p>A summary of the Jetty-Home&#8217;s distribution contents follows.
The top-level directory contains:</p>
</div>
<table class="tableblock frame-all grid-all" style="width: 80%;">
<caption class="title">Table 18. Contents</caption>
<colgroup>
<col style="width: 40%;">
<col style="width: 60%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Location</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">license-eplv10-aslv20.html</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">License file for Jetty</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">VERSION.txt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Release information</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">etc/</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Directory for Jetty XML configuration files</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">lib/</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All the JAR files necessary to run Jetty</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">modules/</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Directory of module definitions</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">notice.html</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">License information and exceptions</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">start.jar</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Jar that invokes Jetty (see also <a href="#quickstart-running-jetty">Running Jetty</a>)</p></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="quickstart-running-jetty"><a class="anchor" href="#quickstart-running-jetty"></a><a class="link" href="#quickstart-running-jetty">Running Jetty</a></h3>
<div class="paragraph">
<p>Once you have a copy of the Jetty distribution downloaded, extract the <code>zip</code> or <code>tar.gz</code> file to a location where you have read and write access.
Jetty has no GUI (Graphical User Interface), so running the server and performing many configuration options is done from the command line.</p>
</div>
<div class="paragraph">
<p>Once you have access to your system&#8217;s command line, navigate to the directory where you unpacked your copy of the Jetty distribution.
To start Jetty on the default port of 8080, run the following command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ java -jar start.jar
2017-09-20 15:45:11.986:INFO::main: Logging initialized @683ms to org.eclipse.jetty.util.log.StdErrLog
2017-09-20 15:45:12.197:WARN:oejs.HomeBaseWarning:main: This instance of Jetty is not running from a separate {jetty.base} directory, this is not recommended. See documentation at https://www.eclipse.org/jetty/documentation/current/startup.html
2017-09-20 15:45:12.243:INFO:oejs.Server:main: 10.0.0-SNAPSHOT
2017-09-20 15:45:12.266:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///installs/repository/jetty/webapps/] at interval 1
2017-09-20 15:45:12.298:INFO:oejs.AbstractConnector:main: Started ServerConnector@39c0f4a{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2017-09-20 15:45:12.298:INFO:oejs.Server:main: Started @995ms</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can point a browser at this server at <a href="http://localhost:8080" class="bare">http://localhost:8080</a>.
However, as there are no webapps deployed in the <code>$JETTY_HOME</code> directory, you will see a 404 error page served by Jetty.
To stop the server, press <code>CTRL</code> + <code>c</code> or <code>CTRL</code> + <code>z</code> in your terminal.</p>
</div>
<div class="paragraph">
<p><strong>Note</strong> the <code>HomeBaseWarning</code> - it is <strong>not</strong> recommended to run Jetty from the <code>$JETTY_HOME</code> directory.
Instead, see how to <a href="#creating-jetty-base">create a Jetty Base</a> below.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
You will see examples throughout the documentation referencing <code>$JETTY_HOME</code> and <code>$JETTY_BASE</code> as well as <code>{jetty.home}</code> and <code>{jetty.base}</code>.
These terms are used to refer to the location of your Jetty installation directories.
Many users find it helpful to define <code>$JETTY_HOME</code> as an environment variable that maps to their Jetty distribution directory.
More information can be found in our Administration section on <a href="#startup-base-and-home">managing Jetty Home and Jetty Base.</a>
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect3">
<h4 id="demo-webapps-base"><a class="anchor" href="#demo-webapps-base"></a><a class="link" href="#demo-webapps-base">Demo Base</a></h4>
<div class="paragraph">
<p>Within the standard Jetty distribution there is the <code>demo-base</code> directory.
This is a fully-functioning Jetty Base (more on that later) complete with numerous web applications demonstrating different Jetty functionality.
Additionally, the <code>demo-base</code> demonstrates the recommended way to run a Jetty base in a directory separate from <code>$JETTY_HOME</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cd demo-base/
[my-base]$ java -jar /path/to/jetty-home/start.jar
2017-09-20 16:23:03.563:INFO::main: Logging initialized @429ms to org.eclipse.jetty.util.log.StdErrLog
2017-09-20 16:23:03.802:WARN::main: demo test-realm is deployed. DO NOT USE IN PRODUCTION!
2017-09-20 16:23:03.804:INFO:oejs.Server:main: 10.0.0-SNAPSHOT
2017-09-20 16:23:03.819:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///installs/repository/jetty/demo-base/webapps/] at interval 1
2017-09-20 16:23:04.098:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=102ms
2017-09-20 16:23:04.103:WARN::main: async-rest webapp is deployed. DO NOT USE IN PRODUCTION!
2017-09-20 16:23:04.267:INFO:oejs.session:main: DefaultSessionIdManager workerName=node0
2017-09-20 16:23:04.267:INFO:oejs.session:main: No SessionScavenger set, using defaults
2017-09-20 16:23:04.268:INFO:oejs.session:main: Scavenging every 660000ms
2017-09-20 16:23:04.306:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@371a67ec{/async-rest,[file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-async-rest.war-_async-rest-any-5319296087878801290.dir/webapp/, jar:file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-async-rest.war-_async-rest-any-5319296087878801290.dir/webapp/WEB-INF/lib/example-async-rest-jar-10.0.0-SNAPSHOT.jar!/META-INF/resources],AVAILABLE}{/async-rest.war}
2017-09-20 16:23:04.429:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=53ms
2017-09-20 16:23:04.432:WARN::main: test webapp is deployed. DO NOT USE IN PRODUCTION!
2017-09-20 16:23:04.511:INFO:oejsh.ManagedAttributeListener:main: update PushFilter null-&gt;org.eclipse.jetty.servlets.PushCacheFilter@2362f559 on o.e.j.w.WebAppContext@35e2d654{/test,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test.war-_test-any-6279588879522983394.dir/webapp/,STARTING}{/test.war}
2017-09-20 16:23:04.516:INFO:oejsh.ManagedAttributeListener:main: update QoSFilter null-&gt;org.eclipse.jetty.servlets.QoSFilter@7770f470 on o.e.j.w.WebAppContext@35e2d654{/test,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test.war-_test-any-6279588879522983394.dir/webapp/,STARTING}{/test.war}
2017-09-20 16:23:04.519:WARN:oeju.DeprecationWarning:main: Using @Deprecated Class org.eclipse.jetty.servlets.MultiPartFilter
2017-09-20 16:23:04.549:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@35e2d654{/test,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test.war-_test-any-6279588879522983394.dir/webapp/,AVAILABLE}{/test.war}
2017-09-20 16:23:04.646:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=12ms
2017-09-20 16:23:04.649:WARN::main: test-jndi webapp is deployed. DO NOT USE IN PRODUCTION!
2017-09-20 16:23:04.697:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@561b6512{/test-jndi,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test-jndi.war-_test-jndi-any-6023636263414992288.dir/webapp/,AVAILABLE}{/test-jndi.war}
2017-09-20 16:23:04.770:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=40ms
2017-09-20 16:23:05.036:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@2beee7ff{/proxy,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-javadoc-proxy.war-_javadoc-proxy-any-2758874759195597975.dir/webapp/,AVAILABLE}{/javadoc-proxy.war}
2017-09-20 16:23:05.072:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=16ms
2017-09-20 16:23:05.074:WARN::main: test-jaas webapp is deployed. DO NOT USE IN PRODUCTION!
2017-09-20 16:23:05.098:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@506ae4d4{/test-jaas,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test-jaas.war-_test-jaas-any-8067423971450448377.dir/webapp/,AVAILABLE}{/test-jaas.war}
2017-09-20 16:23:05.182:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=37ms
2017-09-20 16:23:05.184:WARN::main: test-spec webapp is deployed. DO NOT USE IN PRODUCTION!
2017-09-20 16:23:05.243:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@45099dd3{/test-spec,[file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test-spec.war-_test-spec-any-1205866915335004234.dir/webapp/, jar:file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test-spec.war-_test-spec-any-1205866915335004234.dir/webapp/WEB-INF/lib/test-web-fragment-10.0.0-SNAPSHOT.jar!/META-INF/resources],AVAILABLE}{/test-spec.war}
2017-09-20 16:23:05.247:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.MovedContextHandler@3e08ff24{/oldContextPath,null,AVAILABLE}
2017-09-20 16:23:05.274:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=18ms
2017-09-20 16:23:05.296:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@5ddeb7cb{/,file:///installs/repository/jetty/demo-base/webapps/ROOT/,AVAILABLE}{/ROOT}
2017-09-20 16:23:05.326:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=21ms
2017-09-20 16:23:05.352:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@6b695b06{/doc,file:///installs/repository/jetty/demo-base/webapps/doc/,AVAILABLE}{/doc}
2017-09-20 16:23:05.370:INFO:oejs.AbstractConnector:main: Started ServerConnector@28cda624{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2017-09-20 16:23:05.380:INFO:oejus.SslContextFactory:main: x509=X509@126253fd(jetty,h=[jetty.eclipse.org],w=[]) for SslContextFactory@57db2b13(file:///installs/repository/jetty/demo-base/etc/keystore,file:///installs/repository/jetty/demo-base/etc/keystore)
2017-09-20 16:23:05.381:INFO:oejus.SslContextFactory:main: x509=X509@475c9c31(mykey,h=[],w=[]) for SslContextFactory@57db2b13(file:///installs/repository/jetty/demo-base/etc/keystore,ffile:///installs/repository/jetty/demo-base/etc/keystore)
2017-09-20 16:23:05.523:INFO:oejs.AbstractConnector:main: Started ServerConnector@53f3bdbd{SSL,[ssl, http/1.1]}{0.0.0.0:8443}
2017-09-20 16:23:05.524:INFO:oejs.Server:main: Started @2390ms</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can visit this demo server by pointing a browser at <a href="http://localhost:8080" class="bare">http://localhost:8080</a>, which will now show a welcome page and several demo/test web applications.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
The demonstration web applications are not necessarily secure and should <strong>not</strong> be deployed in production web servers.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>You can see the configuration of the <code>demo-base</code> by using the following commands:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; cd $JETTY_HOME/demo-base/
&gt; java -jar $JETTY_HOME/start.jar --list-modules
...
&gt; java -jar $JETTY_HOME/start.jar --list-config
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>--list-modules</code> command will return a complete list of available and enabled modules for the server.
It will also display the location of the modules, how and in what order they are implemented, dependent modules, and associated jar files.</p>
</div>
<div class="paragraph">
<p>The <code>--list-config</code> command displays a trove of information about the server including the Java and Jetty environments, the configuration order, any JVM arguments or System Properties set, general server properties, a full listing of the Jetty server class path, and active Jetty XML files.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="quickstart-common-config"><a class="anchor" href="#quickstart-common-config"></a><a class="link" href="#quickstart-common-config">Common Jetty Configuration</a></h3>
<div class="sect3">
<h4 id="creating-jetty-base"><a class="anchor" href="#creating-jetty-base"></a><a class="link" href="#creating-jetty-base">Creating a new Jetty Base</a></h4>
<div class="paragraph">
<p>The <code>demo-base</code> directory described earlier is an example of the <a href="#startup-base-and-home"><code>jetty.base</code></a> mechanism.
A Jetty base directory allows the configuration and web applications of a server instance to be stored separately from the Jetty distribution, so that upgrades can be done with minimal disruption.
Jetty&#8217;s default configuration is based on two properties:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">jetty.home</dt>
<dd>
<p>The property that defines the location of the Jetty distribution, its libs, default modules and default XML files (typically start.jar, lib, etc).</p>
</dd>
<dt class="hdlist1">jetty.base</dt>
<dd>
<p>The property that defines the location of a specific implementation of a Jetty server, its configuration, logs and web applications (typically start.d/*.ini files, logs and webapps).</p>
</dd>
</dl>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
Your Jetty Home directory should be treated as a standard of truth and remain unmodified or changed.
Changes or additions to your configuration should take place in the Jetty Base directory.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>The <code>jetty.home</code> and <code>jetty.base</code> properties may be explicitly set on the command line, or they can be inferred from the environment if used with commands like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; cd $JETTY_BASE
&gt; java -jar $JETTY_HOME/start.jar</code></pre>
</div>
</div>
<div class="paragraph">
<p>The following commands create a new base directory, enables both the HTTP connector and the web application deployer modules, and copies a demo webapp to be deployed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; JETTY_BASE=/tmp/mybase
&gt; mkdir $JETTY_BASE
&gt; cd $JETTY_BASE
&gt; java -jar $JETTY_HOME/start.jar
WARNING: Nothing to start, exiting ...
Usage: java -jar start.jar [options] [properties] [configs]
java -jar start.jar --help # for more information
&gt; java -jar $JETTY_HOME/start.jar --create-startd
INFO : Base directory was modified
&gt; java -jar $JETTY_HOME/start.jar --add-to-start=http,deploy
INFO: server initialised (transitively) in ${jetty.base}/start.d/server.ini
INFO: http initialised in ${jetty.base}/start.d/http.ini
INFO: security initialised (transitively) in ${jetty.base}/start.d/security.ini
INFO: servlet initialised (transitively) in ${jetty.base}/start.d/servlet.ini
INFO: webapp initialised (transitively) in ${jetty.base}/start.d/webapp.ini
INFO: deploy initialised in ${jetty.base}/start.d/deploy.ini
MKDIR: ${jetty.base}/webapps
INFO: Base directory was modified
&gt; cp $JETTY_HOME/demo-base/webapps/async-rest.war webapps/ROOT.war
&gt; java -jar $JETTY_HOME/start.jar
2015-06-04 11:10:16.286:INFO::main: Logging initialized @274ms
2015-06-04 11:10:16.440:INFO:oejs.Server:main: jetty-9.3.0.v20150601
2015-06-04 11:10:16.460:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///tmp/mybase/webapps/] at interval 1
2015-06-04 11:10:16.581:WARN::main: async-rest webapp is deployed. DO NOT USE IN PRODUCTION!
2015-06-04 11:10:16.589:INFO:oejw.StandardDescriptorProcessor:main: NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServlet
2015-06-04 11:10:16.628:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@1a407d53{/,[file:///tmp/jetty-0.0.0.0-8080-ROOT.war-_-any-4510228025526425427.dir/webapp/, jar:file:///tmp/jetty-0.0.0.0-8080-ROOT.war-_-any-4510228025526425427.dir/webapp/WEB-INF/lib/example-async-rest-jar-10.0.0-SNAPSHOT.jar!/META-INF/resources],AVAILABLE}{/ROOT.war}
2015-06-04 11:10:16.645:INFO:oejs.ServerConnector:main: Started ServerConnector@3abbfa04{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2015-06-04 11:10:16.646:INFO:oejs.Server:main: Started @634ms</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="quickstart-changing-jetty-port"><a class="anchor" href="#quickstart-changing-jetty-port"></a><a class="link" href="#quickstart-changing-jetty-port">Changing the Jetty Port</a></h4>
<div class="paragraph">
<p>You can configure Jetty to run on a different port by setting the <code>jetty.http.port</code> property on the command line:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; cd $JETTY_BASE
&gt; java -jar $JETTY_HOME/start.jar jetty.http.port=8081
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>When the server starts, it will now run on port <code>8081</code>.
It is important to note that setting properties on the command line will only take affect for that instance of the server.
To change the configuration so that the server will always start on the desired port, you will need to edit the <code>start.d/http.ini</code></p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The configuration by properties works via the following chain:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The <code>start.d/http.ini</code> file is part of the effective command line and contains the <code>--module=http</code> argument which activates the http module.</p>
</li>
<li>
<p>The <code>modules/http.mod</code> file defines the http module which specifies the <code>etc/jetty-http.xml</code> configuration file and the template ini properties it uses.</p>
</li>
<li>
<p>The <code>jetty.http.port</code> property is used by the Property XML element in <code>etc/jetty.http.xml</code> to inject the <code>ServerConnector</code> instance with the port.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For more information see the <a href="#quick-start-configure">Quickstart Configuration Guide</a> and <a href="#configuring-connectors">Configuring Connectors</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="quickstart-starting-https"><a class="anchor" href="#quickstart-starting-https"></a><a class="link" href="#quickstart-starting-https">Adding SSL for HTTPS &amp; HTTP2</a></h4>
<div class="paragraph">
<p>Building on the example above, we can activate additional modules to add support HTTPS and HTTP2 for the server.
To add HTTPS and HTTP2 connectors to a Jetty configuration, the modules can be activated by the following command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar $JETTY_HOME/start.jar --add-to-start=https,http2
ALERT: There are enabled module(s) with licenses.
The following 1 module(s):
+ contains software not provided by the Eclipse Foundation!
+ contains software not covered by the Eclipse Public License!
+ has not been audited for compliance with its license
Module: alpn-impl/alpn-8
+ ALPN is a hosted at github under the GPL v2 with ClassPath Exception.
+ ALPN replaces/modifies OpenJDK classes in the sun.security.ssl package.
+ http://github.com/jetty-project/jetty-alpn
+ http://openjdk.java.net/legal/gplv2+ce.html
Proceed (y/N)? y
INFO : alpn-impl/alpn-1.8.0_92 dynamic dependency of alpn-impl/alpn-8
INFO : alpn transitively enabled, ini template available with --add-to-start=alpn
INFO : alpn-impl/alpn-8 dynamic dependency of alpn
INFO : http2 initialized in ${jetty.base}/start.d/http2.ini
INFO : https initialized in ${jetty.base}/start.d/https.ini
INFO : ssl transitively enabled, ini template available with --add-to-start=ssl
MKDIR : ${jetty.base}/lib/alpn
DOWNLD: https://repo1.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.8.v20160420/alpn-boot-8.1.8.v20160420.jar to ${jetty.base}/lib/alpn/alpn-boot-8.1.8.v20160420.jar
MKDIR : ${jetty.base}/etc
COPY : ${jetty.home}/modules/ssl/keystore to ${jetty.base}/etc/keystore
INFO : Base directory was modified
&gt; java -jar $JETTY_HOME/start.jar
[...]
2017-05-22 12:48:23.271:INFO:oejs.AbstractConnector:main: Started ServerConnector@134d0064{SSL,[ssl, alpn, h2, http/1.1]}{0.0.0.0:8443}
[...]</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>--add-to-start</code> command sets up the effective command line in the ini files to run an ssl connection that supports the HTTPS and HTTP2 protocols as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>transitively enabled the <code>ssl</code> module that configures an SSL connector (eg port, keystore etc.) by adding <code>etc/jetty-ssl.xml</code> and <code>etc/jetty-ssl-context.xml</code> to the effective command line.</p>
</li>
<li>
<p>transitively enabled the <code>alpn</code> module that configures protocol negotiation on the SSL connector by adding <code>etc/jetty-alpn.xml</code> to the effective command line.</p>
</li>
<li>
<p>creates <code>start.d/https.ini</code> that configures the HTTPS protocol on the SSL connector by adding <code>etc/jetty-https.xml</code> to the effective command line.</p>
</li>
<li>
<p>creates <code>start.d/http2.ini</code> that configures the HTTP/2 protocol on the SSL connector by adding <code>etc/jetty-http2.xml</code> to the effective command line.</p>
</li>
<li>
<p>checks for the existence of a <code>etc/keystore</code> file and if not present, downloads a demonstration keystore file.</p>
</li>
</ul>
</div>
<div class="sect4">
<h5 id="quickstart-changing-https-port"><a class="anchor" href="#quickstart-changing-https-port"></a><a class="link" href="#quickstart-changing-https-port">Changing the Jetty HTTPS Port</a></h5>
<div class="paragraph">
<p>You can configure the SSL connector to run on a different port by setting the <code>jetty.ssl.port</code> property on the command line:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; cd $JETTY_BASE
&gt; java -jar $JETTY_HOME/start.jar jetty.ssl.port=8444</code></pre>
</div>
</div>
<div class="paragraph">
<p>Alternatively, property values can be added to the effective command line built from the <code>start.ini</code> file or <code>start.d/*.ini</code> files, depending on your set up.
Please see the section on <a href="#start-vs-startd">Start.ini vs. Start.d</a> for more information.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_more-start-jar-options"><a class="anchor" href="#_more-start-jar-options"></a><a class="link" href="#_more-start-jar-options">More start.jar Options</a></h4>
<div class="paragraph">
<p>The job of the <code>start.jar</code> is to interpret the command line, <code>start.ini</code> and <code>start.d</code> directory (and associated .ini files) to build a Java classpath and list of properties and configuration files to pass to the main class of the Jetty XML configuration mechanism.
The <code>start.jar</code> mechanism has many options which are documented in the <a href="#startup">Starting Jetty</a> administration section and you can see them in summary by using the command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar $JETTY_HOME/start.jar --help</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="quick-start-configure"><a class="anchor" href="#quick-start-configure"></a><a class="link" href="#quick-start-configure">An Introduction to Jetty Configuration</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="quickstart-config-how"><a class="anchor" href="#quickstart-config-how"></a><a class="link" href="#quickstart-config-how">How to Configure Jetty</a></h3>
<div class="paragraph">
<p>To understand Jetty configuration, you need to understand the "How" and the "What".
This section covers how to configure Jetty in terms of what mechanisms exist to perform configuration.
The <a href="#quickstart-config-what">next section</a> gives an overview of the action components and fields that you can configure with these mechanisms.</p>
</div>
<div class="sect3">
<h4 id="_jetty-pojo-configuration"><a class="anchor" href="#_jetty-pojo-configuration"></a><a class="link" href="#_jetty-pojo-configuration">Jetty POJO Configuration</a></h4>
<div class="paragraph">
<p>The core components of Jetty are Plain Old Java Objects (<a href="http://en.wikipedia.org/wiki/Plain_Old_Java_Object">POJOs</a>)
The process of configuring Jetty is mostly the process of instantiating, assembling and setting fields on the Jetty POJOs.
This can be achieved by:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Writing Java code to directly instantiate and assemble Jetty objects.
This is referred to as <a href="#embedding-jetty">Embedding Jetty</a>.</p>
</li>
<li>
<p>Using Jetty XML configuration, which is an <a href="http://en.wikipedia.org/wiki/Inversion_of_Control">Inversion of Control (IoC)</a> framework, to instantiate and assemble Jetty objects as XML objects.
The <code>etc/jetty.xml</code> file is the main Jetty XML configuration file, but there are many other <code>etc/jetty-<em>feature</em>.xml</code> files included in the Jetty distribution.</p>
</li>
<li>
<p>Using a third party <a href="http://en.wikipedia.org/wiki/Inversion_of_Control">IoC</a> framework like <a href="http://en.wikipedia.org/wiki/Spring_Framework">Spring</a>, to instantiate and assemble Jetty objects as Spring beans.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Because the main Jetty configuration is done by IoC, the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/">Jetty API documentation</a> is the ultimate configuration reference.</p>
</div>
</div>
<div class="sect3">
<h4 id="_jetty-start-configuration-files"><a class="anchor" href="#_jetty-start-configuration-files"></a><a class="link" href="#_jetty-start-configuration-files">Jetty Start Configuration Files</a></h4>
<div class="paragraph">
<p>The Jetty distribution uses the following configuration files to instantiate, inject and start server via the <code>start.jar</code> mechanism.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>ini</code> files</dt>
<dd>
<p>The Jetty Start mechanism uses the command line, the <code>$JETTY_BASE/start.ini</code> and/or <code>$JETTY_BASE/start.d/*.ini</code> files to create an effective command line of arguments.
Arguments may be:</p>
<div class="ulist">
<ul>
<li>
<p>Module activations in the form <code>--module=name</code></p>
</li>
<li>
<p>Properties in the form of <code>name=value</code>, used to parameterize Jetty IoC XML</p>
</li>
<li>
<p>XML files in Jetty IoC (or Spring) XML format</p>
</li>
<li>
<p>A standard <a href="http://en.wikipedia.org/wiki/Java_properties">Java property file</a> containing additional start properties</p>
</li>
<li>
<p>Other start.jar options (see <code>java -jar start.jar --help</code>)</p>
</li>
<li>
<p>Some JVM options in combination with <code>--exec</code>, such as <code>-Xbootclasspath</code>.</p>
</li>
</ul>
</div>
</dd>
</dl>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>It is the <code>ini</code> files located in the Jetty base directory (if different from Jetty home) that are typically edited to change the configuration (e.g. change ports).</p>
</div>
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>mod</code> files</dt>
<dd>
<p>The <code>$JETTY_HOME/modules/*.mod</code> files contain the definition of modules that can be activated by <code>--module=name</code>.
Each <code>mod</code> file defines:</p>
<div class="ulist">
<ul>
<li>
<p>Module dependencies for ordering and activation</p>
</li>
<li>
<p>The libraries needed by the module to be added to the classpath</p>
</li>
<li>
<p>The XML files needed by the module to be added to the effective command line</p>
</li>
<li>
<p>Files needed by the activated module</p>
</li>
<li>
<p>A template <code>ini</code> file to be used when activating the <code>--add-to-start=name</code> option</p>
<div class="paragraph">
<p>Typically module files are rarely edited and only then for significant structural changes.
The <code><strong>.mod</code> files are normally located in <code>$JETTY_HOME/modules/</code>, but extra or edited modules may be added to <code>$JETTY_BASE/module</code>.
If module changes are required, it is best practice to copy the particular <code></strong>.mod</code> file from <code>$JETTY_HOME/modules/</code> to <code>$JETTY_BASE/modules/</code> before being modified.</p>
</div>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1">XML files</dt>
<dd>
<p>XML files in <a href="#jetty-xml-syntax">Jetty IoC XML format</a> or Spring IoC format are listed either on the command line, in <code>ini</code> files, or are added to the effective command line by a module definition.
The XML files instantiate and inject the actual Java objects that comprise the server, connectors and contexts.
Because Jetty IoC XML files use properties, most common configuration tasks can be accomplished without editing these XML files and can instead be achieved by editing the property in the corresponding <code>ini</code> files.
XML files are normally located in <code>$JETTY_HOME/etc/</code>, but extra or edited XML files may be added to <code>$JETTY_BASE/etc/</code>.
<strong>Note</strong> If XML configuration changes are required, it is best practice to copy the XML file from <code>$JETTY_HOME/etc/</code> to <code>$JETTY_BASE/etc/</code> before being modified.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Below is an illustration of how the various Jetty configuration files (<code>ini</code>, <code>mod</code> and XML) are related:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="Jetty_Configuration_File_Relationships.png" alt="image" width="693"></span></p>
</div>
</div>
<div class="sect3">
<h4 id="_a-closer-look"><a class="anchor" href="#_a-closer-look"></a><a class="link" href="#_a-closer-look">A Closer Look</a></h4>
<div class="paragraph">
<p>To put it simply: XML files are responsible for instantiating the Jetty POJOs that make up the server.
They define properties which users can modify to meet the needs of their server.
These XML files are broken up by type in the distribution so they can be consumed as a user/server needs them.
For example, a server may need HTTP and HTTPS functionality, but opt out of using HTTP/2 and Websocket.</p>
</div>
<div class="paragraph">
<p>Module files allow users to enable and remove functionality quickly and easily from their server implementation.
They include a template of the different properties included in the associated XML file, as well as a pointer to the XML or JAR file(s) they are referencing.
When a module is activated these properties are added to a related <code>ini</code> file where users can configure them to meet their needs.
We will discuss modules in further detail in an upcoming chapter.</p>
</div>
<div class="paragraph">
<p>Ini files are where most users will spend the bulk of their time editing the configuration for their server.
As mentioned, they contain properties which were defined in their associated XML files which in turn reference Jetty Java objcts.</p>
</div>
<div class="paragraph">
<p>This can be a bit overwhelming at first, so let&#8217;s look at an example - in this case the <code>http</code> module.
We will work backwards from an ini file to the associated module and then the XML file in question.</p>
</div>
<div class="paragraph">
<p>First up, the <code>http.ini</code> file.
If we take a look at it&#8217;s contents, we will see the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cat start.d/http.ini
# ---------------------------------------
# Module: http
# Enables a HTTP connector on the server.
# By default HTTP/1 is support, but HTTP2C can
# be added to the connector with the http2c module.
# ---------------------------------------
--module=http
### HTTP Connector Configuration
## Connector host/address to bind to
# jetty.http.host=0.0.0.0
## Connector port to listen on
# jetty.http.port=8080
## Connector idle timeout in milliseconds
# jetty.http.idleTimeout=30000
## Number of acceptors (-1 picks default based on number of cores)
# jetty.http.acceptors=-1
## Number of selectors (-1 picks default based on number of cores)
# jetty.http.selectors=-1
## ServerSocketChannel backlog (0 picks platform default)
# jetty.http.acceptQueueSize=0
## Thread priority delta to give to acceptor threads
# jetty.http.acceptorPriorityDelta=0
## Reserve threads for high priority tasks (-1 use a heuristic, 0 no reserved threads)
# jetty.http.reservedThreads=-1
## Connect Timeout in milliseconds
# jetty.http.connectTimeout=15000
## HTTP Compliance: RFC7230, RFC2616, LEGACY
# jetty.http.compliance=RFC7230</code></pre>
</div>
</div>
<div class="paragraph">
<p>So what do we see?
We have a module name, the module activation (<code>--module=http</code>), as well as a description and what look like properties to configure.
Those will some scripting/coding experience might notice that most of the lines are commented out with <code>#</code> and you&#8217;d be correct.
When a module is enabled and an <code>ini</code> file is created, all of the properties you see here were set to these defaults - the server is already using the values shown
If you wanted to change one of the properties though, say <code>jetty.http.port</code>, you&#8217;d simply uncomment the line and change the value.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cat start.d/http.ini
# ---------------------------------------
# Module: http
# Enables a HTTP connector on the server.
# By default HTTP/1 is support, but HTTP2C can
# be added to the connector with the http2c module.
# ---------------------------------------
--module=http
### HTTP Connector Configuration
## Connector host/address to bind to
# jetty.http.host=0.0.0.0
## Connector port to listen on
jetty.http.port=1234
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>As seen before, these properties were populated in this ini file based on a related module.
Standard Jetty modules live in the Home of the Jetty Distribution in the aptly named <code>modules</code> directory.
So let&#8217;s take a quick look at the associated <code>$JETTY_HOME/modules/http.mod</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cat $JETTY_HOME/modules/http.mod
[description]
Enables a HTTP connector on the server.
By default HTTP/1 is support, but HTTP2C can
be added to the connector with the http2c module.
[tags]
connector
http
[depend]
server
[xml]
etc/jetty-http.xml
[ini-template]
### HTTP Connector Configuration
## Connector host/address to bind to
# jetty.http.host=0.0.0.0
## Connector port to listen on
# jetty.http.port=8080
## Connector idle timeout in milliseconds
# jetty.http.idleTimeout=30000
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>At first blush, it looks remarkable similar to the <code>ini</code> file we just looked at.
We still have a description and the properties we could edit, but now we also have several other sections.
These other sections will be looked at further in our chapter on modules, but for now it is worth noting the <code>[xml]</code> and <code>[ini-template]</code> sections.
As you could probably have puzzled out, the <code>[ini-template]</code> contains a template (go figure) for properties to be placed in the associated <code>ini</code> file when a module is activated.
The <code>[xml]</code> section refers to the file and location of the XML file these properties are based on.
It is important to note that not every module file will have the same sections, but most should look structurally the same.</p>
</div>
<div class="paragraph">
<p>Now that we know what XML file these properties relate to, we can navigate to it and have a look.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">$ cat $JETTY_HOME/etc/jetty-http.xml
&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;!-- ============================================================= --&gt;
&lt;!-- Configure the Jetty Server instance with an ID "Server" --&gt;
&lt;!-- by adding a HTTP connector. --&gt;
&lt;!-- This configuration must be used in conjunction with jetty.xml --&gt;
&lt;!-- ============================================================= --&gt;
&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;!-- =========================================================== --&gt;
&lt;!-- Add a HTTP Connector. --&gt;
&lt;!-- Configure an o.e.j.server.ServerConnector with a single --&gt;
&lt;!-- HttpConnectionFactory instance using the common httpConfig --&gt;
&lt;!-- instance defined in jetty.xml --&gt;
&lt;!-- --&gt;
&lt;!-- Consult the javadoc of o.e.j.server.ServerConnector and --&gt;
&lt;!-- o.e.j.server.HttpConnectionFactory for all configuration --&gt;
&lt;!-- that may be set here. --&gt;
&lt;!-- =========================================================== --&gt;
&lt;Call name="addConnector"&gt;
&lt;Arg&gt;
&lt;New id="httpConnector" class="org.eclipse.jetty.server.ServerConnector"&gt;
&lt;Arg name="server"&gt;&lt;Ref refid="Server" /&gt;&lt;/Arg&gt;
&lt;Arg name="acceptors" type="int"&gt;&lt;Property name="jetty.http.acceptors" deprecated="http.acceptors" default="-1"/&gt;&lt;/Arg&gt;
&lt;Arg name="selectors" type="int"&gt;&lt;Property name="jetty.http.selectors" deprecated="http.selectors" default="-1"/&gt;&lt;/Arg&gt;
&lt;Arg name="factories"&gt;
&lt;Array type="org.eclipse.jetty.server.ConnectionFactory"&gt;
&lt;Item&gt;
&lt;New class="org.eclipse.jetty.server.HttpConnectionFactory"&gt;
&lt;Arg name="config"&gt;&lt;Ref refid="httpConfig" /&gt;&lt;/Arg&gt;
&lt;Arg name="compliance"&gt;&lt;Call class="org.eclipse.jetty.http.HttpCompliance" name="valueOf"&gt;&lt;Arg&gt;&lt;Property name="jetty.http.compliance" default="RFC7230"/&gt;&lt;/Arg&gt;&lt;/Call&gt;&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Arg&gt;
&lt;Set name="host"&gt;&lt;Property name="jetty.http.host" deprecated="jetty.host" /&gt;&lt;/Set&gt;
&lt;Set name="port"&gt;&lt;Property name="jetty.http.port" deprecated="jetty.port" default="8080" /&gt;&lt;/Set&gt;
&lt;Set name="idleTimeout"&gt;&lt;Property name="jetty.http.idleTimeout" deprecated="http.timeout" default="30000"/&gt;&lt;/Set&gt;
&lt;Set name="acceptorPriorityDelta"&gt;&lt;Property name="jetty.http.acceptorPriorityDelta" deprecated="http.acceptorPriorityDelta" default="0"/&gt;&lt;/Set&gt;
&lt;Set name="acceptQueueSize"&gt;&lt;Property name="jetty.http.acceptQueueSize" deprecated="http.acceptQueueSize" default="0"/&gt;&lt;/Set&gt;
&lt;Get name="SelectorManager"&gt;
&lt;Set name="connectTimeout"&gt;&lt;Property name="jetty.http.connectTimeout" default="15000"/&gt;&lt;/Set&gt;
&lt;Set name="reservedThreads"&gt;&lt;Property name="jetty.http.reservedThreads" default="-2"/&gt;&lt;/Set&gt;
&lt;/Get&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now we can see where those properties in our <code>ini</code> and module files came from.
In Jetty XML files, Jetty objects come to life; defined properties are set which link back to the jar libraries and run the server to a user&#8217;s specification.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
It is important to remember that you should <strong>not</strong> modify the XML files in your <code>$JETTY_HOME</code>.
If you do for some reason feel you want to change the way an XML file operates, it is best to make a copy of it in your <code>$JETTY_BASE</code> in an <code>/etc</code> directory.
Jetty will always look first to the <code>$JETTY_BASE</code> for configuration.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="_other-configuration-files"><a class="anchor" href="#_other-configuration-files"></a><a class="link" href="#_other-configuration-files">Other Configuration Files</a></h4>
<div class="paragraph">
<p>In addition to the configuration files described above, the configuration of the server can use the following file types:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Context XML files</dt>
<dd>
<p>Any XML files in <a href="#jetty-xml-syntax">Jetty IoC XML format</a> or Spring IoC format that is discovered in the <code>/webapps</code> directory are used by the deploy module to instantiate and inject <code>HttpContext</code> instances to create a specific context.
These may be standard web applications or bespoke contexts created from special purpose handlers.</p>
</dd>
<dt class="hdlist1">web.xml</dt>
<dd>
<p>The <a href="http://en.wikipedia.org/wiki/Servlet">Servlet</a> Specification defines the <a href="http://en.wikipedia.org/wiki/Web.xml"><code>web.xml</code></a> deployment descriptor that defines and configures the filters, servlets and resources a <a href="http://en.wikipedia.org/wiki/Web_application">web application</a> uses.
The Jetty <code>WebAppContext</code> component uses this XML format to:</p>
<div class="ulist">
<ul>
<li>
<p>Set up the default configuration of a web application context.</p>
</li>
<li>
<p>Interpret the application-specific configuration supplied with a web application in the <code>WEB-INF/web.xml</code> file.</p>
</li>
<li>
<p>Interpret descriptor fragments included in the <code>META-INF</code> directory of Jar files within <code>WEB-INF/lib.</code></p>
<div class="paragraph">
<p>Normally the <code>web.xml</code> file for a web application is found in the <code>WEB-INF/web.xml</code> location within the war file/directory or as <code>web.xml</code> fragments with <code>.jar</code> files found in <code>WEB-INF/lib</code>.
Jetty also supports multiple <code>web.xml</code> files so that a default descriptor may be applied before <code>WEB-INF/web.xml</code> (typically set to <code>etc/webdefault.xml</code> by the deploy module) and an override descriptor may be applied after <code>WEB-INF/web.xml</code> (typically set by a context XML file see <code>test.xml</code>)</p>
</div>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1">Property Files</dt>
<dd>
<p>Standard <a href="http://en.wikipedia.org/wiki/Java_properties">Java property files</a> are also used for Jetty configuration in several ways:</p>
<div class="ulist">
<ul>
<li>
<p>To parameterize Jetty IoC XML via the use of the <code>Property</code> element.</p>
</li>
<li>
<p>To configure the default logging mechanism (<code>StdErrLog</code>). Other logging frameworks can be utilized and also use property files (for example, <code>log4j</code>).</p>
</li>
<li>
<p>As a simple database for login usernames and credentials.</p>
</li>
</ul>
</div>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="_jetty-ioc-xml-format"><a class="anchor" href="#_jetty-ioc-xml-format"></a><a class="link" href="#_jetty-ioc-xml-format">Jetty IoC XML format</a></h4>
<div class="paragraph">
<p>To understand the <a href="#jetty-xml-syntax">Jetty IoC XML format</a>, consider the following example of an embedded Jetty server instantiated and configured in Java:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in gettingstarted/configuring/how-to-configure.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/ExampleServer.java[]</code></pre>
</div>
</div>
<div class="paragraph">
<p><a href="#jetty-xml-syntax">Jetty IoC XML format</a> allows you to instantiate and configure the exact same server in XML without writing any java code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">Unresolved directive in gettingstarted/configuring/how-to-configure.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/resources/exampleserver.xml[]</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="quickstart-config-what"><a class="anchor" href="#quickstart-config-what"></a><a class="link" href="#quickstart-config-what">What to Configure in Jetty</a></h3>
<div class="paragraph">
<p>This section gives an overview of the components of Jetty you typically configure using the mechanisms outlined in the previous section.
<a href="#basic-architecture">[basic-architecture]</a> describes the structure of a Jetty server, which is good background reading to understand configuration, and is vital if you want to change the structure of the server as set up by the default configurations in the Jetty distribution.
However, for most purposes, configuration is a matter of identifying the correct configuration file and modifying existing configuration values.</p>
</div>
<div class="sect3">
<h4 id="intro-jetty-configuration-server"><a class="anchor" href="#intro-jetty-configuration-server"></a><a class="link" href="#intro-jetty-configuration-server">Configuring the Server</a></h4>
<div class="paragraph">
<p>The Server instance is the central coordination object of a Jetty server; it provides services and life cycle management for all other Jetty server components.
In the standard Jetty distribution, the core server configuration is in <code>etc/jetty.xml</code> file, but you can mix in other server configurations which can include:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">ThreadPool</dt>
<dd>
<p>The Server instance provides a ThreadPool instance that is the default Executor service other Jetty server components use.
The prime configuration of the thread pool is the maximum and minimum size and is set in <code>start.ini</code> or <code>start.d/server.ini</code>.</p>
</dd>
<dt class="hdlist1">Handlers</dt>
<dd>
<p>A Jetty server can have only a single Handler instance to handle incoming HTTP requests.
However a handler may be a container or wrapper of other handlers forming a tree of handlers that typically
handle a request as a collaboration between the handlers from a branch of the tree from root to leaf.
The default handler tree set up in the <code>etc/jetty.xml</code> file is a Handler Collection containing a Context Handler Collection and the Default Handler.
The Context Handler Collection selects the next handler by context path and is where deployed Context Handler and Web Application Contexts are added to the handler tree.
The Default Handler handles any requests not already handled and generates the standard 404 page.
Other configuration files may add handlers to this tree (for example, <code>jetty-rewrite.xml</code>, <code>jetty-requestlog.xml</code>) or configure components to hot deploy handlers (for example, <code>jetty-deploy.xml</code>).</p>
</dd>
<dt class="hdlist1">Server Attributes</dt>
<dd>
<p>The server holds a generic attribute map of strings to objects so that other Jetty components can associate named objects with the server, and if the value objects implement the LifeCycle interface, they are started and stopped with the server.
Typically server attributes hold server-wide default values.</p>
</dd>
<dt class="hdlist1">Server fields</dt>
<dd>
<p>The server also has some specific configuration fields that you set in <code>start.ini</code> or <code>start.d/server.ini</code> for controlling, among other things, the sending of dates and versions in HTTP responses.</p>
</dd>
<dt class="hdlist1">Connectors</dt>
<dd>
<p>The server holds a collection of connectors that receive connections for HTTP and the other protocols that Jetty supports.
The next section, <a href="#intro-jetty-configuration-connectors">Configuring Connectors</a> describes configuration of the connectors themselves.
For the server you can either set the collection of all connectors or add/remove individual connectors.</p>
</dd>
<dt class="hdlist1">Services</dt>
<dd>
<p>The server can hold additional service objects, sometimes as attributes, but often as aggregated LifeCycle beans.
Examples of services are Login Services and DataSources, which you configure at the server level and then inject into the web applications that use them.</p>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="intro-jetty-configuration-connectors"><a class="anchor" href="#intro-jetty-configuration-connectors"></a><a class="link" href="#intro-jetty-configuration-connectors">Configuring Connectors</a></h4>
<div class="paragraph">
<p>A Jetty Server Connector is a network end point that accepts connections for one or more protocols which produce requests and/or messages for the Jetty server.
In the standard Jetty server distribution, several provided configuration files add connectors to the server for various protocols and combinations of protocols: <code>http.ini</code>, <code>https.ini</code> and <code>jetty-http2.xml</code>.
The configuration needed for connectors is typically:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Port</dt>
<dd>
<p>The TCP/IP port on which the connector listens for connections is set using the the XML Property element which looks up the <code>jetty.http.port</code> (or <code>jetty.ssl.port</code>) property, and if not found defaults to 8080 (or 8443 for TLS).</p>
</dd>
<dt class="hdlist1">Host</dt>
<dd>
<p>You can configure a host either as a host name or IP address to identify a specific network interface on which to listen.
If not set, or set to the value of 0.0.0.0, the connector listens on all local interfaces.
The XML Property element is used to look up the host value from the <code>jetty.host</code> property.</p>
</dd>
<dt class="hdlist1">Idle Timeout</dt>
<dd>
<p>The time in milliseconds that a connection can be idle before the connector takes action to close the connection.</p>
</dd>
<dt class="hdlist1">HTTP Configuration</dt>
<dd>
<p>Connector types that accept HTTP semantics (including HTTP, HTTPS and HTTP2) are configured with a <code>HttpConfiguration</code> instance that contains common HTTP configuration that is independent of the specific wire protocol used.
Because these values are often common to multiple connector types, the standard Jetty Server distribution creates a single <code>HttpConfiguration</code> in the <code>jetty.xml</code> file which is used via the XML Ref element in the specific connector files.</p>
</dd>
<dt class="hdlist1">SSL Context Factory</dt>
<dd>
<p>The TLS connector types (HTTPS and HTTP2) configure an SSL Context Factory with the location of the server keystore and truststore for obtaining server certificates.</p>
</dd>
</dl>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Virtual hosts are not configured on connectors. You must configure individual contexts with the virtual hosts to which they respond.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Prior to Jetty 9, the type of the connector reflected both the protocol supported (HTTP, HTTPS, AJP, SPDY), and the nature of the implementation (NIO or BIO).
From Jetty 9 onwards there is only one prime Connector type (<code>ServerConnector</code>), which is NIO based and uses Connection Factories to handle one or more protocols.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="intro-jetty-configuration-contexts"><a class="anchor" href="#intro-jetty-configuration-contexts"></a><a class="link" href="#intro-jetty-configuration-contexts">Configuring Contexts</a></h4>
<div class="paragraph">
<p>A Jetty context is a handler that groups other handlers under a context path together with associated resources and is roughly equivalent to the standard ServletContext API.
A context may contain either standard Jetty handlers or a custom application handler.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The servlet specification defines a web application.
In Jetty a standard web application is a specialized context that uses a standard layout and <code>WEB-INF/web.xml</code> to instantiate and configure classpath, resource base and handlers for sessions, security, and servlets, plus servlets for JSPs and static content.
Standard web applications often need little or no additional configuration, but you can also use the techniques for arbitrary contexts to refine or modify the configuration of standard web applications.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Configuration values that are common to all contexts are:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">contextPath</dt>
<dd>
<p>The contextPath is a URL prefix that identifies which context a HTTP request is destined for.
For example, if a context has a context path <code>/foo</code>, it handles requests to <code>/foo</code>, <code>/foo/index.html</code>,
<code>/foo/bar/</code>, and <code>/foo/bar/image.png</code> but it does not handle requests like <code>/</code>, <code>/other/</code>, or <code>/favicon.ico</code>.
A context with a context path of / is called the root context.</p>
<div class="paragraph">
<p>The context path can be set by default from the deployer (which uses the filename as the basis for the context path); or in code; or it can be set by a Jetty IoC XML that is either applied by the deployer or found in the <code>WEB-INF/jetty-web.xml</code> file of a standard web app context.</p>
</div>
</dd>
<dt class="hdlist1">virtualHost</dt>
<dd>
<p>A context may optionally have one or more virtual hosts set.
Unlike the host set on a connector (which selects the network interface on which to listen), a virtual host does not set any network parameters.
Instead a virtual host represents an alias assigned by a name service to an IP address, which may have many aliases.
To determine which virtual host a request is intended for, the HTTP client (browser) includes in the request the name used to look up the network address.
A context with a virtual host set only handles requests that have a matching virtual host in their request headers.</p>
</dd>
<dt class="hdlist1">classPath</dt>
<dd>
<p>A context may optionally have a classpath, so that any thread that executes a handler within the context has a thread context classloader set with the classpath.
A standard web application has the classpath initialized by the <code>WEB-INF/lib</code> and <code>WEB-INF/classes</code> directory and
has additional rules about delegating classloading to the parent classloader.
All contexts may have additional classpath entries added.</p>
</dd>
<dt class="hdlist1">attributes</dt>
<dd>
<p>Attributes are arbitrary named objects that are associated with a context and are frequently used to pass entities between a web application and its container.
For example the attribute <code>javax.servlet.context.tempdir</code> is used to pass the File instance that represents the assigned temporary directory for a web application.</p>
</dd>
<dt class="hdlist1">resourceBase</dt>
<dd>
<p>The resource base is a directory (or collection of directories or URL) that contains the static resources for the context.
These can be images and HTML files ready to serve or JSP source files ready to be compiled.
In traditional web servers this value is often called the docroot.</p>
</dd>
</dl>
</div>
<div class="sect4">
<h5 id="_context-configuration-by-api"><a class="anchor" href="#_context-configuration-by-api"></a><a class="link" href="#_context-configuration-by-api">Context Configuration by API</a></h5>
<div class="paragraph">
<p>In an embedded server, you configure contexts by directly calling the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ContextHandler.html">ContextHandler</a> API as in the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in gettingstarted/configuring/what-to-configure.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/OneContext.java[]</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_context-configuration-by-ioc-xml"><a class="anchor" href="#_context-configuration-by-ioc-xml"></a><a class="link" href="#_context-configuration-by-ioc-xml">Context Configuration by IoC XML</a></h5>
<div class="paragraph">
<p>You can create and configure a context entirely by IoC XML (either Jetty&#8217;s or Spring).
The deployer discovers and hot deploys context IoC descriptors like the following which creates a context to serve the Javadoc from the Jetty distribution:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;!--
Configure a custom context for serving javadoc as static resources
--&gt;
&lt;Configure class="org.eclipse.jetty.server.handler.ContextHandler"&gt;
&lt;Set name="contextPath"&gt;/javadoc&lt;/Set&gt;
&lt;Set name="resourceBase"&gt;&lt;SystemProperty name="jetty.home" default="."/&gt;/javadoc/&lt;/Set&gt;
&lt;Set name="handler"&gt;
&lt;New class="org.eclipse.jetty.server.handler.ResourceHandler"&gt;
&lt;Set name="welcomeFiles"&gt;
&lt;Array type="String"&gt;
&lt;Item&gt;index.html&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Set&gt;
&lt;Set name="cacheControl"&gt;max-age=3600,public&lt;/Set&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="intro-jetty-configuration-webapps"><a class="anchor" href="#intro-jetty-configuration-webapps"></a><a class="link" href="#intro-jetty-configuration-webapps">Configuring Web Applications</a></h5>
<div class="paragraph">
<p>The servlet specification defines a web application, which when packaged as a zip is called WAR file (Web application ARchive).
Jetty implements both WAR files and unpacked web applications as a specialized context that is configured by means of:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A standard layout which sets the location of the resourceBase (the root of the WAR) and initializes the classpath from jars found in <code>WEB-INF/lib</code> and classes found in <code>WEB-INF/classes</code>.</p>
</li>
<li>
<p>The standard <code>WEB-INF/web.xml</code> deployment descriptor which is parsed to define and configure init parameters, filters, servlets, listeners, security constraints, welcome files and resources to be injected.</p>
</li>
<li>
<p>A default <code>web.xml</code> format deployment descriptor provided either by Jetty or in configuration configures the JSP servlet and the default servlet for handling static content.
The standard <code>web.xml</code> may override the default <code>web.xml</code>.</p>
</li>
<li>
<p>Annotations discovered on classes in Jars contained in <code>WEB-INF/lib</code> can declare additional filters, servlets and listeners.</p>
</li>
<li>
<p>Standard deployment descriptor fragments discovered in Jars contained in <code>WEB-INF/lib</code> can declare additional init parameters, filters, servlets, listeners, security constraints, welcome files and resources to be injected.</p>
</li>
<li>
<p>An optional <code>WEB-INF/jetty-web.xml</code> file may contain Jetty IoC configuration to configure the Jetty specific APIs of the context and handlers.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Because these configuration mechanisms are contained within the WAR file (or unpacked web application), typically a web application contains much of its own configuration and deploying a WAR is often just a matter of dropping the WAR file in to the webapps directory that is scanned by the <a href="#quickstart-config-deployer">Jetty deployer</a>.</p>
</div>
<div class="paragraph">
<p>If you need to configure something within a web application, often you do so by unpacking the WAR file and editing the <code>web.xml</code> and other configuration files.
However, both the servlet standard and some Jetty features allow for other configuration to be applied to a web application externally from the WAR:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Configured data sources and security realms in the server can be injected into a web application either explicitly or by name matching.</p>
</li>
<li>
<p>Jetty allows one or more override deployment descriptors, in <code>web.xml</code> format, to be set on a context (via code or IoC XML) to amend the configuration set by the default and standard <code>web.xml</code>.</p>
</li>
<li>
<p>The normal Jetty Java API may be called by code or IoC XML to amend the configuration of a web application.</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="_setting-the-context-path"><a class="anchor" href="#_setting-the-context-path"></a><a class="link" href="#_setting-the-context-path">Setting the Context Path</a></h5>
<div class="paragraph">
<p>The web application standard provides no configuration mechanism for a web application or WAR file to set its own <code>contextPath</code>.
By default the deployer uses conventions to set the context path:
If you deploy a WAR file called <code>foobar.WAR</code>, the context path is <code>/foobar</code>; if you deploy a WAR file called <code>ROOT.WAR</code> the context path is <code>/</code>.</p>
</div>
<div class="paragraph">
<p>However, it is often desirable to explicitly set the context path so that information (for example, version numbers) may be included in the filename of the WAR.
Jetty allows the context Path of a WAR file to be set internally (by the WAR itself) or externally (by the deployer of the WAR).</p>
</div>
<div class="paragraph">
<p>To set the contextPath from within the WAR file, you can include a <code>WEB-INF/jetty-web.xml</code> file which contains IoC XML to set the context path:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/contextpath&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Alternately, you can configure the classpath externally without the need to modify the WAR file itself.
Instead of allowing the WAR file to be discovered by the deployer, an IoC XML file may be deployed that both sets the context path and declares the WAR file that it applies to:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="war"&gt;&lt;SystemProperty name="jetty.home" default="."/&gt;/webapps/test.war&lt;/Set&gt;
&lt;Set name="contextPath"&gt;/test&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>An example of setting the context path is included with the Jetty distribution in <code>$JETTY_HOME/webapps/test.xml</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="quickstart-config-deployer"><a class="anchor" href="#quickstart-config-deployer"></a><a class="link" href="#quickstart-config-deployer">Web Application Deployment</a></h5>
<div class="paragraph">
<p>Jetty is capable of deploying a variety of Web Application formats.
This is accomplished via scans of the <code>${jetty.base}/webapps</code> directory for contexts to deploy.</p>
</div>
<div class="paragraph">
<p>A Context can be any of the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A standard WAR file. (must in &#8220;.war&#8221;).</p>
</li>
<li>
<p>A directory containing an expanded WAR file. (must contain <code>{dir}/WEB-INF/web.xml</code> file).</p>
</li>
<li>
<p>A directory containing static content.</p>
</li>
<li>
<p>A XML descriptor in <a href="#jetty-xml-syntax">[jetty-xml-syntax]</a> that configures a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ContextHandler.html">ContextHandler</a> instance (Such as a
<a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html">WebAppContext</a>).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The new WebAppProvider will attempt to avoid double deployments during the directory scan with the following heuristics:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Hidden files (starting with <code>"."</code>) are ignored</p>
</li>
<li>
<p>Directories with names ending in <code>".d"</code> are ignored</p>
</li>
<li>
<p>If a directory and matching WAR file exist with the same base name (eg: <code>foo/</code> and <code>foo.war</code>), then the directory is assumed to be the unpacked WAR and only the WAR is deployed (which may reuse the unpacked directory)</p>
</li>
<li>
<p>If a directory and matching XML file exists (eg: <code>foo/</code> and <code>foo.xml</code>), then the directory is assumed to be an unpacked WAR and only the XML is deployed (which may use the directory in its own configuration)</p>
</li>
<li>
<p>If a WAR file and matching XML file exist (eg: <code>foo.war</code> and <code>foo.xml</code>), then the WAR is assumed to be configured by the XML and only the XML is deployed.</p>
</li>
</ul>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
In prior versions of Jetty there was a separate ContextDeployer that provided XML-based deployment. As of Jetty 9 the ContextDeployer no longer exists and its functionality has been merged with the new <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/deploy/providers/WebAppProvider.html">WebAppProvider</a> to avoid double deployment scenarios.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect4">
<h5 id="_setting-an-authentication-realm"><a class="anchor" href="#_setting-an-authentication-realm"></a><a class="link" href="#_setting-an-authentication-realm">Setting an Authentication Realm</a></h5>
<div class="paragraph">
<p>The authentication method and realm name for a standard web application may be set in the <code>web.xml</code> deployment descriptor with elements like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">...
&lt;login-config&gt;
&lt;auth-method&gt;BASIC&lt;/auth-method&gt;
&lt;realm-name&gt;Test Realm&lt;/realm-name&gt;
&lt;/login-config&gt;
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example declares that the BASIC authentication mechanism will be used with credentials validated against a realm called "Test Realm."
However the standard does not describe how the realm itself is implemented or configured.
In Jetty, there are several realm implementations (called LoginServices) and the simplest of these is the HashLoginService, which can read usernames and credentials from a Java properties file.</p>
</div>
<div class="paragraph">
<p>To configure an instance of HashLoginService that matches the "Test Realm" configured above, the following <code>$JETTY_BASE/etc/test-realm.xml</code> IoC XML file should be passed on the command line or set in <code>start.ini</code> or <code>start.d/server.ini</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">Unresolved directive in gettingstarted/configuring/what-to-configure.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/etc/test-realm.xml[]</code></pre>
</div>
</div>
<div class="paragraph">
<p>This creates and configures the LoginService as an aggregate bean on the server.
When a web application is deployed that declares a realm called "Test Realm," the server beans are searched for a matching Login Service.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="upgrading-jetty"><a class="anchor" href="#upgrading-jetty"></a><a class="link" href="#upgrading-jetty">Upgrading Jetty</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Unresolved directive in gettingstarted/upgrading/chapter.adoc - include::upgrading-from-jetty-9.adoc[]</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="http2"><a class="anchor" href="#http2"></a><a class="link" href="#http2">HTTP/2</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="http2-configuring-push"><a class="anchor" href="#http2-configuring-push"></a><a class="link" href="#http2-configuring-push">Configuring HTTP/2 Push</a></h3>
<div class="paragraph">
<p>HTTP/2 Push is a mechanism that allows the server to send multiple resources to the client for a single client request.
This will reduce the amount of round-trips necessary to retrieve all the resources that make up a web page and can significantly improve the page load time.</p>
</div>
<div class="paragraph">
<p>HTTP/2 Push can be automated in your application by configuring a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/servlets/PushCacheFilter.html"><code>PushCacheFilter</code></a> in the <code>web.xml</code>, in this way:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
metadata-complete="true"
version="3.1"&gt;
...
&lt;filter&gt;
&lt;filter-name&gt;PushFilter&lt;/filter-name&gt;
&lt;filter-class&gt;org.eclipse.jetty.servlets.PushCacheFilter&lt;/filter-class&gt;
&lt;async-supported&gt;true&lt;/async-supported&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;PushFilter&lt;/filter-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
...
&lt;/web-app&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>PushCacheFilter</code> analyzes the HTTP requests for resources that arrive to your web application.
Some of these requests contain the HTTP <code>Referer</code> header that points to a resource that has been requested previously.</p>
</div>
<div class="paragraph">
<p>This allows the <code>PushCacheFilter</code> to organize resources in a tree, for example a root <code>index.html</code> resource having two children resources, <code>styles.css</code> and <code>application.js</code>, and <code>styles.css</code> having a child resource, <code>background.png</code>.
The root resource is called the <em>primary</em> resource, while descendant resources are called <em>secondary</em> resources.</p>
</div>
<div class="paragraph">
<p>The resource tree is built using a time window so that when a root resource is requested, only subsequent requests that are made within the time window will be added to the resource tree.
The resource tree can also be limited in size so that the number of secondary resources associated to a primary resource is limited.</p>
</div>
<div class="paragraph">
<p>By default, only the resource <em>path</em> (without the <em>query</em> string) is used to associate secondary resources to the primary resource, but you can configure <code>PushCacheFilter</code> to take the query string into account.</p>
</div>
<div class="paragraph">
<p><code>PushCacheFilter</code> can be configured with the following <code>init-params</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>associatePeriod</code>: the time window, in milliseconds, within which a request for a secondary resource will be associated to a primary resource; defaults to 4000 ms</p>
</li>
<li>
<p><code>maxAssociations</code>: the max number of secondary resources that may be associated to a primary resource; defaults to 16</p>
</li>
<li>
<p><code>hosts</code>: a comma separated list of hosts that are allowed in the <code>Referer</code> header; defaults to the host in the <code>Host</code> header</p>
</li>
<li>
<p><code>ports</code>: a comma separated list of ports that are allowed in the <code>Referer</code> header; defaults to the port in the <code>Host</code> header</p>
</li>
<li>
<p><code>useQueryInKey</code>: a boolean indicating whether the query string of the request should be considered when associating secondary resources to primary resources; defaults to <code>false</code></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="http2-configuring-haproxy"><a class="anchor" href="#http2-configuring-haproxy"></a><a class="link" href="#http2-configuring-haproxy">Configuring HAProxy and Jetty</a></h3>
<div class="paragraph">
<p>Typical website deployments have Apache (or Nginx) configured as reverse proxy to talk to one or more backend Jetty instances.
This configuration cannot be used for HTTP/2 because Apache does not yet support HTTP/2 (nor does Nginx).</p>
</div>
<div class="paragraph">
<p><a href="http://haproxy.org">HAProxy</a> is an open source solution that offers load balancing and proxying for TCP and HTTP based application, and can be used as a replacement for Apache or Nginx when these are used as reverse proxies and has the major benefit that supports HTTP/2.
It also offers load balancing and several other features which can position it as a complete replacement for Apache or Nginx.</p>
</div>
<div class="paragraph">
<p>The deployment proposed here will have HAProxy play the role that Apache and Nginx usually do: to perform the TLS offloading (that is, decrypt and encrypt TLS) and then forwarding the now clear-text traffic to a backend Jetty server, speaking either HTTP/1.1 or HTTP/2.</p>
</div>
<div class="paragraph">
<p>The instructions that follow are for Linux.</p>
</div>
<div class="sect3">
<h4 id="http2-haproxy-install"><a class="anchor" href="#http2-haproxy-install"></a><a class="link" href="#http2-haproxy-install">Installing HAProxy</a></h4>
<div class="paragraph">
<p>You will need HAProxy 1.5 or later, because it provides support for SSL and ALPN, both required by HTTP/2. Most Linux distributions have the HAProxy package available to be installed out of the box. For example on Ubuntu 15.04:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ sudo apt-get install haproxy</code></pre>
</div>
</div>
<div class="paragraph">
<p>Alternatively you can download the HAProxy source code and build it on your environment by following the README bundled with the HAProxy source code tarball.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
HAProxy supports ALPN only if built with OpenSSL 1.0.2 or greater.
Use <code>haproxy -vv</code> to know with which OpenSSL version HAProxy has been built.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="http2-haproxy-ssl"><a class="anchor" href="#http2-haproxy-ssl"></a><a class="link" href="#http2-haproxy-ssl">Setup SSL for HAProxy</a></h4>
<div class="paragraph">
<p>HAProxy will perform the TLS decryption and encryption much more efficiently than a Java implementation.</p>
</div>
<div class="paragraph">
<p>HAProxy will need a single file containing the X509 certificates and the private key, all in <a href="https://en.wikipedia.org/wiki/X.509">PEM format</a>, with the following order:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>The site certificate; this certificate&#8217;s Common Name refers to the site domain (for example: CN=*.webtide.com) and is signed by Certificate Authority #1.</p>
</li>
<li>
<p>The Certificate Authority #1 certificate; this certificate may be signed by Certificate Authority #2.</p>
</li>
<li>
<p>The Certificate Authority #2 certificate; this certificate may be signed by Certificate Authority #3; and so on until the Root Certificate Authority.</p>
</li>
<li>
<p>The Root Certificate Authority certificate.</p>
</li>
<li>
<p>The private key corresponding to the site certificate.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Let&#8217;s use <code>keytool</code> to generate a self signed certificate:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ keytool -genkeypair -keyalg RSA -keystore keystore.p12 -storetype pkcs12 -storepass storepwd -ext SAN=DNS:domain.com
What is your first and last name?
[Unknown]: *.domain.com
What is the name of your organizational unit?
[Unknown]: Unit
What is the name of your organization?
[Unknown]: Domain
What is the name of your City or Locality?
[Unknown]: Torino
What is the name of your State or Province?
[Unknown]: TO
What is the two-letter country code for this unit?
[Unknown]: IT
Is CN=*.domain.com, OU=Unit, O=Domain, L=Torino, ST=TO, C=IT correct?
[no]: yes</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above command will generate a self signed certificate and private key for <code>domain.com</code> and subdomains, stored in the <code>keystore.p12</code> file in PKCS#12 format.
We need to extract the certificate and the private key in PEM format.</p>
</div>
<div class="paragraph">
<p>To extract the certificate into <code>certificate.pem</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ keytool -exportcert -keystore keystore.p12 -storetype pkcs12 -storepass storepwd -rfc -file certificate.pem</code></pre>
</div>
</div>
<div class="paragraph">
<p>To export the private key into <code>private_key.pem</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ openssl pkcs12 -in keystore.p12 -nodes -nocerts -out private_key.pem -passin pass:storepwd</code></pre>
</div>
</div>
<div class="paragraph">
<p>At this point you just need to concatenate the two files into one, in the correct order:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cat certificate.pem private_key.pem &gt; domain.pem</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>domain.pem</code> file will be used later by HAProxy.</p>
</div>
</div>
<div class="sect3">
<h4 id="http2-haproxy-cfg"><a class="anchor" href="#http2-haproxy-cfg"></a><a class="link" href="#http2-haproxy-cfg">HAProxy Configuration File</a></h4>
<div class="paragraph">
<p>Now we can setup <code>haproxy.cfg</code> to configure HAProxy.
This is a minimal configuration:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>global
tune.ssl.default-dh-param 1024
defaults
timeout connect 10000ms
timeout client 60000ms
timeout server 60000ms
frontend fe_http
mode http
bind *:80
# Redirect to https
redirect scheme https code 301
frontend fe_https
mode tcp
bind *:443 ssl no-sslv3 crt domain.pem ciphers TLSv1.2 alpn h2,http/1.1
default_backend be_http
backend be_http
mode tcp
server domain 127.0.0.1:8282</code></pre>
</div>
</div>
<div class="paragraph">
<p>The HAProxy configuration file works in the following way.
The <code>fe_http</code> front-end accepts connections on port 80 and redirects them to use the <code>https</code> scheme.</p>
</div>
<div class="paragraph">
<p>The <code>fe_https</code> front-end accepts connections on port 443 and it is where the TLS decryption/encryption happens.
You must specify the path to the PEM file containing the TLS key material (the <code>crt domain.pem</code> part), the ciphers that are suitable for HTTP/2 (the <code>ciphers TLSv1.2</code>), and the ALPN protocols supported (the <code>alpn h2,http/1.1</code> ).
This front-end then forwards the now decrypted bytes to the back-end in <code>mode tcp</code>. The <code>mode tcp</code> says that HAProxy will not try to interpret the bytes as HTTP/1.1 but instead opaquely forward them to the back-end.</p>
</div>
<div class="paragraph">
<p>The <code>be_http</code> back-end will forward (again in <code>mode tcp</code>) the clear-text bytes to a Jetty connector that talks clear-text HTTP/2 and HTTP/1.1 on port 8282.</p>
</div>
</div>
<div class="sect3">
<h4 id="http2-haproxy-jetty"><a class="anchor" href="#http2-haproxy-jetty"></a><a class="link" href="#http2-haproxy-jetty">Setup Jetty for HTTP/2 and HTTP/1.1</a></h4>
<div class="paragraph">
<p>The Jetty setup follows the steps of having Jetty installed in the <code>JETTY_HOME</code> directory, creating a <code>JETTY_BASE</code> directory and initializing it using Jetty&#8217;s command line tools.
You must enable the <code>http2c</code> module, that is the module that speaks clear-text HTTP/2.
Since the <code>http2c</code> module depends on the <code>http</code> module, the <code>http</code> module will be enabled transitively, and the final setup will therefore support both HTTP/2 and HTTP/1.1 in clear text.</p>
</div>
<div class="paragraph">
<p>Additionally, you will also enable the <code>deploy</code> module to be able to deploy a sample web application:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ JETTY_BASE=haproxy-jetty-http2
$ mkdir $JETTY_BASE
$ cd $JETTY_BASE
$ java -jar $JETTY_HOME/start.jar --add-to-start=http2c,deploy</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now let&#8217;s deploy a demo web application and start Jetty:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cd $JETTY_BASE
$ cp $JETTY_HOME/demo-base/webapps/async-rest.war $JETTY_BASE/webapps/
$ java -jar $JETTY_HOME/start.jar jetty.http.host=127.0.0.1 jetty.http.port=8282</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now you can browse <a href="https://domain.com/async-rest" class="bare">https://domain.com/async-rest</a> (replace <code>domain.com</code> with your own domain, or with <code>localhost</code>, to make this example work).</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
You want the Jetty connector that listens on port 8282 to be available only to HAProxy, and not to remote clients.
For this reason, you want to specify the <code>jetty.http.host</code> property on the command line (or in <code>start.ini</code>/ <code>start.d/http.ini</code> to make this setting persistent) to bind the Jetty connector only on the loopback interface (127.0.0.1), making it available to HAProxy but not to remote clients.
If your Jetty instance runs on a different machine and/or on a different (sub)network, you may want to adjust both the back-end section of the HAProxy configuration file and the <code>jetty.http.host</code> property to match accordingly.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Browsers supporting HTTP/2 will connect to HAProxy, which will decrypt the traffic and send it to Jetty.
Likewise, HTTP/1.1 clients will connect to HAProxy, which will decrypt the traffic and send it to Jetty.</p>
</div>
<div class="paragraph">
<p>The Jetty connector, configured with the <code>http2c</code> module (and therefore transitively with the <code>http</code> module) is able to distinguish whether the incoming bytes are HTTP/2 or HTTP/1.1 and will handle the request accordingly.</p>
</div>
<div class="paragraph">
<p>The response is relayed back to HAProxy, which will encrypt it and send it back to the remote client.</p>
</div>
<div class="paragraph">
<p>This configuration offers you efficient TLS offloading, HTTP/2 support and transparent fallback to HTTP/1.1 for clients that don&#8217;t support HTTP/1.1.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="reference-section"><a class="anchor" href="#reference-section"></a><a class="link" href="#reference-section">Jetty XML Reference</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="jetty-xml-usage"><a class="anchor" href="#jetty-xml-usage"></a><a class="link" href="#jetty-xml-usage">Jetty XML Usage</a></h3>
<div class="paragraph">
<p>Jetty provides an XML-based configuration.
It is grounded in Java&#8217;s Reflection API. Classes in the <code>java.lang.reflect</code> represent Java methods and classes, such that you can instantiate objects and invoke their methods based on their names and argument types.
Behind the scenes, Jetty&#8217;s XML config parser translates the XML elements and attributes into Reflection calls.</p>
</div>
<div class="sect3">
<h4 id="using-jettyxml"><a class="anchor" href="#using-jettyxml"></a><a class="link" href="#using-jettyxml">Using jetty.xml</a></h4>
<div class="paragraph">
<p>To use <code>jetty.xml</code>, specify it as a configuration file when running Jetty.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java"> java -jar start.jar etc/jetty.xml</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If you start Jetty without specifying a configuration file, Jetty automatically locates and uses the default installation <code>jetty.xml</code> file.
Therefore <code>java -jar start.jar</code> is equivalent to <code>java -jar start.jar etc/jetty.xml</code> .
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="using-multiple-configuration-files"><a class="anchor" href="#using-multiple-configuration-files"></a><a class="link" href="#using-multiple-configuration-files">Using Multiple Configuration Files</a></h4>
<div class="paragraph">
<p>You are not limited to one configuration file; you can use multiple configuration files when running Jetty, and Jetty will configure the appropriate server instance.
The ID of the server in the <code>&lt;Configure&gt;</code> tag specifies the instance you want to configure.
Each server ID in a configuration file creates a new server instance within the same JVM.
If you use the same ID across multiple configuration files, those configurations are all applied to the same server.</p>
</div>
</div>
<div class="sect3">
<h4 id="setting-parameters-in-configuration-files"><a class="anchor" href="#setting-parameters-in-configuration-files"></a><a class="link" href="#setting-parameters-in-configuration-files">Setting Parameters in Configuration Files</a></h4>
<div class="paragraph">
<p>You can set parameters in configuration files either with system properties (using <code>&lt;SystemProperty&gt;</code>) or properties files (using <code>&lt;Property&gt;</code>) passed via the command line.
For example, this code in <code>jetty.xml</code> allows the port to be defined on the command line, falling back onto `8080`if the port is not specified:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;Set name="port"&gt;&lt;SystemProperty name="jetty.http.port" default="8080"/&gt;&lt;/Set&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then you modify the port while running Jetty by using this command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java"> java -Djetty.http.port=8888 -jar start.jar etc/jetty.xml</code></pre>
</div>
</div>
<div class="paragraph">
<p>An example of defining both system properties and properties files from the command line:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java"> java -Djetty.http.port=8888 -jar start.jar myjetty.properties etc/jetty.xml etc/other.xml</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jetty-xml-config"><a class="anchor" href="#jetty-xml-config"></a><a class="link" href="#jetty-xml-config">jetty.xml</a></h3>
<div class="paragraph">
<p><code>jetty.xml</code> is the default configuration file for Jetty, typically located at <code>$JETTY_HOME/etc/jetty.xml</code>. Usually the <code>jetty.xml</code> configures:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The Server class (or subclass if extended) and global options.</p>
</li>
<li>
<p>A ThreadPool (min and max thread).</p>
</li>
<li>
<p>Connectors (ports, timeouts, buffer sizes, protocol).</p>
</li>
<li>
<p>The handler structure (default handlers and/or a contextHandlerCollections).</p>
</li>
<li>
<p>The deployment manager that scans for and deploys webapps and contexts.</p>
</li>
<li>
<p>Login services that provide authentication checking.</p>
</li>
<li>
<p>A request log.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Not all Jetty features are configured in <code>jetty.xml</code>.
There are several optional configuration files that share the same format as <code>jetty.xml</code> and, if specified, concatenate to it.
These configuration files are also stored in <code>$JETTY_HOME/etc/</code>, and examples of them are in <a href="http://github.com/eclipse/jetty.project/jetty-server/src/main/config/etc/">Github Repository</a>.
The selection of which configuration files to use is controlled by <code>start.jar</code> and the process of merging configuration is described in <a href="#jetty-xml-usage">Jetty XML Usage</a>.</p>
</div>
<div class="sect3">
<h4 id="root-element-jetty-xml"><a class="anchor" href="#root-element-jetty-xml"></a><a class="link" href="#root-element-jetty-xml">Root Element</a></h4>
<div class="paragraph">
<p><code>jetty.xml</code> configures an instance of the <code>Jetty org.eclipse.jetty.server.Server.</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
...
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="jetty-xml-examples"><a class="anchor" href="#jetty-xml-examples"></a><a class="link" href="#jetty-xml-examples">Examples</a></h4>
<div class="paragraph">
<p><code>$JETTY_HOME/etc</code> contains the default <code>jetty.xml</code>, as well as other sample configuration files (<code>jetty-*.xml</code>) which can be passed to the server via the command line.</p>
</div>
</div>
<div class="sect3">
<h4 id="jetty-xml-additional-resources"><a class="anchor" href="#jetty-xml-additional-resources"></a><a class="link" href="#jetty-xml-additional-resources">Additional Resources</a></h4>
<div class="ulist">
<ul>
<li>
<p><a href="#jetty-xml-syntax">[jetty-xml-syntax]</a> –in-depth reference for Jetty-specific configuration XML syntax.</p>
</li>
<li>
<p><a href="#jetty-xml-config">jetty.xml</a> –configuration file for configuring the entire server</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jetty-web-xml-config"><a class="anchor" href="#jetty-web-xml-config"></a><a class="link" href="#jetty-web-xml-config">jetty-web.xml</a></h3>
<div class="paragraph">
<p><code>jetty-web.xml</code> is a Jetty configuration file that you can bundle with a specific web application.
The format of <code>jetty-web.xml</code> is the same as <a href="#jetty-xml-config">jetty.xml</a> – it is an XML mapping of the Jetty API.</p>
</div>
<div class="paragraph">
<p>This document offers an overview for using the <code>jetty-web.xml</code> configuration file.
For a more in-depth look at the syntax, see <a href="#jetty-xml-syntax">[jetty-xml-syntax]</a>.</p>
</div>
<div class="sect3">
<h4 id="root-element-jetty-web-xml"><a class="anchor" href="#root-element-jetty-web-xml"></a><a class="link" href="#root-element-jetty-web-xml">Root Element</a></h4>
<div class="paragraph">
<p><code>jetty-web.xml</code> applies on a per-webapp basis, and configures an instance of <code>org.eclipse.jetty.webapp.WebAppContext</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
..
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock caution">
<table>
<tr>
<td class="icon">
<i class="fa icon-caution" title="Caution"></i>
</td>
<td class="content">
Make sure you are applying the configuration to an instance of the proper class. <code>jetty-web.xml</code> configures an instance of <code>WebAppContext</code>; <code>jetty.xml</code> configures an instance of <code>Server</code>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="using-jetty-web-xml"><a class="anchor" href="#using-jetty-web-xml"></a><a class="link" href="#using-jetty-web-xml">Using jetty-web.xml</a></h4>
<div class="paragraph">
<p>Place the <code>jetty-web.xml</code> into your web application&#8217;s <code>WEB-INF</code> folder.
When Jetty deploys a web application, it looks for a file called <code>WEB-INF/jetty-web.xml</code> or <code>WEB-INF/web-jetty.xml</code> within the web application (or WAR) and applies the configuration found there.
Be aware that <code>jetty-web.xml</code> is called <em>after</em> all other configuration has been applied to the web application.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
It is important to note that <code>jetty-web.xml</code> files utilize the webapp classpath, not the classpath of the server.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="jetty-web-xml-examples"><a class="anchor" href="#jetty-web-xml-examples"></a><a class="link" href="#jetty-web-xml-examples">jetty-web.xml Examples</a></h4>
<div class="paragraph">
<p>The distribution contains an example of <code>jetty-web.xml</code> inside the WEB-INF folder of the <code>test</code> webapp WAR (<code>$JETTY_HOME/demo-base/webapps/test.war/WEB-INF/jetty-web.xml</code>).</p>
</div>
</div>
<div class="sect3">
<h4 id="additional-jetty-web-xml-resources"><a class="anchor" href="#additional-jetty-web-xml-resources"></a><a class="link" href="#additional-jetty-web-xml-resources">Additional <code>jetty-web.xml</code> Resources</a></h4>
<div class="ulist">
<ul>
<li>
<p><a href="#jetty-xml-syntax">[jetty-xml-syntax]</a> –in-depth reference for Jetty-specific configuration XML syntax.</p>
</li>
<li>
<p><a href="#jetty-xml-config">jetty.xml</a> –configuration file for configuring the entire server</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jetty-env-xml"><a class="anchor" href="#jetty-env-xml"></a><a class="link" href="#jetty-env-xml">jetty-env.xml</a></h3>
<div class="paragraph">
<p><code>jetty-env.xml</code> is an optional Jetty file that configures JNDI resources for an individual webapp.
The format of <code>jetty-env.xml</code> is the same as <a href="#jetty-xml-config">jetty.xml</a> –it is an XML mapping of the Jetty API.</p>
</div>
<div class="paragraph">
<p>When Jetty deploys a web application, it automatically looks for a file called ` WEB-INF/jetty-env.xml` within the web application (or WAR), and sets up the webapp naming environment so that naming references in the <code>WEB-INF/web.xml</code> file can be resolved from the information provided in the <code>WEB-INF/jetty-env.xml</code> and <a href="#jetty-xml-config">jetty.xml</a> files.
You define global naming resources on the server via <code>jetty.xml</code>.</p>
</div>
<div class="sect3">
<h4 id="jetty-env-root-element"><a class="anchor" href="#jetty-env-root-element"></a><a class="link" href="#jetty-env-root-element">jetty-env.xml Root Element</a></h4>
<div class="paragraph">
<p>Jetty applies <code>jetty-env.xml</code> on a per-webapp basis, and configures an instance of <code>org.eclipse.jetty.webapp.WebAppContext.</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
..
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock caution">
<table>
<tr>
<td class="icon">
<i class="fa icon-caution" title="Caution"></i>
</td>
<td class="content">
Make sure you are applying the configuration to an instance of the proper class. <code>jetty-env.xml</code> configures an instance of WebAppContext, and not an instance of Server.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="using-jetty-env-xml"><a class="anchor" href="#using-jetty-env-xml"></a><a class="link" href="#using-jetty-env-xml">Using <code>jetty-env.xml</code></a></h4>
<div class="paragraph">
<p>Place the <code>jetty-env.xml</code> file in your web application&#8217;s WEB-INF folder.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd"&gt;
&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;!-- Add an EnvEntry only valid for this webapp --&gt;
&lt;New id="gargle" class="org.eclipse.jetty.plus.jndi.EnvEntry"&gt;
&lt;Arg&gt;gargle&lt;/Arg&gt;
&lt;Arg type="java.lang.Double"&gt;100&lt;/Arg&gt;
&lt;Arg type="boolean"&gt;true&lt;/Arg&gt;
&lt;/New&gt;
&lt;!-- Add an override for a global EnvEntry --&gt;
&lt;New id="wiggle" class="org.eclipse.jetty.plus.jndi.EnvEntry"&gt;
&lt;Arg&gt;wiggle&lt;/Arg&gt;
&lt;Arg type="java.lang.Double"&gt;55.0&lt;/Arg&gt;
&lt;Arg type="boolean"&gt;true&lt;/Arg&gt;
&lt;/New&gt;
&lt;!-- an XADataSource --&gt;
&lt;New id="mydatasource99" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;jdbc/mydatasource99&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="com.atomikos.jdbc.SimpleDataSourceBean"&gt;
&lt;Set name="xaDataSourceClassName"&gt;org.apache.derby.jdbc.EmbeddedXADataSource&lt;/Set&gt;
&lt;Set name="xaDataSourceProperties"&gt;databaseName=testdb99;createDatabase=create&lt;/Set&gt;
&lt;Set name="UniqueResourceName"&gt;mydatasource99&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="additional-jetty-env-xml-resources"><a class="anchor" href="#additional-jetty-env-xml-resources"></a><a class="link" href="#additional-jetty-env-xml-resources">Additional jetty-env.xml Resources</a></h4>
<div class="ulist">
<ul>
<li>
<p><a href="#jetty-xml-syntax">[jetty-xml-syntax]</a> –In-depth reference for Jetty-specific configuration XML syntax.</p>
</li>
<li>
<p><a href="#jetty-xml-config">jetty.xml</a> –Configuration file for configuring the entire server.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="webdefault-xml"><a class="anchor" href="#webdefault-xml"></a><a class="link" href="#webdefault-xml">webdefault.xml</a></h3>
<div class="paragraph">
<p>The <code>webdefault.xml</code> file saves web applications from having to define a lot of house-keeping and container-specific elements in their own <code>web.xml</code> files.
For example, you can use it to set up MIME-type mappings and JSP servlet-mappings.
Jetty applies <code>webdefault.xml</code> to a web application <em>before</em> the application&#8217;s own <code>WEB-INF/web.xml</code>, which means that it <strong>cannot</strong> override values inside the webapp&#8217;s <code>web.xml</code>.
It uses the <a href="#jetty-xml-config">jetty.xml</a> syntax.
Generally, it is convenient for all webapps in a Jetty instance to share the same <code>webdefault.xml</code> file.
However, it is certainly possible to provide differentiated ` webdefault.xml` files for individual web applications.</p>
</div>
<div class="paragraph">
<p>The <code>webdefault.xml</code> file is located in <code>$(jetty.home)/etc/webdefault.xml</code>.</p>
</div>
<div class="sect3">
<h4 id="using-webdefault-xml"><a class="anchor" href="#using-webdefault-xml"></a><a class="link" href="#using-webdefault-xml">Using webdefault.xml</a></h4>
<div class="paragraph">
<p>You can specify a custom configuration file to use for specific webapps, or for all webapps. If you do not specify an alternate defaults descriptor, the <code>$JETTY-HOME/etc/jetty-deploy.xml</code> file will configure jetty to automatically use <code>$JETTY_HOME/etc/webdefault.xml</code>.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
To ensure your <code>webdefault.xml</code> files are validated, you will need to set the <code>validateXml</code> attribute to true as described <a href="#jetty-xml-dtd">here.</a>
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>The <code>webdefault.xml</code> <a href="{GITBROWSURL}/jetty-webapp/src/main/config/etc/webdefault.xml">included with the Jetty Distribution</a> contains several configuration options, such as init params and servlet mappings, and is separated into sections for easy navigation.
Some of the more common options include, but are not limited to:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">dirAllowed</dt>
<dd>
<p>If true, directory listings are returned if no welcome file is found.
Otherwise 403 Forbidden displays.</p>
</dd>
<dt class="hdlist1">precompressed</dt>
<dd>
<p>If set to a comma separated list of file extensions, these indicate compressed formats that are known to map to a MIME-type that may be listed in a requests Accept-Encoding header.
If set to a boolean True, then a default set of compressed formats will be used, otherwise no pre-compressed formats.</p>
</dd>
<dt class="hdlist1">maxCacheSize</dt>
<dd>
<p>Maximum total size of the cache or 0 for no cache.</p>
</dd>
<dt class="hdlist1">maxCachedFileSize</dt>
<dd>
<p>Maximum size of a file to cache.</p>
</dd>
<dt class="hdlist1">maxCachedFiles</dt>
<dd>
<p>Maximum number of files to cache.</p>
</dd>
</dl>
</div>
<div class="sect4">
<h5 id="creating-custom-webdefault-xml-one-webapp"><a class="anchor" href="#creating-custom-webdefault-xml-one-webapp"></a><a class="link" href="#creating-custom-webdefault-xml-one-webapp">Creating a Custom webdefault.xml for One WebApp</a></h5>
<div class="paragraph">
<p>You can specify a custom <code>webdefault.xml</code> for an individual web application in that webapp&#8217;s <a href="#jetty-xml-config">jetty.xml</a> as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
...
&lt;!-- Set up the absolute path to the custom webdefault.xml --&gt;
&lt;Set name="defaultsDescriptor"&gt;/my/path/to/webdefault.xml&lt;/Set&gt;
...
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The equivalent in code is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import org.eclipse.jetty.webapp.WebAppContext;
...
WebAppContext wac = new WebAppContext();
...
//Set up the absolute path to the custom webdefault.xml.
wac.setDefaultsDescriptor("/my/path/to/webdefault.xml");
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>Alternatively, you can use a <a href="#jetty-classloading">Jetty Classloading</a> to find the resource representing your custom <code>webdefault.xml</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="creating-custom-webdefault-xml-multiple-webapps"><a class="anchor" href="#creating-custom-webdefault-xml-multiple-webapps"></a><a class="link" href="#creating-custom-webdefault-xml-multiple-webapps">Creating a Custom webdefault.xml for Multiple WebApps</a></h5>
<div class="paragraph">
<p>If you want to apply the same custom <code>webdefault.xml</code> to a number of webapps, provide the path to the file in <a href="#jetty-xml-config">jetty.xml</a> in the <code>$JETTY_HOME/etc/jetty-deploy.xml</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;Set name="defaultsDescriptor"&gt;&lt;Property name="jetty.home" default="." /&gt;/other/path/to/another/webdefault.xml&lt;/Set&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="webdefault-xml-using-jetty-maven-plugin"><a class="anchor" href="#webdefault-xml-using-jetty-maven-plugin"></a><a class="link" href="#webdefault-xml-using-jetty-maven-plugin">Using the Jetty Maven Plugin</a></h5>
<div class="paragraph">
<p>Similarly, when using the <a href="#jetty-maven-plugin">Jetty Maven Plugin</a> you provide a customized <code>webdefault.xml</code> file for your webapp as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project&gt;
...
&lt;plugins&gt;
&lt;plugin&gt;
...
&lt;artifactId&gt;jetty-maven-plugin&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;webApp&gt;
...
&lt;defaultsDescriptor&gt;/my/path/to/webdefault.xml&lt;/defaultsDescriptor&gt;
&lt;/webApp&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
...
&lt;/plugins&gt;
...
&lt;/project&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="webdefault-xml-additional-resources"><a class="anchor" href="#webdefault-xml-additional-resources"></a><a class="link" href="#webdefault-xml-additional-resources">Additional Resources</a></h5>
<div class="ulist">
<ul>
<li>
<p><a href="#jetty-web-xml-config">jetty-web.xml</a> –Reference for <code>web.xml</code> files</p>
</li>
<li>
<p><a href="#override-web-xml">Jetty override-web.xml</a> –Information for this <code>web.xml</code> -formatted file, applied after the webapp&#8217;s <code>web.xml</code> webapp.</p>
</li>
<li>
<p><a href="#jetty-xml-config">jetty.xml</a> –Reference for <code>jetty.xml</code> files</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="override-web-xml"><a class="anchor" href="#override-web-xml"></a><a class="link" href="#override-web-xml">Jetty override-web.xml</a></h3>
<div class="paragraph">
<p>To deploy a web application or WAR into different environments, most likely you will need to customize the webapp for compatibility with each environment.
The challenge is to do so without changing the webapp itself. You can use a <code>jetty.xml</code> file for some of this work since it is not part of the webapp.
But there are some changes that <code>jetty.xml</code> cannot accomplish, for example, modifications to servlet init-params and context init-params.
Using <code>webdefault.xml</code> is not an option because Jetty applies <code>webdefault.xml</code> to a web application <em>before</em> the application&#8217;s own <code>WEB-INF/web.xml</code>, which means that it cannot override values inside the webapp&#8217;s ` web.xml`.</p>
</div>
<div class="paragraph">
<p>The solution is <code>override-web.xml</code>.
It is a <code>web.xml</code> file that Jetty applies to a web application <em>after</em> the application&#8217;s own <code>WEB-INF/web.xml</code>, which means that it can override values or add new elements.
This is defined on a per-webapp basis, using the <a href="#jetty-xml-syntax">[jetty-xml-syntax]</a>.</p>
</div>
<div class="sect3">
<h4 id="using-override-web-xml"><a class="anchor" href="#using-override-web-xml"></a><a class="link" href="#using-override-web-xml">Using override-web.xml</a></h4>
<div class="paragraph">
<p>You can specify the <code>override-web.xml</code> to use for an individual web application in a deployable xml file located in Jetty webapps folder .
For example, if you had a webapp named MyApp, you would place a deployable xml file named <code>myapp.xml</code> in <code>${jetty.base}/webapps</code> which includes an <code>overrideDescriptor</code> entry for the <code>override-web.xml</code> file.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
...
&lt;!-- Set up the path to the custom override descriptor,
relative to your $(jetty.home) directory or to the current directory --&gt;
&lt;Set name="overrideDescriptor"&gt;&lt;SystemProperty name="jetty.home" default="."/&gt;/my/path/to/override-web.xml&lt;/Set&gt;
...
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The equivalent in code is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import org.eclipse.jetty.webapp.WebAppContext;
...
WebAppContext wac = new WebAppContext();
...
//Set the path to the override descriptor, based on your $(jetty.home) directory
wac.setOverrideDescriptor(System.getProperty("jetty.home")+"/my/path/to/override-web.xml");
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>Alternatively, you can use the classloader (<a href="#jetty-classloading">Jetty Classloading</a>) to get the path to the override descriptor as a resource.</p>
</div>
</div>
<div class="sect3">
<h4 id="override-using-jetty-maven-plugin"><a class="anchor" href="#override-using-jetty-maven-plugin"></a><a class="link" href="#override-using-jetty-maven-plugin">Using the Jetty Maven Plugin</a></h4>
<div class="paragraph">
<p>Use the <code>&lt;overrideDescriptor&gt;</code> tag as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;project&gt;
...
&lt;plugins&gt;
&lt;plugin&gt;
...
&lt;artifactId&gt;jetty-maven-plugin&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;webAppConfig&gt;
...
&lt;overrideDescriptor&gt;src/main/resources/override-web.xml&lt;/overrideDescriptor&gt;
&lt;/webAppConfig&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
...
&lt;/plugins&gt;
...
&lt;/project&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="override-web-xml-additional-resources"><a class="anchor" href="#override-web-xml-additional-resources"></a><a class="link" href="#override-web-xml-additional-resources">Additional Resources</a></h4>
<div class="ulist">
<ul>
<li>
<p><a href="#webdefault-xml">webdefault.xml</a> –Information for this <code>web.xml</code> -formatted file, applied before the webapp&#8217;s <code>web.xml</code> webapp.</p>
</li>
<li>
<p><a href="#jetty-xml-config">jetty.xml</a> –Reference for <code>jetty.xml</code> files</p>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="jmx-chapter"><a class="anchor" href="#jmx-chapter"></a><a class="link" href="#jmx-chapter">Java Management Extensions (JMX)</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <a href="http://java.sun.com/products/JavaManagement/">Java Management Extensions (JMX) API</a> is a standard API for managing and monitoring resources such as applications, devices, services, and the Java virtual machine.</p>
</div>
<div class="paragraph">
<p>Typical uses of the JMX technology include:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Consulting and changing application configuration</p>
</li>
<li>
<p>Accumulating and making available statistics about application behavior</p>
</li>
<li>
<p>Notifying of state changes and erroneous conditions</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The JMX API includes remote access, so a remote management program can interact with a running application for these purposes.</p>
</div>
<div class="sect2">
<h3 id="using-jmx"><a class="anchor" href="#using-jmx"></a><a class="link" href="#using-jmx">Using JMX with Jetty</a></h3>
<div class="paragraph">
<p>Jetty&#8217;s architecture is based on POJO components (see <a href="#basic-architecture">[basic-architecture]</a>).
These components are organized in a tree and each component may have a lifecycle that spans the <code>Server</code> lifetime, or a web application lifetime, or even shorter lifetimes such as that of a TCP connection.</p>
</div>
<div class="paragraph">
<p>Every time a component is added or removed from the component tree, an event is emitted, and <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/util/component/Container.html"><code>Container.Listener</code></a> implementations can listen to those events and perform additional actions.</p>
</div>
<div class="paragraph">
<p>One such <code>Container.Listener</code> is <code>MBeanContainer</code> that uses <code>ObjectMBean</code> to create an MBean from an arbitrary POJO, and register/unregister the MBean to/from the platform <code>MBeanServer</code>.</p>
</div>
<div class="paragraph">
<p>Jetty components are annotated with <a href="#jetty-jmx-annotations">Jetty JMX Annotations</a> and provide specific JMX details so that <code>ObjectMBean</code> can build a more precise representation of the JMX metadata associated with the component POJO.</p>
</div>
<div class="paragraph">
<p>Therefore, when a component is added to the component tree, <code>MBeanContainer</code> is notified, it creates the MBean from the component POJO and registers it to the <code>MBeanServer</code>.
Similarly, when a component is removed from the tree, <code>MBeanContainer</code> is notified, and unregisters the MBean from the <code>MBeanServer</code>.</p>
</div>
<div class="paragraph">
<p>The Jetty MBeans can be accessed via any JMX console such as Java Mission Control (JMC), VisualVM, JConsole or others.</p>
</div>
<div class="sect3">
<h4 id="configuring-jmx"><a class="anchor" href="#configuring-jmx"></a><a class="link" href="#configuring-jmx">Configuring JMX</a></h4>
<div class="paragraph">
<p>This guide describes the various ways to initialize and configure the Jetty JMX integration.
Configuring the Jetty JMX integration only registers the Jetty MBeans into the platform <code>MBeanServer</code>, and therefore the MBeans can only be accessed locally (from the same machine), not from remote machines.</p>
</div>
<div class="paragraph">
<p>This means that this configuration is enough for development, where you have easy access (with graphical user interface) to the machine where Jetty runs, but it is typically not enough when the machine Jetty where runs is remote, or only accessible via SSH or otherwise without graphical user interface support.
In these cases, you have to enable <a href="#jmx-remote-access">JMX Remote Access</a>.</p>
</div>
<div class="sect4">
<h5 id="jmx-standalone-jetty"><a class="anchor" href="#jmx-standalone-jetty"></a><a class="link" href="#jmx-standalone-jetty">Standalone Jetty Server</a></h5>
<div class="paragraph">
<p>JMX is not enabled by default in the Jetty distribution.
To enable JMX in the Jetty distribution run the following, where <code>{$jetty.home}</code> is the directory where you have the Jetty distribution installed, and <code>${jetty.base}</code> is the directory where you have your Jetty configuration (see <a href="#startup-base-and-home">the documentation for Jetty base vs. home examples</a>):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cd ${jetty.base}
$ java -jar {$jetty.home}/start.jar --add-to-start=jmx</code></pre>
</div>
</div>
<div class="paragraph">
<p>Running the above command will append the available configurable elements of the <code>jmx</code> module to the <code>{$jetty.base}/start.ini</code> file, or create the <code>${jetty.base}/start.d/jmx.ini</code> file.</p>
</div>
</div>
<div class="sect4">
<h5 id="jmx-embedded-jetty"><a class="anchor" href="#jmx-embedded-jetty"></a><a class="link" href="#jmx-embedded-jetty">Embedded Jetty Server</a></h5>
<div class="paragraph">
<p>When running Jetty embedded into an application, create and configure an <code>MBeanContainer</code> instance as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Server server = new Server();
// Setup JMX.
MBeanContainer mbeanContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
server.addBean(mbeanContainer);
// Export the loggers as MBeans.
server.addBean(Log.getLog());</code></pre>
</div>
</div>
<div class="paragraph">
<p>Because logging is initialized prior to the <code>MBeanContainer</code> (even before the <code>Server</code> itself), it is necessary to register the logger manually via <code>server.addBean()</code> so that the loggers may show up in the JMX tree as MBeans.</p>
</div>
</div>
<div class="sect4">
<h5 id="jmx-jetty-maven-plugin"><a class="anchor" href="#jmx-jetty-maven-plugin"></a><a class="link" href="#jmx-jetty-maven-plugin">Using the Jetty Maven Plugin with JMX</a></h5>
<div class="paragraph">
<p>If you are using the <a href="#jetty-maven-plugin">Jetty Maven plugin</a> you should copy the <code>${jetty.home}/etc/jetty-jmx.xml</code> file into your webapp project somewhere, such as <code>src/main/config/etc/</code>, then add a <code>&lt;jettyXml&gt;</code> element to the <code>&lt;configuration&gt;</code> element of the Jetty Maven Plugin:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;plugin&gt;
&lt;groupid&gt;org.eclipse.jetty&lt;/groupid&gt;
&lt;artifactid&gt;jetty-maven-plugin&lt;/artifactid&gt;
&lt;version&gt;10.0.0-SNAPSHOT&lt;/version&gt;
&lt;configuration&gt;
&lt;scanintervalseconds&gt;10&lt;/scanintervalseconds&gt;
&lt;jettyXml&gt;src/main/config/etc/jetty-jmx.xml&lt;/jettyXml&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="accessing-jetty-mbeans"><a class="anchor" href="#accessing-jetty-mbeans"></a><a class="link" href="#accessing-jetty-mbeans">Using JConsole or Java Mission Control to Access Jetty MBeans</a></h4>
<div class="paragraph">
<p>The simplest way to access the MBeans that Jetty publishes is to use <a href="#jetty-jconsole">Java Mission Control (JMC) or JConsole.</a></p>
</div>
<div class="paragraph">
<p>Both these tools can connect to local or remote JVMs to display the MBeans.</p>
</div>
<div class="paragraph">
<p>For local access, you just need to start JConsole or JMC and then choose from their user interface the local JVM you want to connect to.</p>
</div>
<div class="paragraph">
<p>For remote access, you need first to enable JMX Remote Access in Jetty.</p>
</div>
</div>
<div class="sect3">
<h4 id="jmx-remote-access"><a class="anchor" href="#jmx-remote-access"></a><a class="link" href="#jmx-remote-access">Enabling JMX Remote Access</a></h4>
<div class="paragraph">
<p>There are two ways of enabling remote connectivity so that JConsole or JMC can connect to the remote JVM to visualize MBeans.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Use the <code>com.sun.management.jmxremote</code> system property on the command line.
Unfortunately, this solution does not work well with firewalls and is not flexible.</p>
</li>
<li>
<p>Use Jetty&#8217;s <code>jmx-remote</code> module or - equivalently - the <code>ConnectorServer</code> class.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p><code>ConnectorServer</code> will use by default RMI to allow connection from remote clients,
and it is a wrapper around the standard JDK class <code>JMXConnectorServer</code>, which is the class that provides remote access to JMX clients.</p>
</div>
<div class="paragraph">
<p>Connecting to the remote JVM is a two step process:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>First, the client will connect to the RMI <em>registry</em> to download the RMI stub for the <code>JMXConnectorServer</code>; this RMI stub contains the IP address and port to connect to the RMI server, i.e. the remote <code>JMXConnectorServer</code>.</p>
</li>
<li>
<p>Second, the client uses the RMI stub to connect to the RMI <em>server</em> (i.e. the remote <code>JMXConnectorServer</code>) typically on an address and port that may be different from the RMI registry address and port.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The configuration for the RMI registry and the RMI server is specified by a <code>JMXServiceURL</code>.
The string format of an RMI <code>JMXServiceURL</code> is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">service:jmx:rmi://&lt;rmi_server_host&gt;:&lt;rmi_server_port&gt;/jndi/rmi://&lt;rmi_registry_host&gt;:&lt;rmi_registry_port&gt;/jmxrmi</code></pre>
</div>
</div>
<div class="paragraph">
<p>Default values are:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">rmi_server_host = localhost
rmi_server_port = 1099
rmi_registry_host = localhost
rmi_registry_port = 1099</code></pre>
</div>
</div>
<div class="paragraph">
<p>With the default configuration, only clients that are local to the server machine can connect to the RMI registry and RMI server - this is done for security reasons.
With this configuration it would still be possible to access the MBeans from remote using a <a href="#jmx-remote-access-ssh-tunnel">SSH tunnel.</a></p>
</div>
<div class="paragraph">
<p>By specifying an appropriate <code>JMXServiceURL</code>, you can fine tune the network interfaces the RMI registry and the RMI server bind to, and the ports that the RMI registry and the RMI server listen to.
The RMI server and RMI registry hosts and ports can be the same (as in the default configuration) because RMI is able to multiplex traffic arriving to a port to multiple RMI objects.</p>
</div>
<div class="paragraph">
<p>If you need to allow JMX remote access through a firewall, you must open both the RMI registry and the RMI server ports.</p>
</div>
<div class="paragraph">
<p>Examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">service:jmx:rmi:///jndi/rmi:///jmxrmi
rmi_server_host = local host address
rmi_server_port = randomly chosen
rmi_registry_host = local host address
rmi_registry_port = 1099
service:jmx:rmi://0.0.0.0:1099/jndi/rmi://0.0.0.0:1099/jmxrmi
rmi_server_host = any address
rmi_server_port = 1099
rmi_registry_host = any address
rmi_registry_port = 1099
service:jmx:rmi://localhost:1100/jndi/rmi://localhost:1099/jmxrmi
rmi_server_host = loopback address
rmi_server_port = 1100
rmi_registry_host = loopback address
rmi_registry_port = 1099</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>When <code>ConnectorServer</code> is started, its RMI stub is exported to the RMI registry.
The RMI stub contains the IP address and port to connect to the RMI object, but the IP address is typically the machine host name, not the host specified in the <code>JMXServiceURL</code>.</p>
</div>
<div class="paragraph">
<p>To control the IP address stored in the RMI stub you need to set the system property <code>java.rmi.server.hostname</code> with the desired value.
This is especially important when binding the RMI server host to the loopback address for security reasons. See also <a href="#jmx-remote-access-ssh-tunnel">JMX Remote Access via SSH Tunnel.</a></p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect4">
<h5 id="_enabling-jmx-remote-access-in-standalone-jetty-server"><a class="anchor" href="#_enabling-jmx-remote-access-in-standalone-jetty-server"></a><a class="link" href="#_enabling-jmx-remote-access-in-standalone-jetty-server">Enabling JMX Remote Access in Standalone Jetty Server</a></h5>
<div class="paragraph">
<p>Similarly to <a href="#jmx-standalone-jetty">enabling JMX in a standalone Jetty server</a>, you enable the <code>jmx-remote</code> module:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cd ${jetty.base}
$ java -jar {$jetty.home}/start.jar --add-to-start=jmx-remote</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_enabling-jmx-remote-access-in-embedded-jetty"><a class="anchor" href="#_enabling-jmx-remote-access-in-embedded-jetty"></a><a class="link" href="#_enabling-jmx-remote-access-in-embedded-jetty">Enabling JMX Remote Access in Embedded Jetty</a></h5>
<div class="paragraph">
<p>When running Jetty embedded into an application, create and configure a <code>ConnectorServer</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Server server = new Server();
// Setup JMX
MBeanContainer mbeanContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
server.addBean(mbeanContainer);
// Setup ConnectorServer
JMXServiceURL jmxURL = new JMXServiceURL("rmi", null, 1999, "/jndi/rmi:///jmxrmi");
ConnectorServer jmxServer = new ConnectorServer(jmxURL, "org.eclipse.jetty.jmx:name=rmiconnectorserver");
server.addBean(jmxServer);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>JMXServiceURL</code> above specifies that the RMI server binds to the wildcard address on port 1999, while the RMI registry binds to the wildcard address on port 1099 (the default RMI registry port).</p>
</div>
</div>
<div class="sect4">
<h5 id="jmx-remote-access-authorization"><a class="anchor" href="#jmx-remote-access-authorization"></a><a class="link" href="#jmx-remote-access-authorization">JMX Remote Access Authorization</a></h5>
<div class="paragraph">
<p>The standard <code>JMXConnectorServer</code> provides several options to authorize access.
For a complete guide to controlling authentication and authorization in JMX, see <a href="https://blogs.oracle.com/lmalventosa/entry/jmx_authentication_authorization">Authentication and Authorization in JMX RMI connectors</a>.</p>
</div>
<div class="paragraph">
<p>To authorize access to the <code>JMXConnectorServer</code> you can use this configuration, where the <code>jmx.password</code> and <code>jmx.access</code> files have the format specified in the blog entry above:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New id="ConnectorServer" class="org.eclipse.jetty.jmx.ConnectorServer"&gt;
&lt;Arg&gt;
&lt;New class="javax.management.remote.JMXServiceURL"&gt;
&lt;Arg type="java.lang.String"&gt;rmi&lt;/Arg&gt;
&lt;Arg type="java.lang.String" /&gt;
&lt;Arg type="java.lang.Integer"&gt;1099&lt;/Arg&gt;
&lt;Arg type="java.lang.String"&gt;/jndi/rmi:///jmxrmi&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;Arg&gt;
&lt;Map&gt;
&lt;Entry&gt;
&lt;Item&gt;jmx.remote.x.access.file&lt;/Item&gt;
&lt;Item&gt;
&lt;New class="java.lang.String"&gt;&lt;Arg&gt;&lt;Property name="jetty.base" default="." /&gt;/resources/jmx.access&lt;/Arg&gt;&lt;/New&gt;
&lt;/Item&gt;
&lt;/Entry&gt;
&lt;Entry&gt;
&lt;Item&gt;jmx.remote.x.password.file&lt;/Item&gt;
&lt;Item&gt;
&lt;New class="java.lang.String"&gt;&lt;Arg&gt;&lt;Property name="jetty.base" default="." /&gt;/resources/jmx.password&lt;/Arg&gt;&lt;/New&gt;
&lt;/Item&gt;
&lt;/Entry&gt;
&lt;/Map&gt;
&lt;/Arg&gt;
&lt;Arg&gt;org.eclipse.jetty.jmx:name=rmiconnectorserver&lt;/Arg&gt;
&lt;Call name="start" /&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Similarly, in code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">JMXServiceURL jmxURL = new JMXServiceURL("rmi", null, 1099, "/jndi/rmi:///jmxrmi");
Map&lt;String, Object&gt; env = new HashMap&lt;&gt;();
env.put("jmx.remote.x.access.file", "resources/jmx.access");
env.put("jmx.remote.x.password.file", "resources/jmx.password");
ConnectorServer jmxServer = new ConnectorServer(jmxURL, env, "org.eclipse.jetty.jmx:name=rmiconnectorserver");
jmxServer.start();</code></pre>
</div>
</div>
<div class="paragraph">
<p>Calling <code>ConnectorServer.start()</code> may be explicit as in the examples above, or can be skipped when adding the <code>ConnectorServer</code> as a bean to the <code>Server</code>, so that starting the <code>Server</code> will also start the <code>ConnectorServer</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="_securing-jmx-remote-access-with-tls"><a class="anchor" href="#_securing-jmx-remote-access-with-tls"></a><a class="link" href="#_securing-jmx-remote-access-with-tls">Securing JMX Remote Access with TLS</a></h5>
<div class="paragraph">
<p>The JMX communication via RMI happens by default in clear-text.</p>
</div>
<div class="paragraph">
<p>It is possible to configure the <code>ConnectorServer</code> with a <code>SslContextFactory</code> so that the JMX communication via RMI is encrypted:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New id="ConnectorServer" class="org.eclipse.jetty.jmx.ConnectorServer"&gt;
&lt;Arg&gt;
&lt;New class="javax.management.remote.JMXServiceURL"&gt;
&lt;Arg type="java.lang.String"&gt;rmi&lt;/Arg&gt;
&lt;Arg type="java.lang.String" /&gt;
&lt;Arg type="java.lang.Integer"&gt;1099&lt;/Arg&gt;
&lt;Arg type="java.lang.String"&gt;/jndi/rmi:///jmxrmi&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;Arg /&gt;
&lt;Arg&gt;org.eclipse.jetty.jmx:name=rmiconnectorserver&lt;/Arg&gt;
&lt;Arg&gt;&lt;Ref refid="sslContextFactory" /&gt;&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Similarly, in code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStorePath("/path/to/keystore");
sslContextFactory.setKeyStorePassword("secret");
JMXServiceURL jmxURL = new JMXServiceURL("rmi", null, 1099, "/jndi/rmi:///jmxrmi");
ConnectorServer jmxServer = new ConnectorServer(jmxURL, null, "org.eclipse.jetty.jmx:name=rmiconnectorserver", sslContextFactory);</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is possible to use the same <code>SslContextFactory</code> used to configure the Jetty <code>ServerConnector</code> that supports TLS for the HTTP protocol.
This is used in the XML example above: the <code>SslContextFactory</code> configured for the TLS <code>ServerConnector</code> is registered with an id of <code>sslContextFactory</code> which is referenced in the XML via the <code>Ref</code> element.</p>
</div>
<div class="paragraph">
<p>The keystore must contain a valid certificate signed by a Certification Authority.</p>
</div>
<div class="paragraph">
<p>The RMI mechanic is the usual one: the RMI client (typically a monitoring console) will connect first to the RMI registry (using TLS), download the RMI server stub that contains the address and port of the RMI server to connect to, then connect to the RMI server (using TLS).</p>
</div>
<div class="paragraph">
<p>This also mean that if the RMI registry and the RMI server are on different hosts, the RMI client must have available the cryptographic material to validate both hosts.</p>
</div>
<div class="paragraph">
<p>Having certificates signed by a Certification Authority simplifies by a lot the configuration needed to get the JMX communication over TLS working properly.</p>
</div>
<div class="paragraph">
<p>If that is not the case (for example the certificate is self-signed), then you need to specify the required system properties that allow RMI (especially when acting as an RMI client) to retrieve the cryptographic material necessary to establish the TLS connection.</p>
</div>
<div class="paragraph">
<p>For example, trying to connect using the JDK standard <code>JMXConnector</code> with both the RMI server and the RMI registry to <code>domain.com</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">// System properties necessary for an RMI client to trust a self-signed certificate.
System.setProperty("javax.net.ssl.trustStore", "/path/to/trustStore");
System.setProperty("javax.net.ssl.trustStorePassword", "secret");
JMXServiceURL jmxURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://domain.com:1100/jmxrmi")
Map&lt;String, Object&gt; clientEnv = new HashMap&lt;&gt;();
// Required to connect to the RMI registry via TLS.
clientEnv.put(ConnectorServer.RMI_REGISTRY_CLIENT_SOCKET_FACTORY_ATTRIBUTE, new SslRMIClientSocketFactory());
try (JMXConnector client = JMXConnectorFactory.connect(jmxURL, clientEnv))
{
Set&lt;ObjectName&gt; names = client.getMBeanServerConnection().queryNames(null, null);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Similarly, to launch JMC:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">$ jmc -vmargs -Djavax.net.ssl.trustStore=/path/to/trustStore -Djavax.net.ssl.trustStorePassword=secret</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that these system properties are required when launching the <code>ConnectorServer</code> too, on the server, because it acts as an RMI client with respect to the RMI registry.</p>
</div>
</div>
<div class="sect4">
<h5 id="jmx-remote-access-ssh-tunnel"><a class="anchor" href="#jmx-remote-access-ssh-tunnel"></a><a class="link" href="#jmx-remote-access-ssh-tunnel">JMX Remote Access with Port Forwarding via SSH Tunnel</a></h5>
<div class="paragraph">
<p>You can access JMX MBeans on a remote machine when the RMI ports are not open, for example because of firewall policies, but you have SSH access to the machine using local port forwarding via a SSH tunnel.</p>
</div>
<div class="paragraph">
<p>In this case you want to configure the <code>ConnectorServer</code> with a <code>JMXServiceURL</code> that binds the RMI server and the RMI registry to the loopback interface only: <code>service:jmx:rmi://localhost:1099/jndi/rmi://localhost:1099/jmxrmi</code>.</p>
</div>
<div class="paragraph">
<p>Then you setup the local port forwarding with the SSH tunnel:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ ssh -L 1099:localhost:1099 &lt;user&gt;@&lt;machine_host&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now you can use JConsole or JMC to connect to <code>localhost:1099</code> on your local computer.
The traffic will be forwarded to <code>machine_host</code> and when there, SSH will forward the traffic to <code>localhost:1099</code>, which is exactly where the <code>ConnectorServer</code> listens.</p>
</div>
<div class="paragraph">
<p>When you configure <code>ConnectorServer</code> in this way, you must set the system property <code>-Djava.rmi.server.hostname=localhost</code>, on the server.</p>
</div>
<div class="paragraph">
<p>This is required because when the RMI server is exported, its address and port are stored in the RMI stub. You want the address in the RMI stub to be <code>localhost</code> so that when the RMI stub is downloaded to the remote client, the RMI communication will go through the SSH tunnel.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jetty-jmx-annotations"><a class="anchor" href="#jetty-jmx-annotations"></a><a class="link" href="#jetty-jmx-annotations">Jetty JMX Annotations</a></h3>
<div class="paragraph">
<p>When the <code>jetty-jmx</code> libraries are present on startup and the wiring is enabled for exposing Jetty MBeans to JMX, there are three annotations that govern when and how MBeans are created and exposed.</p>
</div>
<div class="sect3">
<h4 id="jmx-annotation-introspection"><a class="anchor" href="#jmx-annotation-introspection"></a><a class="link" href="#jmx-annotation-introspection">Annotation Introspection</a></h4>
<div class="paragraph">
<p>When JMX is configured and enabled in Jetty, any time an object is registered with the Server it is introspected as a potential MBean to be exposed.
This introspection proceeds as follows assuming the class is named <code>com.acme.Foo</code>:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>All influences for <code>com.acme.Foo</code> determined.
These include each class in the chain of super classes, and by convention each of these classes following a form of <code>com.acme.jmx.FooMBean</code>.
All super classes and their corresponding MBean representations are then used in the next step.</p>
</li>
<li>
<p>Each potential influencing class is checked for the <code>@ManagedObject</code> annotation.
Should this annotation exist at any point in the chain of influencers then an MBran is created with the description of the version <code>@ManagedObject</code> discovered.</p>
</li>
<li>
<p>Once a MBean has been created for an object then each potential influencing object is introspected for <code>@ManagedAttribute</code> and <code>@ManagedOperation</code> annotations and the corresponding type is exposed to the MBean.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>The convention of looking for <code>@ManagedObject</code> annotations on <code>.jmx.ClassMBean</code> allows for a normal POJOs to be wrapped in an MBean without itself without requiring it being marked up with annotations.
Since the POJO is passed to these wrapped derived Mbean instances and is an internal variable then the MBean can be used to better expose a set of attributes and operations that may not have been anticipated when the original object was created.</p>
</div>
</div>
<div class="sect3">
<h4 id="jmx-managed-object"><a class="anchor" href="#jmx-managed-object"></a><a class="link" href="#jmx-managed-object">@ManagedObject</a></h4>
<div class="paragraph">
<p>The <code>@ManagedObject</code> annotation is used on a class at the top level to indicate that it should be exposed as an MBean.
It has only one attribute to it which is used as the description of the MBean.
Should multiple <code>@ManagedObject</code> annotations be found in the chain of influence then the first description is used.</p>
</div>
<div class="paragraph">
<p>The list of attributes available are:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">value</dt>
<dd>
<p>The description of the Managed Object.</p>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="jmx-managed-attribute"><a class="anchor" href="#jmx-managed-attribute"></a><a class="link" href="#jmx-managed-attribute">@ManagedAttribute</a></h4>
<div class="paragraph">
<p>The <code>@ManagedAttribute</code> annotation is used to indicate that a given method exposes a JMX attribute.
This annotation is placed always on the reader method of a given attribute.
Unless it is marked as read-only in the configuration of the annotation a corresponding setter is looked for following normal naming conventions.
For example if this annotation is on a method called <code>getFoo()</code> then a method called <code>setFoo()</code> would be looked for and if found wired automatically into the JMX attribute.</p>
</div>
<div class="paragraph">
<p>The list of attributes available are:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">value</dt>
<dd>
<p>The description of the Managed Attribute.</p>
</dd>
<dt class="hdlist1">name</dt>
<dd>
<p>The name of the Managed Attribute.</p>
</dd>
<dt class="hdlist1">proxied</dt>
<dd>
<p>Value is true if the corresponding MBean for this object contains the method of this JMX attribute in question.</p>
</dd>
<dt class="hdlist1">readonly</dt>
<dd>
<p>By default this value is false which means that a corresponding setter will be looked for an wired into the attribute should one be found.
Setting this to true make the JMX attribute read only.</p>
</dd>
<dt class="hdlist1">setter</dt>
<dd>
<p>This attribute can be used when the corresponding setter for a JMX attribute follows a non-standard naming convention and it should still be exposed as the setter for the attribute.</p>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="jmx-managed-operation"><a class="anchor" href="#jmx-managed-operation"></a><a class="link" href="#jmx-managed-operation">@ManagedOperation</a></h4>
<div class="paragraph">
<p>The <code>@ManagedOperation</code> annotation is used to indicate that a given method should be considered a JMX operation.</p>
</div>
<div class="paragraph">
<p>The list of attributes available are:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">value</dt>
<dd>
<p>The description of the Managed Operation.</p>
</dd>
<dt class="hdlist1">impact</dt>
<dd>
<p>The impact of an operation.
By default this value is "UNKNOWN" and acceptable values are "ACTION", "INFO", "ACTION_INFO" and should be used according to their definitions with JMX.</p>
</dd>
<dt class="hdlist1">proxied</dt>
<dd>
<p>Value is true if the corresponding MBean for this object contains the method of this JMX operation in question.</p>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="jmx-name-annotation"><a class="anchor" href="#jmx-name-annotation"></a><a class="link" href="#jmx-name-annotation">@Name</a></h4>
<div class="paragraph">
<p>A fourth annotation is often used in conjunction with the JMX annotations mentioned above.
This annotation is used to describe variables in method signatures so that when rendered into tools like JConsole it is clear what the parameters are.
For example:</p>
</div>
<div class="paragraph">
<p>The list of attributes available are:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">value</dt>
<dd>
<p>The name of the parameter.</p>
</dd>
<dt class="hdlist1">description</dt>
<dd>
<p>The description of the parameter.</p>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="jmx-annotation-example"><a class="anchor" href="#jmx-annotation-example"></a><a class="link" href="#jmx-annotation-example">Example</a></h4>
<div class="paragraph">
<p>The following is an example of each of the annotations mentioned above in practice.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">package com.acme;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.annotation.ManagedOperation;
import org.eclipse.jetty.util.annotation.Name;
@ManagedObject("Test MBean Annotations")
public class Derived extends Base implements Signature
{
String fname="Full Name";
@ManagedAttribute(value="The full name of something", name="fname")
public String getFullName()
{
return fname;
}
public void setFullName(String name)
{
fname=name;
}
@ManagedOperation("Doodle something")
public void doodle(@Name(value="doodle", description="A description of the argument") String doodle)
{
System.err.println("doodle "+doodle);
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jetty-jconsole"><a class="anchor" href="#jetty-jconsole"></a><a class="link" href="#jetty-jconsole">Managing Jetty with JConsole and JMC</a></h3>
<div class="paragraph">
<p>JConsole and the Java Mission Control (JMX) are graphical tools; they allow you to remotely manage and monitor your server and web application status using JMX.
When following the instructions given below, please also ensure that you make any necessary changes to any anti-virus software you may be using which may prevent JConsole or JMC from running.</p>
</div>
<div class="sect3">
<h4 id="_starting-jetty-standalone"><a class="anchor" href="#_starting-jetty-standalone"></a><a class="link" href="#_starting-jetty-standalone">Starting Jetty Standalone</a></h4>
<div class="paragraph">
<p>The simplest way to enable support is to add the JMX-Remote support module to your <code>{$jetty.base}</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=jmx-remote, jmx
INFO: jmx-remote initialised in ${jetty.base}/start.ini
INFO: jmx initialised in ${jetty.base}/start.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then open the <code>{$jetty.base}/start.ini</code> (or <code>{$jetty.base}/start.d/jmx-remote.ini</code>) file and edit the properties to suit your needs:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">#
# Initialize module jmx-remote
#
--module=jmx-remote
## JMX Configuration
## Enable for an open port accessible by remote machines
jetty.jmxrmihost=localhost
jetty.jmxrmiport=1099</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="jetty-jconsole-monitoring"><a class="anchor" href="#jetty-jconsole-monitoring"></a><a class="link" href="#jetty-jconsole-monitoring">Monitoring Jetty with JConsole</a></h4>
<div class="paragraph">
<p>To monitor Jetty&#8217;s server status with JConsole, start Jetty and then start JConsole by typing <code>jconsole</code> on the command line.</p>
</div>
<div class="sect4">
<h5 id="_connecting-to-your-server-process"><a class="anchor" href="#_connecting-to-your-server-process"></a><a class="link" href="#_connecting-to-your-server-process">Connecting to your server process</a></h5>
<div class="paragraph">
<p>After you start Jetty, you will see a dialog box in JConsole with a list of running processes to which you can connect.
It should look something like so:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="jconsole1.jpg" alt="image" width="576"></span></p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
If you don&#8217;t see your Jetty process in the list of processes you can connect to, quickly switch tabs, or close and reopen a new "New Connection" dialog window.
This forces JConsole to refresh the list, and recognize your newly-started Jetty process.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Select the start.jar entry and click the "Connect" button.
A new JConsole window opens:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="jconsole2.jpg" alt="image" width="576"></span></p>
</div>
<div class="paragraph">
<p>From this window you can monitor memory usage, thread usage, classloading and VM statistics.
You can also perform operations such as a manual garbage collect.
JConsole is an extremely powerful and useful tool.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_managing-jetty-objects-with-jconsole"><a class="anchor" href="#_managing-jetty-objects-with-jconsole"></a><a class="link" href="#_managing-jetty-objects-with-jconsole">Managing Jetty Objects with JConsole</a></h4>
<div class="paragraph">
<p>The MBean tab of JConsole allows access to managed objects within the Java application, including MBeans the JVM provides.
If you also want to interact with the Jetty JMX implementation via JConsole, you need to start Jetty JMX in a form that JConsole can access.
See <a href="#using-jmx">Using JMX with Jetty</a> for more information.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="jconsole3.png" alt="image" width="576"></span></p>
</div>
</div>
<div class="sect3">
<h4 id="jetty-jmc-monitoring"><a class="anchor" href="#jetty-jmc-monitoring"></a><a class="link" href="#jetty-jmc-monitoring">Monitoring Jetty with JMC</a></h4>
<div class="paragraph">
<p>To monitor Jetty&#8217;s server status with JMC, start Jetty and then start JMC by typing <code>jmc</code> on the command line.</p>
</div>
<div class="sect4">
<h5 id="_connecting-to-your-server-process-2"><a class="anchor" href="#_connecting-to-your-server-process-2"></a><a class="link" href="#_connecting-to-your-server-process-2">Connecting to your server process</a></h5>
<div class="paragraph">
<p>After you start Jetty, you will see a dialog box in JMC with a list of running processes to which you can connect.
It should look something like so:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="jmc1.png" alt="image" width="576"></span></p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
If you don&#8217;t see your Jetty process in the list of processes you can connect to, quickly switch tabs, or close and reopen a new "New Connection" dialog window.
This forces JMC to refresh the list, and recognize your newly-started Jetty process.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Double-click the start.jar entry or right-click the start.jar entry and select "Start JMX Console".
A new JMC window opens on the right:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="jmc2.png" alt="image" width="576"></span></p>
</div>
<div class="paragraph">
<p>From this window you can monitor memory usage, thread usage, classloading and VM statistics.
You can also perform operations such as a manual garbage collect.
JMC is an extremely powerful and useful tool.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_managing-jetty-objects-with-jconsole-2"><a class="anchor" href="#_managing-jetty-objects-with-jconsole-2"></a><a class="link" href="#_managing-jetty-objects-with-jconsole-2">Managing Jetty Objects with JConsole</a></h4>
<div class="paragraph">
<p>The MBean tab of JMC allows access to managed objects within the Java application, including MBeans the JVM provides.
If you also want to interact with the Jetty JMX implementation via JMC, you need to start Jetty JMX in a form that JMC can access.
See <a href="#using-jmx">Using JMX with Jetty</a> for more information.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="jmc3.png" alt="image" width="576"></span></p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="jndi"><a class="anchor" href="#jndi"></a><a class="link" href="#jndi">Configuring JNDI</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Jetty supports <code>java:comp/env</code> lookups in webapps.
This is an optional feature for which some configuration is required.</p>
</div>
<div class="sect2">
<h3 id="jndi-quick-setup"><a class="anchor" href="#jndi-quick-setup"></a><a class="link" href="#jndi-quick-setup">Quick Setup</a></h3>
<div class="paragraph">
<p>If you are using the standard distribution of Jetty, you must enable the <em>JNDI</em> <a href="#startup-modules">module</a> to obtain Jetty&#8217;s JNDI implementation, and the <strong>plus</strong> <a href="#startup-modules">module</a> which provides classes for interacting with JNDI.
As the <em>plus</em> module depends on the <em>JNDI</em> module, you only need to enable the <em>plus</em> module to enable both.
Assuming you have Jetty installed in <code>/opt/jetty</code>, and you have made a <a href="#startup-base-and-home">jetty base</a> in <code>/opt/jetty/my-base</code>, do:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cd /opt/jetty
$ cd my-base
$ java -jar $JETTY_HOME/start.jar --add-to-start=plus</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can now start Jetty and use JNDI within your webapps.
See <a href="#using-jndi">Using JNDI</a> for information on how to add entries to the JNDI environment that Jetty can look up within webapps.</p>
</div>
<div class="paragraph">
<p>If you have extra jars associated with your JNDI resources, for example a database driver jar, and you haven&#8217;t made a custom <a href="#startup-modules">module</a> for it, you can put the jars into your <code>{$jetty base}ext/</code> directory.
You will then need to enable the <em>ext</em> module to ensure the jars in the <code>ext/</code> directory are on the classpath.
Assuming you have Jetty installed in <code>/opt/jetty</code>, and you have made a <a href="#startup-base-and-home">jetty base</a> in <code>/opt/jetty/my-base</code>, do:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cd /opt/jetty
$ cd my-base
$ java -jar $JETTY_HOME/start.jar --add-to-start=ext</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="using-jetty-jndi"><a class="anchor" href="#using-jetty-jndi"></a><a class="link" href="#using-jetty-jndi">Working with Jetty JNDI</a></h3>
<div class="sect3">
<h4 id="_defining-the-web-xml"><a class="anchor" href="#_defining-the-web-xml"></a><a class="link" href="#_defining-the-web-xml">Defining the web.xml</a></h4>
<div class="paragraph">
<p>You can configure naming resources to reference in a <code>web.xml</code> file and access from within the <code>java:comp/env</code> naming environment of the webapp during execution.
Specifically, you can configure support for the following <code>web.xml</code> elements:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;env-entry/&gt;
&lt;resource-ref/&gt;
&lt;resource-env-ref/&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p><a href="#configuring-jndi-env-entries">Configuring env-entries</a> shows you how to set up overrides for <code>env-entry</code> elements in <code>web.xml</code>, while <a href="#configuring-resource-refs-and-resource-env-refs">Configuring <code>resource-refs</code> and <code>resource-env-refs</code></a> discusses how to configure support resources such as <code>javax.sql.DataSource</code>.</p>
</div>
<div class="paragraph">
<p>You can also plug a JTA <code>javax.transaction.UserTransaction</code> implementation into Jetty so that webapps can look up <code>java:comp/UserTransaction</code> to obtain a distributed transaction manager: see <a href="#configuring-xa-transactions">Configuring XA Transactions</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="defining-jndi-naming-entries"><a class="anchor" href="#defining-jndi-naming-entries"></a><a class="link" href="#defining-jndi-naming-entries">Declaring Resources</a></h4>
<div class="paragraph">
<p>You must declare the objects you want bound into the Jetty environment so that you can then hook into your webapp via <code>env-entry</code>, <code>resource-ref</code> and <code>resource-env-refs</code> in <code>web.xml</code>.
You create these bindings by using declarations of the following types:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>org.eclipse.jetty.plus.jndi.EnvEntry</code></dt>
<dd>
<p>For <code>env-entry</code> type of entries</p>
</dd>
<dt class="hdlist1"><code>org.eclipse.jetty.plus.jndi.Resource</code></dt>
<dd>
<p>For all other type of resources</p>
</dd>
<dt class="hdlist1"><code>org.eclipse.jetty.plus.jndi.Transaction</code></dt>
<dd>
<p>For a JTA manager</p>
</dd>
<dt class="hdlist1"><code>org.eclipse.jetty.plus.jndi.Link</code></dt>
<dd>
<p>For the link between a <code>web.xml</code> resource name and a naming entry</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Declarations of each of these types follow the same general pattern:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New class="org.eclipse.jetty.plus.jndi.xxxx"&gt;
&lt;Arg&gt;&lt;!-- scope --&gt;&lt;/Arg&gt;
&lt;Arg&gt;&lt;!-- name --&gt;&lt;/Arg&gt;
&lt;Arg&gt;&lt;!-- value --&gt;&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can place these declarations into three different files, depending on your needs and the <a href="#jndi-name-scope">scope</a> of the resources being declared.</p>
</div>
</div>
<div class="sect3">
<h4 id="jndi-where-to-declare"><a class="anchor" href="#jndi-where-to-declare"></a><a class="link" href="#jndi-where-to-declare">Deciding Where to Declare Resources</a></h4>
<div class="paragraph">
<p>You can define naming resources in three places:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><em>jetty.xml</em></dt>
<dd>
<p>Naming resources defined in a <code>jetty.xml</code> file are <a href="#jndi-name-scope">scoped</a> at either the JVM level or the Server level.
The classes for the resource must be visible at the Jetty container level.
If the classes for the resource only exist inside your webapp, you must declare it in a <code>WEB-INF/jetty-env.xml</code> file.</p>
</dd>
<dt class="hdlist1">WEB-INF/jetty-env.xml</dt>
<dd>
<p>Naming resources in a <code>WEB-INF/jetty-env.xml</code> file are <a href="#jndi-name-scope">scoped</a> to the web app in which the file resides.
While you can enter JVM or Server scopes if you choose, we do not recommend doing so.
The resources defined here may use classes from inside your webapp.
This is a Jetty-specific mechanism.</p>
</dd>
<dt class="hdlist1">Context xml file</dt>
<dd>
<p>Entries in a context xml file should be <a href="#jndi-name-scope">scoped</a> at the level of the webapp to which they apply, although you can supply a less strict scoping level of Server or JVM if you choose.
As with resources declared in a <code>jetty.xml</code> file, classes associated with the resource must be visible on the container&#8217;s classpath.</p>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="jndi-name-scope"><a class="anchor" href="#jndi-name-scope"></a><a class="link" href="#jndi-name-scope">Scope of Resource Names</a></h4>
<div class="paragraph">
<p>Naming resources within Jetty belong to one of three different scopes, in increasing order of restrictiveness:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">JVM scope</dt>
<dd>
<p>The name is unique across the JVM instance, and is visible to all application code.
You represent this scope by a <code>null</code> first parameter to the resource declaration.
For example:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New id="cf" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt; &lt;!-- empty arg --&gt;
&lt;Arg&gt;jms/connectionFactory&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="org.apache.activemq.ActiveMQConnectionFactory"&gt;
&lt;Arg&gt;vm://localhost?broker.persistent=false&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">Server scope</dt>
<dd>
<p>The name is unique to a Server instance, and is only visible to code associated with that instance.
You represent this scope by referencing the Server instance as the first parameter to the resource declaration.
For example:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id="Server" class="org.eclipse.jetty.Server"&gt;
&lt;New id="cf" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;Ref refid="Server"/&gt;&lt;/Arg&gt; &lt;!-- reference to Server instance --&gt;
&lt;Arg&gt;jms/connectionFactory&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="org.apache.activemq.ActiveMQConnectionFactory"&gt;
&lt;Arg&gt;vm://localhost?broker.persistent=false&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</dd>
<dt class="hdlist1">Webapp scope</dt>
<dd>
<p>The name is unique to the WebAppContext instance, and is only visible to code associated with that instance.
You represent this scope by referencing the <code>WebAppContext</code> instance as the first parameter to the resource declaration.
For example:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;New id="cf" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;Ref refid='wac'/&gt;&lt;/Arg&gt; &lt;!-- reference to WebAppContext --&gt;
&lt;Arg&gt;jms/connectionFactory&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="org.apache.activemq.ActiveMQConnectionFactory"&gt;
&lt;Arg&gt;vm://localhost?broker.persistent=false&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="binding-objects-into-jetty-jndi"><a class="anchor" href="#binding-objects-into-jetty-jndi"></a><a class="link" href="#binding-objects-into-jetty-jndi">What Can Be Bound as a Resource?</a></h4>
<div class="paragraph">
<p>You can bind four types of objects into a Jetty JNDI reference:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>An ordinary POJO instance.</p>
</li>
<li>
<p>A <a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/naming/Reference.html">javax.naming.Reference</a> instance.</p>
</li>
<li>
<p>An object instance that implements the <a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/naming/Referenceable.html">javax.naming.Referenceable</a> interface.</p>
</li>
<li>
<p>A link between a name as referenced in <code>web.xml</code> and as referenced in the Jetty environment.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jndi-configuration"><a class="anchor" href="#jndi-configuration"></a><a class="link" href="#jndi-configuration">Configuring JNDI</a></h3>
<div class="sect3">
<h4 id="configuring-jndi-env-entries"><a class="anchor" href="#configuring-jndi-env-entries"></a><a class="link" href="#configuring-jndi-env-entries">Configuring JNDI <em>env-entries</em></a></h4>
<div class="paragraph">
<p>Sometimes it is useful to pass configuration information to a webapp at runtime that you either cannot or cannot conveniently code into a <code>web.xml</code> env-entry.
In such cases, you can use the <code>org.eclipse.jetty.plus.jndi.EnvEntry</code> class, and even override an entry of the same name in <code>web.xml</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New class="org.eclipse.jetty.plus.jndi.EnvEntry"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;mySpecialValue&lt;/Arg&gt;
&lt;Arg type="java.lang.Integer"&gt;4000&lt;/Arg&gt;
&lt;Arg type="boolean"&gt;true&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example defines a virtual <code>env-entry</code> called <code>mySpecialValue</code> with value <code>4000</code> that is <a href="#jndi-name-scope">scoped</a> to the JVM.
It is put into JNDI at <code>java:comp/env/mySpecialValue</code> for <em>every</em> web app deployed.
Moreover, the boolean argument indicates that this value overrides an <code>env-entry</code> of the same name in <code>web.xml</code>.
If you don&#8217;t want to override, omit this argument, or set it to <code>false</code>.</p>
</div>
<div class="paragraph">
<p>The Servlet Specification allows binding only the following object types to an <code>env-entry</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>java.lang.String</p>
</li>
<li>
<p>java.lang.Integer</p>
</li>
<li>
<p>java.lang.Float</p>
</li>
<li>
<p>java.lang.Double</p>
</li>
<li>
<p>java.lang.Long</p>
</li>
<li>
<p>java.lang.Short</p>
</li>
<li>
<p>java.lang.Character</p>
</li>
<li>
<p>java.lang.Byte</p>
</li>
<li>
<p>java.lang.Boolean</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>That being said, Jetty is a little more flexible and allows you to also bind custom POJOs, <a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/naming/Reference.html"><code>javax.naming.References</code></a> and <a href="http://docs.oracle.com/javase/1.5.0/docs/api/javax/naming/Referenceable.html"><code>javax.naming.Referenceables</code></a>.
Be aware that if you take advantage of this feature, your web application is <em>not portable</em>.</p>
</div>
<div class="paragraph">
<p>To use the <code>env-entry</code> configured above, use code in your <code>servlet/filter/etc.</code>, such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import javax.naming.InitialContext;
public class MyClass {
public void myMethod() {
InitialContext ic = new InitialContext();
Integer mySpecialValue = (Integer)ic.lookup("java:comp/env/mySpecialValue");
...
}
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="configuring-resource-refs-and-resource-env-refs"><a class="anchor" href="#configuring-resource-refs-and-resource-env-refs"></a><a class="link" href="#configuring-resource-refs-and-resource-env-refs">Configuring <em>resource-refs</em> and <em>resource-env-refs</em></a></h4>
<div class="paragraph">
<p>You can configure any type of resource that you want to refer to in a <code>web.xml</code> file as a <code>resource-ref</code> or <code>resource-env-ref</code>, using the <code>org.eclipse.jetty.plus.jndi.Resource</code> type of naming entry.
You provide the scope, the name of the object (relative to <code>java:comp/env</code>) and a POJO instance or a <code>javax.naming.Reference</code> instance or <code>javax.naming.Referenceable</code> instance.</p>
</div>
<div class="paragraph">
<p>The <a href="http://jcp.org/aboutJava/communityprocess/pr/jsr244/index.html">J2EE Specification</a> recommends storing DataSources in <code>java:comp/env/jdbc</code>, JMS connection factories under <code>java:comp/env/jms</code>, JavaMail connection factories under <code>java:comp/env/mail</code> and URL connection factories under <code>java:comp/env/url</code>.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 19. DataSource Declaration Conventions</caption>
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Resource Type</th>
<th class="tableblock halign-left valign-top">Name in <code>jetty.xml</code></th>
<th class="tableblock halign-left valign-top">Environment Lookup</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">javax.sql.DataSource</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">jdbc/myDB</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">java:comp/env/jdbc/myDB</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">javax.jms.QueueConnectionFactory</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">jms/myQueue</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">java:comp/env/jms/myQueue</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">javax.mail.Session</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">mail/myMailService</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">java:comp/env/mail/myMailService</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="configuring-datasources"><a class="anchor" href="#configuring-datasources"></a><a class="link" href="#configuring-datasources">Configuring DataSources</a></h4>
<div class="paragraph">
<p>Here is an example of configuring a <code>javax.sql.DataSource</code>.
Jetty can use any DataSource implementation available on its classpath.
In this example, the DataSource is from the <a href="http://db.apache.org/derby">Derby</a> relational database, but you can use any implementation of a <code>javax.sql.DataSource</code>.
This example configures it as scoped to a web app with the id of <em>wac</em>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;New id="myds" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;Ref refid="wac"/&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/myds&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="org.apache.derby.jdbc.EmbeddedDataSource"&gt;
&lt;Set name="DatabaseName"&gt;test&lt;/Set&gt;
&lt;Set name="createDatabase"&gt;create&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The code above creates an instance of <code>org.apache.derby.jdbc.EmbeddedDataSource</code>, calls the two setter methods <code>setDatabaseName("test"),</code> and <code>setCreateDatabase("create"),</code> and binds it into the JNDI scope for the web app.
If you do not have the appropriate <code>resource-ref</code> set up in your <code>web.xml</code>, it is available from application lookups as <code>java:comp/env/jdbc/myds</code>.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example <code>web.xml</code> declaration for the datasource above:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;resource-ref&gt;
&lt;res-ref-name&gt;jdbc/myds&lt;/res-ref-name&gt;
&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
&lt;res-auth&gt;Container&lt;/res-auth&gt;
&lt;/resource-ref&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>To look up your DataSource in your <code>servlet/filter/etc.</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import javax.naming.InitialContext;
import javax.sql.DataSource;
public class MyClass {
public void myMethod() {
InitialContext ic = new InitialContext();
DataSource myDS = (DataSource)ic.lookup("java:comp/env/jdbc/myds");
...
}
}</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Careful! When configuring Resources, ensure that the type of object you configure matches the type of object you expect to look up in <code>java:comp/env</code>.
For database connection factories, this means that the object you register as a Resource <em>must</em> implement the <code>javax.sql.DataSource</code> interface.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>For more examples of datasource configurations, see <a href="#jndi-datasource-examples">Datasource Examples</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="configuring-jms-queues-topics-connectionfactories"><a class="anchor" href="#configuring-jms-queues-topics-connectionfactories"></a><a class="link" href="#configuring-jms-queues-topics-connectionfactories">Configuring JMS Queues, Topics and ConnectionFactories</a></h4>
<div class="paragraph">
<p>Jetty can bind any implementation of the JMS destinations and connection factories.
You just need to ensure the implementation Jars are available on Jetty&#8217;s classpath.
Here is an example of binding an <a href="http://activemq.apache.org">ActiveMQ</a> in-JVM connection factory:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;New id="cf" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;Ref refid='wac'/&gt;&lt;/Arg&gt;
&lt;Arg&gt;jms/connectionFactory&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="org.apache.activemq.ActiveMQConnectionFactory"&gt;
&lt;Arg&gt;vm://localhost?broker.persistent=false&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The entry in <code>web.xml</code> would be:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;resource-ref&gt;
&lt;res-ref-name&gt;jms/connectionFactory&lt;/res-ref-name&gt;
&lt;res-type&gt;javax.jms.ConnectionFactory&lt;/res-type&gt;
&lt;res-auth&gt;Container&lt;/res-auth&gt;
&lt;/resource-ref&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="configuring-mail-with-jndi"><a class="anchor" href="#configuring-mail-with-jndi"></a><a class="link" href="#configuring-mail-with-jndi">Configuring Mail</a></h4>
<div class="paragraph">
<p>Jetty also provides infrastructure for access to <code>javax.mail.Sessions</code> from within an application:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;New id="mail" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;Ref refid="wac"/&gt;&lt;/Arg&gt;
&lt;Arg&gt;mail/Session&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.jndi.factories.MailSessionReference"&gt;
&lt;Set name="user"&gt;fred&lt;/Set&gt;
&lt;Set name="password"&gt;OBF:1xmk1w261z0f1w1c1xmq&lt;/Set&gt;
&lt;Set name="properties"&gt;
&lt;New class="java.util.Properties"&gt;
&lt;Put name="mail.smtp.host"&gt;XXX&lt;/Put&gt;
&lt;Put name="mail.from"&gt;me@me&lt;/Put&gt;
&lt;Put name="mail.debug"&gt;true&lt;/Put&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This setup creates an instance of the <code>org.eclipse.jetty.jndi.factories.MailSessionReference</code> class, calls it&#8217;s setter methods to set up the authentication for the mail system, and populates a set of Properties, setting them on the <code>MailSessionReference</code> instance.
The result is that an application can look up <code>java:comp/env/mail/Session</code> at runtime and obtain access to a <code>javax.mail.Session</code> that has the necessary configuration to permit it to send email via SMTP.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
As of Jetty 10, the <a href="http://central.maven.org/maven2/org/eclipse/jetty/orbit/javax.mail.glassfish/1.4.1.v201005082020/javax.mail.glassfish-1.4.1.v201005082020.jar"><code>javax.mail</code></a> and <a href="http://central.maven.org/maven2/org/eclipse/jetty/orbit/javax.activation/1.1.0.v201105071233/javax.activation-1.1.0.v201105071233.jar"><code>javax.activation</code></a> jar files are not included in the Jetty Distribution and will need to be downloaded separately from Maven Central.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
You can set the password to be plain text, or use Jetty&#8217;s <a href="#configuring-security-secure-passwords">Secure Password Obfuscation</a> (OBF:) mechanism to make the config file a little more secure from prying eyes.
Remember that you cannot use the other Jetty encryption mechanisms of MD5 and Crypt because they do not allow you to recover the original password, which the mail system requires.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="configuring-xa-transactions"><a class="anchor" href="#configuring-xa-transactions"></a><a class="link" href="#configuring-xa-transactions">Configuring XA Transactions</a></h4>
<div class="paragraph">
<p>If you want to perform distributed transactions with your resources, you need a <em>transaction manager</em> that supports the JTA interfaces, and that you can look up as <code>java:comp/UserTransaction</code> in your webapp.
Jetty does not ship with one as standard, but you can plug in the one you prefer.
You can configure a transaction manager using the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/plus/jndi/Transaction.html">JNDI Transaction</a> object in a Jetty config file.
The following example configures the <a href="http://www.atomikos.com/">Atomikos</a> transaction manager:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New id="tx" class="org.eclipse.jetty.plus.jndi.Transaction"&gt;
&lt;Arg&gt;
&lt;New class="com.atomikos.icatch.jta.J2eeUserTransaction"/&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="configuring-links"><a class="anchor" href="#configuring-links"></a><a class="link" href="#configuring-links">Configuring Links</a></h4>
<div class="paragraph">
<p>Generally, the name you set for your <code>Resource</code> should be the same name you use for it in <code>web.xml</code>.
For example:</p>
</div>
<div class="paragraph">
<p>In a context xml file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;New id="myds" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;Ref refid="wac"/&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/mydatasource&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="org.apache.derby.jdbc.EmbeddedDataSource"&gt;
&lt;Set name="DatabaseName"&gt;test&lt;/Set&gt;
&lt;Set name="createDatabase"&gt;create&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>In a <code>web.xml</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;resource-ref&gt;
&lt;res-ref-name&gt;jdbc/mydatasource&lt;/res-ref-name&gt;
&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
&lt;res-auth&gt;Container&lt;/res-auth&gt;
&lt;injection-target&gt;
&lt;injection-target-class&gt;com.acme.JNDITest&lt;/injection-target-class&gt;
&lt;injection-target-name&gt;myDatasource&lt;/injection-target-name&gt;
&lt;/injection-target&gt;
&lt;/resource-ref&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>However, you can refer to it in <code>web.xml</code> by a different name, and link it to the name in your <code>org.eclipse.jetty.plus.jndi.Resource</code> by using an <code>org.eclipse.jetty.plus.jndi.Link</code>.
For the example above, you can refer to the <code>jdbc/mydatasource</code> resource as <code>jdbc/mydatasource1</code> as follows:</p>
</div>
<div class="paragraph">
<p>In a context xml file declare <code>jdbc/mydatasource</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;New id="myds" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;Ref refid="wac"/&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/mydatasource&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="org.apache.derby.jdbc.EmbeddedDataSource"&gt;
&lt;Set name="DatabaseName"&gt;test&lt;/Set&gt;
&lt;Set name="createDatabase"&gt;create&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then in a <code>WEB-INF/jetty-env.xml</code> file, link the name <code>jdbc/mydatasource</code> to the name you want to reference it as in
<code>web.xml</code>, which in this case is <code>jdbc/mydatasource1</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New id="map1" class="org.eclipse.jetty.plus.jndi.Link"&gt;
&lt;Arg&gt;&lt;Ref refid='wac'/&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/mydatasource1&lt;/Arg&gt; &lt;!-- name in web.xml --&gt;
&lt;Arg&gt;jdbc/mydatasource&lt;/Arg&gt; &lt;!-- name in container environment --&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now you can refer to <code>jdbc/mydatasource1</code> in the <code>web.xml</code> like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;resource-ref&gt;
&lt;res-ref-name&gt;jdbc/mydatasource1&lt;/res-ref-name&gt;
&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
&lt;res-auth&gt;Container&lt;/res-auth&gt;
&lt;injection-target&gt;
&lt;injection-target-class&gt;com.acme.JNDITest&lt;/injection-target-class&gt;
&lt;injection-target-name&gt;myDatasource&lt;/injection-target-name&gt;
&lt;/injection-target&gt;
&lt;/resource-ref&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This can be useful when you cannot change a JNDI resource directly in the <code>web.xml</code> but need to link it to a specific resource in your deployment environment.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jndi-embedded"><a class="anchor" href="#jndi-embedded"></a><a class="link" href="#jndi-embedded">Using JNDI with Jetty Embedded</a></h3>
<div class="sect3">
<h4 id="_setting-up-the-classpath-2"><a class="anchor" href="#_setting-up-the-classpath-2"></a><a class="link" href="#_setting-up-the-classpath-2">Setting up the Classpath</a></h4>
<div class="paragraph">
<p>In addition to the jars that you require for your application, and the jars needed for core Jetty, you will need to place the following jars onto your classpath:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>jetty-jndi.jar
jetty-plus.jar</pre>
</div>
</div>
<div class="paragraph">
<p>If you are using transactions, you will also need the <code>javax.transaction</code> api.
You can obtain this jar <a href="http://central.maven.org/maven2/org/eclipse/jetty/orbit/javax.transaction/1.1.1.v201105210645/javax.transaction-1.1.1.v201105210645.jar">here.</a></p>
</div>
<div class="paragraph">
<p>If you wish to use mail, you will also need the <code>javax.mail</code> api and implementation which <a href="http://central.maven.org/maven2/org/eclipse/jetty/orbit/javax.mail.glassfish/1.4.1.v201005082020/javax.mail.glassfish-1.4.1.v201005082020.jar">you can download here.</a>
Note that this jar also requires the <code>javax.activation</code> classes, which is available <a href="http://central.maven.org/maven2/org/eclipse/jetty/orbit/javax.activation/1.1.0.v201105071233/javax.activation-1.1.0.v201105071233.jar">at this link.</a></p>
</div>
</div>
<div class="sect3">
<h4 id="_example-code"><a class="anchor" href="#_example-code"></a><a class="link" href="#_example-code">Example Code</a></h4>
<div class="paragraph">
<p>Here is an example class that sets up some JNDI entries and deploys a webapp that references these JNDI entries in code.
We&#8217;ll use some mocked up classes for the transaction manager and the DataSource in this example for simplicity:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import java.util.Properties;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
/**
* ServerWithJNDI
*
*
*/
public class ServerWithJNDI
{
public static void main(String[] args) throws Exception
{
//Create the server
Server server = new Server(8080);
//Enable parsing of jndi-related parts of web.xml and jetty-env.xml
org.eclipse.jetty.webapp.Configuration.ClassList classlist = org.eclipse.jetty.webapp.Configuration.ClassList.setServerDefault(server);
classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration", "org.eclipse.jetty.plus.webapp.EnvConfiguration", "org.eclipse.jetty.plus.webapp.PlusConfiguration");
//Create a WebApp
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
webapp.setWar("./my-foo-webapp.war");
server.setHandler(webapp);
//Register new transaction manager in JNDI
//At runtime, the webapp accesses this as java:comp/UserTransaction
org.eclipse.jetty.plus.jndi.Transaction transactionMgr = new org.eclipse.jetty.plus.jndi.Transaction(new com.acme.MockUserTransaction());
//Define an env entry with Server scope.
//At runtime, the webapp accesses this as java:comp/env/woggle
//This is equivalent to putting an env-entry in web.xml:
//&lt;env-entry&gt;
// &lt;env-entry-name&gt;woggle&lt;/env-entry-name&gt;
// &lt;env-entry-type&gt;java.lang.Integer&lt;/env-entry-type&gt;
// &lt;env-entry-value&gt;4000&lt;/env-entry-value&gt;
//&lt;/env-entry&gt;
org.eclipse.jetty.plus.jndi.EnvEntry woggle = new org.eclipse.jetty.plus.jndi.EnvEntry(server, "woggle", new Integer(4000), false);
//Define an env entry with webapp scope.
//At runtime, the webapp accesses this as java:comp/env/wiggle
//This is equivalent to putting a web.xml entry in web.xml:
//&lt;env-entry&gt;
// &lt;env-entry-name&gt;wiggle&lt;/env-entry-name&gt;
// &lt;env-entry-value&gt;100&lt;/env-entry-value&gt;
// &lt;env-entry-type&gt;java.lang.Double&lt;/env-entry-type&gt;
//&lt;/env-entry&gt;
//Note that the last arg of "true" means that this definition for "wiggle" would override an entry of the
//same name in web.xml
org.eclipse.jetty.plus.jndi.EnvEntry wiggle = new org.eclipse.jetty.plus.jndi.EnvEntry(webapp, "wiggle", new Double(100), true);
//Register a reference to a mail service scoped to the webapp.
//This must be linked to the webapp by an entry in web.xml:
// &lt;resource-ref&gt;
// &lt;res-ref-name&gt;mail/Session&lt;/res-ref-name&gt;
// &lt;res-type&gt;javax.mail.Session&lt;/res-type&gt;
// &lt;res-auth&gt;Container&lt;/res-auth&gt;
// &lt;/resource-ref&gt;
//At runtime the webapp accesses this as java:comp/env/mail/Session
org.eclipse.jetty.jndi.factories.MailSessionReference mailref = new org.eclipse.jetty.jndi.factories.MailSessionReference();
mailref.setUser("CHANGE-ME");
mailref.setPassword("CHANGE-ME");
Properties props = new Properties();
props.put("mail.smtp.auth", "false");
props.put("mail.smtp.host","CHANGE-ME");
props.put("mail.from","CHANGE-ME");
props.put("mail.debug", "false");
mailref.setProperties(props);
org.eclipse.jetty.plus.jndi.Resource xxxmail = new org.eclipse.jetty.plus.jndi.Resource(webapp, "mail/Session", mailref);
// Register a mock DataSource scoped to the webapp
//This must be linked to the webapp via an entry in web.xml:
//&lt;resource-ref&gt;
// &lt;res-ref-name&gt;jdbc/mydatasource&lt;/res-ref-name&gt;
// &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
// &lt;res-auth&gt;Container&lt;/res-auth&gt;
//&lt;/resource-ref&gt;
//At runtime the webapp accesses this as java:comp/env/jdbc/mydatasource
org.eclipse.jetty.plus.jndi.Resource mydatasource = new org.eclipse.jetty.plus.jndi.Resource(webapp, "jdbc/mydatasource",
new com.acme.MockDataSource());
server.start();
server.join();
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jndi-datasource-examples"><a class="anchor" href="#jndi-datasource-examples"></a><a class="link" href="#jndi-datasource-examples">Datasource Examples</a></h3>
<div class="paragraph">
<p>Here are examples of configuring a JNDI datasource for various databases.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Read <a href="#configuring-datasources">Configuring DataSources</a> in <a href="#jndi-configuration">Configuring JNDI</a> for more information about configuring datasources.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>All of these examples correspond to a <code>resource-ref</code> in <code>web.xml</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;resource-ref&gt;
&lt;description&gt;My DataSource Reference&lt;/description&gt;
&lt;res-ref-name&gt;jdbc/DSTest&lt;/res-ref-name&gt;
&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
&lt;res-auth&gt;Container&lt;/res-auth&gt;
&lt;/resource-ref&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>These examples assume that all of the datasources are declared at the JVM scope, but you can use other scopes if desired.
You can configure all JNDI resources in a <code>jetty.xml</code> file, a <code>WEB-INF/jetty-env.xml</code> file, or a context XML file.
See the section <a href="#jndi-where-to-declare">Deciding Where to Declare Resources</a> for more information.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
You must provide Jetty with the libraries necessary to instantiate the datasource you have configured by putting the corresponding Jar in <code>JETTY_HOME/lib/ext</code>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect3">
<h4 id="pooling-datasources"><a class="anchor" href="#pooling-datasources"></a><a class="link" href="#pooling-datasources">Pooling DataSources</a></h4>
<div class="paragraph">
<p>Pooling datasources enables connection pooling, which lets you reuse an existing connection instead of creating a new connection to the database.
This is highly efficient in terms of memory allocation and speed of the request to the database.
We highly recommend this option for production environments.</p>
</div>
<div class="paragraph">
<p>The following is a list of the pooled datasource examples we have worked with in the past:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="#hikaricp-datasource">HikariCP</a></p>
</li>
<li>
<p><a href="#bonecp-datasource">BoneCP</a></p>
</li>
<li>
<p><a href="#c3p0-datasource">c3p0</a></p>
</li>
<li>
<p><a href="#dbcp-datasource">DBCP</a></p>
</li>
<li>
<p><a href="#atomikos-datasource">Atomikos 3.3.2+</a></p>
</li>
<li>
<p><a href="#mysql-pooled-datasource">MySQL</a></p>
</li>
<li>
<p><a href="#postgreSQL-pooled-datasource">PostgreSQL</a></p>
</li>
<li>
<p><a href="#DB2-pooled-datasource">DB2</a></p>
</li>
</ul>
</div>
<div class="sect4">
<h5 id="hikaricp-datasource"><a class="anchor" href="#hikaricp-datasource"></a><a class="link" href="#hikaricp-datasource">HikariCP</a></h5>
<div class="paragraph">
<p>Connection pooling, available at <a href="http://search.maven.org/remotecontent?filepath=com/zaxxer/HikariCP/1.4.0/HikariCP-1.4.0.jar">HikariCP Download</a>.
All configuration options for HikariCP are described here: <a href="https://github.com/brettwooldridge/HikariCP">HikariCP documentation</a>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="com.zaxxer.hikari.HikariDataSource"&gt;
&lt;Arg&gt;
&lt;New class="com.zaxxer.hikari.HikariConfig"&gt;
&lt;Set name="minimumPoolSize"&gt;5&lt;/Set&gt;
&lt;Set name="maximumPoolSize"&gt;20&lt;/Set&gt;
&lt;Set name="dataSourceClassName"&gt;com.mysql.jdbc.jdbc2.optional.MysqlDataSource&lt;/Set&gt;
&lt;Set name="username"&gt;jdbc.user&lt;/Set&gt;
&lt;Set name="password"&gt;jdbc.pass&lt;/Set&gt;
&lt;Call name="addDataSourceProperty"&gt;
&lt;Arg&gt;url&lt;/Arg&gt;
&lt;Arg&gt;jdbc.url&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="bonecp-datasource"><a class="anchor" href="#bonecp-datasource"></a><a class="link" href="#bonecp-datasource">BoneCP</a></h5>
<div class="paragraph">
<p>Connection pooling, available at <a href="http://jolbox.com/index.html?page=http://jolbox.com/download.html">BoneCP Download</a>.
All configuration options for BoneCP are described here: <a href="http://jolbox.com/bonecp/downloads/site/apidocs/com/jolbox/bonecp/BoneCPDataSource.html">BoneCP API</a>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="com.jolbox.bonecp.BoneCPDataSource"&gt;
&lt;Set name="driverClass"&gt;com.mysql.jdbc.Driver&lt;/Set&gt;
&lt;Set name="jdbcUrl"&gt;jdbc.url&lt;/Set&gt;
&lt;Set name="username"&gt;jdbc.user&lt;/Set&gt;
&lt;Set name="password"&gt;jdbc.pass&lt;/Set&gt;
&lt;Set name="minConnectionsPerPartition"&gt;5&lt;/Set&gt;
&lt;Set name="maxConnectionsPerPartition"&gt;50&lt;/Set&gt;
&lt;Set name="acquireIncrement"&gt;5&lt;/Set&gt;
&lt;Set name="idleConnectionTestPeriod"&gt;30&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="c3p0-datasource"><a class="anchor" href="#c3p0-datasource"></a><a class="link" href="#c3p0-datasource">c3p0</a></h5>
<div class="paragraph">
<p>Connection pooling, available at <a href="https://repo1.maven.org/maven2/c3p0/c3p0/0.9.1.2/c3p0-0.9.1.2.jar">c3p0 Jar</a>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="com.mchange.v2.c3p0.ComboPooledDataSource"&gt;
&lt;Set name="driverClass"&gt;org.some.Driver&lt;/Set&gt;
&lt;Set name="jdbcUrl"&gt;jdbc.url&lt;/Set&gt;
&lt;Set name="user"&gt;jdbc.user&lt;/Set&gt;
&lt;Set name="password"&gt;jdbc.pass&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="dbcp-datasource"><a class="anchor" href="#dbcp-datasource"></a><a class="link" href="#dbcp-datasource">DBCP</a></h5>
<div class="paragraph">
<p>Connection pooling, available at <a href="https://repo1.maven.org/maven2/commons-dbcp/commons-dbcp/1.2/commons-dbcp-1.2.jar">dbcp Jar</a>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="org.apache.commons.dbcp.BasicDataSource"&gt;
&lt;Set name="driverClassName"&gt;org.some.Driver&lt;/Set&gt;
&lt;Set name="url"&gt;jdbc.url&lt;/Set&gt;
&lt;Set name="username"&gt;jdbc.user&lt;/Set&gt;
&lt;Set name="password"&gt;jdbc.pass&lt;/Set&gt;
&lt;/New&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="atomikos-datasource"><a class="anchor" href="#atomikos-datasource"></a><a class="link" href="#atomikos-datasource">Atomikos 3.3.2+</a></h5>
<div class="paragraph">
<p>Connection pooling + XA transactions.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="com.atomikos.jdbc.AtomikosDataSourceBean"&gt;
&lt;Set name="minPoolSize"&gt;2&lt;/Set&gt;
&lt;Set name="maxPoolSize"&gt;50&lt;/Set&gt;
&lt;Set name="xaDataSourceClassName"&gt;com.mysql.jdbc.jdbc2.optional.MysqlXADataSource&lt;/Set&gt;
&lt;Set name="UniqueResourceName"&gt;DSTest&lt;/Set&gt;
&lt;Get name="xaProperties"&gt;
&lt;Call name="setProperty"&gt;
&lt;Arg&gt;url&lt;/Arg&gt;
&lt;Arg&gt;jdbc:mysql://localhost:3306/databasename&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Call name="setProperty"&gt;
&lt;Arg&gt;user&lt;/Arg&gt;
&lt;Arg&gt;some_username&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Call name="setProperty"&gt;
&lt;Arg&gt;password&lt;/Arg&gt;
&lt;Arg&gt;some_password&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Get&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="mysql-pooled-datasource"><a class="anchor" href="#mysql-pooled-datasource"></a><a class="link" href="#mysql-pooled-datasource">MySQL</a></h5>
<div class="paragraph">
<p>Implements <code>javax.sql.DataSource</code> and <code>javax.sql.ConnectionPoolDataSource</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"&gt;
&lt;Set name="Url"&gt;jdbc:mysql://localhost:3306/databasename&lt;/Set&gt;
&lt;Set name="User"&gt;user&lt;/Set&gt;
&lt;Set name="Password"&gt;pass&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="postgreSQL-pooled-datasource"><a class="anchor" href="#postgreSQL-pooled-datasource"></a><a class="link" href="#postgreSQL-pooled-datasource">PostgreSQL</a></h5>
<div class="paragraph">
<p>Implements <code>javax.sql.ConnectionPoolDataSource</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="org.postgresql.ds.PGConnectionPoolDataSource"&gt;
&lt;Set name="User"&gt;user&lt;/Set&gt;
&lt;Set name="Password"&gt;pass&lt;/Set&gt;
&lt;Set name="DatabaseName"&gt;dbname&lt;/Set&gt;
&lt;Set name="ServerName"&gt;localhost&lt;/Set&gt;
&lt;Set name="PortNumber"&gt;5432&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="DB2-pooled-datasource"><a class="anchor" href="#DB2-pooled-datasource"></a><a class="link" href="#DB2-pooled-datasource">DB2</a></h5>
<div class="paragraph">
<p>Implements <code>javax.sql.ConnectionPoolDataSource</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="com.ibm.db2.jcc.DB2ConnectionPoolDataSource"&gt;
&lt;Set name="DatabaseName"&gt;dbname&lt;/Set&gt;
&lt;Set name="User"&gt;user&lt;/Set&gt;
&lt;Set name="Password"&gt;pass&lt;/Set&gt;
&lt;Set name="ServerName"&gt;servername&lt;/Set&gt;
&lt;Set name="PortNumber"&gt;50000&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="non-pooling-datasources"><a class="anchor" href="#non-pooling-datasources"></a><a class="link" href="#non-pooling-datasources">Non-pooling DataSources</a></h4>
<div class="paragraph">
<p>If you are deploying in a production environment, we highly recommend using a Pooling DataSource.
Since that is not always an option we have a handful of examples for non-pooling datasources listed here as well.</p>
</div>
<div class="paragraph">
<p>The following is a list of the non-pooled datasource examples:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="#sql-server-2000-datasource">SQL Server 2000</a></p>
</li>
<li>
<p><a href="#oracle-9i10g-datasource">Oracle 9i/10g</a></p>
</li>
<li>
<p><a href="#postgreSQL-datasource">PostgreSQL</a></p>
</li>
<li>
<p><a href="#sybase-datasource">Sybase</a></p>
</li>
<li>
<p><a href="#DB2-datasource">DB2</a></p>
</li>
</ul>
</div>
<div class="sect4">
<h5 id="sql-server-2000-datasource"><a class="anchor" href="#sql-server-2000-datasource"></a><a class="link" href="#sql-server-2000-datasource">SQL Server 2000</a></h5>
<div class="paragraph">
<p>Implements <code>javax.sql.DataSource</code> and <code>javax.sql.ConnectionPoolDataSource</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="net.sourceforge.jtds.jdbcx.JtdsDataSource"&gt;
&lt;Set name="User"&gt;user&lt;/Set&gt;
&lt;Set name="Password"&gt;pass&lt;/Set&gt;
&lt;Set name="DatabaseName"&gt;dbname&lt;/Set&gt;
&lt;Set name="ServerName"&gt;localhost&lt;/Set&gt;
&lt;Set name="PortNumber"&gt;1433&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="oracle-9i10g-datasource"><a class="anchor" href="#oracle-9i10g-datasource"></a><a class="link" href="#oracle-9i10g-datasource">Oracle 9i/10g</a></h5>
<div class="paragraph">
<p>Implements <code>javax.sql.DataSource</code> and <code>javax.sql.ConnectionPoolDataSource</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="oracle.jdbc.pool.OracleDataSource"&gt;
&lt;Set name="DriverType"&gt;thin&lt;/Set&gt;
&lt;Set name="URL"&gt;jdbc:oracle:thin:@fmsswdb1:10017:otcd&lt;/Set&gt;
&lt;Set name="User"&gt;xxxx&lt;/Set&gt;
&lt;Set name="Password"&gt;xxxx&lt;/Set&gt;
&lt;Set name="connectionCachingEnabled"&gt;true&lt;/Set&gt;
&lt;Set name="connectionCacheProperties"&gt;
&lt;New class="java.util.Properties"&gt;
&lt;Call name="setProperty"&gt;
&lt;Arg&gt;MinLimit&lt;/Arg&gt;
&lt;Arg&gt;5&lt;/Arg&gt;
&lt;/Call&gt;
&lt;!-- put the other properties in here too --&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>For more information, refer to: <a href="http://docs.oracle.com/cd/B14117_01/java.101/b10979/conncache.htm">Oracle Database JDBC documentation</a>.</p>
</div>
</div>
<div class="sect4">
<h5 id="postgreSQL-datasource"><a class="anchor" href="#postgreSQL-datasource"></a><a class="link" href="#postgreSQL-datasource">PostgreSQL</a></h5>
<div class="paragraph">
<p>Implements <code>javax.sql.DataSource</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="org.postgresql.ds.PGSimpleDataSource"&gt;
&lt;Set name="User"&gt;user&lt;/Set&gt;
&lt;Set name="Password"&gt;pass&lt;/Set&gt;
&lt;Set name="DatabaseName"&gt;dbname&lt;/Set&gt;
&lt;Set name="ServerName"&gt;localhost&lt;/Set&gt;
&lt;Set name="PortNumber"&gt;5432&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="sybase-datasource"><a class="anchor" href="#sybase-datasource"></a><a class="link" href="#sybase-datasource">Sybase</a></h5>
<div class="paragraph">
<p>Implements <code>javax.sql.DataSource</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="com.sybase.jdbc2.jdbc.SybDataSource"&gt;
&lt;Set name="DatabaseName"&gt;dbname&lt;/Set&gt;
&lt;Set name="User"&gt;user&lt;/Set&gt;
&lt;Set name="Password"&gt;pass&lt;/Set&gt;
&lt;Set name="ServerName"&gt;servername&lt;/Set&gt;
&lt;Set name="PortNumber"&gt;5000&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="DB2-datasource"><a class="anchor" href="#DB2-datasource"></a><a class="link" href="#DB2-datasource">DB2</a></h5>
<div class="paragraph">
<p>Implements <code>javax.sql.DataSource</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="com.ibm.db2.jcc.DB2SimpleDataSource"&gt;
&lt;Set name="DatabaseName"&gt;dbname&lt;/Set&gt;
&lt;Set name="User"&gt;user&lt;/Set&gt;
&lt;Set name="Password"&gt;pass&lt;/Set&gt;
&lt;Set name="ServerName"&gt;servername&lt;/Set&gt;
&lt;Set name="PortNumber"&gt;50000&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configuring-jsp"><a class="anchor" href="#configuring-jsp"></a><a class="link" href="#configuring-jsp">Configuring JSP Support</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="jsp-support"><a class="anchor" href="#jsp-support"></a><a class="link" href="#jsp-support">Configuring JSP</a></h3>
<div class="paragraph">
<p>This document provides information about configuring Java Server Pages (JSP) for Jetty.</p>
</div>
<div class="sect3">
<h4 id="which-jsp-implementation"><a class="anchor" href="#which-jsp-implementation"></a><a class="link" href="#which-jsp-implementation">Which JSP Implementation</a></h4>
<div class="paragraph">
<p>Jetty uses Jasper from <a href="http://tomcat.apache.org/tomcat-8.0-doc/jasper-howto.html">Apache</a> as the default JSP container implementation.</p>
</div>
<div class="paragraph">
<p>By default the Jetty distribution enables the JSP <a href="#startup-modules">module</a>, and by default, this module is set to Apache Jasper.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain"># DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables JSP for all web applications deployed on the server.
[depend]
servlet
annotations
apache-jsp</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that the availability of some JSP features may depend on which JSP container implementation you are using.
Note also that it may not be possible to precompile your JSPs with one container and deploy to the other.</p>
</div>
<div class="sect4">
<h5 id="_logging"><a class="anchor" href="#_logging"></a><a class="link" href="#_logging">Logging</a></h5>
<div class="paragraph">
<p>The Apache Jasper logging system is bridged to the jetty logging system.
Thus, you can enable logging for jsps in the same way you have setup for your webapp.
For example, assuming you are using Jetty&#8217;s default StdErr logger, you would enable DEBUG level logging for jsps by adding the system property <code>-Dorg.apache.jasper.LEVEL=DEBUG</code> to the command line.</p>
</div>
</div>
<div class="sect4">
<h5 id="_jsps-and-embedding"><a class="anchor" href="#_jsps-and-embedding"></a><a class="link" href="#_jsps-and-embedding">JSPs and Embedding</a></h5>
<div class="paragraph">
<p>If you have an embedded setup for your webapp and wish to use JSPs, you will need to ensure that a JSP engine is correctly initialized.</p>
</div>
<div class="paragraph">
<p>For Apache, a Servlet Specification 3.1 style <a href="#servlet-container-initializers">ServletContainerInitializer</a> is used to accomplish this.
You will need to ensure that this ServletContainerInitializer is run by jetty. Perhaps the easiest way to do this is to enable annotations processing so that Jetty automatically discovers and runs it.
The <a href="#embedded-examples">Embedded Examples</a> section includes a <a href="#embedded-webapp-jsp">worked code example</a> of how to do this.</p>
</div>
<div class="paragraph">
<p>Alternatively, you can manually wire in the appropriate ServletContainerInitializer as shown in the <a href="https://github.com/jetty-project/embedded-jetty-jsp/blob/master/src/main/java/org/eclipse/jetty/demo/Main.java">embedded-jetty-jsp</a> example on <a href="https://github.com/jetty-project">GitHub</a>, in which case you will not need the jetty-annotations jar on your classpath, nor include the AnnotationConfiguration in the list of <a href="#webapp-configurations">configuration classes</a>.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_precompiling-jsps"><a class="anchor" href="#_precompiling-jsps"></a><a class="link" href="#_precompiling-jsps">Precompiling JSPs</a></h4>
<div class="paragraph">
<p>You can either follow the instructions on precompilation provided by Apache, or if you are using Maven for your builds, you can use the <a href="#jetty-jspc-maven-plugin">jetty-jspc-maven</a> plugin to do it for you.</p>
</div>
<div class="paragraph">
<p>If you have precompiled your JSPs, and have customized the output package prefix (which is <code>org.apache.jsp</code> by default), you should configure your webapp context to tell Jetty about this custom package name.
You can do this using a servlet context init-param called <code>org.eclipse.jetty.servlet.jspPackagePrefix</code>.</p>
</div>
<div class="paragraph">
<p>For example, suppose you have precompiled your JSPs with the custom package prefix of <code>com.acme</code>, then you would add the following lines to your <code>web.xml</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;context-param&gt;
&lt;param-name&gt;org.eclipse.jetty.servlet.jspPackagePrefix&lt;/param-name&gt;
&lt;param-value&gt;com.acme&lt;/param-value&gt;
&lt;/context-param&gt;</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Both Jetty Maven plugins - <a href="#jetty-jspc-maven-plugin">jetty-jspc-maven-plugin</a> and the <a href="#jetty-maven-plugin">jetty-maven-plugin</a> - will only use Apache Jasper.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect4">
<h5 id="compiling-jsps"><a class="anchor" href="#compiling-jsps"></a><a class="link" href="#compiling-jsps">Apache JSP Container</a></h5>
<div class="paragraph">
<p>By default, the Apache JSP container will look for the Eclipse Java Compiler (jdt).
The Jetty distribution ships a copy of this in <code>{$jetty.home}/lib/apache-jsp</code>.
If you wish to use a different compiler, you will need to configure the <code>compilerClassName</code> init-param on the <code>JspServlet</code> with the name of the class.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 20. Understanding Apache JspServlet Parameters</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">init param</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Default</th>
<th class="tableblock halign-left valign-top"><code>webdefault.xml</code></th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">checkInterval</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If non-zero and <code>development</code> is <code>false</code>, background jsp recompilation is enabled. This value is the interval in seconds between background recompile checks.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">classpath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The classpath is dynamically generated if the context has a URL classloader. The <code>org.apache.catalina.jsp_classpath</code>
context attribute is used to add to the classpath, but if this is not set, this <code>classpath</code> configuration item is added to the classpath instead.`</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">classdebuginfo</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Include debugging info in class file.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">TRUE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">compilerClassName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If not set, defaults to the Eclipse jdt compiler.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">compiler</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Used if the Eclipse jdt compiler cannot be found on the
classpath. It is the classname of a compiler that Ant should invoke.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">compilerTargetVM</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Target vm to compile for.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.8</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">compilerSourceVM</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Sets source compliance level for the jdt compiler.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.8</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">development</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If <code>true</code> recompilation checks occur at the frequency governed by <code>modificationTestInterval</code>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">TRUE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">displaySourceFragment</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Should a source fragment be included in
exception messages</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">TRUE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">dumpSmap</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Dump SMAP JSR45 info to a file.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">FALSE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">enablePooling</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Determines whether tag handler pooling is enabled.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">TRUE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">engineOptionsClass</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Allows specifying the Options class used to
configure Jasper. If not present, the default EmbeddedServletOptions
will be used.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">errorOnUseBeanInvalidClassAttribute</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Should Jasper issue an error when
the value of the class attribute in an useBean action is not a valid
bean class</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">TRUE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">fork</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Only relevant if you use Ant to compile jsps: by default Jetty will use the Eclipse jdt compiler.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">TRUE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">genStrAsCharArray</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Option for generating Strings as char arrays.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">FALSE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">ieClassId</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The class-id value to be sent to Internet Explorer when
using &lt;jsp:plugin&gt; tags.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">clsid:8AD9C840-044E-11D1-B3E9-00805F499D93</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">javaEncoding</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Pass through the encoding to use for the compilation.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UTF8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">jspIdleTimeout</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The amount of time in seconds a JSP can be idle before
it is unloaded. A value of zero or less indicates never unload.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">keepgenerated</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Do you want to keep the generated Java files around?</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">TRUE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">mappedFile</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Support for mapped Files. Generates a servlet that has a
print statement per line of the JSP file </p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">TRUE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">maxLoadedJsps</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The maximum number of JSPs that will be loaded for a web
application. If more than this number of JSPs are loaded, the least
recently used JSPs will be unloaded so that the number of JSPs loaded at
any one time does not exceed this limit. A value of zero or less
indicates no limit.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">modificationTestInterval</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If <code>development=true</code>, interval between
recompilation checks, triggered by a request.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">quoteAttributeEL</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">When EL is used in an attribute value on a JSP page, should the rules for quoting of attributes described in JSP.1.6 be applied to the expression</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">TRUE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">recompileOnFail</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If a JSP compilation fails should the
modificationTestInterval be ignored and the next access trigger a
re-compilation attempt? Used in development mode only and is disabled by
default as compilation may be expensive and could lead to excessive
resource usage.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">FALSE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">scratchDir</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Directory where servlets are generated. The default is the value of the context attribute <code>javax.servlet.context.tempdir</code>, or the system property <code>java.io.tmpdir</code> if the context attribute is not set.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">strictQuoteEscaping</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Should the quote escaping required by section JSP.1.6 of the JSP specification be applied to scriplet expression.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">TRUE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">suppressSmap</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Generation of SMAP info for JSR45 debugging.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">FALSE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">trimSpaces</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Should template text that consists entirely of whitespace be removed from the output (true), replaced with a single space (single) or left unchanged (false)? Note that if a JSP page or tag file specifies a trimDirectiveWhitespaces value of true, that will take precedence over this configuration setting for that page/tag.
trimmed?</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">FALSE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">–</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">xpoweredBy</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Generate an X-Powered-By response header.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">FALSE</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">FALSE</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect4">
<h5 id="configuring-jsp-for-jetty"><a class="anchor" href="#configuring-jsp-for-jetty"></a><a class="link" href="#configuring-jsp-for-jetty">Configuration</a></h5>
<div class="paragraph">
<p>The JSP engine has many configuration parameters.
Some parameters affect only precompilation, and some affect runtime recompilation checking.
Parameters also differ among the various versions of the JSP engine.
This page lists the configuration parameters, their meanings, and their default settings.
Set all parameters on the <code>org.eclipse.jetty.jsp.JettyJspServlet</code> instance defined in the <a href="#webdefault-xml"><code>webdefault.xml</code></a> file.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Be careful: for all of these parameters, if the value you set doesn&#8217;t take effect, try using all lower case instead of camel case, or capitalizing only some of the words in the name, as JSP is inconsistent in its parameter naming strategy.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
</div>
<div class="sect3">
<h4 id="modifying-configuration"><a class="anchor" href="#modifying-configuration"></a><a class="link" href="#modifying-configuration">Modifying Configuration</a></h4>
<div class="sect4">
<h5 id="overriding-webdefault.xml"><a class="anchor" href="#overriding-webdefault.xml"></a><a class="link" href="#overriding-webdefault.xml">Overriding <code>webdefault.xml</code></a></h5>
<div class="paragraph">
<p>You can make a copy of the <a href="#webdefault-xml">{$jetty.home}/etc/webdefault.xml</a> that ships with Jetty, apply your changes, and use it instead of the shipped version.
The example below shows how to do this when using the Jetty Maven plugin.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;plugin&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-maven-plugin&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;webApp&gt;
&lt;defaultsDescriptor&gt;src/main/resources/webdefault.xml&lt;/defaultsDescriptor&gt;
&lt;/webApp&gt;
&lt;/plugin&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you are using the Jetty distribution, and you want to change the JSP settings for just one or a few of your webapps, copy the <code>{$jetty.home}/etc/webdefault.xml</code> file somewhere, modify it, and then use a <a href="#intro-jetty-configuration-contexts">context xml</a> file to set this file as the <code>defaultsDescriptor</code> for your webapp. Here&#8217;s a snippet:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/foo&lt;/Set&gt;
&lt;Set name="war"&gt;&lt;Property name="jetty.home" default="."/&gt;/webapps/foobar.war&lt;/Set&gt;
&lt;Set name="defaultsDescriptor"&gt;/home/smith/dev/webdefault.xml&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you want to change the JSP settings for all webapps, edit the <code>{$jetty.home}/etc/webdefaults.xml</code> file directly instead.</p>
</div>
</div>
<div class="sect4">
<h5 id="configuring-jsp-servlet-in-web.xml"><a class="anchor" href="#configuring-jsp-servlet-in-web.xml"></a><a class="link" href="#configuring-jsp-servlet-in-web.xml">Configuring the JSP Servlet in web.xml</a></h5>
<div class="paragraph">
<p>Another option is to add an entry for the JSPServlet to the <code>WEB-INF/web.xml</code> file of your webapp and change or add init-params.
You may also add (but not remove) servlet-mappings.
You can use the entry in <a href="#webdefault-xml">{$jetty.home}/etc/webdefault.xml</a> as a starting point.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;servlet id="jsp"&gt;
&lt;servlet-name&gt;jsp&lt;/servlet-name&gt;
&lt;servlet-class&gt;org.eclipse.jetty.jsp.JettyJspServlet&lt;/servlet-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;keepgenerated&lt;/param-name&gt;
&lt;param-value&gt;true&lt;/param-value&gt;
&lt;/init-param&gt;
...
&lt;load-on-startup&gt;0&lt;/load-on-startup&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;jsp&lt;/servlet-name&gt;
&lt;url-pattern&gt;*.jsp&lt;/url-pattern&gt;
&lt;url-pattern&gt;*.jspf&lt;/url-pattern&gt;
&lt;url-pattern&gt;*.jspx&lt;/url-pattern&gt;
&lt;url-pattern&gt;*.xsp&lt;/url-pattern&gt;
&lt;url-pattern&gt;*.JSP&lt;/url-pattern&gt;
&lt;url-pattern&gt;*.JSPF&lt;/url-pattern&gt;
&lt;url-pattern&gt;*.JSPX&lt;/url-pattern&gt;
&lt;url-pattern&gt;*.XSP&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
&lt;servlet id="my-servlet"&gt;
&lt;servlet-name&gt;myServlet&lt;/servlet-name&gt;
&lt;servlet-class&gt;com.acme.servlet.MyServlet&lt;/servlet-class&gt;
...</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="jsp-async-support"><a class="anchor" href="#jsp-async-support"></a><a class="link" href="#jsp-async-support">Configuring Async Support</a></h5>
<div class="paragraph">
<p>By default, Jetty does not enable async support for the JSP servlet.
Configuring the JSP servlet for async is relatively easy - simply define the <code>async-supported</code> parameter as <code>true</code> in either your <code>webdefault.xml</code> or the <code>web.xml</code> for a specific context.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;servlet id="jsp"&gt;
&lt;servlet-name&gt;jsp&lt;/servlet-name&gt;
&lt;async-supported&gt;true&lt;/async-supported&gt;
&lt;/servlet&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="using-jstl-taglibs-for-jetty7-jetty8"><a class="anchor" href="#using-jstl-taglibs-for-jetty7-jetty8"></a><a class="link" href="#using-jstl-taglibs-for-jetty7-jetty8">Using JSTL Taglibs</a></h4>
<div class="paragraph">
<p>The JavaServer Pages Standlard Tag Library (JSTL) is part of the Jetty distribution and is automatically put on the classpath when you <a href="#which-jsp-implementation">select your flavour of JSP</a>.
It is also automatically on the classpath for the Jetty Maven plugin, which uses the Apache JSP engine.</p>
</div>
<div class="sect4">
<h5 id="_embedding-2"><a class="anchor" href="#_embedding-2"></a><a class="link" href="#_embedding-2">Embedding</a></h5>
<div class="paragraph">
<p>If you are using Jetty in an embedded scenario, and you need to use JSTL, then you must ensure that the JSTL jars are included on the <em>container&#8217;s</em> classpath - that is the classpath that is the <em>parent</em> of the webapp&#8217;s classpath.
This is a restriction that arises from the JavaEE specification.</p>
</div>
<div class="sect5">
<h6 id="_apache-jsp"><a class="anchor" href="#_apache-jsp"></a><a class="link" href="#_apache-jsp">Apache JSP</a></h6>
<div class="paragraph">
<p>You will need to put the jars that are present in the <code>{$jetty.home}/lib/apache-jstl</code> directory onto the <em>container&#8217;s</em> classpath.
The Apache JSP engine will find the JSTL tag definitions inside these jars during startup.</p>
</div>
<div class="paragraph">
<p>As an efficiency enhancement, you can have jetty examine the JSTL jars to find the tags, and pre-feed them into the Apache JSP engine.
This is more efficient, because jetty will only scan the jars you tell it to, whereas the Apache JSP engine will scan every jar, which can be time-consuming in applications with a lot of jars on the container classpath.</p>
</div>
<div class="paragraph">
<p>To take advantage of this efficiency enhancement, set up the <a href="#container-include-jar-pattern">org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</a> to include a <a href="http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html">pattern</a> that will match the names of the JSTL jars.
The <a href="#embedded-examples">Embedded Examples</a> section includes a <a href="#embedded-webapp-jsp">worked code example</a> of how to do this.
Below is a snippet from the example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java"> webapp.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",".*/[^/]*taglibs.*\\.jar$");</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="using-jsf-taglibs"><a class="anchor" href="#using-jsf-taglibs"></a><a class="link" href="#using-jsf-taglibs">Using JSF Taglibs</a></h4>
<div class="paragraph">
<p>The following sections provide information about using JSF TagLibs with Jetty Standalone and the Jetty Maven Plugin.</p>
</div>
<div class="sect4">
<h5 id="using-jsf-taglibs-with-jetty-standalone"><a class="anchor" href="#using-jsf-taglibs-with-jetty-standalone"></a><a class="link" href="#using-jsf-taglibs-with-jetty-standalone">Using JSF Taglibs with Jetty Distribution</a></h5>
<div class="paragraph">
<p>If you want to use JSF with your webapp, you need to copy the JSF implementation Jar (whichever Jar contains the <code>META-INF/*.tld</code> files from your chosen JSF implementation) into Jetty&#8217;s shared container lib directory.
You can either put them into the lib directory for Apache <code>{$jetty.home}/lib/apache-jsp</code> or put them into <code>{$jetty.home}/lib/ext</code>.</p>
</div>
</div>
<div class="sect4">
<h5 id="using-jsf-taglibs-with-jetty-maven-plugin"><a class="anchor" href="#using-jsf-taglibs-with-jetty-maven-plugin"></a><a class="link" href="#using-jsf-taglibs-with-jetty-maven-plugin">Using JSF Taglibs with Jetty Maven Plugin</a></h5>
<div class="paragraph">
<p>You should make your JSF jars dependencies of the plugin and <em>not</em> the webapp itself.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;plugin&gt;
&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
&lt;artifactId&gt;jetty-maven-plugin&lt;/artifactId&gt;
&lt;configuration&gt;
&lt;webApp&gt;
&lt;contextPath&gt;/${artifactId}&lt;/contextPath&gt;
&lt;/webApp&gt;
&lt;/configuration&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;com.sun.faces&lt;/groupId&gt;
&lt;artifactId&gt;jsf-api&lt;/artifactId&gt;
&lt;version&gt;2.0.8&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;com.sun.faces&lt;/groupId&gt;
&lt;artifactId&gt;jsf-impl&lt;/artifactId&gt;
&lt;version&gt;2.0.8&lt;/version&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;/plugin&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configuring-logging"><a class="anchor" href="#configuring-logging"></a><a class="link" href="#configuring-logging">Jetty Logging</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>This chapter discusses various options for configuring logging.</p>
</div>
<div class="sect2">
<h3 id="configuring-jetty-logging"><a class="anchor" href="#configuring-jetty-logging"></a><a class="link" href="#configuring-jetty-logging">Configuring Jetty Logging</a></h3>
<div class="paragraph">
<p>Jetty provides logging via its own <code>org.eclipse.jetty.util.log.Logger</code> layer, and does not natively use any existing Java logging framework.
All logging events, produced via the Jetty logging layer, have a name, a level, and a message.
The name is a FQCN (fully qualified class name) similar to how all existing Java logging frameworks operate.</p>
</div>
<div class="paragraph">
<p>Jetty logging, however, has a slightly different set of levels that it uses internally:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">WARN</dt>
<dd>
<p>For events serious enough to inform and log, but not fatal.</p>
</dd>
<dt class="hdlist1">INFO</dt>
<dd>
<p>Informational events.</p>
</dd>
<dt class="hdlist1">DEBUG</dt>
<dd>
<p>Debugging events (very noisy).</p>
</dd>
<dt class="hdlist1">IGNORE</dt>
<dd>
<p>Exception events that you can safely ignore, but useful for some people.
You might see this level as DEBUG under some Java logging framework configurations, where it retains the <em>ignore</em> phrase somewhere in the logging.</p>
</dd>
</dl>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Jetty logging produces no FATAL or SEVERE events.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect3">
<h4 id="selecting-log-framework"><a class="anchor" href="#selecting-log-framework"></a><a class="link" href="#selecting-log-framework">Selecting the Log Framework</a></h4>
<div class="paragraph">
<p>Configure the Jetty logging layer via the <code>org.eclipse.jetty.util.log.Log</code> class, following <a href="https://github.com/eclipse/jetty.project/tree/master/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java">these rules</a>.</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Load Properties</p>
<div class="ulist">
<ul>
<li>
<p>First from a Classpath Resource called <code>jetty-logging.properties</code> (if found).</p>
</li>
<li>
<p>Then from the <code>System.getProperties()</code>.</p>
</li>
</ul>
</div>
</li>
<li>
<p>Determine the log implementation.</p>
<div class="ulist">
<ul>
<li>
<p>If property <code>org.eclipse.jetty.util.log.class</code> is defined, load the class it defines as the logger implementation from the server <code>classpath</code>.</p>
</li>
<li>
<p>If the class <code>org.slf4j.Logger</code> exists in server classpath, the Jetty implementation becomes <code>org.eclipse.jetty.util.log.Slf4jLog</code>.</p>
</li>
<li>
<p>If no logger implementation is specified, default to <code>org.eclipse.jetty.util.log.StdErrLog</code>.</p>
</li>
</ul>
</div>
</li>
</ol>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
You can create your own custom logging by providing an implementation of the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOTorg/eclipse/jetty/util/log/Logger.html">Jetty Logger API</a>.
For an example of a custom logger, see <a href="https://github.com/eclipse/jetty.project/tree/master/jetty-util/src/main/java/org/eclipse/jetty/util/log/JavaUtilLog.java">JavaUtilLog.java</a>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect3">
<h4 id="configuring-jetty-stderrlog"><a class="anchor" href="#configuring-jetty-stderrlog"></a><a class="link" href="#configuring-jetty-stderrlog">The jetty-logging.properties file</a></h4>
<div class="paragraph">
<p>By default, the internal Jetty Logging discovery mechanism will load logging specific properties from a classpath resource called <code>jetty-logging.properties</code> and then initialize the Logging from a combination of properties found in that file, along with any System Properties.
A typical jetty-logging.properties file will include at least the declaration of which logging implementation you want to use by defining a value for the <code>org.eclipse.jetty.util.log.class</code> property.</p>
</div>
<div class="paragraph">
<p>Examples for various logging frameworks can be found later in this documentation.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Default Logging with <a href="#default-logging-with-stderrlog">Jetty&#8217;s StdErrLog</a></p>
</li>
<li>
<p>Using <a href="#example-logging-log4j">Log4j or Log4j2 via SLF4J</a></p>
</li>
<li>
<p>Using <a href="#example-logging-logback">Logback via SLF4J</a></p>
</li>
<li>
<p>Using <a href="#example-logging-java-util-logging">Java Util Logging via SLF4J</a></p>
</li>
<li>
<p>Using <a href="#example-logging-java-commons-logging">Java Commons Logging via SLF4J</a></p>
</li>
<li>
<p><a href="#example-logging-logback-centralized">Centralized Logging with Logback and Sfl4jLog</a></p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="default-logging-with-stderrlog"><a class="anchor" href="#default-logging-with-stderrlog"></a><a class="link" href="#default-logging-with-stderrlog">Default Logging with Jetty&#8217;s StdErrLog</a></h3>
<div class="sect3">
<h4 id="stderrlog-configuration"><a class="anchor" href="#stderrlog-configuration"></a><a class="link" href="#stderrlog-configuration">StdErrLog Configuration</a></h4>
<div class="paragraph">
<p>If you do nothing to configure a separate logging framework, Jetty will default to using an internal <code>org.eclipse.jetty.util.log.StdErrLog</code> implementation.
This will output all logging events to STDERR (aka <code>System.err</code>).</p>
</div>
<div class="paragraph">
<p>Simply use Jetty and <code>StdErrLog</code>-based logging is output to the console.</p>
</div>
<div class="paragraph">
<p>Included in the Jetty distribution is a logging module named <code>console-capture</code> that is capable of performing simple capturing of all STDOUT (<code>System.out</code>) and STDERR (<code>System.err</code>) output to a file that is rotated daily.</p>
</div>
<div class="paragraph">
<p>To enable this feature, simply activate the <code>console-capture</code> module on the command line:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=console-capture
INFO : console-capture initialized in ${jetty.base}/start.d/console-capture.ini
MKDIR : ${jetty.base}/logs
INFO : Base directory was modified
[my-base]$ tree
.
├── logs
└── start.d
└── console-capture.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>The default configuration for logging output will create a file <code>${jetty.base}/logs/yyyy_mm_dd.stderrout.log</code> which allows configuration of the output directory by setting the <code>jetty.logs</code> property.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
By default, logs are not set to be appended, meaning a the log file is wiped clean upon sever restart.
You can change this setting by editing the <code>console-capture.ini</code> and un-commenting the line that reads <code>jetty.console-capture.append=true</code>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Just enabling the <code>console-capture</code> will simply output the values of STDERR and STDOUT to a log file.
To customize the log further, a module named <code>logging-jetty</code> is available to provides a default properties file to configure.
As with <code>console-capture</code>, you activate the <code>logging-jetty</code> on the command line.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=logging-jetty
INFO : logging-jetty initialized in ${jetty.base}/start.d/logging-jetty.ini
INFO : resources transitively enabled
MKDIR : ${jetty.base}/resources
COPY : ${jetty.home}/modules/logging-jetty/resources/jetty-logging.properties to ${jetty.base}/resources/jetty-logging.properties
INFO : Base directory was modified
[my-base]$ tree
.
├── logs
├── resources
│   └── jetty-logging.properties
└── start.d
├── console-capture.ini
└── logging-jetty.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>Once activated, you can find the properties file at <code>${jetty.base}/resources/jetty-logging.properties</code>.
By default, the following parameters are defined.
To change them, un-comment the line and substitute your naming scheme and configuration choices.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-properties" data-lang="properties">## Force jetty logging implementation
#org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
## Set logging levels from: ALL, DEBUG, INFO, WARN, OFF
#org.eclipse.jetty.LEVEL=INFO
#com.example.LEVEL=INFO
## Hide stacks traces in logs?
#com.example.STACKS=false
## Show the source file of a log location?
#com.example.SOURCE=false</code></pre>
</div>
</div>
<div class="paragraph">
<p>There are a number of properties that can be defined in the configuration that will affect the behavior of StdErr logging with <code>console-capture</code>.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>&lt;name&gt;.LEVEL=&lt;level&gt;</code></dt>
<dd>
<p>Sets the logging level for all loggers within the <code>name</code> specified to the level, which can be (in increasing order of restriction) <code>ALL</code>, <code>DEBUG</code>, <code>INFO</code>, <code>WARN</code>, <code>OFF</code>.
The name (or hierarchy) can be a specific fully qualified class or a package namespace.
For example, <code>org.eclipse.jetty.http.LEVEL=DEBUG</code> is a package namespace approach to turn all loggers in the Jetty HTTP package to DEBUG level, and <code>org.eclipse.jetty.io.ChanelEndPoint.LEVEL=ALL</code> turns on all logging events for the specific class, including <code>DEBUG</code>, <code>INFO</code>, <code>WARN</code> (and even special internally ignored exception classes).
If more than one system property specifies a logging level, the most specific one applies.</p>
</dd>
<dt class="hdlist1"><code>&lt;name&gt;.SOURCE=&lt;boolean&gt;</code></dt>
<dd>
<p>Named Logger specific, attempts to print the Java source file name and line number from where the logging event originated.
Name must be a fully qualified class name (this configurable does not support package name hierarchy).
Default is false.
Be aware that this is a slow operation and has an impact on performance.</p>
</dd>
<dt class="hdlist1"><code>&lt;name&gt;.STACKS=&lt;boolean&gt;</code></dt>
<dd>
<p>Named Logger specific, controls the display of stacktraces.
Name must be a fully qualified class name (this configurable does not support package name hierarchy).
Default is true.</p>
</dd>
<dt class="hdlist1"><code>org.eclipse.jetty.util.log.stderr.SOURCE=&lt;boolean&gt;</code></dt>
<dd>
<p>Special Global Configuration.
Attempts to print the Java source file name and line number from where the logging event originated.
Default is false.</p>
</dd>
<dt class="hdlist1"><code>org.eclipse.jetty.util.log.stderr.LONG=&lt;boolean&gt;</code></dt>
<dd>
<p>Special Global Configuration.
When true, outputs logging events to <code>STDERR</code> using long form, fully qualified class names.
When false, uses abbreviated package names.
Default is false.</p>
<div class="ulist">
<ul>
<li>
<p>Example when set to false:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">2016-10-21 15:31:01.248:INFO::main: Logging initialized @332ms to org.eclipse.jetty.util.log.StdErrLog
2016-10-21 15:31:01.370:INFO:oejs.Server:main: jetty-10.0.0-SNAPSHOT
2016-10-21 15:31:01.400:INFO:oejs.AbstractConnector:main: Started ServerConnector@2c330fbc{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2016-10-21 15:31:01.400:INFO:oejs.Server:main: Started @485ms</code></pre>
</div>
</div>
</li>
<li>
<p>Example when set to true:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">2016-10-21 15:31:35.020:INFO::main: Logging initialized @340ms to org.eclipse.jetty.util.log.StdErrLog
2016-10-21 15:31:35.144:INFO:org.eclipse.jetty.server.Server:main: jetty-10.0.0-SNAPSHOT
2016-10-21 15:31:35.174:INFO:org.eclipse.jetty.server.AbstractConnector:main: Started ServerConnector@edf4efb{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2016-10-21 15:31:35.175:INFO:org.eclipse.jetty.server.Server:main: Started @495ms</code></pre>
</div>
</div>
</li>
</ul>
</div>
</dd>
</dl>
</div>
</div>
<div class="sect3">
<h4 id="deprecated-parameters"><a class="anchor" href="#deprecated-parameters"></a><a class="link" href="#deprecated-parameters">Deprecated Parameters</a></h4>
<div class="paragraph">
<p>These parameters existed in prior versions of Jetty, and are no longer supported.
They are included here for historical (and search engine) reasons.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>org.eclipse.jetty.util.log.DEBUG</code></dt>
<dd>
<p>Formerly used to enable DEBUG level logging on any logger used within Jetty (not just Jetty&#8217;s own logger).</p>
<div class="ulist">
<ul>
<li>
<p>Replaced with using the logger implementation specific configuration and level filtering.</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1"><code>org.eclipse.jetty.util.log.stderr.DEBUG</code></dt>
<dd>
<p>Formerly used to enable DEBUG level logging on the internal Jetty <code>StdErrLog</code> implementation.</p>
<div class="ulist">
<ul>
<li>
<p>Replaced with level specific equivalent.
Example: <code>org.eclipse.jetty.LEVEL=DEBUG</code></p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1"><code>DEBUG</code></dt>
<dd>
<p>Ancient debugging flag that turned on all debugging, even non-logging debugging.</p>
<div class="ulist">
<ul>
<li>
<p>Jetty no longer uses because many third party libraries employ this overly simple property name, which would generate far too much console output.</p>
</li>
</ul>
</div>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect2">
<h3 id="configuring-jetty-request-logs"><a class="anchor" href="#configuring-jetty-request-logs"></a><a class="link" href="#configuring-jetty-request-logs">Configuring Jetty Request Logs</a></h3>
<div class="paragraph">
<p>Request logs are a record of the requests that the server has processed.
There is one entry per request received, and commonly in the standard NCSA format, so you can use tools like <a href="http://en.wikipedia.org/wiki/Webalizer">Webalizer</a> to analyze them conveniently.</p>
</div>
<div class="sect3">
<h4 id="constructing-request-log-entry"><a class="anchor" href="#constructing-request-log-entry"></a><a class="link" href="#constructing-request-log-entry">Constructing a Request Log Entry</a></h4>
<div class="paragraph">
<p>A standard request log entry includes the client IP address, date, method, URL, result, size, referrer, user agent and latency.
For example:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>123.4.5.6 - - [20/Jul/2016:10:16:17 +0000]
"GET /jetty/tut/XmlConfiguration.html HTTP/1.1"
200 76793 "http://localhost:8080/jetty/tut/logging.html"
"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040614 Firefox/0.8" 342</pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="implementing-request-log"><a class="anchor" href="#implementing-request-log"></a><a class="link" href="#implementing-request-log">Implementing a Request Log</a></h4>
<div class="paragraph">
<p>Jetty provides an implementation called <code>NCSARequestLog</code> which supports the NCSA format in files that will roll over on a daily basis.</p>
</div>
<div class="paragraph">
<p>The <a href="http://logback.qos.ch/">Logback Project</a> offers <a href="http://logback.qos.ch/access.html">another implementation</a> of a <code>RequestLog</code> interface, providing rich and powerful HTTP-access log functionality.</p>
</div>
<div class="paragraph">
<p>If neither of these options meets your needs, you can implement a custom request logger by implementing Jetty&#8217;s <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/RequestLog.html"><code>RequestLog.java</code></a> interface and plugging it in similar to the <code>NCSARequestLog</code>, as shown below.</p>
</div>
</div>
<div class="sect3">
<h4 id="configuring-request-log"><a class="anchor" href="#configuring-request-log"></a><a class="link" href="#configuring-request-log">Configuring the Request Log module</a></h4>
<div class="paragraph">
<p>To enable the Request Log module for the entire server via the Jetty distribution, it first needs to be enabled on the command line:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=requestlog
INFO: requestlog initialised in ${jetty.base}/start.d/requestlog.ini
MKDIR: ${jetty.base}/logs
INFO: Base directory was modified</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above command will add a new <code>requestlog.ini</code> file to your <a href="#start-vs-startd"><code>{$jetty.base}/start.d</code> directory</a>.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
By default, request logs are not set to be appended, meaning a the log file is wiped clean upon sever restart.
You can change this setting by editing the <code>requestlog.ini</code> and un-commenting the line that reads <code>jetty.requestlog.append=true</code>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>The equivalent code for embedded usages of Jetty is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">NCSARequestLog requestLog = new NCSARequestLog("/var/logs/jetty/jetty-yyyy_mm_dd.request.log");
requestLog.setAppend(true);
requestLog.setExtended(false);
requestLog.setLogTimeZone("GMT");
requestLog.setLogLatency(true);
requestLog.setRetainDays("90");
server.setRequestLog(requestLog);</code></pre>
</div>
</div>
<div class="paragraph">
<p>This configures a request log in <code>{$jetty.home}/logs</code> with filenames including the date.
Existing log files are appended to and the extended NCSA format is used in the GMT time zone.</p>
</div>
<div class="paragraph">
<p>The above configuration enables Log Latency, which is the amount of time it took the server to handle the request.
This value is measured in milliseconds and is appended to the the log file for each request.</p>
</div>
<div class="paragraph">
<p>You can also customize the number of days you wish to keep request logs.
By default, log files are kept for 90 days before being deleted.
The value for <code>retainDays</code> (xml) or <code>setRetainDays</code> (Java) should be configured as <em>1 + n</em> days.
For example, if you wanted to keep the logs for the current day and the day prior you would set the <code>retainDays</code> (or <code>setRetainDays</code>) value to 2.</p>
</div>
</div>
<div class="sect3">
<h4 id="request-log-custom-writer"><a class="anchor" href="#request-log-custom-writer"></a><a class="link" href="#request-log-custom-writer">Introducing RequestLog.Writer</a></h4>
<div class="paragraph">
<p>The concept of a <code>RequestLog.Writer</code>, introduced in Jetty 9.4.15, manages the writing to a log the string generated by the <code>RequestLog</code>.
This allows the <code>CustomRequestLog</code> to match the functionality of other <code>RequestLogger</code> implementations by plugging in any <code>RequestLog.Writer</code> and a custom format string.
Jetty currently has implementations of <code>RequestLog.Writer</code>, <code>RequestLogWriter</code>, <code>AsyncRequestLogWriter</code>, and <code>Slf4jRequestLogWriter</code>.</p>
</div>
<div class="paragraph">
<p>So, the way to create an asynchronous <code>RequestLog</code> using the extended NCSA format has been changed from:</p>
</div>
<div class="paragraph">
<p><code>new AsyncNcsaRequestLog(filename)</code></p>
</div>
<div class="paragraph">
<p>to:</p>
</div>
<div class="paragraph">
<p><code>new CustomRequestLog(new AsyncRequestLogWriter(filename), CustomRequestLog.EXTENDED_NCSA_FORMAT)</code></p>
</div>
<div class="paragraph">
<p>Additionally, there are now two settings for the log timezone to be configured.
There is the configuration for logging the request time, which is set in the <code>timeZone</code> parameter in the <code>%t</code> format code of the string, given in the format <code>%{format|timeZone|locale}t</code>.</p>
</div>
<div class="paragraph">
<p>The other <code>timeZone</code> parameter relates to the generation of the log file name (both at creation and roll over).
This is configured in the <code>requestlog</code> module file, or can be used as a setter on <code>RequestLogWriter</code> via XML.</p>
</div>
<div class="paragraph">
<p>Both timezones are set to GMT by default.</p>
</div>
</div>
<div class="sect3">
<h4 id="configuring-separate-request-log-for-web-application"><a class="anchor" href="#configuring-separate-request-log-for-web-application"></a><a class="link" href="#configuring-separate-request-log-for-web-application">Configuring a Separate Request Log For a Web Application</a></h4>
<div class="paragraph">
<p>To configure a separate request log for specific a web application, add the following to the context XML file.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
...
&lt;Call name="insertHandler"&gt;
&lt;Arg&gt;
&lt;New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"&gt;
&lt;Set name="requestLog"&gt;
&lt;New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog"&gt;
&lt;Set name="filename"&gt;&lt;Property name="jetty.logs" default="./logs"/&gt;/test-yyyy_mm_dd.request.log&lt;/Set&gt;
&lt;Set name="filenameDateFormat"&gt;yyyy_MM_dd&lt;/Set&gt;
&lt;Set name="LogTimeZone"&gt;GMT&lt;/Set&gt;
&lt;Set name="retainDays"&gt;90&lt;/Set&gt;
&lt;Set name="append"&gt;true&lt;/Set&gt;
&lt;Set name="LogLatency"&gt;true&lt;/Set&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
...
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="configuring-logging-modules"><a class="anchor" href="#configuring-logging-modules"></a><a class="link" href="#configuring-logging-modules">Jetty Logging Integrations (SLF4J, Log4j, Logback, JCL, JUL)</a></h3>
<div class="paragraph">
<p>Jetty provides support for several logging frameworks including SLF4J, Java Commons Logging (JCL), Java Util Logging (JUL), Log4j (including version 2), and Logback.
This page includes examples of how to enable the associated modules for these different frameworks.
These modules are designed to capture container/server logs; <a href="#configuring-jetty-request-logs">request logs</a> and application logs need to be configured separately.
Please note that enabling these modules provides typical and basic functionality for each framework; advanced implementations may require their <a href="#startup-modules">own modules</a> or additional configuration.</p>
</div>
<div class="paragraph">
<p>Enabling these frameworks in the Jetty distribution is as easy as activating any other module, by adding <code>--add-to-start=&lt;module name&gt;</code> to the start command for your server, such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=logging-jetty
INFO : logging-jetty initialized in ${jetty.base}/start.d/logging-jetty.ini
INFO : resources transitively enabled
MKDIR : ${jetty.base}/resources
COPY : ${jetty.home}/modules/logging-jetty/resources/jetty-logging.properties to ${jetty.base}/resources/jetty-logging.properties
INFO : Base directory was modified</code></pre>
</div>
</div>
<div class="paragraph">
<p>As noted above, Jetty supports a wide array of logging technologies.
If a particular logging framework requires additional jar files, Jetty will automatically download these as part of enabling the associated module and any dependent modules will be transitively enabled.</p>
</div>
<div class="paragraph">
<p>A list of the base Jetty logging modules by running <code>java -jar &lt;path-to-jetty.home&gt;/start.jar --list-modules=logging,-internal</code>.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">logging-jcl</dt>
<dd>
<p>Configures Jetty logging to use Java Commons Logging (JCL), using SLF4J as a binding.</p>
</dd>
<dt class="hdlist1">logging-jetty</dt>
<dd>
<p>Standard Jetty logging that captures <code>System.err</code> and <code>System.out</code> output.</p>
</dd>
<dt class="hdlist1">logging-jul</dt>
<dd>
<p>Configures Jetty logging to use Java Util Logging (JUL), using SLF4J as a binding.</p>
</dd>
<dt class="hdlist1">logging-log4j</dt>
<dd>
<p>Configures Jetty logging to use Log4j as the logging implementation, using SLF4J as a binding.</p>
</dd>
<dt class="hdlist1">logging-log4j2</dt>
<dd>
<p>Configures Jetty logging to use Log4j2 as the logging implementation, using SLF4J as a binding.</p>
</dd>
<dt class="hdlist1">logging-logback</dt>
<dd>
<p>Configures Jetty logging to use Logback as the logging implementation, using SLF4J as a binding.</p>
</dd>
<dt class="hdlist1">logging-slf4j</dt>
<dd>
<p>Configures Jetty logging to use SLF4J and provides a <code>slf4j-impl</code> which can be used by other logging frameworks.
If no other logging is configured, <code>slf4j-simple</code> is used.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>You can view a list of <strong>all</strong> the Jetty logging modules by running <code>java -jar &lt;path-to-jetty.home&gt;/start.jar --list-modules=logging</code>.
This will display all logging modules, including implementation and binding modules.</p>
</div>
<div class="paragraph">
<p>All these modules (with the exception of <code>logging-jetty</code>) arrange for the Jetty private logging API to be routed to the named technology to actually be logged.
For example, enabling the <code>logging-log4j</code> module will do several things:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>it enables an internal Log4j API module so that any container code that uses Log4j will find the API.</p>
</li>
<li>
<p>it enables an internal Log4j Implementation so that any container code that uses the Log4j API will also use a Log4j implementation to handle the logs (and all the normal Log4j configuration mechanisms etc.)</p>
</li>
<li>
<p>it enables the internal <code>slf4j-log4j</code> logging binding so that any container code that uses the SLF4j API to also use the Log4j implementation via the Log4j API.</p>
</li>
<li>
<p>it configures the Jetty logging API to use the SLF4J API, which is then bound to Log4j.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>So, after enabling <code>logging-log4j</code>, within the server container there are 3 logging APIs available: Jetty, SLF4J and Log4J.
But there is only a single logging <strong>implementation</strong> - Log4j; the 3 APIs act only as facades over the Log4j implementation.</p>
</div>
<div class="paragraph">
<p>Note that you can add additional APIs to this configuration.
For example, enabling the internal module <code>jcl-slf4j</code> would add in a Java Commons Logging facade that also would use the Log4j implementation via the SLF4J binding.</p>
</div>
<div class="paragraph">
<p>Most other top level logging modules work in the same way: <code>logging-jcl</code>, <code>logging-jul</code>, <code>logging-slf4j</code>, <code>logging-log4j2</code> and <code>logging-logback</code> all bind their implementation via SLF4J.</p>
</div>
<div class="sect3">
<h4 id="example-logging-slf4j"><a class="anchor" href="#example-logging-slf4j"></a><a class="link" href="#example-logging-slf4j">Logging with SLF4J</a></h4>
<div class="paragraph">
<p>Jetty uses the SLF4J api as a binding to provide logging information to additional frameworks such as Log4j or Logback.
It can also be used on it&#8217;s own to provide simple server logging.
To enable the SLF4J framework, you need to activate the <code>logging-slf4j</code> module.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=logging-slf4j
ALERT: There are enabled module(s) with licenses.
The following 1 module(s):
+ contains software not provided by the Eclipse Foundation!
+ contains software not covered by the Eclipse Public License!
+ has not been audited for compliance with its license
Module: slf4j-api
+ SLF4J is distributed under the MIT License.
+ Copyright (c) 2004-2013 QOS.ch
+ All rights reserved.
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Proceed (y/N)? y
INFO : slf4j-api transitively enabled
INFO : logging-slf4j initialized in ${jetty.base}/start.d/logging-slf4j.ini
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
INFO : Base directory was modified
ERROR : Module logging-slf4j requires a module providing slf4j-impl from one of [slf4j-simple-impl, slf4j-logback, slf4j-jul, slf4j-log4j2, slf4j-log4j]
ERROR : Unsatisfied module dependencies: logging-slf4j
Usage: java -jar $JETTY_HOME/start.jar [options] [properties] [configs]
java -jar $JETTY_HOME/start.jar --help # for more information</code></pre>
</div>
</div>
<div class="paragraph">
<p>As you probably noticed, the system gives an <code>ERROR</code> when trying to enable the <code>logging-slf4j</code> on it&#8217;s own.
The <code>logging-slf4j</code> module itself provides the SLF4J api, but as SLF4J is often used as a binding for other logging frameworks does not by default provide an implementation.
To enable the simple SLF4J implementation, we will also need to activate the <code>slf4j-simple-impl</code> module.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=slf4j-simple-impl
INFO : slf4j-simple-impl initialized in ${jetty.base}/start.d/slf4j-simple-impl.ini
INFO : resources transitively enabled
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-simple/1.7.21/slf4j-simple-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-simple-1.7.21.jar
MKDIR : ${jetty.base}/resources
COPY : ${jetty.home}/modules/slf4j-simple-impl/resources/simplelogger.properties to ${jetty.base}/resources/simplelogger.properties
INFO : Base directory was modified
[my-base]$ tree
.
├── lib
│   └── slf4j
│   ├── slf4j-api-1.7.21.jar
│   └── slf4j-simple-1.7.21.jar
├── resources
│   └── simplelogger.properties
└── start.d
├── logging-slf4j.ini
└── slf4j-simple-impl.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>Jetty is now configured to log using the SLF4J framework.
A standard SLF4J properties file is located in <code>${jetty.base}/resources/simplelogger.properties</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="example-logging-log4j"><a class="anchor" href="#example-logging-log4j"></a><a class="link" href="#example-logging-log4j">Logging with Log4j and Log4j2</a></h4>
<div class="paragraph">
<p>It is possible to have the Jetty Server logging configured so that Log4j or Log4j2 controls the output of logging events produced by Jetty.
This is accomplished by configuring Jetty for logging to <a href="http://logging.apache.org/log4j/">Apache Log4j</a> via <a href="http://slf4j.org/manual.html">Slf4j</a> and the <a href="http://slf4j.org/manual.html#swapping">Slf4j binding layer for Log4j</a>.
Implementation of Log4j can be done by enabling the <code>logging-log4j</code> module.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=logging-log4j
ALERT: There are enabled module(s) with licenses.
The following 2 module(s):
+ contains software not provided by the Eclipse Foundation!
+ contains software not covered by the Eclipse Public License!
+ has not been audited for compliance with its license
Module: log4j-impl
+ Log4j is released under the Apache 2.0 license.
+ http://www.apache.org/licenses/LICENSE-2.0.html
Module: slf4j-api
+ SLF4J is distributed under the MIT License.
+ Copyright (c) 2004-2013 QOS.ch
+ All rights reserved.
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Proceed (y/N)? y
INFO : slf4j-api transitively enabled
INFO : log4j-impl transitively enabled
INFO : resources transitively enabled
INFO : slf4j-log4j transitively enabled
INFO : logging-log4j initialized in ${jetty.base}/start.d/logging-log4j.ini
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
MKDIR : ${jetty.base}/lib/log4j
COPY : /Users/admin/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar to ${jetty.base}/lib/log4j/log4j-1.2.17.jar
MKDIR : ${jetty.base}/resources
COPY : ${jetty.home}/modules/log4j-impl/resources/log4j.xml to ${jetty.base}/resources/log4j.xml
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-log4j12/1.7.21/slf4j-log4j12-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-log4j12-1.7.21.jar
INFO : Base directory was modified
[my-base]$ tree
.
├── lib
│   ├── log4j
│   │   └── log4j-1.2.17.jar
│   └── slf4j
│   ├── slf4j-api-1.7.21.jar
│   └── slf4j-log4j12-1.7.21.jar
├── resources
│   └── log4j.xml
└── start.d
└── logging-log4j.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>Jetty is now configured to log using the Log4j framework.
A standard Log4j configuration file is located in <code>${jetty.base}/resources/log4j.xml</code>.</p>
</div>
<div class="paragraph">
<p>Or, to set up Log4j2, enable the <code>logging-log4j2</code> module.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=logging-log4j2
ALERT: There are enabled module(s) with licenses.
The following 2 module(s):
+ contains software not provided by the Eclipse Foundation!
+ contains software not covered by the Eclipse Public License!
+ has not been audited for compliance with its license
Module: log4j2-api
+ Log4j is released under the Apache 2.0 license.
+ http://www.apache.org/licenses/LICENSE-2.0.html
Module: slf4j-api
+ SLF4J is distributed under the MIT License.
+ Copyright (c) 2004-2013 QOS.ch
+ All rights reserved.
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Proceed (y/N)? y
INFO : slf4j-api transitively enabled
INFO : logging-log4j2 initialized in ${jetty.base}/start.d/logging-log4j2.ini
INFO : log4j2-api transitively enabled
INFO : resources transitively enabled
INFO : slf4j-log4j2 transitively enabled
INFO : log4j2-impl transitively enabled
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
MKDIR : ${jetty.base}/lib/log4j2
DOWNLD: https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-api/2.6.1/log4j-api-2.6.1.jar to ${jetty.base}/lib/log4j2/log4j-api-2.6.1.jar
MKDIR : ${jetty.base}/resources
DOWNLD: https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-slf4j-impl/2.6.1/log4j-slf4j-impl-2.6.1.jar to ${jetty.base}/lib/log4j2/log4j-slf4j-impl-2.6.1.jar
DOWNLD: https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-core/2.6.1/log4j-core-2.6.1.jar to ${jetty.base}/lib/log4j2/log4j-core-2.6.1.jar
COPY : ${jetty.home}/modules/log4j2-impl/resources/log4j2.xml to ${jetty.base}/resources/log4j2.xml
INFO : Base directory was modified
[my-base]$ tree
.
├── lib
│   ├── log4j2
│   │   ├── log4j-api-2.6.1.jar
│   │   ├── log4j-core-2.6.1.jar
│   │   └── log4j-slf4j-impl-2.6.1.jar
│   └── slf4j
│   └── slf4j-api-1.7.21.jar
├── resources
│   └── log4j2.xml
└── start.d
└── logging-log4j2.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>At this point Jetty is configured so that the Jetty server itself will log using Log4j2, using the Log4j2 configuration found in <code>{$jetty.base}/resources/log4j2.xml</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="example-logging-logback"><a class="anchor" href="#example-logging-logback"></a><a class="link" href="#example-logging-logback">Logging with Logback</a></h4>
<div class="paragraph">
<p>It is possible to have the Jetty Server logging configured so that Logback controls the output of logging events produced by Jetty.
This is accomplished by configuring Jetty for logging to <code>Logback</code>, which uses <a href="http://slf4j.org/manual.html">Slf4j</a> and the <a href="http://logback.qos.ch/">Logback Implementation for Slf4j</a>.</p>
</div>
<div class="paragraph">
<p>To set up Jetty logging via Logback, enable the <code>logging-logback</code> module.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=logging-logback
ALERT: There are enabled module(s) with licenses.
The following 2 module(s):
+ contains software not provided by the Eclipse Foundation!
+ contains software not covered by the Eclipse Public License!
+ has not been audited for compliance with its license
Module: logback-impl
+ Logback: the reliable, generic, fast and flexible logging framework.
+ Copyright (C) 1999-2012, QOS.ch. All rights reserved.
+ This program and the accompanying materials are dual-licensed under
+ either:
+ the terms of the Eclipse Public License v1.0
+ as published by the Eclipse Foundation:
+ http://www.eclipse.org/legal/epl-v10.html
+ or (per the licensee's choosing) under
+ the terms of the GNU Lesser General Public License version 2.1
+ as published by the Free Software Foundation:
+ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
Module: slf4j-api
+ SLF4J is distributed under the MIT License.
+ Copyright (c) 2004-2013 QOS.ch
+ All rights reserved.
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Proceed (y/N)? y
INFO : slf4j-api transitively enabled
INFO : logback-impl transitively enabled
INFO : slf4j-logback transitively enabled
INFO : logging-logback initialized in ${jetty.base}/start.d/logging-logback.ini
INFO : resources transitively enabled
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
MKDIR : ${jetty.base}/lib/logback
DOWNLD: https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.1.7/logback-core-1.1.7.jar to ${jetty.base}/lib/logback/logback-core-1.1.7.jar
MKDIR : ${jetty.base}/resources
COPY : ${jetty.home}/modules/logback-impl/resources/logback.xml to ${jetty.base}/resources/logback.xml
DOWNLD: https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.1.7/logback-classic-1.1.7.jar to ${jetty.base}/lib/logback/logback-classic-1.1.7.jar
INFO : Base directory was modified
[my-base]$ tree
.
├── lib
│   ├── logback
│   │   ├── logback-classic-1.1.7.jar
│   │   └── logback-core-1.1.7.jar
│   └── slf4j
│   └── slf4j-api-1.7.21.jar
├── resources
│   └── logback.xml
└── start.d
└── logging-logback.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>At this point Jetty is configured so that the Jetty server itself will log using Logback, using the Logback configuration found in <code>{$jetty.base}/resources/logback.xml</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="_logging-with-java-util-logging"><a class="anchor" href="#_logging-with-java-util-logging"></a><a class="link" href="#_logging-with-java-util-logging">Logging with Java Util Logging</a></h4>
<div class="sect4">
<h5 id="example-logging-java-util-logging"><a class="anchor" href="#example-logging-java-util-logging"></a><a class="link" href="#example-logging-java-util-logging">Java Util Logging with SLF4J</a></h5>
<div class="paragraph">
<p>It is possible to have the Jetty Server logging configured so that <code>java.util.logging</code> controls the output of logging events produced by Jetty.</p>
</div>
<div class="paragraph">
<p>This example demonstrates how to configuring Jetty for logging to <code>java.util.logging</code> via <a href="http://slf4j.org/manual.html">SLF4J</a> as a binding layer.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=logging-jul
ALERT: There are enabled module(s) with licenses.
The following 1 module(s):
+ contains software not provided by the Eclipse Foundation!
+ contains software not covered by the Eclipse Public License!
+ has not been audited for compliance with its license
Module: slf4j-api
+ SLF4J is distributed under the MIT License.
+ Copyright (c) 2004-2013 QOS.ch
+ All rights reserved.
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Proceed (y/N)? y
INFO : jul-impl transitively enabled
INFO : slf4j-api transitively enabled
INFO : slf4j-jul transitively enabled
INFO : logging-jul initialized in ${jetty.base}/start.d/logging-jul.ini
INFO : resources transitively enabled
MKDIR : ${jetty.base}/etc
COPY : ${jetty.home}/modules/jul-impl/etc/java-util-logging.properties to ${jetty.base}/etc/java-util-logging.properties
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-jdk14/1.7.21/slf4j-jdk14-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-jdk14-1.7.21.jar
INFO : Base directory was modified
[my-base]$ tree
.
├── etc
│   └── java-util-logging.properties
├── lib
│   └── slf4j
│   ├── slf4j-api-1.7.21.jar
│   └── slf4j-jdk14-1.7.21.jar
└── start.d
└── logging-jul.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>Jetty is now configured to log using the JUL framework.
A standard JUL properties file is located in <code>${jetty.base}/etc/java-util-logging.properties</code>.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_capturing-console-output"><a class="anchor" href="#_capturing-console-output"></a><a class="link" href="#_capturing-console-output">Capturing Console Output</a></h4>
<div class="paragraph">
<p>By default, enabling the above modules will output log information to the console.
Included in the distribution is the <code>console-capture</code> module, which can be used in lieu of additional configuration to the selected logging module to capture this output to a <code>logs</code> directory in your <code>${jetty.base}</code>.
To enable this functionality, activate the <code>console-capture</code> module.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=console-capture
INFO : console-capture initialized in ${jetty.base}/start.d/console-capture.ini
MKDIR : ${jetty.base}/logs
INFO : Base directory was modified
[my-base]$ tree
.
├── logs
└── start.d
└── console-capture.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>As an example, here is the output from Logback before using the <code>console-capture</code> module:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar
419 [main] INFO org.eclipse.jetty.util.log - Logging initialized @508ms to org.eclipse.jetty.util.log.Slf4jLog
540 [main] INFO org.eclipse.jetty.server.Server - jetty-10.0.0-SNAPSHOT
575 [main] INFO o.e.jetty.server.AbstractConnector - Started ServerConnector@3c0ecd4b{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
575 [main] INFO org.eclipse.jetty.server.Server - Started @668ms</code></pre>
</div>
</div>
<div class="paragraph">
<p>After enabling <code>console-capture</code>, the output is as follows, which displays the location the log is being saved to:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar
151 [main] INFO org.eclipse.jetty.util.log - Logging initialized @238ms to org.eclipse.jetty.util.log.Slf4jLog
196 [main] INFO org.eclipse.jetty.util.log - Console stderr/stdout captured to /installs/jetty-distribution/mybase/logs/2016_10_21.jetty.log</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="example-logging-logback-centralized"><a class="anchor" href="#example-logging-logback-centralized"></a><a class="link" href="#example-logging-logback-centralized">Centralized Logging using Logback</a></h3>
<div class="paragraph">
<p>The term <em>Centralized Logging</em> refers to a forced logging configuration for the Jetty Server and all web applications that are deployed on the server.
It routes all logging events from the web applications to a single configuration on the Server side.</p>
</div>
<div class="paragraph">
<p>The example below shows how to accomplish this with Jetty and Slf4j, using <code>Logback</code> to manage the final writing of logs to disk.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
This mechanism forces all webapps to use the server&#8217;s configuration for logging, something that isn&#8217;t 100% appropriate for all webapps.
An example would be having Jenkins-CI deployed as an webapp, if you force its logging configuration to the server side, you lose the ability on <a href="http://jenkins-ci.org/">Jenkins-CI</a> to see the logs from the various builds (as now those logs are actually going to the main server log).
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>This configuration is essentially the multiple logger configuration with added configuration to the deployers to force a <code>WebAppClassLoader</code> change to use the server classpath over the webapps classpath for the logger specific classes.</p>
</div>
<div class="paragraph">
<p>The technique used by this configuration is to provide an <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOTorg/eclipse/jetty/deploy/AppLifeCycle.Binding.html">AppLifeCycle.Binding</a> against the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/deploy/AppLifeCycle.html">`"deploying"`node</a> that modifies the
<a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#getSystemClasspathPattern()">WebAppContext.getSystemClasspathPattern().add(String)</a> for the common logging classes.
See <a href="https://github.com/jetty-project/jetty-webapp-logging/blob/master/jetty-webapp-logging/src/main/java/org/eclipse/jetty/webapp/logging/CentralizedWebAppLoggingBinding.java">org.eclipse.jetty.logging.CentralizedWebAppLoggingBinding</a> for actual implementation.</p>
</div>
<div class="paragraph">
<p>A convenient replacement <code>logging</code> module has been created to bootstrap your <code>${jetty.base}</code> directory for capturing all Jetty server logging from multiple logging frameworks into a single logging output file managed by Logback.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[mybase]$ curl -O https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-webapp-logging/9.4.27/jetty-webapp-logging-9.4.27-config.jar
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3402 100 3402 0 0 15823 0 --:--:-- --:--:-- --:--:-- 15750
[mybase]$ jar -xf jetty-webapp-logging-9.4.27-config.jar
[my-base]$ java -jar /path/to/jetty-home/start.jar --create-startd --add-to-start=centralized-webapp-logging
ALERT: There are enabled module(s) with licenses.
The following 2 module(s):
+ contains software not provided by the Eclipse Foundation!
+ contains software not covered by the Eclipse Public License!
+ has not been audited for compliance with its license
Module: logback-impl
+ Logback: the reliable, generic, fast and flexible logging framework.
+ Copyright (C) 1999-2012, QOS.ch. All rights reserved.
+ This program and the accompanying materials are dual-licensed under
+ either:
+ the terms of the Eclipse Public License v1.0
+ as published by the Eclipse Foundation:
+ http://www.eclipse.org/legal/epl-v10.html
+ or (per the licensee's choosing) under
+ the terms of the GNU Lesser General Public License version 2.1
+ as published by the Free Software Foundation:
+ http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
Module: slf4j-api
+ SLF4J is distributed under the MIT License.
+ Copyright (c) 2004-2013 QOS.ch
+ All rights reserved.
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Proceed (y/N)? y
INFO : slf4j-api transitively enabled
INFO : log4j-over-slf4j transitively enabled
INFO : jcl-slf4j transitively enabled
INFO : logback-impl transitively enabled
INFO : jul-slf4j transitively enabled
INFO : slf4j-logback transitively enabled
INFO : centralized-webapp-logging initialized in ${jetty.base}/start.d/centralized-webapp-logging.ini
INFO : logging-logback transitively enabled
INFO : resources transitively enabled
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.25.jar
MKDIR : ${jetty.base}/lib/logging
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/log4j-over-slf4j/1.7.25/log4j-over-slf4j-1.7.25.jar to ${jetty.base}/lib/logging/log4j-over-slf4j-1.7.25.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/jcl-over-slf4j/1.7.25/jcl-over-slf4j-1.7.25.jar to ${jetty.base}/lib/slf4j/jcl-over-slf4j-1.7.25.jar
MKDIR : ${jetty.base}/lib/logback
DOWNLD: https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar to ${jetty.base}/lib/logback/logback-core-1.2.3.jar
DOWNLD: https://repo1.maven.org/maven2/org/slf4j/jul-to-slf4j/1.7.25/jul-to-slf4j-1.7.25.jar to ${jetty.base}/lib/slf4j/jul-to-slf4j-1.7.25.jar
COPY : ${jetty.home}/modules/jul-slf4j/etc/java-util-logging.properties to ${jetty.base}/etc/java-util-logging.properties
DOWNLD: https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar to ${jetty.base}/lib/logback/logback-classic-1.2.3.jar
MKDIR : ${jetty.base}/logs
DOWNLD: https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-webapp-logging/9.4.27/jetty-webapp-logging-9.4.27.jar to ${jetty.base}/lib/logging/jetty-webapp-logging-9.4.27.jar
INFO : Base directory was modified
$</code></pre>
</div>
</div>
<div class="paragraph">
<p>This replacement <code>centralized-webapp-logging.mod</code> performs a number of tasks.</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p><code>mybase</code> is a <code>${jetty.base}</code> directory.</p>
</li>
<li>
<p>The jetty-distribution is unpacked (and untouched) into <code>/opt/jetty-dist/</code> and becomes the <code>${jetty.home}</code> directory for this demonstration.</p>
</li>
<li>
<p>The <code>curl</code> command downloads the replacement config overlay for the <code>${jetty.base}/modules/</code> directory to use.</p>
</li>
<li>
<p>The <code>start.jar --add-to-start=centralized-webapp-logging</code> command performs a number of steps to make the centralized-webapp-logging module available to the <code>${jetty.base}</code> configuration.</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>A new <code>${jetty.base}/start.d/centralized-webapp-logging.ini</code> configuration was created.</p>
</li>
<li>
<p>Required <code>${jetty.base}</code> directories are created: <code>${jetty.base}/logs</code> and <code>${jetty.base}/resources</code>.</p>
</li>
<li>
<p>Required logging libraries are downloaded (if not present already) to the <code>${jetty.base}/lib/logging/</code> directory:</p>
<div class="ulist">
<ul>
<li>
<p><code>slf4j-api.jar</code> - API jar for Slf4j (used by most of the rest of the jars)</p>
</li>
<li>
<p><code>log4j-over-slf4j.jar</code> - Slf4j jar that captures all log4j emitted logging events</p>
</li>
<li>
<p><code>jul-to-slf4j.jar</code> - Slf4j jar that captures all java.util.logging events</p>
</li>
<li>
<p><code>jcl-over-slf4j.jar</code> - Slf4j jar that captures all commons-logging events</p>
</li>
<li>
<p><code>logback-classic.jar</code> - the Slf4j adapter jar that routes all of the captured logging events to logback itself.</p>
</li>
<li>
<p><code>logback-core.jar</code> - the logback implementation jar, that handles all of the filtering and output of the logging events.</p>
</li>
</ul>
</div>
</li>
<li>
<p>Required webapp-logging library is downloaded (if not present already) to the <code>${jetty.base}/lib/webapp-logging/</code> directory:</p>
<div class="ulist">
<ul>
<li>
<p><code>jetty-webapp-logging.jar</code> - the Jetty side deployment manger app-lifecycle bindings for modifying the <code>WebAppClassloaders</code> of deployed webapps.</p>
</li>
</ul>
</div>
</li>
</ol>
</div>
</li>
</ol>
</div>
<div class="paragraph">
<p>At this point the Jetty <code>mybase</code> is configured so that the jetty server itself will log using slf4j, and all other logging events from other Jetty Server components (such as database drivers, security layers, jsp, mail, and other 3rd party server components) are routed to logback for filtering and output.</p>
</div>
<div class="paragraph">
<p>All webapps deployed via the <code>DeploymentManager</code> have their <code>WebAppClassLoader</code> modified to use server side classes and configuration for all logging implementations.</p>
</div>
<div class="paragraph">
<p>The server classpath can be verified by using the <code>start.jar --list-config</code> command.</p>
</div>
<div class="paragraph">
<p>In essence, Jetty is now configured to emit its own logging events to slf4j, and various slf4j bridge jars are acting on behalf of <code>log4j</code>, <code>java.util.logging</code>, and <code>commons-logging</code>, routing all of the logging events to <code>logback</code>
(a slf4j implementation) for routing (to console, file, etc&#8230;&#8203;).</p>
</div>
</div>
<div class="sect2">
<h3 id="jetty-server-dump"><a class="anchor" href="#jetty-server-dump"></a><a class="link" href="#jetty-server-dump">Jetty Server Dump</a></h3>
<div class="paragraph">
<p>The dump feature in Jetty provides a snapshot of the bean containment tree of the main Jetty components together with a summary of their configuration.This includes threadpool, connectors, contexts, webapplications, servlets and so forth.</p>
</div>
<div class="sect3">
<h4 id="configuring-dump-feature"><a class="anchor" href="#configuring-dump-feature"></a><a class="link" href="#configuring-dump-feature">Configuring the Jetty Server Dump</a></h4>
<div class="paragraph">
<p>You can request that Jetty do a dump immediately after starting and just before stopping by calling the appropriate setters on the <code>Server</code> instance.
This functionality can be enabled using two properties to control this behaviour which are referenced in <code>jetty.xml</code> to call these setters.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">jetty.server.dumpAfterStart=true
jetty.server.dumpBeforeStop=true</code></pre>
</div>
</div>
<div class="paragraph">
<p>The server dump can be temporarily enabled by supplying either of these properties as command line arguments,
or they can be enabled via the <code>server.ini</code> file (see <a href="#quick-start-configure">An Introduction to Jetty Configuration</a>).</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-shell" data-lang="shell">$ java -jar $JETTY_HOME/start.jar jetty.server.dumpAfterStart=true jetty.server.dumpBeforeStop=true</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="extra-threadpool-info"><a class="anchor" href="#extra-threadpool-info"></a><a class="link" href="#extra-threadpool-info">Extra ThreadPool Information</a></h4>
<div class="paragraph">
<p>To get maximum detail from the <code>QueuedThreadPool</code> in the dump, you need to enable a detailed dump on any instances of <code>QueuedThreadPool</code> you are using.
This extra detail in the detailed dump consists of full stack traces for every running thread, and a list of queued jobs waiting to be run.</p>
</div>
<div class="paragraph">
<p>This can be enabled using the <code>threadpool</code> module and configuring the <code>jetty.threadPool.detailedDump</code> property.
See <a href="#startup-modules">Managing Startup Modules</a> for information on how to enable a module.
This same property can also be set via the command line the same as the server dump property.</p>
</div>
</div>
<div class="sect3">
<h4 id="dump-tool-via-jmx"><a class="anchor" href="#dump-tool-via-jmx"></a><a class="link" href="#dump-tool-via-jmx">Using the Dump Feature via JMX</a></h4>
<div class="paragraph">
<p>The <code>dump</code> method is on the Server instance and many of its nested components (Handlers, Connectors, and so forth).
Dumps may be obtained by calling these methods either in code or via JMX (see <a href="#using-jmx">Using JMX with Jetty</a>).</p>
</div>
<div class="paragraph">
<p>The Server MBean has a <code>dump()</code> method, which dumps everything, plus a <code>dumpStdErr()</code> operation that dumps to StdErr rather than replying to JConsole.</p>
</div>
</div>
<div class="sect3">
<h4 id="examing-jetty-distro-dump"><a class="anchor" href="#examing-jetty-distro-dump"></a><a class="link" href="#examing-jetty-distro-dump">Explanation of the Dump Key</a></h4>
<div class="ulist">
<ul>
<li>
<p><code>+- bean</code> is a java POJO that is contained by the parent object as a bean added with the addBean method.</p>
</li>
<li>
<p><code>+= managed</code> is a bean that is also a LifeCycle that is started and stopped with the parent object.</p>
</li>
<li>
<p><code>+~ unmanaged</code> is a bean that is also a LifeCycle that is started and stopped with the parent object. It is typically shared with other objects (hence its children are not dumped).</p>
</li>
<li>
<p><code>+? auto</code> is a bean that has been added to an unstarted parent. If it is a LifeCycle that is not started when the parent is started, then it is started and becomes a managed bean, otherwise it becomes either unmanaged or just a bean.</p>
</li>
<li>
<p><code>+: iterable</code> is an object that is contained within an iterable field of the parent (eg a list, set etc).</p>
</li>
<li>
<p><code>+] array</code> is an object that is contained within an array field of the parent.</p>
</li>
<li>
<p><code>+@ map</code> is an object that is contained within an map field of the parent.</p>
</li>
<li>
<p><code>+&gt; undefined</code> is an object that is contained within the parent by an undefined relationship.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_jetty-server-dump-example"><a class="anchor" href="#_jetty-server-dump-example"></a><a class="link" href="#_jetty-server-dump-example">Jetty Server Dump Example</a></h4>
<div class="paragraph">
<p>This is a dump of the OneServletContext embedded example with extra threadpool information:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>Server@59906517{STARTED}[9.4.32-SNAPSHOT] - STARTED
+= QueuedThreadPool[qtp488044861]@1d16f93d{STARTED,8&lt;=8&lt;=200,i=2,r=4,q=0}[ReservedThreadExecutor@16267862{s=2/4,p=0}] - STARTED
| += ReservedThreadExecutor@16267862{s=2/4,p=0} - STARTED
| +&gt; threads size=8
| | +&gt; qtp488044861-13 RUNNABLE tid=13 prio=5 SELECTING
| | +&gt; qtp488044861-15-acceptor-0@296e0338-ServerConnector@1e6d1014{HTTP/1.1, (http/1.1)}{0.0.0.0:8080} RUNNABLE tid=15 prio=3 ACCEPTING
| | +&gt; qtp488044861-17 TIMED_WAITING tid=17 prio=5 RESERVED
| | +&gt; qtp488044861-19 RUNNABLE tid=19 prio=5
| | | +&gt; app//org.eclipse.jetty.http.pathmap.PathMappings.getMatch(PathMappings.java:130)
| | | +&gt; app//org.eclipse.jetty.servlet.ServletHandler.getMappedServlet(ServletHandler.java:591)
| | | +&gt; app//org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:474)
| | | +&gt; app//org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1582)
| | | +&gt; app//org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
| | | +&gt; app//org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349)
| | | +&gt; app//org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
| | | +&gt; app//org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
| | | +&gt; app//org.eclipse.jetty.server.Server.handle(Server.java:516)
| | | +&gt; app//org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383)
| | | +&gt; app//org.eclipse.jetty.server.HttpChannel$$Lambda$102/0x000000010016d440.dispatch(Unknown Source)
| | | +&gt; app//org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:556)
| | | +&gt; app//org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375)
| | | +&gt; app//org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:273)
| | | +&gt; app//org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
| | | +&gt; app//org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
| | | +&gt; app//org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
| | | +&gt; app//org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
| | | +&gt; app//org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
| | | +&gt; app//org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
| | | +&gt; app//org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
| | | +&gt; app//org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:375)
| | | +&gt; app//org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:773)
| | | +&gt; app//org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:905)
| | | +&gt; java.base@11.0.5/java.lang.Thread.run(Thread.java:834)
| | +&gt; qtp488044861-16 TIMED_WAITING tid=16 prio=5 RESERVED
| | +&gt; qtp488044861-21 RUNNABLE tid=21 prio=5 SELECTING
| | +&gt; qtp488044861-18 TIMED_WAITING tid=18 prio=5 IDLE
| | +&gt; qtp488044861-14 TIMED_WAITING tid=14 prio=5 IDLE
| +&gt; jobs size=0
+= ServerConnector@1e6d1014{HTTP/1.1, (http/1.1)}{0.0.0.0:8080} - STARTED
| +~ Server@59906517{STARTED}[9.4.32-SNAPSHOT] - STARTED
| +~ QueuedThreadPool[qtp488044861]@1d16f93d{STARTED,8&lt;=8&lt;=200,i=2,r=4,q=0}[ReservedThreadExecutor@16267862{s=2/4,p=0}] - STARTED
| += ScheduledExecutorScheduler@453da22c{STARTED} - STARTED
| | +&gt; java.base@11.0.5/jdk.internal.misc.Unsafe.park(Native Method)
| | +&gt; java.base@11.0.5/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)
| | +&gt; java.base@11.0.5/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2123)
| | +&gt; java.base@11.0.5/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1182)
| | +&gt; java.base@11.0.5/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
| | +&gt; java.base@11.0.5/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1054)
| | +&gt; java.base@11.0.5/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1114)
| | +&gt; java.base@11.0.5/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
| | +&gt; java.base@11.0.5/java.lang.Thread.run(Thread.java:834)
| +- org.eclipse.jetty.io.ArrayByteBufferPool@71248c21
| += HttpConnectionFactory@3fd7a715[HTTP/1.1] - STARTED
| | +- HttpConfiguration@442675e1{32768/8192,8192/8192,https://:0,[]}
| | +&gt; customizers size=0
| | +&gt; formEncodedMethods size=2
| | | +&gt; POST
| | | +&gt; PUT
| | +&gt; outputBufferSize=32768
| | +&gt; outputAggregationSize=8192
| | +&gt; requestHeaderSize=8192
| | +&gt; responseHeaderSize=8192
| | +&gt; headerCacheSize=1024
| | +&gt; secureScheme=https
| | +&gt; securePort=0
| | +&gt; idleTimeout=-1
| | +&gt; blockingTimeout=-1
| | +&gt; sendDateHeader=true
| | +&gt; sendServerVersion=true
| | +&gt; sendXPoweredBy=false
| | +&gt; delayDispatchUntilContent=true
| | +&gt; persistentConnectionsEnabled=true
| | +&gt; maxErrorDispatches=10
| | +&gt; minRequestDataRate=0
| | +&gt; minResponseDataRate=0
| | +&gt; cookieCompliance=RFC6265
| | +&gt; setRequestCookieCompliance=RFC6265
| | +&gt; notifyRemoteAsyncErrors=true
| | +&gt; relativeRedirectAllowed=false
| += SelectorManager@ServerConnector@1e6d1014{HTTP/1.1, (http/1.1)}{0.0.0.0:8080} - STARTED
| | += ManagedSelector@38364841{STARTED} id=0 keys=0 selected=0 updates=0 - STARTED
| | | += EatWhatYouKill@28c4711c/SelectorProducer@59717824/PRODUCING/p=false/QueuedThreadPool[qtp488044861]@1d16f93d{STARTED,8&lt;=8&lt;=200,i=2,r=4,q=0}[ReservedThreadExecutor@16267862{s=2/4,p=0}][pc=0,pic=0,pec=0,epc=0]@2020-09-04T10:57:20.077669+10:00 - STARTED
| | | | +- SelectorProducer@59717824
| | | | +~ QueuedThreadPool[qtp488044861]@1d16f93d{STARTED,8&lt;=8&lt;=200,i=2,r=4,q=0}[ReservedThreadExecutor@16267862{s=2/4,p=0}] - STARTED
| | | +&gt; updates @ 2020-09-04T10:57:20.058489+10:00 size=0
| | | +&gt; keys @ 2020-09-04T10:57:20.061714+10:00 size=0
| | += ManagedSelector@146044d7{STARTED} id=1 keys=1 selected=0 updates=0 - STARTED
| | += EatWhatYouKill@1e9e725a/SelectorProducer@15d9bc04/PRODUCING/p=false/QueuedThreadPool[qtp488044861]@1d16f93d{STARTED,8&lt;=8&lt;=200,i=2,r=4,q=0}[ReservedThreadExecutor@16267862{s=2/4,p=0}][pc=0,pic=0,pec=1,epc=14]@2020-09-04T10:57:20.082696+10:00 - STARTED
| | | +- SelectorProducer@15d9bc04
| | | +~ QueuedThreadPool[qtp488044861]@1d16f93d{STARTED,8&lt;=8&lt;=200,i=2,r=4,q=0}[ReservedThreadExecutor@16267862{s=2/4,p=0}] - STARTED
| | +&gt; updates @ 2020-09-04T10:57:20.078661+10:00 size=0
| | +&gt; keys @ 2020-09-04T10:57:20.082035+10:00 size=1
| | +&gt; SelectionKey@74bb45ed{i=0}-&gt;SocketChannelEndPoint@569ef11f{l=/127.0.0.1:8080,r=/127.0.0.1:58702,OPEN,fill=-,flush=-,to=3/30000}{io=0/0,kio=0,kro=1}-&gt;HttpConnection@25b03990[p=HttpParser{s=CONTENT,0 of -1},g=HttpGenerator@218fb9fe{s=START}]=&gt;HttpChannelOverHttp@648d33ab{s=HttpChannelState@717b7e16{s=HANDLING rs=BLOCKING os=OPEN is=IDLE awp=false se=false i=true al=0},r=54,c=false/false,a=HANDLING,uri=//localhost:8080/,age=4}
| +- sun.nio.ch.ServerSocketChannelImpl[/0:0:0:0:0:0:0:0:8080]
| +- qtp488044861-15-acceptor-0@296e0338-ServerConnector@1e6d1014{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
+= AttributeContainerMap@473b46c3{size=0} - STARTED
+= o.e.j.s.ServletContextHandler@3ffcd140{/,file:///tmp/,AVAILABLE} - STARTED
| += org.eclipse.jetty.server.session.SessionHandler1089504328==dftMaxIdleSec=-1 - STARTED
| | += ServletHandler@516be40f{STARTED} - STARTED
| | | +&gt; listeners ServletHandler@516be40f{STARTED} size=2
| | | | +&gt; ListenerHolder@3c0a50da{STARTED}: org.eclipse.jetty.demos.OneServletContext$InitListener - STARTED
| | | | +&gt; ListenerHolder@646be2c3{STARTED}: org.eclipse.jetty.demos.OneServletContext$RequestListener - STARTED
| | | +&gt; filters ServletHandler@516be40f{STARTED} size=2
| | | | +&gt; org.eclipse.jetty.demos.OneServletContext$TestFilter-e874448@e874448==org.eclipse.jetty.demos.OneServletContext$TestFilter,inst=true,async=true - STARTED
| | | | | +&gt; org.eclipse.jetty.demos.OneServletContext$TestFilter@797badd3
| | | | +&gt; org.eclipse.jetty.demos.OneServletContext$TestFilter-60285225@60285225==org.eclipse.jetty.demos.OneServletContext$TestFilter,inst=true,async=true - STARTED
| | | | +&gt; org.eclipse.jetty.demos.OneServletContext$TestFilter@77be656f
| | | +&gt; filterMappings ServletHandler@516be40f{STARTED} size=2
| | | | +&gt; [/test/*]/[]/[REQUEST]=&gt;org.eclipse.jetty.demos.OneServletContext$TestFilter-e874448
| | | | +&gt; [*.test]/[]/[ASYNC, REQUEST]=&gt;org.eclipse.jetty.demos.OneServletContext$TestFilter-60285225
| | | +&gt; servlets ServletHandler@516be40f{STARTED} size=3
| | | | +&gt; org.eclipse.jetty.demos.HelloServlet-58c1670b@d20bf05b==org.eclipse.jetty.demos.HelloServlet,jsp=null,order=-1,inst=false,async=true - STARTED
| | | | | +&gt; class org.eclipse.jetty.demos.HelloServlet
| | | | +&gt; debug@5b09653==org.eclipse.jetty.demos.DumpServlet,jsp=null,order=-1,inst=false,async=true - STARTED
| | | | | +&gt; class org.eclipse.jetty.demos.DumpServlet
| | | | +&gt; org.eclipse.jetty.servlet.DefaultServlet-6b9651f3@8eb381d1==org.eclipse.jetty.servlet.DefaultServlet,jsp=null,order=-1,inst=true,async=true - STARTED
| | | | +&gt; org.eclipse.jetty.servlet.DefaultServlet@78a2da20
| | | +&gt; servletMappings ServletHandler@516be40f{STARTED} size=4
| | | +&gt; [/hello/*]=&gt;org.eclipse.jetty.demos.HelloServlet-58c1670b
| | | +&gt; [/dump/*]=&gt;debug
| | | +&gt; [*.dump]=&gt;debug
| | | +&gt; [/]=&gt;org.eclipse.jetty.servlet.DefaultServlet-6b9651f3
| | += org.eclipse.jetty.server.session.DefaultSessionCache@dd3b207[evict=-1,removeUnloadable=false,saveOnCreate=false,saveOnInactiveEvict=false] - STARTED
| | | += org.eclipse.jetty.server.session.NullSessionDataStore@551bdc27[passivating=false,graceSec=3600] - STARTED
| | +~ DefaultSessionIdManager@58fdd99{STARTED}[worker=node0] - STARTED
| +&gt; No ClassLoader
| +&gt; eventListeners o.e.j.s.ServletContextHandler@3ffcd140{/,file:///tmp/,AVAILABLE} size=2
| | +&gt; org.eclipse.jetty.demos.OneServletContext$InitListener@6b1274d2
| | +&gt; org.eclipse.jetty.demos.OneServletContext$RequestListener@7bc1a03d
| +&gt; handler attributes o.e.j.s.ServletContextHandler@3ffcd140{/,file:///tmp/,AVAILABLE} size=1
| | +&gt; org.eclipse.jetty.server.Executor=QueuedThreadPool[qtp488044861]@1d16f93d{STARTED,8&lt;=8&lt;=200,i=2,r=4,q=0}[ReservedThreadExecutor@16267862{s=2/4,p=0}]
| +&gt; context attributes o.e.j.s.ServletContextHandler@3ffcd140{/,file:///tmp/,AVAILABLE} size=2
| | +&gt; org.eclipse.jetty.util.DecoratedObjectFactory=org.eclipse.jetty.util.DecoratedObjectFactory[decorators=1]
| | +&gt; X-Init=true
| +&gt; initparams o.e.j.s.ServletContextHandler@3ffcd140{/,file:///tmp/,AVAILABLE} size=0
+= ErrorHandler@ba8d91c{STARTED} - STARTED
+= DefaultSessionIdManager@58fdd99{STARTED}[worker=node0] - STARTED
| += HouseKeeper@60438a68{STARTED}[interval=660000, ownscheduler=true] - STARTED
+&gt; jdk.internal.loader.ClassLoaders$AppClassLoader@2c13da15
+&gt; jdk.internal.loader.ClassLoaders$PlatformClassLoader@7364985f
key: +- bean, += managed, +~ unmanaged, +? auto, +: iterable, +] array, +@ map, +&gt; undefined</pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jetty-maven-scanning"><a class="anchor" href="#jetty-maven-scanning"></a><a class="link" href="#jetty-maven-scanning">Files Scanned by the Jetty Maven Plugin</a></h3>
<div class="paragraph">
<p>If you set a non zero <code>scanIntervalSeconds</code> <a href="#jetty-maven-plugin">configuration parameter</a>, the <code>jetty-maven-plugin</code> will scan certain files for changes, and redeploy the webapp if necessary.
The files that are scanned depend on the goal being executed.</p>
</div>
<div class="sect3">
<h4 id="scanner-matrix"><a class="anchor" href="#scanner-matrix"></a><a class="link" href="#scanner-matrix">Scanner Matrix</a></h4>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 66.6667%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Goal</th>
<th class="tableblock halign-left valign-top">Files</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#jetty-run-goal">jetty:run</a></p></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="ulist">
<ul>
<li>
<p>pom.xml</p>
</li>
<li>
<p>&lt;dependencies&gt;</p>
</li>
<li>
<p>&lt;classesDirectory&gt;</p>
</li>
<li>
<p>&lt;testClassesDirectory&gt;</p>
</li>
<li>
<p>&lt;webApp&gt;&lt;descriptor/&gt;&lt;/webApp&gt; or src/main/webapp/WEB-INF/web.xml</p>
</li>
<li>
<p>&lt;webApp&gt;&lt;jettyEnvXml/&gt;&lt;/webApp&gt; or src/main/webapp/WEB-INF/jetty-web.xml</p>
</li>
<li>
<p>&lt;webApp&gt;&lt;baseResource&gt;/WEB-INF/jetty-web.xml</p>
</li>
<li>
<p>&lt;scanTargets&gt;</p>
</li>
<li>
<p>&lt;scanTargetPatterns&gt;</p>
</li>
<li>
<p>any <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#setDefaultsDescriptor%28java.lang.String%29">defaultsDescriptor</a> for the webapp</p>
</li>
<li>
<p>any <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#setOverrideDescriptor%28java.lang.String%29">overrideDescriptor</a> for the webapp</p>
</li>
<li>
<p>any dependencies that are wars or zips</p>
</li>
</ul>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#running-assembled-webapp-as-war">jetty:run-war</a></p></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="ulist">
<ul>
<li>
<p>pom.xml</p>
</li>
<li>
<p>&lt;war&gt;</p>
</li>
</ul>
</div></div></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="platforms"><a class="anchor" href="#platforms"></a><a class="link" href="#platforms">Platforms, Stacks and Alternative Distributions</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_many-many-options"><a class="anchor" href="#_many-many-options"></a><a class="link" href="#_many-many-options">Many many options&#8230;&#8203;</a></h3>
<div class="paragraph">
<p>In addition to using Jetty in its distribution form and its multiple embedded forms, there are a number of alternative ways to use Jetty.
Many products and open source projects out there distribute Jetty themselves, in both distribution and embedded forms, not to mention different operating systems bundling Jetty in other installable forms.</p>
</div>
<div class="paragraph">
<p>If your platform supports Jetty from a distribution or deployment perspective and want to be included on this list just fork the documentation and submit a pull request, or contact us.
Check out our list of <a href="http://www.eclipse.org/jetty/powered">Powered By</a> page for software that makes use of Jetty, often in novel and exciting ways.</p>
</div>
</div>
<div class="sect2">
<h3 id="jelastic"><a class="anchor" href="#jelastic"></a><a class="link" href="#jelastic">Jelastic</a></h3>
<div class="paragraph">
<p>Jelastic is a wonderful place to host your applications with solid support for Jetty.
As a cloud hosting platform they take the majority of configuration and installation details out of the picture and focus on letting you focus on your web application.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="http://jelastic.com/why">Why Jelastic?</a></p>
</li>
<li>
<p><a href="http://jelastic.com/jetty-hosting">Jetty Hosting</a></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="cloudfoundry"><a class="anchor" href="#cloudfoundry"></a><a class="link" href="#cloudfoundry">CloudFoundry</a></h3>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
This is an increasingly aged integration, things like likely changed enough this is not directly useful but may serve as a useful starting point should someone want to look into it.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect3">
<h4 id="cloudfoundry-overview"><a class="anchor" href="#cloudfoundry-overview"></a><a class="link" href="#cloudfoundry-overview">Overview</a></h4>
<div class="paragraph">
<p><a href="http://www.cloudfoundry.com">CloudFoundry</a> is an open platform intended as a place to deploy end user applications in a manner which is both simple and eminently scalable to fit the needs of the application.
With the release of their V2 framework the Jetty project has created a buildpack which allows you to deploy your java based web application onto Jetty and still make use of the remainder of the CloudFoundry platform.</p>
</div>
<div class="paragraph">
<p>This buildpack itself is quite simple to use.
A collection of ruby scripting and the buildpack conventions will allow Jetty to be downloaded, configured and customized to your needs and then have your web application deployed onto it.
While the default buildpack we have created is useful to deploy a stock configuration of jetty, it is quite likely that you will want to fork the buildpack and tweak it to fit your immediate needs.
This process is made trivial since buildpacks install from a github repository.
For example, to change the jetty version simply fork it in GitHub and tweak the <code>JETTY_VERSION</code> string in the <code>jetty_web.rb</code> file.</p>
</div>
<div class="paragraph">
<p>If you have additional modifications to make to the Jetty server, like perhaps configuring additional static contexts, setting up a proxy servlet, adding jar files to the jetty home/lib/ext directory, etc you can either adapt the ruby scripting directly or place them under the appropriate location in the <code>/resources</code> directory of this buildpack and they will be copied into the correct location.</p>
</div>
<div class="paragraph">
<p>For the time being I&#8217;ll leave this buildpack under my personal github account and should there be interest expressed I am more then happy to push it over to <a href="https://github.com/jetty-project" class="bare">https://github.com/jetty-project</a> down the road for proper contributions, etc.</p>
</div>
</div>
<div class="sect3">
<h4 id="cloudfoundry-usage"><a class="anchor" href="#cloudfoundry-usage"></a><a class="link" href="#cloudfoundry-usage">Usage</a></h4>
<div class="paragraph">
<p>To show how incredibly easy it is to use the Jetty buildpack with cloudfoundry, this is all the more you need to do to deploy your application.
Refer to the CloudFoundry <a href="http://docs.cloudfoundry.com/">documentation</a> to get started, get the <code>cf</code> utilities installed and an environment configured.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ cf push snifftest --buildpack=git://github.com/jmcc0nn3ll/jetty-buildpack.git</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
In this example the web application is uploaded from the <strong>current</strong> directory so make sure you have changed directory into the root of your web application.
The <code>snifftest</code> on the commandline refers to what you are calling the application, not the directory to deploy.
Also note that the webapplication is installed into the <code>ROOT</code> context of Jetty as is available at the root context of the server.
Any additional web applications will have to be configured within the buildpack as mentioned above.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>You will be prompted to answer a series of questions describing the execution environment and any additional services you need enabled (databases, etc).</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">Instances&gt; 1
Custom startup command&gt; none
1: 64M
2: 128M
3: 256M
4: 512M
5: 1G
Memory Limit&gt; 256M
Creating snifftest... OK
1: snifftest
2: none
Subdomain&gt; snifftest
1: a1-app.cf-app.com
2: none
Domain&gt; a1-app.cf-app.com
Binding snifftest.a1-app.cf-app.com to snifftest... OK
Create services for application?&gt; n
Save configuration?&gt; n</code></pre>
</div>
</div>
<div class="paragraph">
<p>Once answered you will see the installation process of your application.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">Uploading snifftest... OK
Starting snifftest... OK
-&gt; Downloaded app package (4.0K)
Initialized empty Git repository in /tmp/buildpacks/jetty-buildpack.git/.git/
Installing jetty-buildpack.git.
Downloading JDK...
Copying openjdk-1.7.0_21.tar.gz from the buildpack cache ...
Unpacking JDK to .jdk
Downloading Jetty: jetty-distribution-10.0.0-SNAPSHOT.tar.gz
Downloading jetty-distribution-10.0.0-SNAPSHOT.tar.gz from http://repo2.maven.org/maven2/org/eclipse/jetty/jetty-distribution/9.0.3.v20130506/ ...
Unpacking Jetty to .jetty
-&gt; Uploading staged droplet (36M)
-&gt; Uploaded droplet
Checking snifftest...
Staging in progress...
Staging in progress...
Staging in progress...
Staging in progress...
Staging in progress...
Staging in progress...
0/1 instances: 1 starting
0/1 instances: 1 starting
0/1 instances: 1 starting
0/1 instances: 1 starting
1/1 instances: 1 running
OK</code></pre>
</div>
</div>
<div class="paragraph">
<p>The application is now available at the configured location! Under the url <code><a href="http://snifftest.a1-app.cf-app.com/" class="bare">http://snifftest.a1-app.cf-app.com/</a></code> in this particular example.</p>
</div>
</div>
<div class="sect3">
<h4 id="cloudfoundry-acknowledgements"><a class="anchor" href="#cloudfoundry-acknowledgements"></a><a class="link" href="#cloudfoundry-acknowledgements">Acknowledgements</a></h4>
<div class="paragraph">
<p>The Jetty buildpack was forked from the CloudFoundry Java buildpack. The Virgo Buildpack that Glyn worked on was used as a sanity check.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="http://github.com/cloudfoundry/cloudfoundry-buildpack-java" class="bare">http://github.com/cloudfoundry/cloudfoundry-buildpack-java</a></p>
</li>
<li>
<p><a href="http://github.com/glyn/virgo-buildpack" class="bare">http://github.com/glyn/virgo-buildpack</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>CloudFoundry buildpacks were modelled on Heroku buildpacks.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="elastic-beanstalk"><a class="anchor" href="#elastic-beanstalk"></a><a class="link" href="#elastic-beanstalk">Amazon Elastic Beanstalk</a></h3>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
This is an increasingly aged integration, things like likely changed enough this is not directly useful but may serve as a useful starting point should someone want to look into it.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p><a href="http://aws.amazon.com/elasticbeanstalk/">Elastic Beanstalk</a> is a component with the <a href="http://aws.amazon.com">Amazon Web Services</a> offering that allows you to configure an entire virtual machine based on one of several available baseline configurations and then customize it through a powerful configuration system. While the default offerings currently available are based on Tomcat for for the java community, we worked out the basics using that configuration system to enable the usage of Jetty instead.</p>
</div>
<div class="sect3">
<h4 id="elastic-beanstalk-overview"><a class="anchor" href="#elastic-beanstalk-overview"></a><a class="link" href="#elastic-beanstalk-overview">Overview</a></h4>
<div class="paragraph">
<p>Elastic beanstalk has a very <a href="http://aws.amazon.com/about-aws/whats-new/2012/10/02/introducing-aws-elastic-beanstalk-configuration-files/">powerful configuration mechanism</a> so this integration taps into that to effectively rework the tomcat configuration and replace it with the bits required to make jetty run in its place. Below is a walk through of what the various configuration files are doing and how the general flow of configuration on beanstalk happens.</p>
</div>
<div class="paragraph">
<p>There is an <code>.ebextensions</code> directory in your beanstalk application which contains all of the files requires to configure and customize your beanstalk and application combo.
Files that end in .config in this directory are processed in alphabetical order.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">00-java7.config</dt>
<dd>
<p>installs java 7 onto the beanstalk environment and makes it the default</p>
</dd>
<dt class="hdlist1">10-tweak.config</dt>
<dd>
<p>not required, but changes the <code>/opt/elasticbeanstalk</code> directory to be readable making debugging easier</p>
</dd>
<dt class="hdlist1">11-jetty.config</dt>
<dd>
<p>installs jetty9 into <code>/opt/jetty-9</code> and removes unneeded distribution files</p>
</dd>
<dt class="hdlist1">12-beanstalk.config</dt>
<dd>
<p>handles replacing tomcat with jetty in many configuration files, configures logging and wires up system startup processes.
Some files in your <code>.ebextensions</code> directory are moved to replace files under /opt/elasticbeanstalk.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>If you look in the <code>.ebextensions</code> directory of your application you should also see other jetty specific xml and ini files.
The final config file handles these as they are largely customization for your application.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">20-testapp.config</dt>
<dd>
<p>layers application specific configuration files into the jetty installation</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>The files in our example test webapp here enable various OPTIONS for libraries that need to be loaded, customize the root application being deployed and even deploy additional contexts like we do in our jetty distribution demo.
This is also the mechanism that you would use to wire up application specific things, for example if you needed additional software installed, customized directories made, etc.</p>
</div>
</div>
<div class="sect3">
<h4 id="elastic-beanstalk-maven"><a class="anchor" href="#elastic-beanstalk-maven"></a><a class="link" href="#elastic-beanstalk-maven">Maven Bits</a></h4>
<div class="paragraph">
<p>Support for this feature leverages Maven to make things easy and is composed of three different modules.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">jetty-beanstalk-overlay</dt>
<dd>
<p>This is the collection of scripts that are required to wedge jetty into the normal beanstalk setup.
This module is intended to extract into an webapp to enable it for beanstalk usage with jetty.</p>
</dd>
<dt class="hdlist1">jetty-beanstalk-resources</dt>
<dd>
<p>This generates an artifact of files that are downloaded by the configuration process and contains replacements for certain beanstalk files as well as various system level jetty configuration files like an updated <code>jetty.sh</code> script for the <code>/etc/init.d</code> setup.</p>
</dd>
<dt class="hdlist1">jetty-beanstalk-testapp</dt>
<dd>
<p>An example webapp that shows both how to combine the war file from another maven module with the jetty-beanstalk-overlay to produce a beanstalk enabled application bundle.
Also included is examples of how to alter the jetty configuration for things like a customized
<code>start.ini</code> file.</p>
</dd>
</dl>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The test webapps needs access to a snapshot version of the test-jetty-webapp so it really serves as more of an example of how to layer your webapp with the bits required to customize your app for beanstalk and jetty.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>To actually make use of these artifacts you currently must clone this git repository and build it locally.
Once you have the artifacts you simply need to copy the approach in the jetty-beanstalk-testapp to apply the configuration to your webapp.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://github.com/jmcc0nn3ll/jetty-beanstalk" class="bare">https://github.com/jmcc0nn3ll/jetty-beanstalk</a></p>
</li>
</ul>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
Bluepill is used to manage the start and stop process of the app server.
This seems to be a problematic bit of software with a colored history and the version in use at the time of this writing is old.
When starting and stopping (or restarting) the appserver you may see error messages show up that the Server timed out getting a response or things like that.
These are red herrings and my experience is that jetty has started and stopped just fine, the pid file required shows up in a very timely fashion (under <code>/var/run/jetty.pid</code>) so do check that the app server has started, but please be aware there is a strangeness here that hasn&#8217;t been sorted out yet.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
</div>
<div class="sect2">
<h3 id="fedora"><a class="anchor" href="#fedora"></a><a class="link" href="#fedora">Fedora</a></h3>
<div class="paragraph">
<p>As of Fedora 19, Jetty 9 is the version of Jetty available.
This distribution of Jetty is not created or maintained by the Jetty project though we have had a fair amount of communication with the folks behind it and we are very pleased with how this Linux distribution has stayed current.
Releases are kept largely in sync with our releases as there is a wonderful automatic notification mechanism in place for Fedora that detects our releases and immediately opens an issue for them to update.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://admin.fedoraproject.org/pkgdb/acls/name/jetty">Jetty on Fedora</a></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="ubuntu"><a class="anchor" href="#ubuntu"></a><a class="link" href="#ubuntu">Ubuntu</a></h3>
<div class="paragraph">
<p>Currently there are no actual <code>.deb</code> files available for installing on Debian based Linux machines but there is a handy blog that as been largely been kept up to date on the steps involved through the comments.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="http://pietervogelaar.nl/ubuntu-12-04-install-jetty-9/">Install Jetty9
on Ubuntu</a></p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="runner"><a class="anchor" href="#runner"></a><a class="link" href="#runner">Jetty Runner</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>This chapter explains how to use the <code>jetty-runner</code> to run your webapps without needing an installation of Jetty.</p>
</div>
<div class="sect2">
<h3 id="jetty-runner"><a class="anchor" href="#jetty-runner"></a><a class="link" href="#jetty-runner">Use Jetty Without an Installed Distribution</a></h3>
<div class="paragraph">
<p>The idea of the <code>jetty-runner</code> is extremely simple – run a webapp directly from the command line using a single jar file and as much default configuration as possible.
Of course, if your webapp is not as straightforward, the <code>jetty-runner</code> has command line options which allow you to customize the execution environment.</p>
</div>
<div class="sect3">
<h4 id="jetty-runner-preparation"><a class="anchor" href="#jetty-runner-preparation"></a><a class="link" href="#jetty-runner-preparation">Preparation</a></h4>
<div class="paragraph">
<p>You will need the <code>jetty-runner</code> jar:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Download the <code>jetty-runner</code> jar available at <a href="https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-runner/">Maven Central</a>.</p>
</li>
</ol>
</div>
</div>
<div class="sect3">
<h4 id="_deploying-a-simple-context"><a class="anchor" href="#_deploying-a-simple-context"></a><a class="link" href="#_deploying-a-simple-context">Deploying a Simple Context</a></h4>
<div class="paragraph">
<p>Let&#8217;s assume we have a very simple webapp that does not need any resources from its environment, nor any configuration apart from the defaults.
Starting it is as simple as performing the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar simple.war</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will start Jetty on port 8080, and deploy the webapp to <code>/</code>.</p>
</div>
<div class="paragraph">
<p>Your webapp does not have to be packed into a war, you can deploy a webapp that is a directory instead in the same way:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar simple</code></pre>
</div>
</div>
<div class="paragraph">
<p>In fact, the webapp does not have to be a war or even a directory, it can simply be a Jetty <a href="#using-context-provider">context xml</a> file that describes your webapp:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar simple-context.xml</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
When using a context xml file, the application being deployed is not even required to be a fully-fledged webapp.
It can simply be a Jetty <a href="#what-is-a-context">context</a>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>By default, <code>jetty-runner</code> implements all Configuration Classes so that users can set up and deploy new instances with as little configuration as possible.
If you wish to only implement certain Configuration Classes, they will need to be defined in the context xml for the webapp/context.
The default Configuration Classes are:</p>
</div>
<div class="paragraph">
<p><code>org.eclipse.jetty.webapp.WebInfConfiguration</code>
<code>org.eclipse.jetty.webapp.WebXmlConfiguration</code>
<code>org.eclipse.jetty.webapp.MetaInfConfiguration</code>
<code>org.eclipse.jetty.webapp.FragmentConfiguration</code>
<code>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</code>
<code>org.eclipse.jetty.plus.webapp.EnvConfiguration</code>
<code>org.eclipse.jetty.plus.webapp.PlusConfiguration</code>
<code>org.eclipse.jetty.annotations.AnnotationConfiguration</code></p>
</div>
<div class="paragraph">
<p>You can learn more about implementing specific Configuration Classes <a href="https://www.eclipse.org/jetty/documentation/current/configuring-webapps.html#webapp-configurations">here.</a></p>
</div>
</div>
<div class="sect3">
<h4 id="_deploying-multiple-contexts"><a class="anchor" href="#_deploying-multiple-contexts"></a><a class="link" href="#_deploying-multiple-contexts">Deploying Multiple Contexts</a></h4>
<div class="paragraph">
<p>If you have more than one webapp that must be deployed, simply provide them all on the command line.
You can control the context paths for them using the <code>--path</code> parameter.
Here&#8217;s an example of deploying 2 wars (although either or both of them could be unpacked directories instead):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --path /one my1.war --path /two my2.war</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you have context xml files that describe your webapps, you can fully configure your webapps in them and hence you won&#8217;t need to use the command line switches.
Just provide the list of context files like so:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar my-first-context.xml my-second-context.xml my-third-context.xml</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Switched used on the command line override configuration file settings.
So, for example, you could set the context path for the webapp inside the context xml file, and use the <code>--path</code> switch to override it on the command line.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect4">
<h5 id="_changing-the-default-port"><a class="anchor" href="#_changing-the-default-port"></a><a class="link" href="#_changing-the-default-port">Changing the Default Port</a></h5>
<div class="paragraph">
<p>By default the <code>jetty-runner</code> will listen on port 8080.
You can easily change this on the command line using the <code>--port</code> command.
Here&#8217;s an example that runs our simple.war on port 9090:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --port 9090 simple.war</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_using-jetty-xml-files"><a class="anchor" href="#_using-jetty-xml-files"></a><a class="link" href="#_using-jetty-xml-files">Using jetty.xml Files</a></h5>
<div class="paragraph">
<p>Instead of, or in addition to, using command line switches, you can use one or more <code>jetty.xml</code> files to configure the environment for your webapps.
Here&#8217;s an example where we apply two different <code>jetty.xml</code> files:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --config jetty.xml --config jetty-https.xml simple.war</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="runner-configuration-reference"><a class="anchor" href="#runner-configuration-reference"></a><a class="link" href="#runner-configuration-reference">Full Configuration Reference</a></h4>
<div class="paragraph">
<p>You can see the fill set of configuration options using the <code>--help</code> switch:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --help</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here&#8217;s what the output will look like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-plain" data-lang="plain">Usage: java [-Djetty.home=dir] -jar jetty-runner.jar [--help|--version] [ server opts] [[ context opts] context ...]
Server opts:
--version - display version and exit
--log file - request log filename (with optional 'yyyy_mm_dd' wildcard
--out file - info/warn/debug log filename (with optional 'yyyy_mm_dd' wildcard
--host name|ip - interface to listen on (default is all interfaces)
--port n - port to listen on (default 8080)
--stop-port n - port to listen for stop command (or -DSTOP.PORT=n)
--stop-key n - security string for stop command (required if --stop-port is present) (or -DSTOP.KEY=n)
[--jar file]*n - each tuple specifies an extra jar to be added to the classloader
[--lib dir]*n - each tuple specifies an extra directory of jars to be added to the classloader
[--classes dir]*n - each tuple specifies an extra directory of classes to be added to the classloader
--stats [unsecure|realm.properties] - enable stats gathering servlet context
[--config file]*n - each tuple specifies the name of a jetty xml config file to apply (in the order defined)
Context opts:
[[--path /path] context]*n - WAR file, web app dir or context xml file, optionally with a context path</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_printing-the-version"><a class="anchor" href="#_printing-the-version"></a><a class="link" href="#_printing-the-version">Printing the Version</a></h5>
<div class="paragraph">
<p>Print out the version of Jetty and then exit immediately.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --version</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_configuring-a-request-log"><a class="anchor" href="#_configuring-a-request-log"></a><a class="link" href="#_configuring-a-request-log">Configuring a Request Log</a></h5>
<div class="paragraph">
<p>Cause Jetty to write a request log with the given name.
If the file is prefixed with <code>yyyy_mm_dd</code> then the file will be automatically rolled over.
Note that for finer grained configuration of the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/NCSARequestLog.html">request log</a>, you will need to use a Jetty xml file instead.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --log yyyy_mm_dd-requests.log my.war</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_configuring-the-output-log"><a class="anchor" href="#_configuring-the-output-log"></a><a class="link" href="#_configuring-the-output-log">Configuring the Output Log</a></h5>
<div class="paragraph">
<p>Redirect the output of jetty logging to the named file.
If the file is prefixed with <code>yyyy_mm_dd</code> then the file will be automatically rolled over.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --out yyyy_mm_dd-output.log my.war</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_configuring-the-interface-for-http"><a class="anchor" href="#_configuring-the-interface-for-http"></a><a class="link" href="#_configuring-the-interface-for-http">Configuring the Interface for HTTP</a></h5>
<div class="paragraph">
<p>Like Jetty standalone, the default is for the connectors to listen on all interfaces on a machine.
You can control that by specifying the name or ip address of the particular interface you wish to use with the <code>--host</code> argument:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --host 192.168.22.19 my.war</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_configuring-the-port-for-http"><a class="anchor" href="#_configuring-the-port-for-http"></a><a class="link" href="#_configuring-the-port-for-http">Configuring the Port for HTTP</a></h5>
<div class="paragraph">
<p>The default port number is 8080.
To <a href="#how-to-configure-connectors">configure a https connector</a>, use a Jetty xml config file instead.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --port 9090 my.war</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_configuring-stop"><a class="anchor" href="#_configuring-stop"></a><a class="link" href="#_configuring-stop">Configuring Stop</a></h5>
<div class="paragraph">
<p>You can configure a port number for Jetty to listen on for a stop command, so you are able to stop it from a different terminal.
This requires the use of a "secret" key, to prevent malicious or accidental termination.
Use the <code>--stop-port</code> and <code>--stop-key</code> (or <code>-DSTOP.PORT=</code> and <code>-DSTOP.KEY=</code>, respectively) parameters as arguments to the <code>jetty-runner</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --stop-port 8181 --stop-key abc123</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then, to stop Jetty from a different terminal, you need to supply the same port and key information.
For this you&#8217;ll either need a local installation of Jetty, the <a href="#jetty-maven-plugin">jetty-maven-plugin</a>, the <a href="#jetty-ant">jetty-ant plugin</a>, or a custom class.
Here&#8217;s how to use a Jetty installation to perform a stop:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar start.jar -DSTOP.PORT=8181 -DSTOP.KEY=abc123 --stop</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_configuring-the-container-classpath"><a class="anchor" href="#_configuring-the-container-classpath"></a><a class="link" href="#_configuring-the-container-classpath">Configuring the Container Classpath</a></h5>
<div class="paragraph">
<p>With a local installation of Jetty, you add jars and classes to the container&#8217;s classpath by putting them in the <code>{$jetty.base}/lib</code> directory.
With the <code>jetty-runner</code>, you can use the <code>--lib</code>, <code>--jar</code> and <code>--classes</code> arguments instead to achieve the same thing.</p>
</div>
<div class="paragraph">
<p><code>--lib</code> adds the location of a directory which contains jars to add to the container classpath.
You can add 1 or more.
Here&#8217;s an example of configuring 2 directories:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --lib /usr/local/external/lib --lib $HOME/external-other/lib my.war</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>--jar</code> adds a single jar file to the container classpath.
You can add 1 or more.
Here&#8217;s an example of configuring 3 extra jars:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --jar /opt/stuff/jars/jar1.jar --jar $HOME/jars/jar2.jar --jar /usr/local/proj/jars/jar3.jar my.war</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>--classes</code> add the location of a directory containing classes to add to the container classpath.
You can add 1 or more.
Here&#8217;s an example of configuring a single extra classes dir:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --classes /opt/stuff/classes my.war</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
When using the <code>--jar</code> and/or <code>--lib</code> arguments, by default these will <strong>not</strong> be inspected for <code>META-INF</code> information such as <code>META-INF/resources</code>, <code>META-INF/web-fragment.xml</code>, or <code>META-INF/taglib.tld</code>.
If you require these jar files inspected you will need to define the <a href="https://www.eclipse.org/jetty/documentation/current/configuring-webapps.html#webapp-context-attributes">jar pattern in your context xml file</a>.
Jetty-Runner automatically provides and appends a suitable pattern for jtsl taglibs (this pattern is different than the one in the standard Jetty distribution).
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect4">
<h5 id="_gathering-statistics"><a class="anchor" href="#_gathering-statistics"></a><a class="link" href="#_gathering-statistics">Gathering Statistics</a></h5>
<div class="paragraph">
<p>If statistics gathering is enabled, then they are viewable by surfing to the context <code>/stats</code>.
You may optionally protect access to that context with a password.
Here&#8217;s an example of enabling statistics, with no password protection:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --stats unsecure my.war</code></pre>
</div>
</div>
<div class="paragraph">
<p>If we wished to protect access to the <code>/stats</code> context, we would provide the location of a Jetty realm configuration file containing authentication and authorization information.
For example, we could use the following example realm file from the Jetty distribution:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">jetty: MD5:164c88b302622e17050af52c89945d44,user
admin: CRYPT:adpexzg3FUZAk,server-administrator,content-administrator,admin
other: OBF:1xmk1w261u9r1w1c1xmq,user
plain: plain,user
user: password,user
# This entry is for digest auth. The credential is a MD5 hash of username:realmname:password
digest: MD5:6e120743ad67abfbc385bc2bb754e297,user</code></pre>
</div>
</div>
<div class="paragraph">
<p>Assuming we&#8217;ve copied it into the local directory, we would apply it like so</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">&gt; java -jar jetty-runner.jar --stats realm.properties my.war</code></pre>
</div>
</div>
<div class="paragraph">
<p>After navigating to <a href="http://localhost:8080/" class="bare">http://localhost:8080/</a> a few times, we can point to the stats servlet on <a href="http://localhost:8080/stats" class="bare">http://localhost:8080/stats</a> to see the output:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>Statistics:
Statistics gathering started 1490627ms ago
Requests:
Total requests: 9
Active requests: 1
Max active requests: 1
Total requests time: 63
Mean request time: 7.875
Max request time: 26
Request time standard deviation: 8.349764752888037
Dispatches:
Total dispatched: 9
Active dispatched: 1
Max active dispatched: 1
Total dispatched time: 63
Mean dispatched time: 7.875
Max dispatched time: 26
Dispatched time standard deviation: 8.349764752888037
Total requests suspended: 0
Total requests expired: 0
Total requests resumed: 0
Responses:
1xx responses: 0
2xx responses: 7
3xx responses: 1
4xx responses: 0
5xx responses: 0
Bytes sent total: 1453
Connections:
org.eclipse.jetty.server.ServerConnector@203822411
Protocols:http/1.1
Statistics gathering started 1490606ms ago
Total connections: 7
Current connections open: 1
Max concurrent connections open: 2
Total connections duration: 72883
Mean connection duration: 12147.166666666666
Max connection duration: 65591
Connection duration standard deviation: 23912.40292977684
Total messages in: 7
Total messages out: 7
Memory:
Heap memory usage: 49194840 bytes
Non-heap memory usage: 12611696 bytes</pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configuring-security"><a class="anchor" href="#configuring-security"></a><a class="link" href="#configuring-security">Configuring Security</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="configuring-security-authentication"><a class="anchor" href="#configuring-security-authentication"></a><a class="link" href="#configuring-security-authentication">Authentication and Authorization</a></h3>
<div class="paragraph">
<p>There are two aspects to securing a web application(or context) within the Jetty server:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Authentication</dt>
<dd>
<p>The web application can be configured with a mechanism to determine the identity of the user.
This is configured by a mix of standard declarations and jetty specific mechanisms and is covered in this section.</p>
</dd>
<dt class="hdlist1">Authorization</dt>
<dd>
<p>Once the identify of the user is known (or not known), the web application can be configured via standard descriptors with security constraints that declare what resources that user may access.</p>
</dd>
</dl>
</div>
<div class="sect3">
<h4 id="_configuring-an-authentication-mechanism"><a class="anchor" href="#_configuring-an-authentication-mechanism"></a><a class="link" href="#_configuring-an-authentication-mechanism">Configuring an Authentication mechanism</a></h4>
<div class="paragraph">
<p>Jetty server supports several standard authentication mechanisms: <a href="http://en.wikipedia.org/wiki/Basic_access_authentication">BASIC</a>; <a href="http://en.wikipedia.org/wiki/Digest_authentication">DIGEST</a>; <a href="http://en.wikipedia.org/wiki/Form-based_authentication">FORM</a>; CLIENT-CERT; and other mechanisms can be plugged in using the extensible <a href="http://docs.oracle.com/cd/E19462-01/819-6717/gcszc/index.html">JASPI</a> or <a href="http://en.wikipedia.org/wiki/SPNEGO">SPNEGO</a> mechanisms.</p>
</div>
<div class="paragraph">
<p>Internally, configuring an authentication mechanism is done by setting an instance of a the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/security/Authenticator.html">Authenticator</a> interface onto the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/security/SecurityHandler.html">SecurityHandler</a> of the context, but in most cases it is done by declaring a <code>&lt;login-config&gt;</code> element in the standard web.xml descriptor or via annotations.</p>
</div>
<div class="paragraph">
<p>Below is an example taken from the <a href="https://github.com/eclipse/jetty.project/tree/master/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml?h=release-9">jetty-test-webapp web.xml</a> that configures BASIC authentication:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;login-config&gt;
&lt;auth-method&gt;BASIC&lt;/auth-method&gt;
&lt;realm-name&gt;Test Realm&lt;/realm-name&gt;
&lt;/login-config&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <a href="https://github.com/eclipse/jetty.project/tree/master/tests/test-webapps/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml?h=release-9">jetty-test-webapp web.xml</a> also includes commented out examples of other DIGEST and FORM configuration:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;login-config&gt;
&lt;auth-method&gt;FORM&lt;/auth-method&gt;
&lt;realm-name&gt;Test Realm&lt;/realm-name&gt;
&lt;form-login-config&gt;
&lt;form-login-page&gt;/logon.html?param=test&lt;/form-login-page&gt;
&lt;form-error-page&gt;/logonError.html?param=test&lt;/form-error-page&gt;
&lt;/form-login-config&gt;
&lt;/login-config&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>With FORM Authentication, you must also configure URLs of pages to generate a login form and handle errors.
Below is a simple HTML form from the <a href="https://github.com/eclipse/jetty.project/tree/master/tests/test-webapps/test-jetty-webapp/src/main/webapp/logon.html?h=release-9">test webapp logon.html</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;HTML&gt;
&lt;H1&gt;FORM Authentication demo&lt;/H1&gt;
&lt;form method="POST" action="j_security_check"&gt;
&lt;table border="0" cellspacing="2" cellpadding="1"&gt;
&lt;tr&gt;
&lt;td&gt;Username:&lt;/td&gt;
&lt;td&gt;&lt;input size="12" value="" name="j_username" maxlength="25" type="text"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password:&lt;/td&gt;
&lt;td&gt;&lt;input size="12" value="" name="j_password" maxlength="25" type="password"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan="2" align="center"&gt;
&lt;input name="submit" type="submit" value="Login"&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/form&gt;
&lt;/HTML&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The Authentication mechanism declared for a context / web application defines how the server obtain authentication credentials from the
client, but it does not define how the server checks if those credentials are valid.
To check credentials, the server and/or context also need to be configured with a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/security/LoginService.html">LoginService</a> instance, which may be matched by the declared realm-name.</p>
</div>
</div>
<div class="sect3">
<h4 id="security-realms"><a class="anchor" href="#security-realms"></a><a class="link" href="#security-realms">Security Realms</a></h4>
<div class="paragraph">
<p>Security realms allow you to secure your web applications against unauthorized access.
Protection is based on authentication that identifies who is requesting access to the webapp and access control that restricts what can be accessed and how it is accessed within the webapp.</p>
</div>
<div class="paragraph">
<p>A webapp statically declares its security requirements in its web.xml file.
Authentication is controlled by the <code>&lt;login-config&gt;</code> element.
Access controls are specified by <code>&lt;security-constraint&gt;</code> and <code>&lt;security-role-ref&gt;</code> elements.
When a request is received for a protected resource, the web container checks if the user performing the request is authenticated, and if the user has a role assignment that permits access to the requested resource.</p>
</div>
<div class="paragraph">
<p>The Servlet Specification does not address how the static security information in the <code>WEB-INF/web.xml</code> file is mapped to the runtime environment of the container.
For Jetty, the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/security/LoginService.html">LoginService</a> performs this function.</p>
</div>
<div class="paragraph">
<p>A <code>LoginService</code> has a unique name, and gives access to information about a set of users.
Each user has authentication information (e.g. a password) and a set of roles associated with him/herself.</p>
</div>
<div class="paragraph">
<p>You may configure one or many different LoginServices depending on your needs.
A single realm would indicate that you wish to share common security information across all of your web applications.
Distinct realms allow you to partition your security information webapp by webapp.</p>
</div>
<div class="paragraph">
<p>When a request to a web application requires authentication or authorization, Jetty will use the <code>&lt;realm-name&gt;</code> sub-element inside <code>&lt;login-config&gt;</code> element in the web.xml file to perform an <em>exact match</em> to a LoginService.</p>
</div>
</div>
<div class="sect3">
<h4 id="_scoping-security-realms"><a class="anchor" href="#_scoping-security-realms"></a><a class="link" href="#_scoping-security-realms">Scoping Security Realms</a></h4>
<div class="paragraph">
<p>A <code>LoginService</code> has a unique name, and is composed of a set of users.
Each user has authentication information (for example, a password) and a set of roles associated with him/herself.
You can configure one or many different realms depending on your needs.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Configure a single LoginService to share common security information across all of your web applications.</p>
</li>
<li>
<p>Configure distinct LoginServices to partition your security information webapp by webapp.</p>
</li>
</ul>
</div>
<div class="sect4">
<h5 id="_globally-scoped"><a class="anchor" href="#_globally-scoped"></a><a class="link" href="#_globally-scoped">Globally Scoped</a></h5>
<div class="paragraph">
<p>A LoginService is available to all web applications on a Server instance if you add it as a bean to the Server.
Such a definition would go into an xml file in your <code>${jetty.base}/etc</code> directory, e.g. <code>${jetty.base}/etc/my-realm.xml</code> and you would add this xml file to the execution path via <code>start.ini</code> or <code>start.d</code> (you may want to review the material in the <a href="#startup">Starting Jetty</a> chapter).
Here&#8217;s an example of an xml file that defines an in-memory type of LoginService called the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/security/HashLoginService.html">HashLoginService</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;Call name="addBean"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.security.HashLoginService"&gt;
&lt;Set name="name"&gt;Test Realm&lt;/Set&gt;
&lt;Set name="config"&gt;&lt;SystemProperty name="jetty.home" default="."/&gt;/etc/realm.properties&lt;/Set&gt;
&lt;Set name="hotReload"&gt;true&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you define more than one <code>LoginService</code> on a Server, you will need to specify which one you want used for each context.
You can do that by telling the context the name of the <code>LoginService</code>, or passing it the <code>LoginService</code> instance.
Here&#8217;s an example of doing both of these, using a <a href="#deployable-descriptor-file">context xml file</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Get name="securityHandler"&gt;
&lt;!-- Either: --&gt;
&lt;Set name="loginService"&gt;
&lt;New class="org.eclipse.jetty.security.HashLoginService"&gt;
&lt;Set name="name"&gt;Test Realm&lt;/Set&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;!-- or if you defined a LoginService called "Test Realm" in jetty.xml : --&gt;
&lt;Set name="realmName"&gt;Test Realm&lt;/Set&gt;
&lt;/Get&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_per-webapp-scoped"><a class="anchor" href="#_per-webapp-scoped"></a><a class="link" href="#_per-webapp-scoped">Per-Webapp Scoped</a></h5>
<div class="paragraph">
<p>Alternatively, you can define a <code>LoginService</code> for just a single web application.
Here&#8217;s how to define the same HashLoginService, but inside a <a href="#deployable-descriptor-file">context xml file</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/test&lt;/Set&gt;
&lt;Set name="war"&gt;&lt;SystemProperty name="jetty.home" default="."/&gt;/webapps/test&lt;/Set&gt;
&lt;Get name="securityHandler"&gt;
&lt;Set name="loginService"&gt;
&lt;New class="org.eclipse.jetty.security.HashLoginService"&gt;
&lt;Set name="name"&gt;Test Realm&lt;/Set&gt;
&lt;Set name="config"&gt;&lt;SystemProperty name="jetty.home" default="."/&gt;/etc/realm.properties&lt;/Set&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/Get&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Jetty provides a number of different <code>LoginService</code> types which can be seen in the next section.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="configuring-login-service"><a class="anchor" href="#configuring-login-service"></a><a class="link" href="#configuring-login-service">Configuring a LoginService</a></h4>
<div class="paragraph">
<p>A <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/security/LoginService.html"><code>LoginService</code></a> instance is required by each context/webapp that has a authentication mechanism, which is used to check the validity of the username and credentials collected by the authentication mechanism. Jetty provides the following implementations of <code>LoginService</code>:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/security/HashLoginService.html">HashLoginService</a></dt>
<dd>
<p>A user realm that is backed by a hash map that is filled either programatically or from a Java properties file.</p>
</dd>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/security/JDBCLoginService.html">JDBCLoginService</a></dt>
<dd>
<p>Uses a JDBC connection to an SQL database for authentication</p>
</dd>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/plus/security/DataSourceLoginService.html">DataSourceLoginService</a></dt>
<dd>
<p>Uses a JNDI defined <a href="http://docs.oracle.com/javase/7/docs/api/javax/sql/DataSource.html">DataSource</a> for authentication</p>
</dd>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/jaas/JAASLoginService.html">JAASLoginService</a></dt>
<dd>
<p>Uses a <a href="http://en.wikipedia.org/wiki/Java_Authentication_and_Authorization_Service">JAAS</a> provider for authentication; see the section on
<a href="#jaas-support">JAAS support</a> for more information</p>
</dd>
<dt class="hdlist1"><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/security/SpnegoLoginService.html">SpnegoLoginService</a></dt>
<dd>
<p><a href="http://en.wikipedia.org/wiki/SPNEGO">SPNEGO</a> Authentication; see the section on <a href="#spnego-support">SPNEGO support</a> for more information.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>An instance of a <code>LoginService</code> can be matched to a context/webapp by:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A <code>LoginService</code> instance may be set directly on the <code>SecurityHandler</code> instance via embedded code or IoC XML</p>
</li>
<li>
<p>Matching the realm-name defined in web.xml with the name of a <code>LoginService</code> instance that has been added to the Server instance as a dependent bean</p>
</li>
<li>
<p>If only a single <code>LoginService</code> instance has been set on the Server then it is used as the login service for the context</p>
</li>
</ul>
</div>
<div class="sect4">
<h5 id="hash-login-service"><a class="anchor" href="#hash-login-service"></a><a class="link" href="#hash-login-service">HashLoginService</a></h5>
<div class="paragraph">
<p>The <code>HashLoginService</code> is a simple and efficient login service that loads usernames, credentials and roles from a Java properties file in the format:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-properties" data-lang="properties">username: password[,rolename ...]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Where:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">username</dt>
<dd>
<p>is the user&#8217;s unique identity</p>
</dd>
<dt class="hdlist1">password</dt>
<dd>
<p>is the user&#8217;s (possibly obfuscated or MD5 encrypted) password;</p>
</dd>
<dt class="hdlist1">rolename</dt>
<dd>
<p>is a role of the user</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-properties" data-lang="properties">admin: CRYPT:ad1ks..kc.1Ug,server-administrator,content-administrator,admin
other: OBF:1xmk1w261u9r1w1c1xmq
guest: guest,read-only</code></pre>
</div>
</div>
<div class="paragraph">
<p>You configure the <code>HashLoginService</code> with a name and a reference to the location of the properties file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Item&gt;
&lt;New class="org.eclipse.jetty.security.HashLoginService"&gt;
&lt;Set name="name"&gt;Test Realm&lt;/Set&gt;
&lt;Set name="config"&gt;&lt;SystemProperty name="jetty.home" default="."/&gt;/etc/realm.properties&lt;/Set&gt;
&lt;/New&gt;
&lt;/Item&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also configure it to reload the configuration file when changes to it are detected.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New class="org.eclipse.jetty.security.HashLoginService"&gt;
&lt;Set name="name"&gt;Test Realm&lt;/Set&gt;
&lt;Set name="config"&gt;&lt;SystemProperty name="jetty.home" default="."/&gt;/etc/realm.properties&lt;/Set&gt;
&lt;Set name="hotReload"&gt;true&lt;/Set&gt;
&lt;Call name="start"&gt;&lt;/Call&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="jdbc-login-service"><a class="anchor" href="#jdbc-login-service"></a><a class="link" href="#jdbc-login-service">JDBCLoginService</a></h5>
<div class="paragraph">
<p>In this implementation, authentication and role information is stored in a database accessed via JDBC.
A properties file defines the JDBC connection and database table information.
Here is an example of a properties file for this realm implementation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-properties" data-lang="properties">jdbcdriver = org.gjt.mm.mysql.Driver
url = jdbc:mysql://localhost/jetty
username = jetty
password = jetty
usertable = users
usertablekey = id
usertableuserfield = username
usertablepasswordfield = pwd
roletable = roles
roletablekey = id
roletablerolefield = role
userroletable = user_roles
userroletableuserkey = user_id
userroletablerolekey = role_id
cachetime = 300</code></pre>
</div>
</div>
<div class="paragraph">
<p>The format of the database tables is (pseudo-sql):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-sql" data-lang="sql">users
(
id integer PRIMARY KEY,
username varchar(100) NOT NULL UNIQUE KEY,
pwd varchar(50) NOT NULL
);
user_roles
(
user_id integer NOT NULL,
role_id integer NOT NULL,
UNIQUE KEY (user_id, role_id),
INDEX(user_id)
);
roles
(
id integer PRIMARY KEY,
role varchar(100) NOT NULL UNIQUE KEY
);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Where:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>users</strong> is a table containing one entry for every user consisting of:</p>
<div class="dlist">
<dl>
<dt class="hdlist1">id</dt>
<dd>
<p>the unique identity of a user</p>
</dd>
<dt class="hdlist1">user</dt>
<dd>
<p>the name of the user</p>
</dd>
<dt class="hdlist1">pwd</dt>
<dd>
<p>the user&#8217;s password (possibly obfuscated or MD5 encrypted)</p>
</dd>
</dl>
</div>
</li>
<li>
<p><strong>user-roles</strong> is a table containing one row for every role granted to a
user:</p>
<div class="dlist">
<dl>
<dt class="hdlist1">user_id</dt>
<dd>
<p>the unique identity of the user</p>
</dd>
<dt class="hdlist1">role_id</dt>
<dd>
<p>the role for a user</p>
</dd>
</dl>
</div>
</li>
<li>
<p><strong>roles</strong> is a a table containing one role for every role in the system:</p>
<div class="dlist">
<dl>
<dt class="hdlist1">id</dt>
<dd>
<p>the unique identifier of a role</p>
</dd>
<dt class="hdlist1">role</dt>
<dd>
<p>a human-readable name for a role</p>
</dd>
</dl>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>If you want to use obfuscated, MD5 hashed or encrypted passwords the <code>pwd</code> column of the <code>users</code> table must be large enough to hold the obfuscated, hashed or encrypted password text plus the appropriate prefix.</p>
</div>
<div class="paragraph">
<p>You define a <code>JDBCLoginService</code> with the name of the realm and the location of the properties file describing the database:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New class="org.eclipse.jetty.security.JDBCLoginService"&gt;
&lt;Set name="name"&gt;Test JDBC Realm&lt;/Set&gt;
&lt;Set name="config"&gt;etc/jdbcRealm.properties&lt;/Set&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_authorization"><a class="anchor" href="#_authorization"></a><a class="link" href="#_authorization">Authorization</a></h4>
<div class="paragraph">
<p>As far as the <a href="https://jcp.org/en/jsr/detail?id=340">Servlet Specification</a> is concerned, authorization is based on roles.
As we have seen, a <code>LoginService</code> associates a user with a set of roles.
When a user requests a resource that is access protected, the <code>LoginService</code> will be asked to authenticate the user if they are not already, and then asked to confirm if that user possesses one of the roles permitted access to the resource.</p>
</div>
<div class="paragraph">
<p>Until Servlet 3.1, role-based authorization could define:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Access granted to a set of named roles:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;security-constraint&gt;
&lt;web-resource-collection&gt;
&lt;web-resource-name&gt;Foo Admin Data&lt;/web-resource-name&gt;
&lt;url-pattern&gt;/foo/admin/*&lt;/url-pattern&gt;
&lt;/web-resource-collection&gt;
&lt;auth-constraint&gt;
&lt;role-name&gt;admin&lt;/role-name&gt;
&lt;role-name&gt;manager&lt;/role-name&gt;
&lt;/auth-constraint&gt;
&lt;/security-constraint&gt;</code></pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>Access totally forbidden, regardless of role:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;security-constraint&gt;
&lt;web-resource-collection&gt;
&lt;web-resource-name&gt;Foo Protected Data&lt;/web-resource-name&gt;
&lt;url-pattern&gt;/foo/protected/*&lt;/url-pattern&gt;
&lt;/web-resource-collection&gt;
&lt;auth-constraint&gt;
&lt;/auth-constraint&gt;
&lt;/security-constraint&gt;</code></pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>Access granted to a user in any of the roles defined in the effective <code>web.xml</code>.
This is indicated by the special value of <code>*</code> for the <code>&lt;role-name&gt;</code> of a <code>&lt;auth-constraint&gt;</code> in the <code>&lt;security-constraint&gt;</code>:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;security-constraint&gt;
&lt;web-resource-collection&gt;
&lt;web-resource-name&gt;Foo Role Data&lt;/web-resource-name&gt;
&lt;url-pattern&gt;/foo/role/*&lt;/url-pattern&gt;
&lt;/web-resource-collection&gt;
&lt;auth-constraint&gt;
&lt;role-name&gt;*&lt;/role-name&gt;
&lt;/auth-constraint&gt;
&lt;/security-constraint&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Servlet 3.1 introduced an additional authorization:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Access granted to any user who is authenticated, regardless of roles.
This is indicated by the special value of <code>**</code> for the <code>&lt;role-name&gt;</code> of a <code>&lt;auth-constraint&gt;</code> in the <code>&lt;security-constraint&gt;</code>:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;security-constraint&gt;
&lt;web-resource-collection&gt;
&lt;web-resource-name&gt;Foo Authenticated Data&lt;/web-resource-name&gt;
&lt;url-pattern&gt;/foo/authenticated/*&lt;/url-pattern&gt;
&lt;/web-resource-collection&gt;
&lt;auth-constraint&gt;
&lt;role-name&gt;**&lt;/role-name&gt;
&lt;/auth-constraint&gt;
&lt;/security-constraint&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Additionally, when configuring your security constraints you can protect various HTTP methods as well, such as <code>PUT</code>, <code>GET</code>, <code>POST</code>, <code>HEAD</code> or <code>DELETE</code>.
This is done by adding the method you want to protect as a <code>&lt;http-method&gt;</code> in the <code>&lt;web-resource-collection&gt;</code>.
You can then define roles that should be able to perform these protected methods in an <code>&lt;auth-constraint&gt;</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;security-constraint&gt;
&lt;web-resource-collection&gt;
&lt;web-resource-name&gt;Foo Authenticated Data&lt;/web-resource-name&gt;
&lt;url-pattern&gt;/foo/authenticated/*&lt;/url-pattern&gt;
&lt;http-method&gt;DELETE&lt;/http-method&gt;
&lt;http-method&gt;POST&lt;/http-method&gt;
&lt;/web-resource-collection&gt;
&lt;auth-constraint&gt;
&lt;role-name&gt;admin&lt;/role-name&gt;
&lt;/auth-constraint&gt;
&lt;/security-constraint&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the above example, only users with an <code>admin</code> role will be able to perform <code>DELETE</code> or <code>POST</code> methods.</p>
</div>
<div class="sect4">
<h5 id="_configuring-authorization-with-context-xml-files"><a class="anchor" href="#_configuring-authorization-with-context-xml-files"></a><a class="link" href="#_configuring-authorization-with-context-xml-files">Configuring Authorization with Context XML Files</a></h5>
<div class="paragraph">
<p>While the examples above show configuration of Authorization in a <code>web.xml</code> file, they can also be configured as part of the link#<a href="#deployable-descriptor-file">context xml file</a> for a web application.
This is especially helpful if authorization needs change over time and need updated without re-packaging the whole web app.</p>
</div>
<div class="paragraph">
<p>To do this, we add a section for security constraints into the context xml file for our web app as part of the <code>securityHandler</code>.
In the example below, a <code>HashLoginService</code> is defined with authorization being granted too <code>foo/*</code> paths to users with the <code>admin</code> and <code>manager</code> roles.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id="testWebapp" class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Get name="securityHandler"&gt;
&lt;Set name="realmName"&gt;Test Realm&lt;/Set&gt;
&lt;Set name="authMethod"&gt;BASIC&lt;/Set&gt;
&lt;Call name="addConstraintMapping"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.security.ConstraintMapping"&gt;
&lt;Set name="pathSpec"&gt;/foo/*&lt;/Set&gt;
&lt;Set name="constraint"&gt;
&lt;New class="org.eclipse.jetty.util.security.Constraint"&gt;
&lt;Set name="name"&gt;Foo Auth&lt;/Set&gt;
&lt;Set name="authenticate"&gt;true&lt;/Set&gt;
&lt;Set name="roles"&gt;
&lt;Array type="java.lang.String"&gt;
&lt;Item&gt;admin&lt;/Item&gt;
&lt;Item&gt;manager&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Set&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Set name="loginService"&gt;
&lt;New class="org.eclipse.jetty.security.HashLoginService"&gt;
&lt;Set name="name"&gt;Test Realm&lt;/Set&gt;
&lt;Set name="config"&gt;/src/tmp/small-security-test/realm.properties&lt;/Set&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/Get&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>If roles changed in the future, administrators could easily change this context xml file without having to edit the contents of the web app at all.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_authentication-and-authorization-with-embedded-jetty"><a class="anchor" href="#_authentication-and-authorization-with-embedded-jetty"></a><a class="link" href="#_authentication-and-authorization-with-embedded-jetty">Authentication and Authorization with Embedded Jetty</a></h4>
<div class="paragraph">
<p>In addition to the distribution, security can be defined as part of an embedded implementation as well.
Below is an example which, like the one above, sets up a server with a <code>HashLoginService</code> and adds security constraints to restrict access based on roles.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Unresolved directive in security/authentication.adoc - include::/home/jenkins/agent/workspace/nightlies/jetty-10.0.x-snapshots-deploy/jetty-documentation/../examples/embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java[]</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="configuring-form-size"><a class="anchor" href="#configuring-form-size"></a><a class="link" href="#configuring-form-size">Limiting Form Content</a></h3>
<div class="paragraph">
<p>Form content sent to the server is processed by Jetty into a map of parameters to be used by the web application.
This can be vulnerable to denial of service (DOS) attacks since significant memory and CPU can be consumed if a malicious clients sends very large form content or large number of form keys.
Thus Jetty limits the amount of data and keys that can be in a form posted to Jetty.</p>
</div>
<div class="paragraph">
<p>The default maximum size Jetty permits is 200000 bytes and 1000 keys.
You can change this default for a particular webapp or for all webapps on a particular Server instance.</p>
</div>
<div class="sect3">
<h4 id="_configuring-form-limits-for-a-webapp"><a class="anchor" href="#_configuring-form-limits-for-a-webapp"></a><a class="link" href="#_configuring-form-limits-for-a-webapp">Configuring Form Limits for a Webapp</a></h4>
<div class="paragraph">
<p>To configure the form limits for a single web application, the context handler (or webappContext) instance must be configured using the following methods:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">ContextHandler.setMaxFormContentSize(int maxSizeInBytes);
ContextHandler.setMaxFormKeys(int formKeys);</code></pre>
</div>
</div>
<div class="paragraph">
<p>These methods may be called directly when embedding Jetty, but more commonly are configured from a context XML file or WEB-INF/jetty-web.xml file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
...
&lt;Set name="maxFormContentSize"&gt;200000&lt;/Set&gt;
&lt;Set name="maxFormKeys"&gt;200&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_configuring-form-limits-for-the-server"><a class="anchor" href="#_configuring-form-limits-for-the-server"></a><a class="link" href="#_configuring-form-limits-for-the-server">Configuring Form Limits for the Server</a></h4>
<div class="paragraph">
<p>If a context does not have specific form limits configured, then the server attributes are inspected to see if a server wide limit has been set on the size or keys.
The following XML shows how these attributes can be set in <code>jetty.xml</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;configure class="org.eclipse.jetty.server.Server"&gt;
...
&lt;Call name="setAttribute"&gt;
&lt;Arg&gt;org.eclipse.jetty.server.Request.maxFormContentSize&lt;/Arg&gt;
&lt;Arg&gt;100000&lt;/Arg&gt;
&lt;/Call&gt;
&lt;Call name="setAttribute"&gt;
&lt;Arg&gt;org.eclipse.jetty.server.Request.maxFormKeys&lt;/Arg&gt;
&lt;Arg&gt;2000&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/configure&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="serving-aliased-files"><a class="anchor" href="#serving-aliased-files"></a><a class="link" href="#serving-aliased-files">Aliased Files and Symbolic links</a></h3>
<div class="paragraph">
<p>Web applications will often serve static content from the file system provided by the operating system running underneath the JVM.
However, because file systems often implement multiple aliased names for the same file, then security constraints and other servlet URI space mappings may inadvertently be bypassed by aliases.</p>
</div>
<div class="paragraph">
<p>A key example of this is case insensitivity and 8.3 filenames implemented by the Windows file system.
If a file within a web application called <code>/mysecretfile.txt</code> is protected by a security constraint on the URI <code>/mysecretfile.txt</code>, then a request to <code>/MySecretFile.TXT</code> will not match the URI constraint because URIs are case sensitive, but the Windows file system will report that a file does exist at that name and it will be served despite the security constraint.
Less well known than case insensitivity is that Windows files systems also support <a href="http://en.wikipedia.org/wiki/8.3_filename">8.3 filenames</a> for compatibility with legacy programs.
Thus a request to a URI like <code>/MYSECR~1.TXT</code> will again not match the security constraint, but will be reported as an existing file by the file system and served.</p>
</div>
<div class="paragraph">
<p>There are many examples of aliases, not just on Windows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>NTFS Alternate stream names like <code>c:\test\file.txt::$DATA:name</code></p>
</li>
<li>
<p>OpenVMS support file versionig so that <code>/mysecret.txt;N</code> refers to version N of <code>/mysecret.txt</code> and is essentially an alias.</p>
</li>
<li>
<p>The clearcase software configuration management system provides a file system where <code>@@</code> in a file name is an alias to a specific version.</p>
</li>
<li>
<p>The Unix files system supports <code>/./foo.txt</code> as and alias for <code>/foo.txt</code></p>
</li>
<li>
<p>Many JVM implementations incorrectly assume the null character is a string terminator, so that a file name resulting from <code>/foobar.txt%00</code> is an alias for <code>/foobar.txt</code></p>
</li>
<li>
<p>Unix symbolic links and hard links are a form of aliases that allow the same file or directory to have multiple names.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In addition, it is not just URI security constraints that can be bypassed. For example the mapping of the URI pattern <code>*.jsp</code> to the JSP
Servlet may be bypassed by an a request to an alias like <code>/foobar.jsp%00</code>, thus rather than execute the JSP, the source code of the JSP is returned by the file system.</p>
</div>
<div class="sect3">
<h4 id="_good-security-practise"><a class="anchor" href="#_good-security-practise"></a><a class="link" href="#_good-security-practise">Good Security Practise</a></h4>
<div class="paragraph">
<p>Part of the problem with aliases is that the standard web application security model is to allow all requests except the ones that are specifically denied by security constraints.
A best practice for security is to deny all requests and to permit only those that are specifically identified as allowable.
While it is possible to design web application security constraints in this style, it can be difficult in all circumstances and it is not the default. T
hus it is important for Jetty to be able to detect and deny requests to aliased static content.</p>
</div>
</div>
<div class="sect3">
<h4 id="file-alias-detection"><a class="anchor" href="#file-alias-detection"></a><a class="link" href="#file-alias-detection">Alias detection</a></h4>
<div class="paragraph">
<p>It is impossible for Jetty to know of all the aliases that may be implemented by the file system running beneath it, thus it does not attempt to make any specific checks for any know aliases.
Instead Jetty detects aliases by using the canonical path of a file.
If a file resource handled by jetty has a canonical name that differs from the name used to request the resource, then Jetty determines that the resource is an aliased request and it will not be returned by the <code>ServletContext.getResource(String)</code> method (or similar) and thus will not be served as static content nor used as the basis of a JSP.</p>
</div>
<div class="paragraph">
<p>This if Jetty is running on a Windows operating system, then a file called <code>/MySecret.TXT</code> will have a canonical name that exactly matches that case.
So while a request to <code>/mysecret.txt</code> or <code>/MYSECR~1.TXT</code> will result in a File Resource that matches the file, the different canonical name will indicate that those requests are aliases and they will not be served as static content and instead a 404 response returned.</p>
</div>
<div class="paragraph">
<p>Unfortunately this approach denies all aliases, including symbolic links, which can be useful in assembling complex web applications.</p>
</div>
</div>
<div class="sect3">
<h4 id="file-alias-serving"><a class="anchor" href="#file-alias-serving"></a><a class="link" href="#file-alias-serving">Serving Aliases and Symbolic Links</a></h4>
<div class="paragraph">
<p>Not all aliases are bad nor should be seen as attempts to subvert security constraints.
Specifically, symbolic links can be very useful when assembling complex web applications.
As such, Jetty contexts support an extensible <code>AliasCheck</code> mechanism to allow aliases resources to be inspected and conditionally served.
In this way, "good" aliases can be detected and served.
Jetty provides several utility implementations of the <code>AliasCheck</code> interface as nested classes with <code>ContextHandler</code>:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">ApproveAliases</dt>
<dd>
<p>Approve all aliases (<strong>Use with caution!</strong>).</p>
</dd>
<dt class="hdlist1">AllowSymLinkAliasChecker</dt>
<dd>
<p>Approve Aliases using the java-7 <code>Files.readSymbolicLink(path)</code> and <code>Path.toRealPath(&#8230;&#8203;)</code> APIs to check that aliases are valid symbolic links.</p>
</dd>
</dl>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
By default, Jetty serves aliased files for implementations running on UNIX as Contexts are created with both the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/AllowSymLinkAliasChecker.html"><code>AllowSymLinkAliasChecker</code></a> and <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/handler/ContextHandler.ApproveNonExistentDirectoryAliases.html"><code>ApproveNonExistentDirectoryAliases</code></a> alias checkers.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>An application is free to implement its own Alias checking.
Alias Checkers can be installed in a context via the following XML used in a context deployer file or <code>WEB-INF/jetty-web.xml</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;!-- Allow symbolic links --&gt;
&lt;Call name="addAliasCheck"&gt;
&lt;Arg&gt;&lt;New class="org.eclipse.jetty.server.handler.AllowSymLinkAliasChecker"/&gt;&lt;/Arg&gt;
&lt;/Call&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="configuring-security-secure-passwords"><a class="anchor" href="#configuring-security-secure-passwords"></a><a class="link" href="#configuring-security-secure-passwords">Secure Password Obfuscation</a></h3>
<div class="paragraph">
<p>There are many places where you might want to use and store a password, for example for the SSL connectors and user passwords in realms.</p>
</div>
<div class="paragraph">
<p>Passwords can be stored in clear text, obfuscated, checksummed or encrypted in order of increasing security.
The choice of method to secure a password depends on where you are using the password.
In some cases, such as keystore passwords and <code>DIGEST</code> authentication, the system must retrieve the original password, which requires the obfuscation method.
The drawback of the obfuscation algorithm is that it protects passwords <strong>from casual viewing only.</strong></p>
</div>
<div class="paragraph">
<p>When the stored password is compared to one a user enters, the handling code can apply the same algorithm that secures the stored password to the user input and compare results, making password authentication more secure.</p>
</div>
<div class="paragraph">
<p>The class <code>org.eclipse.jetty.util.security.Password</code> can be used to generate all varieties of passwords.</p>
</div>
<div class="paragraph">
<p>Run it without arguments to see usage instructions:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ java -cp lib/jetty-util-10.0.0-SNAPSHOT.jar org.eclipse.jetty.util.security.Password
Usage - java org.eclipse.jetty.util.security.Password [&lt;user&gt;] &lt;password&gt;
If the password is ?, the user will be prompted for the password</code></pre>
</div>
</div>
<div class="paragraph">
<p>For example, to generate a secured version of the password <code>password</code> for the user <code>username</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ java -cp ../lib/jetty-util-10.0.0-SNAPSHOT.jar org.eclipse.jetty.util.security.Password username password
2017-12-13 11:19:27.928:INFO::main: Logging initialized @95ms to org.eclipse.jetty.util.log.StdErrLog
password
OBF:1v2j1uum1xtv1zej1zer1xtn1uvk1v1v
MD5:5f4dcc3b5aa765d61d8327deb882cf99
CRYPT:usjRS48E8ZADM</code></pre>
</div>
</div>
<div class="paragraph">
<p>If using a external tool to create/verify the MD5 hash (such as <code>md5sum</code> or <code>md5</code>), be sure to verify a carriage return (CR) or new line is not added.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">//With a CR included
$ echo password | md5sum
286755fad04869ca523320acce0dc6a4 *-
//Using the `-n` option to exclude a new line from being added.
$ echo -n password | md5sum
5f4dcc3b5aa765d61d8327deb882cf99 *-</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
When using the <code>DIGEST</code> method in tandem with an MD5 hash, you must hash the entire <code>user:realm:password</code> string or you will encounter issues with authenticating.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ java -cp ../lib/jetty-util-10.0.0-SNAPSHOT.jar org.eclipse.jetty.util.security.Password username username:realm:password
2017-12-13 11:34:33.263:INFO::main: Logging initialized @97ms to org.eclipse.jetty.util.log.StdErrLog
username:realm:password
OBF:1w281yf41v1x1z7e1xmi1v1p1tvv1v901c3j1x8k1ugo1ri71uh21x8a1c3j1v9m1tv71v2p1xms1z7o1v2h1yf21w1a
MD5:66999343281b2624585fd58cc9d36dfc
CRYPT:usulxZfApLefk
$ echo -n username:realm:password | md5sum
66999343281b2624585fd58cc9d36dfc *-</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can now cut and paste whichever secure version you choose into your configuration file or Java code.</p>
</div>
<div class="paragraph">
<p>For example, the last line below shows how you would implement the encrypted password generated above into the properties file for a <code>LoginService</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">admin: CRYPT:ad1ks..kc.1Ug,server-administrator,content-administrator,admin
other: OBF:1xmk1w261u9r1w1c1xmq
guest: guest,read-only
me:CRYPT:me/ks90E221EY</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
Don&#8217;t forget to also copy the OBF:, MD5: or CRYPT: prefix on the generated password. It will not be usable by Jetty without it.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>You can also use obfuscated passwords in Jetty xml files where a plain text password is required.
Here&#8217;s an example setting the password for a JDBC Datasource with obfuscation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource"&gt;
&lt;Arg&gt;&lt;/Arg&gt;
&lt;Arg&gt;jdbc/DSTest&lt;/Arg&gt;
&lt;Arg&gt;
&lt;New class="com.jolbox.bonecp.BoneCPDataSource"&gt;
&lt;Set name="driverClass"&gt;com.mysql.jdbc.Driver&lt;/Set&gt;
&lt;Set name="jdbcUrl"&gt;jdbc:mysql://localhost:3306/foo&lt;/Set&gt;
&lt;Set name="username"&gt;dbuser&lt;/Set&gt;
&lt;Set name="password"&gt;
&lt;Call class="org.eclipse.jetty.util.security.Password" name="deobfuscate"&gt;
&lt;Arg&gt;OBF:1ri71v1r1v2n1ri71shq1ri71shs1ri71v1r1v2n1ri7&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Set&gt;
&lt;Set name="minConnectionsPerPartition"&gt;5&lt;/Set&gt;
&lt;Set name="maxConnectionsPerPartition"&gt;50&lt;/Set&gt;
&lt;Set name="acquireIncrement"&gt;5&lt;/Set&gt;
&lt;Set name="idleConnectionTestPeriod"&gt;30&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="setting-port80-access"><a class="anchor" href="#setting-port80-access"></a><a class="link" href="#setting-port80-access">Setting Port 80 Access for a Non-Root User</a></h3>
<div class="paragraph">
<p>On Unix-based systems, port 80 is protected; typically only the superuser <code>root</code> can open it. For security reasons, it is not desirable to run the server as <code>root</code>.
This page presents several options to access port 80 as a non-root user, including using <code>ipchains</code>, <code>iptables</code>, Jetty&#8217;s SetUID feature, <code>xinetd</code>, and the Solaris 10 User Rights Management Framework.</p>
</div>
<div class="sect3">
<h4 id="using-ipchains"><a class="anchor" href="#using-ipchains"></a><a class="link" href="#using-ipchains">Using ipchains</a></h4>
<div class="paragraph">
<p>On some Linux systems you can use the <em>ipchains REDIRECT</em> mechanism to redirect from one port to another inside the kernel (if <code>ipchains</code> is not available, then <code>iptables</code> usually is):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># /sbin/ipchains -I input --proto TCP --dport 80 -j REDIRECT 8080</code></pre>
</div>
</div>
<div class="paragraph">
<p>This command instructs the system as follows: "Insert into the kernel&#8217;s packet filtering the following as the first rule to check on incoming packets: if the protocol is TCP and the destination port is 80, redirect the packet to port 8080".
Be aware that your kernel must be compiled with support for <code>ipchains</code> (virtually all stock kernels are).
You must also have the <code>ipchains</code> command-line utility installed.
You can run this command at any time, preferably just once, since it inserts another copy of the rule every time you run it.</p>
</div>
</div>
<div class="sect3">
<h4 id="using-iptables"><a class="anchor" href="#using-iptables"></a><a class="link" href="#using-iptables">Using iptables</a></h4>
<div class="paragraph">
<p>On many Linux systems you can use the <code>iptables</code> REDIRECT mechanism to redirect from one port to another inside the kernel (if <code>iptables</code> is not available, then usually <code>ipchains</code> is).</p>
</div>
<div class="paragraph">
<p>You need to add something like the following to the startup scripts or your firewall rules:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># /sbin/iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080</code></pre>
</div>
</div>
<div class="paragraph">
<p>The underlying model of <code>iptables</code> is different from <code>ipchains</code>, so the forwarding normally happens only to packets originating outside of the server itself.
You also need to allow incoming packets to port 8080 if you use <code>iptables</code> as a local firewall.</p>
</div>
<div class="paragraph">
<p>Be careful to place rules like this one early in your <em>input</em> chain.
Such rules must precede any rule that accepts the packet, otherwise the redirection won&#8217;t occur.
You can insert as many rules as required if your server needs to listen on multiple ports, as for HTTPS.</p>
</div>
</div>
<div class="sect3">
<h4 id="configuring-jetty-setuid-feature"><a class="anchor" href="#configuring-jetty-setuid-feature"></a><a class="link" href="#configuring-jetty-setuid-feature">Configuring Jetty&#8217;s SetUID Feature</a></h4>
<div class="paragraph">
<p><a href="http://en.wikipedia.org/wiki/Setuid">SetUID</a> is a technique that uses Unix-like file system access rights to allow users to run an executable that would otherwise require higher privileges.</p>
</div>
<div class="paragraph">
<p>Jetty&#8217;s <code>SetUID</code> module allows you to run Jetty as a normal user even when you need to run Jetty on port 80 or 443.</p>
</div>
<div class="paragraph">
<p>To use it with the Jetty distribution:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Ensure that you have the <code>http.mod</code> (and <a href="#quickstart-starting-https">https.mod</a> if you are using SSL) <a href="#startup-modules">modules enabled</a> for the <a href="#creating-jetty-base">base</a> you are using.
The <code>http.mod</code> is enabled by default in the distribution, while the <a href="#quickstart-starting-https">https.mod</a> is only enabled in the <a href="#demo-webapps-base">demo-base</a> directory.</p>
</li>
<li>
<p>Ensure that you have <a href="#quickstart-changing-jetty-port">changed the http port</a> to 80 (and <a href="#quickstart-changing-https-port">changed the https port</a> to 443 if you are using SSL).</p>
</li>
<li>
<p>Enable the <code>setuid.mod</code> module:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># java -jar start.jar --add-to-start=setuid</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The --add-to-start command will enable the setuid module for this and all subsequent executions of jetty.
There are other ways to enable the module, such as for a single execution.
For more information on the alternatives see the section on <a href="#startup-modules">Managing Startup Modules</a>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</li>
<li>
<p>Edit the configuration for the <code>setuid</code> module to substitute the <code>userid</code> and <code>groupid</code> of the user to switch to after starting.
If your server instance has a <code>${jetty.base/start.d}</code> directory, this configuration is in the <code>start.d/setuid.ini</code> file instead.
Otherwise. this configuration is in the <code>${jetty.base}start.ini</code> file.</p>
<div class="literalblock">
<div class="content">
<pre>Below are the lines to configure:</pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-text" data-lang="text">jetty.startServerAsPrivileged=false
jetty.username=foo
jetty.groupname=bar
jetty.umask=002</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
As well as opening the connectors as <code>root</code>, you can also have Jetty start the Server as <code>root</code> before changing to the non-<code>root</code> user.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</li>
<li>
<p>A native code library is required to perform user switching.
This code is hosted as part of the <a href="https://github.com/eclipse/jetty.toolchain">Jetty ToolChain</a> project and is released independently from Jetty itself.
You can find the source code in the <a href="https://github.com/eclipse/jetty.toolchain/tree/master/jetty-setuid">eclipse/jetty.toolchain/jetty-setuid</a> project.
Build it locally, which will produce a native library appropriate for the operating system:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># mvn clean install</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you built on a linux machine you will find the native library in <code>jetty-setuid/libsetuid-linux/target/libsetuid-linux.so</code>.
If you built on a different operating system you will find the library in a different subdirectory, with the name containing the name of the operating system.
You may want copy this file into your Jetty distribution&#8217;s lib directory.</p>
</div>
</li>
<li>
<p>Start Jetty as the <code>root</code> user in your base directory, providing the location of the native library to Java.
Below is an example of how to do it from the command line, assuming you are in the <a href="#demo-webapps-base">demo-base</a> directory:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># sudo java -Djava.library.path=libsetuid-linux -jar $JETTY_HOME/start.jar</code></pre>
</div>
</div>
</li>
</ol>
</div>
</div>
<div class="sect3">
<h4 id="using-solaris10-user-rights-management-framework"><a class="anchor" href="#using-solaris10-user-rights-management-framework"></a><a class="link" href="#using-solaris10-user-rights-management-framework">Using the Solaris 10 User Rights Management Framework</a></h4>
<div class="paragraph">
<p>Solaris 10 provides a User Rights Management framework that can permit users and processes superuser-like abilities:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">usermod -K defaultpriv=basic,net_privaddr myself</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now the <code>myself</code> user can bind to port 80.</p>
</div>
<div class="paragraph">
<p>Refer to the <a href="http://docs.oracle.com/cd/E23823_01/html/816-4557/prbactm-1.html#scrolltoc">Solaris 10</a> and <a href="http://docs.oracle.com/cd/E23824_01/html/821-1456/prbactm-1.html#scrolltoc">Solaris 11 Security Services documentation</a> for more information.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="jaas-support"><a class="anchor" href="#jaas-support"></a><a class="link" href="#jaas-support">JAAS Support</a></h3>
<div class="paragraph">
<p>JAAS implements a Java version of the standard Pluggable Authentication Module (PAM) framework.</p>
</div>
<div class="paragraph">
<p>JAAS can be used for two purposes:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>for authentication of users, to reliably and securely determine who is currently executing Java code, regardless of whether the code is running as an application, an applet, a bean, or a servlet</p>
</li>
<li>
<p>for authorization of users to ensure they have the access control rights (permissions) required to do the actions performed</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>JAAS authentication is performed in a pluggable fashion.
This permits applications to remain independent from underlying authentication technologies.
New or updated authentication technologies can be plugged under an application without requiring modifications to the application itself.
Applications enable the authentication process by instantiating a <code>LoginContext</code> object, which in turn references a configuration to determine the authentication technology(ies), or <code>LoginModule</code>(s), to be used in performing the authentication.
Typical <code>LoginModules</code> may prompt for and verify a username and password.
Others may read and verify a voice or fingerprint sample.</p>
</div>
<div class="paragraph">
<p>See Java Authentication and Authorization Service (JAAS) <a href="http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html">Reference Guide</a> for more information about JAAS.</p>
</div>
<div class="sect3">
<h4 id="jetty-jaas"><a class="anchor" href="#jetty-jaas"></a><a class="link" href="#jetty-jaas">Jetty and JAAS</a></h4>
<div class="paragraph">
<p>Many application servers support JAAS as a means of bringing greater flexibility to the declarative security models of the J2EE (now known as the JavaEE) <a href="http://java.sun.com/javaee/index.jsp">specification</a>.
Jetty support for JAAS provides greater alternatives for servlet security, and increases the portability of web applications.</p>
</div>
<div class="paragraph">
<p>The JAAS support aims to dictate as little as possible whilst providing a sufficiently flexible infrastructure to allow users to drop in their
own custom <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASLMDevGuide.html">LoginModules</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="jaas-configuration"><a class="anchor" href="#jaas-configuration"></a><a class="link" href="#jaas-configuration">Configuration</a></h4>
<div class="paragraph">
<p>Using JAAS with Jetty is very simply a matter of declaring a <code>org.eclipse.jetty.jaas.JAASLoginService</code>, creating a JAAS login module configuration file and specifying it on the Jetty run line.
Let&#8217;s look at an example.</p>
</div>
<div class="sect4">
<h5 id="_step-1"><a class="anchor" href="#_step-1"></a><a class="link" href="#_step-1">Step 1</a></h5>
<div class="paragraph">
<p>Configure a Jetty <code>org.eclipse.jetty.jaas.JAASLoginService</code> to match the <code>&lt;realm-name&gt;</code> in your <code>web.xml</code> file. For example, if the <code>web.xml</code> contains a realm called "Test JAAS Realm" like so:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;login-config&gt;
&lt;auth-method&gt;FORM&lt;/auth-method&gt;
&lt;realm-name&gt;Test JAAS Realm&lt;/realm-name&gt;
&lt;form-login-config&gt;
&lt;form-login-page&gt;/login/login&lt;/form-login-page&gt;
&lt;form-error-page&gt;/login/error&lt;/form-error-page&gt;
&lt;/form-login-config&gt;
&lt;/login-config&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>then you need to create a <code>JAASLoginService</code> with the matching realm name of "Test JAAS Realm":</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New class="org.eclipse.jetty.jaas.JAASLoginService"&gt;
&lt;Set name="Name"&gt;Test JAAS Realm&lt;/Set&gt;
&lt;Set name="LoginModuleName"&gt;xyz&lt;/Set&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>LoginModuleName</code> must match the name of your LoginModule as declared in your login module configuration file (see <a href="#jaas-step-2">Step 2</a>).</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock caution">
<table>
<tr>
<td class="icon">
<i class="fa icon-caution" title="Caution"></i>
</td>
<td class="content">
The name of the realm-name that you declare in <code>web.xml</code> must match <strong>exactly</strong> the <code>Name</code> field of your <code>JAASLoginService</code>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>You can declare your <code>JAASLoginService</code> in a couple of different ways:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>If you have more than one webapp that you would like to use the same security infrastructure, then you can declare your <code>JAASLoginService</code> in a top-level Jetty xml file as a bean that is added to the <code>org.eclipse.jetty.server.Server</code>.
An example:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;Call name="addBean"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.jaas.JAASLoginService"&gt;
&lt;Set name="name"&gt;Test JAAS Realm&lt;/Set&gt;
&lt;Set name="LoginModuleName"&gt;xyz&lt;/Set&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</li>
<li>
<p>Alternatively, you can use a <code>JAASLoginService</code> with just a specific webapp by creating a <a href="#deployable-descriptor-file">context xml</a> file for the webapp, and specifying the <code>JAASLoginService</code> in it:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="securityHandler"&gt;
&lt;New class="org.eclipse.jetty.security.ConstraintSecurityHandler"&gt;
&lt;Set name="loginService"&gt;
&lt;New class="org.eclipse.jetty.jaas.JAASLoginService"&gt;
&lt;Set name="name"&gt;Test JAAS Realm&lt;/Set&gt;
&lt;Set name="loginModuleName"&gt;xyz&lt;/Set&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</li>
</ol>
</div>
</div>
<div class="sect4">
<h5 id="jaas-step-2"><a class="anchor" href="#jaas-step-2"></a><a class="link" href="#jaas-step-2">Step 2</a></h5>
<div class="paragraph">
<p>Set up your <code>LoginModule</code> in a configuration file, following the <a href="https://docs.oracle.com/javase/7/docs/api/javax/security/auth/login/Configuration.html">syntax rules</a> :</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">xyz {
com.acme.SomeLoginModule required debug=true;
};</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock caution">
<table>
<tr>
<td class="icon">
<i class="fa icon-caution" title="Caution"></i>
</td>
<td class="content">
It is imperative that the application name on the first line is <strong>exactly</strong> the same as the <code>LoginModuleName</code> of your <code>JAASLoginService</code>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>You may find it convenient to name this configuration file as <code>etc/login.conf</code> because, as we will see below, some of the wiring up for JAAS has been done for you.</p>
</div>
</div>
<div class="sect4">
<h5 id="_step-3"><a class="anchor" href="#_step-3"></a><a class="link" href="#_step-3">Step 3</a></h5>
<div class="paragraph">
<p>You now need to invoke Jetty with support for JAAS.
There are 2 aspects to this:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>adding JAAS-related jars to the Jetty container classpath</p>
</li>
<li>
<p>setting the System property <code>java.security.auth.login.config</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>To accomplish the above, use the Jetty <a href="#startup-overview">startup</a> <a href="#startup-modules">modules mechanism</a> to add the JAAS <a href="#startup-modules">module</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">java -jar start.jar --add-to-start=jaas</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The top level of the distribution does not have the JAAS module enabled by default.
However, there are several <a href="#demo-webapps-base">demo webapps</a> - including a JAAS webapp - available in the <code>demo-base</code> directory of the distribution which has pre-enabled the JAAS module.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Now you will have a file named <code>start.d/jaas.ini</code>, which contains:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">--module=jaas
jaas.login.conf=etc/login.conf</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>jaas.login.conf</code> property refers to the location of your <code>LoginModule</code> configuration file that you established in <a href="#jaas-step-2">Step 2</a>.
If you called it <code>etc/login.conf</code>, then your work is done. Otherwise, change the value of the <code>jaas.login.conf</code> property to be the location of your LoginModule configuration file.
Jetty will automatically use this property to set the value of the System property <code>java.security.auth.login.config.</code></p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_a-closer-look-at-jaasloginservice"><a class="anchor" href="#_a-closer-look-at-jaasloginservice"></a><a class="link" href="#_a-closer-look-at-jaasloginservice">A Closer Look at JAASLoginService</a></h4>
<div class="paragraph">
<p>To allow the greatest degree of flexibility in using JAAS with web applications, the <code>JAASLoginService</code> supports a couple of configuration options.
Note that you don&#8217;t ordinarily need to set these explicitly, as Jetty has defaults which will work in 99% of cases.
However, should you need to, you can configure:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>a CallbackHandler (Default: <code>org.eclipse.jetty.jaas.callback.DefaultCallbackHandler</code>)</p>
</li>
<li>
<p>a list of classnames for the Principal implementation that equate to a user role (Default: <code>org.eclipse.jetty.jaas.JAASRole</code>)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of setting each of these (to their default values):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New class="org.eclipse.jetty.jaas.JAASLoginService"&gt;
&lt;Set name="Name"&gt;Test JAAS Realm&lt;/Set&gt;
&lt;Set name="LoginModuleName"&gt;xyz&lt;/Set&gt;
&lt;Set name="CallbackHandlerClass"&gt;
org.eclipse.jetty.jaas.callback.DefaultCallbackHandler
&lt;/Set&gt;
&lt;Set name="roleClassNames"&gt;
&lt;Array type="java.lang.String"&gt;
&lt;Item&gt;org.eclipse.jetty.jaas.JAASRole&lt;/Item&gt;
&lt;/Array&gt;
&lt;/Set&gt;
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_callbackhandler"><a class="anchor" href="#_callbackhandler"></a><a class="link" href="#_callbackhandler">CallbackHandler</a></h5>
<div class="paragraph">
<p>A CallbackHandler is responsible for interfacing with the user to obtain usernames and credentials to be authenticated.</p>
</div>
<div class="paragraph">
<p>Jetty ships with the <code>org.eclipse.jetty.jaas.DefaultCallbackHandler</code> which interfaces the information contained in the request to the Callbacks that are requested by <code>LoginModules</code>.
You can replace this default with your own implementation if you have specific requirements not covered by the default.</p>
</div>
</div>
<div class="sect4">
<h5 id="_role-principal-implementation-class"><a class="anchor" href="#_role-principal-implementation-class"></a><a class="link" href="#_role-principal-implementation-class">Role Principal Implementation Class</a></h5>
<div class="paragraph">
<p>When <code>LoginModules</code> authenticate a user, they usually also gather all of the roles that a user has and place them inside the JAAS Subject.
As <code>LoginModules</code> are free to use their own implementation of the JAAS Principal to put into the Subject, Jetty needs to know which Principals represent the user and which represent his/her roles when performing authorization checks on <code>&lt;security-constraint&gt;</code>. The example <code>LoginModules</code> that ship with Jetty all use the <code>org.eclipse.jetty.jaas.JAASRole</code> class. However, if you have plugged in other <code>LoginModules</code>, you must configure the classnames of their role Principal implementations.</p>
</div>
</div>
<div class="sect4">
<h5 id="_sample-loginmodules"><a class="anchor" href="#_sample-loginmodules"></a><a class="link" href="#_sample-loginmodules">Sample LoginModules</a></h5>
<div class="ulist">
<ul>
<li>
<p><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/jaas/spi/JDBCLoginModule.html"><code>org.eclipse.jetty.jaas.spi.JDBCLoginModule</code></a></p>
</li>
<li>
<p><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/jaas/spi/PropertyFileLoginModule.html"><code>org.eclipse.jetty.jaas.spi.PropertyFileLoginModule</code></a></p>
</li>
<li>
<p><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/jaas/spi/DataSourceLoginModule.html"><code>org.eclipse.jetty.jaas.spi.DataSourceLoginModule</code></a></p>
</li>
<li>
<p><a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/jaas/spi/LdapLoginModule.html"><code>org.eclipse.jetty.jaas.ldap.LdapLoginModule</code></a></p>
</li>
</ul>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Passwords can be stored in clear text, obfuscated or checksummed.
The class <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/util/security/Password.html"><code>org.eclipse.jetty.util.security.Password</code></a> should be used to generate all varieties of passwords,the output from which can be put in to property files or entered into database tables.
See more on this under the Configuration section on <a href="#configuring-security-secure-passwords">securing passwords</a>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
<div class="sect4">
<h5 id="_jdbcloginmodule"><a class="anchor" href="#_jdbcloginmodule"></a><a class="link" href="#_jdbcloginmodule">JDBCLoginModule</a></h5>
<div class="paragraph">
<p>The <code>JDBCLoginModule</code> stores user passwords and roles in a database that are accessed via JDBC calls.
You can configure the JDBC connection information, as well as the names of the table and columns storing the username and credential, and the names of the table and columns storing the roles.</p>
</div>
<div class="paragraph">
<p>Here is an example login module configuration file entry for it using an HSQLDB driver:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">jdbc {
org.eclipse.jetty.jaas.spi.JDBCLoginModule required
debug="true"
dbUrl="jdbc:hsqldb:."
dbUserName="sa"
dbDriver="org.hsqldb.jdbcDriver"
userTable="myusers"
userField="myuser"
credentialField="mypassword"
userRoleTable="myuserroles"
userRoleUserField="myuser"
userRoleRoleField="myrole";
};</code></pre>
</div>
</div>
<div class="paragraph">
<p>There is no particular schema required for the database tables storing the authentication and role information.
The properties <code>userTable</code>, <code>userField</code>, <code>credentialField</code>, <code>userRoleTable</code>, <code>userRoleUserField</code>, <code>userRoleRoleField</code> configure the names of the tables and the columns within them that are used to format the following queries:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-sql" data-lang="sql"> select &lt;credentialField&gt; from &lt;userTable&gt;
where &lt;userField&gt; =?
select &lt;userRoleRoleField&gt; from &lt;userRoleTable&gt;
where &lt;userRoleUserField&gt; =?</code></pre>
</div>
</div>
<div class="paragraph">
<p>Credential and role information is lazily read from the database when a previously unauthenticated user requests authentication.
Note that this information is <em>only</em> cached for the length of the authenticated session.
When the user logs out or the session expires, the information is flushed from memory.</p>
</div>
<div class="paragraph">
<p>Note that passwords can be stored in the database in plain text or encoded formats - see the note on "Passwords/Credentials" above.</p>
</div>
</div>
<div class="sect4">
<h5 id="_datasourceloginmodule"><a class="anchor" href="#_datasourceloginmodule"></a><a class="link" href="#_datasourceloginmodule">DataSourceLoginModule</a></h5>
<div class="paragraph">
<p>Similar to the <code>JDBCLoginModule</code>, but this <code>LoginModule</code> uses a <code>DataSource</code> to connect to the database instead of a JDBC driver. The <code>DataSource</code> is obtained by performing a JNDI lookup on <code>java:comp/env/${dnJNDIName}</code>.</p>
</div>
<div class="paragraph">
<p>A sample login module configuration using this method:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">ds {
org.eclipse.jetty.jaas.spi.DataSourceLoginModule required
debug="true"
dbJNDIName="ds"
userTable="myusers"
userField="myuser"
credentialField="mypassword"
userRoleTable="myuserroles"
userRoleUserField="myuser"
userRoleRoleField="myrole";
};</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_propertyfileloginmodule"><a class="anchor" href="#_propertyfileloginmodule"></a><a class="link" href="#_propertyfileloginmodule">PropertyFileLoginModule</a></h5>
<div class="paragraph">
<p>With this login module implementation, the authentication and role information is read from a property file.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">props {
org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required
debug="true"
file="/somewhere/somefile.props";
};</code></pre>
</div>
</div>
<div class="paragraph">
<p>The file parameter is the location of a properties file of the same format as the <code>etc/realm.properties</code> example file.
The format is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-text" data-lang="text">&lt;username&gt;: &lt;password&gt;[,&lt;rolename&gt; ...]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here&#8217;s an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">fred: OBF:1xmk1w261u9r1w1c1xmq,user,admin
harry: changeme,user,developer
tom: MD5:164c88b302622e17050af52c89945d44,user
dick: CRYPT:adpexzg3FUZAk,admin</code></pre>
</div>
</div>
<div class="paragraph">
<p>The contents of the file are fully read in and cached in memory the first time a user requests authentication.</p>
</div>
</div>
<div class="sect4">
<h5 id="_ldaploginmodule"><a class="anchor" href="#_ldaploginmodule"></a><a class="link" href="#_ldaploginmodule">LdapLoginModule</a></h5>
<div class="paragraph">
<p>Here&#8217;s an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">ldaploginmodule {
org.eclipse.jetty.jaas.spi.LdapLoginModule required
debug="true"
contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
hostname="ldap.example.com"
port="389"
bindDn="cn=Directory Manager"
bindPassword="directory"
authenticationMethod="simple"
forceBindingLogin="false"
userBaseDn="ou=people,dc=alcatel"
userRdnAttribute="uid"
userIdAttribute="uid"
userPasswordAttribute="userPassword"
userObjectClass="inetOrgPerson"
roleBaseDn="ou=groups,dc=example,dc=com"
roleNameAttribute="cn"
roleMemberAttribute="uniqueMember"
roleObjectClass="groupOfUniqueNames";
};</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_writing-your-own-loginmodule"><a class="anchor" href="#_writing-your-own-loginmodule"></a><a class="link" href="#_writing-your-own-loginmodule">Writing your Own LoginModule</a></h4>
<div class="paragraph">
<p>If you want to implement your own custom <code>LoginModule</code>, there are two classes to be familiar with: <code>org.eclipse.jetty.jaas.spi.AbstractLoginModule</code> and <code>org.eclipse.jetty.jaas.spi.UserInfo</code>.</p>
</div>
<div class="paragraph">
<p>The <code>org.eclipse.jetty.jaas.spi.AbstractLoginModule</code> implements all of the <code>javax.security.auth.spi.LoginModule</code> methods.
All you need to do is to implement the <code>getUserInfo</code> method to return a <code>org.eclipse.jetty.jaas.UserInfo</code> instance which encapsulates the username, password and role names (note: as <code>java.lang.Strings</code>) for a user.</p>
</div>
<div class="paragraph">
<p>The <code>AbstractLoginModule</code> does not support any caching, so if you want to cache UserInfo (eg as does the <code>org.eclipse.jetty.jaas.spi.PropertyFileLoginModule</code>) then you must provide this yourself.</p>
</div>
</div>
<div class="sect3">
<h4 id="_other-goodies"><a class="anchor" href="#_other-goodies"></a><a class="link" href="#_other-goodies">Other Goodies</a></h4>
<div class="sect4">
<h5 id="_servletrequestcallback"><a class="anchor" href="#_servletrequestcallback"></a><a class="link" href="#_servletrequestcallback">ServletRequestCallback</a></h5>
<div class="paragraph">
<p>This callback gives you access to the ServletRequest that is involved in the authentication, and thus to other features like the current Session. This callback can be configured in your custom LoginModule implementation. Note that none of the LoginModule implementations provided with Jetty currently use this callback.</p>
</div>
</div>
<div class="sect4">
<h5 id="_requestparametercallback"><a class="anchor" href="#_requestparametercallback"></a><a class="link" href="#_requestparametercallback">RequestParameterCallback</a></h5>
<div class="paragraph">
<p>As all servlet containers intercept and process a form submission with action <code>j_security_check</code>, it is usually not possible to insert any extra input fields onto a login form with which to perform authentication: you may only pass <code>j_username</code> and <code>j_password</code>.
For those rare occasions when this is not good enough, and you require more information from the user in order to authenticate them, you can use the JAAS callback handler <code>org.eclipse.jetty.jaas.callback.RequestParameterCallback</code>.
This callback gives you access to all parameters that were passed in the form submission.
To use it, in the <code>login()</code> method of your custom login module, add the <code>RequestParameterCallback</code> to the list of callback handlers the login module uses, tell it which params you are interested in, and then get the value of the parameter back.
Here is an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public class FooLoginModule extends AbstractLoginModule
{
public boolean login()
throws LoginException
{
Callback[] callbacks = new Callback[3];
callbacks[0] = new NameCallback();
callbacks[1] = new ObjectCallback();
//as an example, look for a param named "extrainfo" in the request
//use one RequestParameterCallback() instance for each param you want to access
callbacks[2] = new RequestParameterCallback ();
((RequestParameterCallback)callbacks[2]).setParameterName ("extrainfo");
callbackHandler.handle(callbacks);
String userName = ((NameCallback)callbacks[0]).getName();
Object pwd = ((ObjectCallback)callbacks[1]).getObject();
List paramValues = ((RequestParameterCallback)callbacks[2]).getParameterValues();
//use the userName, pwd and the value(s) of the parameter named "extrainfo" to
//authenticate the user
}
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_example-jaas-webapp"><a class="anchor" href="#_example-jaas-webapp"></a><a class="link" href="#_example-jaas-webapp">Example JAAS WebApp</a></h5>
<div class="paragraph">
<p>An example webapp using JAAS can be found in the Jetty GitHub repository:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://github.com/eclipse/jetty.project/tree/master/tests/test-webapps/test-jaas-webapp">https://github.com/eclipse/jetty.project/tree/jetty-9.4.x/tests/test-webapps/test-jaas-webapp</a></p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="spnego-support"><a class="anchor" href="#spnego-support"></a><a class="link" href="#spnego-support">SPNEGO Support</a></h3>
<div class="paragraph">
<p>Simple and Protected GSSAPI Negotiation Mechanism (SPNEGO) is a way for users
to be seamlessly authenticated when running on systems that rely on Kerberos
for authentication, such as Windows Active Directory based networks.</p>
</div>
<div class="paragraph">
<p>Jetty supports this type of authentication and authorization through the JDK
(which has been enabled since the later versions of Java 6 and 7).</p>
</div>
<div class="sect3">
<h4 id="_configuring-jetty-and-spnego"><a class="anchor" href="#_configuring-jetty-and-spnego"></a><a class="link" href="#_configuring-jetty-and-spnego">Configuring Jetty and SPNEGO</a></h4>
<div class="paragraph">
<p>To run with SPNEGO enabled the following command line options are required:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">-Djava.security.krb5.conf=/path/to/krb5.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>For debugging the SPNEGO authentication the following options are helpful:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">-Dorg.eclipse.jetty.LEVEL=debug
-Dsun.security.spnego.debug=true
-Dsun.security.jgss.debug=true
-Dsun.security.krb5.debug=true</code></pre>
</div>
</div>
<div class="paragraph">
<p>SPNEGO authentication must be enabled in the webapp in the following way.
The name of the role will be different for your network.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;security-constraint&gt;
&lt;web-resource-collection&gt;
&lt;web-resource-name&gt;Secure Area&lt;/web-resource-name&gt;
&lt;url-pattern&gt;/secure/me/*&lt;/url-pattern&gt;
&lt;/web-resource-collection&gt;
&lt;auth-constraint&gt;
&lt;!-- this is the domain that the user is a member of --&gt;
&lt;role-name&gt;MORTBAY.ORG&lt;/role-name&gt;
&lt;/auth-constraint&gt;
&lt;/security-constraint&gt;
&lt;login-config&gt;
&lt;auth-method&gt;SPNEGO&lt;/auth-method&gt;
&lt;realm-name&gt;Test Realm&lt;/realm-name&gt;
&lt;!-- optionally to add custom error page --&gt;
&lt;spnego-login-config&gt;
&lt;spnego-error-page&gt;/loginError.html?param=foo&lt;/spnego-error-page&gt;
&lt;/spnego-login-config&gt;
&lt;/login-config&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>A corresponding <code>UserRealm</code> needs to be created either programmatically if
embedded, via the <code>jetty.xml</code> or in a context file for the webapp.</p>
</div>
<div class="paragraph">
<p>This is what the configuration within a context XML file would look like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Get name="securityHandler"&gt;
&lt;Set name="loginService"&gt;
&lt;New class="org.eclipse.jetty.security.ConfigurableSpnegoLoginService"&gt;
&lt;Arg&gt;Test Realm&lt;/Arg&gt;
&lt;Arg&gt;&lt;Ref refid="authorizationService" /&gt;&lt;/Arg&gt;
&lt;Set name="keyTabPath"&gt;&lt;Ref refid="keyTabPath" /&gt;&lt;/Set&gt;
&lt;/New&gt;
&lt;/Set&gt;
&lt;/Get&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>On the Windows Active Domain Controller run:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ setspn -A HTTP/linux.mortbay.org ADUser</code></pre>
</div>
</div>
<div class="paragraph">
<p>To create the keyTab file use the following process:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ ktpass -out c:\dir\krb5.keytab -princ HTTP/linux.mortbay.org@MORTBAY.ORG -mapUser ADUser -mapOp set -pass ADUserPWD -crypto RC4-HMAC-NT -pType KRB5_NT_PRINCIPAL</code></pre>
</div>
</div>
<div class="paragraph">
<p>This step will give you the keyTab file which should then be copied to the
machine running the http server and referenced from the configuration files.</p>
</div>
</div>
<div class="sect3">
<h4 id="_configuring-firefox"><a class="anchor" href="#_configuring-firefox"></a><a class="link" href="#_configuring-firefox">Configuring Firefox</a></h4>
<div class="paragraph">
<p>The follows steps have been required to inform Firefox that it should use a negotiation dialog to authenticate.</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Browse to about:config and agree to the warnings</p>
</li>
<li>
<p>Search through to find the 'network' settings</p>
</li>
<li>
<p>Set <code>network.negotiate-auth.delegation-uris</code> to <a href="http://,https://" class="bare">http://,https://</a></p>
</li>
<li>
<p>Set <code>network.negotiate-auth.trusted-uris</code> to <a href="http://,https://" class="bare">http://,https://</a></p>
</li>
</ol>
</div>
</div>
<div class="sect3">
<h4 id="_configuring-internet-explorer"><a class="anchor" href="#_configuring-internet-explorer"></a><a class="link" href="#_configuring-internet-explorer">Configuring Internet Explorer</a></h4>
<div class="paragraph">
<p>The follows steps have been required to inform Internet Explorer that it should use a negotiation dialog to authenticate.</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Tools &#8594; Options &#8594; Security &#8594; Local Intranet &#8594; Sites (everything should be checked here)</p>
</li>
<li>
<p>Tools &#8594; Options &#8594; Security &#8594; Local Intranet &#8594; Sites &#8594; Advanced (add url to server (<code>http://</code> and/or <code>https://</code>&#8201;&#8212;&#8201;use the hostname, not the IP)</p>
</li>
<li>
<p>Tools &#8594; Options &#8594; Security &#8594; Local Intranet &#8594; Sites &#8594; Advanced &#8594; Close</p>
</li>
<li>
<p>Tools &#8594; Options &#8594; Security &#8594; Local Intranet &#8594; Sites &#8594; Ok</p>
</li>
<li>
<p>Tools &#8594; Options &#8594; Advanced &#8594; Security (in the checkbox list)</p>
</li>
<li>
<p>Locate and select <code>Enable Integrated Windows Authentication</code></p>
</li>
<li>
<p>Tools &#8594; Options &#8594; Advanced &#8594; Security &#8594; Ok</p>
</li>
<li>
<p>Close IE then reopen and browse to your SPNEGO protected resource</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>You <strong>must</strong> use hostname and not the IP.
If you use the IP it will default to NTLM authentication.
The following conditions must be true for SPNEGO authentication to work:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>You must be within the Intranet Zone of the network</p>
</li>
<li>
<p>Access the server using a Hostname rather than IP</p>
</li>
<li>
<p>Integrated Windows Authentication in IE is enabled and/or the host is trusted in Firefox</p>
</li>
<li>
<p>The server is not local to the browser; it can&#8217;t be running on localhost</p>
</li>
<li>
<p>The client&#8217;s Kerberos system is authenticated to a domain controller</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="openid-support"><a class="anchor" href="#openid-support"></a><a class="link" href="#openid-support">OpenID Support</a></h3>
<div class="sect3">
<h4 id="_external-setup"><a class="anchor" href="#_external-setup"></a><a class="link" href="#_external-setup">External Setup</a></h4>
<div class="sect4">
<h5 id="_registering-an-app-with-openid-provider"><a class="anchor" href="#_registering-an-app-with-openid-provider"></a><a class="link" href="#_registering-an-app-with-openid-provider">Registering an App with OpenID Provider</a></h5>
<div class="paragraph">
<p>You must register the app with an OpenID Provider such as <a href="https://developers.google.com/identity/protocols/OpenIDConnect#authenticatingtheuser">Google</a> or <a href="https://images-na.ssl-images-amazon.com/images/G/01/lwa/dev/docs/website-developer-guide.<em>TTH</em>.pdf">Amazon.</a>
This will give you a Client ID and Client Secret.
Once set up you must also register all the possible URI&#8217;s for your webapp with the path <code>/j_security_check</code> so that the OpenId Provider will allow redirection back to the webapp.</p>
</div>
<div class="paragraph">
<p>These may look like</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code><a href="http://localhost:8080/openid-webapp/j_security_check" class="bare">http://localhost:8080/openid-webapp/j_security_check</a></code></p>
</li>
<li>
<p><code><a href="https://example.com/j_security_check" class="bare">https://example.com/j_security_check</a></code></p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_distribution-configuration"><a class="anchor" href="#_distribution-configuration"></a><a class="link" href="#_distribution-configuration">Distribution Configuration</a></h4>
<div class="sect4">
<h5 id="_openid-provider-configuration"><a class="anchor" href="#_openid-provider-configuration"></a><a class="link" href="#_openid-provider-configuration">OpenID Provider Configuration</a></h5>
<div class="paragraph">
<p>To enable OpenID support, you first need to activate the <code>openid</code> module in your implementation.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ java -jar $JETTY_HOME/start.jar --add-to-start=openid</code></pre>
</div>
</div>
<div class="paragraph">
<p>To configure OpenID Authentication with Jetty you will need to specify the OpenID Provider&#8217;s issuer identifier (case sensitive URL using the <code>https</code> scheme) and the OAuth 2.0 Client ID and Client Secret.
If the OpenID Provider does not allow metadata discovery you will also need to specify the token endpoint and authorization endpoint of the OpenID Provider.
These can be set as properties in the <code>start.ini</code> or <code>start.d/openid.ini</code> files.</p>
</div>
</div>
<div class="sect4">
<h5 id="_webapp-specific-configuration-in-web-xml"><a class="anchor" href="#_webapp-specific-configuration-in-web-xml"></a><a class="link" href="#_webapp-specific-configuration-in-web-xml">WebApp Specific Configuration in web.xml</a></h5>
<div class="paragraph">
<p>The <code>web.xml</code> file needs some specific configuration to use OpenID.
There must be a <code>login-config</code> element with an <code>auth-method</code> value of <code>OPENID</code>, and a <code>realm-name</code> value of the exact URL string used to set the OpenID Provider.</p>
</div>
<div class="paragraph">
<p>To set the error page, an init param is set at <code>"org.eclipse.jetty.security.openid.error_page"</code>, its value should be a path relative to the webapp where authentication errors should be redirected.</p>
</div>
<div class="paragraph">
<p>Example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;login-config&gt;
&lt;auth-method&gt;OPENID&lt;/auth-method&gt;
&lt;realm-name&gt;https://accounts.google.com&lt;/realm-name&gt;
&lt;/login-config&gt;
&lt;context-param&gt;
&lt;param-name&gt;org.eclipse.jetty.security.openid.error_page&lt;/param-name&gt;
&lt;param-value&gt;/error&lt;/param-value&gt;
&lt;/context-param&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_embedded-configuration"><a class="anchor" href="#_embedded-configuration"></a><a class="link" href="#_embedded-configuration">Embedded Configuration</a></h4>
<div class="sect4">
<h5 id="_define-the-openidconfiguration-for-a-specific-openid-provider"><a class="anchor" href="#_define-the-openidconfiguration-for-a-specific-openid-provider"></a><a class="link" href="#_define-the-openidconfiguration-for-a-specific-openid-provider">Define the <code>OpenIdConfiguration</code> for a specific OpenID Provider.</a></h5>
<div class="paragraph">
<p>If the OpenID Provider allows metadata discovery then you can use.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">OpenIdConfiguration openIdConfig = new OpenIdConfiguration(ISSUER, CLIENT_ID, CLIENT_SECRET);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Otherwise you can manually enter the necessary information:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">OpenIdConfiguration openIdConfig = new OpenIdConfiguration(ISSUER, TOKEN_ENDPOINT, AUTH_ENDPOINT, CLIENT_ID, CLIENT_SECRET);</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_configuring-an-openidloginservice"><a class="anchor" href="#_configuring-an-openidloginservice"></a><a class="link" href="#_configuring-an-openidloginservice">Configuring an <code>OpenIdLoginService</code></a></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">LoginService loginService = new OpenIdLoginService(openIdConfig);
securityHandler.setLoginService(loginService);</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_configuring-an-openidauthenticator-with-openidconfiguration-and-error-page-redirect"><a class="anchor" href="#_configuring-an-openidauthenticator-with-openidconfiguration-and-error-page-redirect"></a><a class="link" href="#_configuring-an-openidauthenticator-with-openidconfiguration-and-error-page-redirect">Configuring an <code>OpenIdAuthenticator</code> with <code>OpenIdConfiguration</code> and Error Page Redirect</a></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Authenticator authenticator = new OpenIdAuthenticator(openIdConfig, "/error");
securityHandler.setAuthenticator(authenticator);
servletContextHandler.setSecurityHandler(securityHandler);</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_usage-2"><a class="anchor" href="#_usage-2"></a><a class="link" href="#_usage-2">Usage</a></h5>
<div class="sect5">
<h6 id="_claims-and-access-token"><a class="anchor" href="#_claims-and-access-token"></a><a class="link" href="#_claims-and-access-token">Claims and Access Token</a></h6>
<div class="paragraph">
<p>Claims about the user can be found using attributes on the session attribute <code>"org.eclipse.jetty.security.openid.claims"</code>, and the full response containing the OAuth 2.0 Access Token can be found with the session attribute <code>"org.eclipse.jetty.security.openid.response"</code>.</p>
</div>
<div class="paragraph">
<p>Example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Map&lt;String, Object&gt; claims = (Map)request.getSession().getAttribute("org.eclipse.jetty.security.openid.claims");
String userId = claims.get("sub");
Map&lt;String, Object&gt; response = (Map)request.getSession().getAttribute("org.eclipse.jetty.security.openid.response");
String accessToken = response.get("access_token");</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_scopes"><a class="anchor" href="#_scopes"></a><a class="link" href="#_scopes">Scopes</a></h4>
<div class="paragraph">
<p>The OpenID scope is always used but additional scopes can be requested which can give you additional resources or privileges.
For the Google OpenID Provider it can be useful to request the scopes <code>profile</code> and <code>email</code> which will give you additional user claims.</p>
</div>
<div class="paragraph">
<p>Additional scopes can be requested through the <code>start.ini</code> or <code>start.d/openid.ini</code> files, or with <code>OpenIdConfiguration.addScopes(&#8230;&#8203;);</code> in embedded code.</p>
</div>
</div>
<div class="sect3">
<h4 id="_roles"><a class="anchor" href="#_roles"></a><a class="link" href="#_roles">Roles</a></h4>
<div class="paragraph">
<p>If security roles are required they can be configured through a wrapped <code>LoginService</code> which is deferred to for role information by the <code>OpenIdLoginService</code>.</p>
</div>
<div class="paragraph">
<p>This can be configured in XML through <code>etc/openid-baseloginservice.xml</code> in the Distribution, or in embedded code using the constructor for the <code>OpenIdLoginService</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">LoginService wrappedLoginService = ...; // Optional LoginService for Roles
LoginService loginService = new OpenIdLoginService(openIdConfig, wrappedLoginService);</code></pre>
</div>
</div>
<div class="paragraph">
<p>When using authorization roles, the setting <code>authenticateNewUsers</code> becomes significant.
If set to <code>true</code> users not found by the wrapped <code>LoginService</code> will still be authenticated but will have no roles.
If set to <code>false</code> those users will be not be allowed to authenticate and are redirected to the error page.
This setting is configured through the property <code>jetty.openid.authenticateNewUsers</code> in the <code>start.ini</code> or <code>start.d/openid.ini</code> file, or with <code>OpenIdLoginService.setAuthenticateNewUsers(&#8230;&#8203;);</code> in embedded code.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="startup"><a class="anchor" href="#startup"></a><a class="link" href="#startup">Starting Jetty</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="startup-overview"><a class="anchor" href="#startup-overview"></a><a class="link" href="#startup-overview">Startup Overview</a></h3>
<div class="paragraph">
<p>The <code>start.jar</code> bootstrap manages the startup of standalone Jetty.
It is responsible for:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Building the classpath</dt>
<dd>
<p>The <code>start.jar</code> bootstrap builds a classpath for all the required Jetty features and their dependencies.
It builds the classpath using either the <code>--lib</code> option to <code>start.jar</code> to add an individual classpath entry, or with the <code>--module</code> option that includes all the libs and their dependencies for a module (a named Jetty feature).</p>
</dd>
<dt class="hdlist1">Instantiating the Server Components</dt>
<dd>
<p>The server and its components are instantiated using either Jetty IoC XML or Spring.
The Jetty server is a collection of POJOs for the server, connectors, session managers and others.
These are instantiated, injected, and wired up together in XML files, commonly one per module/feature, that are passed as arguments to <code>start.jar</code>.</p>
</dd>
<dt class="hdlist1">Resolving Server Filesystem Locations</dt>
<dd>
<p>The <code>start.jar</code> mechanism resolves canonical locations for the <code>${jetty.home}</code> and the <code>${jetty.base}</code> directories.
The <code>${jetty.home}</code> directory is the location of the standard distribution of Jetty.
The <code>${jetty.base}</code> directory is the location of the local server customization and configurations.
<br>
If you want to modify the Jetty distribution, base and home can be the same directory.
Separating the base and home directories allows the distribution to remain unmodified, with all customizations in the base directory, and thus simplifies subsequent server version upgrades.</p>
</dd>
<dt class="hdlist1">Parameterizing the Server Configuration</dt>
<dd>
<p>XML files primarily determine the server configuration.
Many of these files are parameterized to allow simple injection of host names, ports, passwords and more.
The <code>start.jar</code> mechanism allows you to set parameters on the command line or in properties files.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>To achieve these start up mechanisms, the <code>start.jar</code> uses:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Command line arguments</dt>
<dd>
<p>You can configure the entire server with command line arguments that specify libraries, properties and XML files.
However in practice the INI and modules mechanisms (below) reduce the verbosity of the command line.</p>
</dd>
<dt class="hdlist1">INI files</dt>
<dd>
<p>The <code>start.jar</code> mechanism uses the contents of the <code>${jetty.base}/start.ini</code> and <code>${jetty.base}/start.d/*.ini</code> files with each line equivalent to a <code>start.jar</code> command line argument.
This means that either a global <code>start.ini</code> file or multiple <code>start.d/feature.ini</code> files control the configuration of the server.</p>
</dd>
</dl>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>It is important to chose <strong>either</strong> <code>${jetty.base}/start.ini</code> or <code>${jetty.base}/start.d/*.ini</code> to manage configuration.
Using both is not recommended and can lead to issues with your server.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Modules</dt>
<dd>
<p>Instead of explicitly listing all the libraries, properties and XML files for a feature, the <code>start.jar</code> mechanism allows you to create modules.
A module is defined in a <code>modules/<strong>.mod</code> file, including the libraries, dependencies, XML, and template INI files for a Jetty feature.
Thus you can use a single <code>--module=name</code> command line option as the equivalent of specifying <code>--lib=location</code>, <code>feature.xml</code> or <code>name=value</code> arguments for a feature and all its dependencies.
Modules also use their dependencies to control the ordering of libraries and XML files.
There are several module files included with the Jetty distribution that cover the most common server features, such as HTTP, HTTPS, SSL, Logging, Annotations&#8230;&#8203;etc.
These module files should *only</strong> be edited if you are making structural changes to the way the feature will perform.
For more information, refer to the section on <a href="#startup-modules">managing startup modules</a> later in this chapter.</p>
</dd>
<dt class="hdlist1">XML Files</dt>
<dd>
<p>XML files in either Jetty IoC or Spring format instantiate the actual POJO components of the server.
This includes all major components such as connectors, keystores, session managers, and data sources.
Typically there are one or more XML files per module, and these are defined and activated in the corresponding module.</p>
</dd>
</dl>
</div>
<div class="sect3">
<h4 id="_startup-example"><a class="anchor" href="#_startup-example"></a><a class="link" href="#_startup-example">Startup Example</a></h4>
<div class="paragraph">
<p>The simplest way to start Jetty is via the <code>start.jar</code> mechanism using the following Java command line:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[user]$ cd jetty-distribution-10.0.0-SNAPSHOT
[jetty-distribution-10.0.0-SNAPSHOT]$ java -jar start.jar --module=http jetty.http.port=8080</code></pre>
</div>
</div>
<div class="paragraph">
<p>This command uses the <code>start.jar</code> mechanism to bootstrap the classpath, properties, and XML files with the metadata obtained from the <code>http</code> module.
Specifically the <code>http</code> module is defined in the <code>${jetty.home}/modules/http.mod</code> file, and includes the following:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[jetty-distribution-10.0.0-SNAPSHOT]$ cat modules/http.mod
[depend]
server
[xml]
etc/jetty-http.xml
[ini-template]
jetty.http.port=8080
http.timeout=30000</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>http</code> module declares that <code>http</code> depends on the server module, uses the <code>jetty-http.xml</code> file, and can be parameterized with <code>jetty.http.port</code> and <code>http.timeout</code> parameters.
The INI-template section is not actually used by the command above, so the <code>jetty.http.port</code> must still be defined on the command line.</p>
</div>
<div class="paragraph">
<p>Following the server dependency, the <code>${jetty.home}/modules/server.mod</code> file includes:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[jetty-distribution-10.0.0-SNAPSHOT]$ cat modules/server.mod
[lib]
lib/jetty-servlet-api-4.0.2.jar
lib/jetty-http-${jetty.version}.jar
lib/jetty-server-${jetty.version}.jar
lib/jetty-xml-${jetty.version}.jar
lib/jetty-util-${jetty.version}.jar
lib/jetty-io-${jetty.version}.jar
[xml]
etc/jetty.xml
[ini-template]
threads.min=10
threads.max=200</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>server</code> module declares the libraries the server needs and to use <code>jetty.xml</code> file.
The combined metadata of the <code>http</code> and <code>server</code> modules results in <code>start.jar</code> generating the effective Java command line required to start Jetty.</p>
</div>
<div class="paragraph">
<p>Another way to see this is by asking Jetty what its configuration looks like by appending --list-config to the command line:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[jetty-distribution-10.0.0-SNAPSHOT]$ java -jar start.jar --module=http jetty.http.port=9099 --list-config
Java Environment:
-----------------
java.home=/user/lib/jvm/jdk-7u21-x64/jre
java.vm.vendor=Oracle Corporation
java.vm.version=23.25-b01
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
java.vm.info=mixed mode
java.runtime.name=Java(TM) SE Runtime Environment
java.runtime.version=1.7.0_25-b15
java.io.tmpdir=/tmp
Jetty Environment:
-----------------
jetty.home=/opt/jetty/jetty-distribution-10.0.0-SNAPSHOT
jetty.base=/opt/jetty/jetty-distribution-10.0.0-SNAPSHOT
jetty.version=10.0.0-SNAPSHOT
JVM Arguments:
--------------
(no jvm args specified)
System Properties:
------------------
jetty.home = /opt/jetty/jetty-distribution-10.0.0-SNAPSHOT
jetty.base = /opt/jetty/jetty-distribution-10.0.0-SNAPSHOT
Properties:
-----------
jetty.http.port = 9099
Jetty Server Classpath:
-----------------------
Version Information on 7 entries in the classpath.
Note: order presented here is how they would appear on the classpath.
changes to the --module=name command line options will be reflected here.
0: 3.1.0 | ${jetty.home}/lib/jetty-servlet-api-4.0.2.jar
2: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-http-10.0.0-SNAPSHOT.jar
3: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-server-10.0.0-SNAPSHOT.jar
4: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-xml-10.0.0-SNAPSHOT.jar
5: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-util-10.0.0-SNAPSHOT.jar
6: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-io-10.0.0-SNAPSHOT.jar
Jetty Active XMLs:
------------------
${jetty.home}/etc/jetty.xml
${jetty.home}/etc/jetty-http.xml</code></pre>
</div>
</div>
<div class="paragraph">
<p>This represents the entirety of the configuration that is applied to start Jetty.</p>
</div>
<div class="paragraph">
<p>If you don&#8217;t want to use the <code>start.jar</code> bootstrap, you can start Jetty using a traditional Java command line.</p>
</div>
<div class="paragraph">
<p>The following is the equivalent Java command line for what the <code>start.jar</code> bootstrap above performs.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[user]$ cd jetty-distribution-10.0.0-SNAPSHOT
[jetty-distribution-10.0.0-SNAPSHOT]$ echo jetty.http.port=8080 &gt; /tmp/jetty.properties
[jetty-distribution-10.0.0-SNAPSHOT]$ export JETTY_HOME=`pwd`
[jetty-distribution-10.0.0-SNAPSHOT]$ export JETTY_BASE=`pwd`
[jetty-distribution-10.0.0-SNAPSHOT]$ export JETTY_VERSION="${project.version}"
[jetty-distribution-10.0.0-SNAPSHOT]$ java -Djetty.home=$JETTY_HOME \
-Djetty.base=$JETTY_BASE \
-cp \
$JETTY_HOME/lib/jetty-servlet-api-4.0.2.jar\
:$JETTY_HOME/lib/jetty-http-$JETTY_VERSION.jar\
:$JETTY_HOME/lib/jetty-server-$JETTY_VERSION.jar \
:$JETTY_HOME/lib/jetty-xml-$JETTY_VERSION.jar\
:$JETTY_HOME/lib/jetty-util-$JETTY_VERSION.jar\
:$JETTY_HOME/lib/jetty-io-$JETTY_VERSION.jar\
org.eclipse.jetty.xml.XmlConfiguration \
/tmp/jetty.properties \
$JETTY_HOME/etc/jetty.xml \
$JETTY_HOME/etc/jetty-http.xml</code></pre>
</div>
</div>
<div class="paragraph">
<p>The Java command line sets up the classpath with the core Jetty jars and the servlet API, executes the XmlConfiguration class and passes it some XML files that define the server and an HTTP connector running on the port defined in the <code>jetty.properties</code> file.</p>
</div>
<div class="paragraph">
<p>You can further simplify the startup of this server by using the INI template defined by the modules to create a <code>start.ini</code> file with the command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[user]$ cd jetty-distribution-10.0.0-SNAPSHOT
[jetty-distribution-10.0.0-SNAPSHOT]$ mkdir example-base
[example-base]$ cd example-base
[example-base]$ ls -la
total 8
drwxrwxr-x 2 user webgroup 4096 Oct 4 11:49 ./
drwxrwxr-x 12 user webgroup 4096 Oct 4 11:49 ../
[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=http
WARNING: http initialised in ${jetty.base}/start.ini (appended)
WARNING: http enabled in ${jetty.base}/start.ini
WARNING: server initialised in ${jetty.base}/start.ini (appended)
WARNING: server enabled in ${jetty.base}/start.ini
[example-base]$ ls -la
total 12
drwxrwxr-x 2 user webgroup 4096 Oct 4 11:55 ./
drwxrwxr-x 12 user webgroup 4096 Oct 4 11:49 ../
-rw-rw-r-- 1 user webgroup 250 Oct 4 11:55 start.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>Once complete, you can edit the <code>start.ini</code> file to modify any parameters and you can run the server with the simple command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar</code></pre>
</div>
</div>
<div class="paragraph">
<p>Unresolved directive in startup/chapter.adoc - include::start-jar.adoc[]</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="startup-base-and-home"><a class="anchor" href="#startup-base-and-home"></a><a class="link" href="#startup-base-and-home">Managing Jetty Base and Jetty Home</a></h3>
<div class="paragraph">
<p>Instead of managing multiple Jetty implementations out of several different distribution locations, it is possible to maintain a separation between the binary installation of the standalone Jetty (known as <code>${jetty.home}</code>), and the customizations for your specific environment(s) (known as <code>${jetty.base}</code>).
In addition to easy management of multiple server instances, is allows for quick, drop-in upgrades of Jetty.
There should always only be <strong>one</strong> Jetty Home (per version of Jetty), but there can be multiple Jetty Base directories that reference it.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Jetty Base</dt>
<dd>
<div class="ulist">
<ul>
<li>
<p>Also known as the <code>${jetty.base}</code> property.</p>
</li>
<li>
<p>This is the location for your configurations and customizations to the Jetty distribution.</p>
</li>
</ul>
</div>
</dd>
<dt class="hdlist1">Jetty Home</dt>
<dd>
<div class="ulist">
<ul>
<li>
<p>Also known as the <code>${jetty.home}</code> property.</p>
</li>
<li>
<p>This is the location for the Jetty distribution binaries, default XML IoC configurations, and default module definitions.</p>
</li>
</ul>
</div>
</dd>
</dl>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
Jetty Home should always be treated as a standard of truth.
All configuration modifications, changes and additions should be made in the appropriate Jetty Base directory.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div id="base-vs-home-resolution" class="paragraph">
<p>Potential configuration is resolved from these 2 directory locations.
When Jetty starts up in processes configuration from them as follows:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Check Jetty Base First</dt>
<dd>
<p>If the referenced configuration exists, relative to the defined Jetty base, it is used.</p>
</dd>
<dt class="hdlist1">Check Jetty Home Second</dt>
<dd>
<p>If the referenced configuration exists, relative to the defined Jetty home, it is used.</p>
</dd>
<dt class="hdlist1">Use java.io.File(String pathname) Logic</dt>
<dd>
<p>Lastly, use the reference as a <code>java.io.File(String pathname)</code> reference, following the default resolution rules outlined by that constructor.In brief, the reference will be used as-is, be it relative (to current working directory, aka $\{user.dir}) or absolute path, or even network reference (such as on Windows and use of UNC paths).</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>For more details on how startup with start.jar works, see <a href="#executing-startjar">Using start.jar: Executing</a></p>
</div>
<div class="sect3">
<h4 id="demo-base"><a class="anchor" href="#demo-base"></a><a class="link" href="#demo-base">Demo-Base in the Jetty Distribution</a></h4>
<div class="paragraph">
<p>The Jetty Distribution comes with an example <code>${jetty.base}</code> which enables the various demonstration webapps and server configurations.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[jetty-distribution-10.0.0-SNAPSHOT]$ ls -la
total 496
drwxrwxr-x 11 user group 4096 Oct 8 15:23 ./
drwxr-xr-x 14 user group 4096 Oct 8 13:04 ../
drwxrwxr-x 2 user group 4096 Oct 8 06:54 bin/
drwxrwxr-x 6 user group 4096 Oct 8 06:54 demo-base/
drwxrwxr-x 2 user group 4096 Oct 11 15:14 etc/
drwxrwxr-x 11 user group 4096 Oct 8 06:54 lib/
-rw-rw-r-- 1 user group 30012 Sep 30 19:55 license-eplv10-aslv20.html
drwxrwxr-x 2 user group 4096 Oct 8 06:54 logs/
drwxrwxr-x 2 user group 4096 Oct 8 06:54 modules/
-rw-rw-r-- 1 user group 6262 Sep 30 19:55 notice.html
-rw-rw-r-- 1 user group 1249 Sep 30 19:55 README.TXT
drwxrwxr-x 2 user group 4096 Oct 8 06:54 resources/
drwxrwxr-x 2 user group 4096 Oct 8 06:54 start.d/
-rw-rw-r-- 1 user group 1780 Sep 30 19:55 start.ini
-rw-rw-r-- 1 user group 71921 Sep 30 19:55 start.jar
-rw-rw-r-- 1 user group 336468 Sep 30 19:55 VERSION.txt
drwxrwxr-x 2 user group 4096 Oct 8 06:54 webapps/
[jetty-distribution-10.0.0-SNAPSHOT]$ cd demo-base
[my-base]$ java -jar /path/to/jetty-home/start.jar
2013-10-16 09:08:47.800:WARN::main: demo test-realm is deployed. DO NOT USE IN PRODUCTION!
2013-10-16 09:08:47.802:INFO:oejs.Server:main: jetty-10.0.0-SNAPSHOT
2013-10-16 09:08:47.817:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/home/user/jetty-distribution-10.0.0-SNAPSHOT/demo-base/webapps/] at interval 1
2013-10-16 09:08:48.072:WARN::main: async-rest webapp is deployed. DO NOT USE IN PRODUCTION!
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you want to see what the Jetty base looks like without executing Jetty, you can simply list the configuration by using the <code>--list-config</code> command.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --list-config
Java Environment:
-----------------
java.home=/usr/lib/jvm/jdk-7u21-x64/jre
java.vm.vendor = Oracle Corporation
java.vm.version = 25.92-b14
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
java.vm.info = mixed mode
java.runtime.name = Java(TM) SE Runtime Environment
java.runtime.version = 1.8.0_92-b14
java.io.tmpdir = /var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/
user.dir = /home/user/jetty-distribution-10.0.0-SNAPSHOT
user.language = en
user.country = US
Jetty Environment:
-----------------
jetty.home=/home/user/jetty-distribution-10.0.0-SNAPSHOT
jetty.tag.version = master
jetty.base=/home/user/jetty-distribution-10.0.0-SNAPSHOT/demo-base
jetty.version=10.0.0-SNAPSHOT
Config Search Order:
--------------------
&lt;command-line&gt;
${jetty.base} -&gt; /home/user/jetty-distribution-10.0.0-SNAPSHOT/demo-base
${jetty.home} -&gt; /home/user/Desktop/jetty-distribution-10.0.0-SNAPSHOT
JVM Arguments:
--------------
(no jvm args specified)
System Properties:
------------------
jetty.base = /home/user/jetty-distribution-10.0.0-SNAPSHOT/demo-base
jetty.home = /home/user/jetty-distribution-10.0.0-SNAPSHOT
Properties:
-----------
demo.realm = etc/realm.properties
https.port = 8443
https.timeout = 30000
jaas.login.conf = etc/login.conf
jetty.dump.start = false
jetty.dump.stop = false
jetty.keymanager.password = OBF:1u2u1wml1z7s1z7a1wnl1u2g
jetty.keystore = etc/keystore
jetty.keystore.password = OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
jetty.http.port = 8080
jetty.secure.port = 8443
jetty.truststore = etc/keystore
jetty.truststore.password = OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
org.eclipse.jetty.websocket.javax = false
threads.max = 200
threads.min = 10
threads.timeout = 60000
Jetty Server Classpath:
-----------------------
Version Information on 42 entries in the classpath.
Note: order presented here is how they would appear on the classpath.
changes to the --module=name command line options will be reflected here.
0: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-client-10.0.0-SNAPSHOT.jar
1: 1.4.1.v201005082020 | ${jetty.base}/lib/ext/javax.mail.glassfish-1.4.1.v201005082020.jar
2: 10.0.0-SNAPSHOT | ${jetty.base}/lib/ext/test-mock-resources-10.0.0-SNAPSHOT.jar
3: (dir) | ${jetty.home}/resources
4: 3.1.0 | ${jetty.home}/lib/jetty-servlet-api-4.0.2.jar
6: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-http-10.0.0-SNAPSHOT.jar
7: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-continuation-10.0.0-SNAPSHOT.jar
8: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-server-10.0.0-SNAPSHOT.jar
9: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-xml-10.0.0-SNAPSHOT.jar
10: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-util-10.0.0-SNAPSHOT.jar
11: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-io-10.0.0-SNAPSHOT.jar
12: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-jaas-10.0.0-SNAPSHOT.jar
13: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-jndi-10.0.0-SNAPSHOT.jar
14: 1.1.0.v201105071233 | ${jetty.home}/lib/jndi/javax.activation-1.1.0.v201105071233.jar
15: 1.4.1.v201005082020 | ${jetty.home}/lib/jndi/javax.mail.glassfish-1.4.1.v201005082020.jar
16: 1.3 | ${jetty.home}/lib/jndi/javax.transaction-api-1.3.jar
17: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-rewrite-10.0.0-SNAPSHOT.jar
18: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-security-10.0.0-SNAPSHOT.jar
19: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-servlet-10.0.0-SNAPSHOT.jar
20: 3.0.0 | ${jetty.home}/lib/jsp/javax.el-3.0.0.jar
21: 1.2.0.v201105211821 | ${jetty.home}/lib/jsp/javax.servlet.jsp.jstl-1.2.0.v201105211821.jar
22: 2.3.2 | ${jetty.home}/lib/jsp/javax.servlet.jsp-2.3.2.jar
23: 2.3.1 | ${jetty.home}/lib/jsp/javax.servlet.jsp-api-2.3.1.jar
24: 2.3.3 | ${jetty.home}/lib/jsp/jetty-jsp-jdt-2.3.3.jar
25: 1.2.0.v201112081803 | ${jetty.home}/lib/jsp/org.apache.taglibs.standard.glassfish-1.2.0.v201112081803.jar
26: 3.8.2.v20130121-145325 | ${jetty.home}/lib/jsp/org.eclipse.jdt.core-3.8.2.v20130121.jar
27: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-plus-10.0.0-SNAPSHOT.jar
28: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-webapp-10.0.0-SNAPSHOT.jar
29: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-annotations-10.0.0-SNAPSHOT.jar
30: 4.1 | ${jetty.home}/lib/annotations/asm-4.1.jar
31: 4.1 | ${jetty.home}/lib/annotations/asm-commons-4.1.jar
32: 1.2 | ${jetty.home}/lib/annotations/javax.annotation-api-1.2.jar
33: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-deploy-10.0.0-SNAPSHOT.jar
34: 1.0 | ${jetty.home}/lib/websocket/javax.websocket-api-1.0.jar
35: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-javax-client-10.0.0-SNAPSHOT.jar
36: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-javax-server-10.0.0-SNAPSHOT.jar
37: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-api-10.0.0-SNAPSHOT.jar
38: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-client-10.0.0-SNAPSHOT.jar
39: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-common-10.0.0-SNAPSHOT.jar
40: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-server-10.0.0-SNAPSHOT.jar
41: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-servlet-10.0.0-SNAPSHOT.jar
Jetty Active XMLs:
------------------
${jetty.home}/etc/jetty.xml
${jetty.home}/etc/jetty-webapp.xml
${jetty.home}/etc/jetty-plus.xml
${jetty.home}/etc/jetty-annotations.xml
${jetty.home}/etc/jetty-deploy.xml
${jetty.home}/etc/jetty-http.xml
${jetty.home}/etc/jetty-ssl.xml
${jetty.home}/etc/jetty-ssl-context.xml
${jetty.home}/etc/jetty-https.xml
${jetty.home}/etc/jetty-jaas.xml
${jetty.home}/etc/jetty-rewrite.xml
${jetty.base}/etc/demo-rewrite-rules.xml
${jetty.base}/etc/test-realm.xml</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>--list-config</code> command line option displays what the configuration will look like when starting Jetty.
This includes information on the Java environment to the system properties, the classpath and the Active Jetty IoC XML used to build up the Jetty server configuration.</p>
</div>
<div class="paragraph">
<p>Of note, is that the output will make it known where the configuration elements came from, be it in either in <code>${jetty.home}</code> or <code>${jetty.base}</code>.</p>
</div>
<div class="paragraph">
<p>If you look at the <code>${jetty.base}/start.ini</code> you will see a layout similar to below.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ cat start.ini
# Enable security via jaas, and configure it
--module=jaas
jaas.login.conf=etc/login.conf
# Enable rewrite examples
--module=rewrite
etc/demo-rewrite-rules.xml
# Websocket chat examples needs websocket enabled
# Don't start for all contexts (set to true in test.xml context)
org.eclipse.jetty.websocket.javax=false
--module=websocket
# Create and configure the test realm
etc/test-realm.xml
demo.realm=etc/realm.properties
# Initialize module server
--module=server
threads.min=10
threads.max=200
threads.timeout=60000
jetty.dump.start=false
jetty.dump.stop=false
--module=deploy
--module=jsp
--module=ext
--module=resources
--module=client
--module=annotations</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example, <code>${jetty.base}/start.ini</code> is the main startup configuration entry point for Jetty.
You will see that we are enabling a few modules for Jetty, specifying some properties, and also referencing some Jetty IoC XML files (namely the <code>etc/demo-rewrite-rules.xml</code> and <code>etc/test-realm.xml</code> files)</p>
</div>
<div class="paragraph">
<p>When Jetty&#8217;s <code>start.jar</code> resolves the entries in the <code>start.ini</code>, it will follow the <a href="#base-vs-home-resolution">resolution rules above</a>.</p>
</div>
<div class="paragraph">
<p>For example, the reference to <code>etc/demo-rewrite-rules.xml</code> was found in <code>${jetty.base}/etc/demo-rewrite-rules.xml</code>.</p>
</div>
</div>
<div class="sect3">
<h4 id="_declaring-jetty-base"><a class="anchor" href="#_declaring-jetty-base"></a><a class="link" href="#_declaring-jetty-base">Declaring Jetty Base</a></h4>
<div class="paragraph">
<p>The Jetty distribution&#8217;s <code>start.jar</code> is the component that manages the behavior of this separation.</p>
</div>
<div class="paragraph">
<p>The Jetty <code>start.jar</code> and XML files always assume that both <code>${jetty.home}</code> and <code>${jetty.base}</code> are defined when starting Jetty.</p>
</div>
<div class="paragraph">
<p>You can opt to manually define the <code>${jetty.home}</code> and <code>${jetty.base}</code> directories, such as this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[jetty-distribution-10.0.0-SNAPSHOT]$ pwd
/home/user/jetty-distribution-10.0.0-SNAPSHOT
[jetty-distribution-10.0.0-SNAPSHOT]$ java -jar start.jar \
jetty.home=/home/user/jetty-distribution-10.0.0-SNAPSHOT \
jetty.base=/home/user/my-base
2013-10-16 09:08:47.802:INFO:oejs.Server:main: jetty-10.0.0-SNAPSHOT
2013-10-16 09:08:47.817:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/home/user/my-base/webapps/] at interval 1
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>Alternately, you can declare one directory and let the other one be discovered.</p>
</div>
<div class="paragraph">
<p>The following example uses default discovery of <code>${jetty.home}</code> by using the parent directory of wherever <code>start.jar</code> itself is, and a manual declaration of <code>${jetty.base}</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[jetty-distribution-10.0.0-SNAPSHOT]$ pwd
/home/user/jetty-distribution-10.0.0-SNAPSHOT
[jetty-distribution-10.0.0-SNAPSHOT]$ java -jar start.jar jetty.base=/home/user/my-base
2013-10-16 09:08:47.802:INFO:oejs.Server:main: jetty-10.0.0-SNAPSHOT
2013-10-16 09:08:47.817:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/home/user/my-base/webapps/] at interval 1
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>But Jetty recommends that you always start Jetty from the directory that is your <code>${jetty.base}</code> and starting Jetty by referencing
the <code>start.jar</code> in your <code>{$jetty.home}</code> remotely.</p>
</div>
<div class="paragraph">
<p>The following demonstrates this by allowing default discovery of <code>${jetty.home}</code> via locating the <code>start.jar</code>, and using the <code>user.dir</code> System Property for <code>${jetty.base}</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[jetty-distribution-10.0.0-SNAPSHOT]$ pwd
/home/user/jetty-distribution-10.0.0-SNAPSHOT
[jetty-distribution-10.0.0-SNAPSHOT]$ cd /home/user/my-base
[my-base]$ java -jar /path/to/jetty-home/start.jar
2013-10-16 09:08:47.802:INFO:oejs.Server:main: jetty-10.0.0-SNAPSHOT
2013-10-16 09:08:47.817:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/home/user/my-base/webapps/] at interval 1
...</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
Be aware of the <code>user.dir</code> system property, as it can only be safely set when the JVM starts and many 3rd party libraries (especially logging) use this system property.
It is strongly recommended that you sit in the directory that is your desired <code>${jetty.base}</code> when starting Jetty to have consistent behavior and use of the <code>user.dir</code> system property.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
</div>
<div class="sect2">
<h3 id="startup-classpath"><a class="anchor" href="#startup-classpath"></a><a class="link" href="#startup-classpath">Managing Server Classpath</a></h3>
<div class="paragraph">
<p>Jetty Server Classpath is determined by a combination of factors.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">The java.class.path System Property</dt>
<dd>
<p>If you start Jetty with a JVM specified classpath, then Jetty will use the java.class.path System Property to populate the initial classpath.</p>
</dd>
<dt class="hdlist1">Module specified Libraries</dt>
<dd>
<p>The module system declares various libraries that are required for that module to operate.
These module defined libraries are added to the Jetty Server classpath when any module is activated with library declarations.</p>
</dd>
<dt class="hdlist1">Command Line Libraries</dt>
<dd>
<p>The command line option <code>--lib=&lt;path&gt;</code> can be used as a final means to add arbitrary entries to the Jetty Server classpath.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Of special note, there are 2 structural modules defined to ease some of this for you.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">--module=ext</dt>
<dd>
<p>The <code>ext</code> module will enable the <code>lib/ext/*.jar</code> logic.
<br>
If this module is activated, then all jar files found in the lib/ext/ paths will be automatically added to the Jetty Server Classpath.</p>
</dd>
<dt class="hdlist1">--module=resources</dt>
<dd>
<p>The <code>resources</code> module will add the <code>resources/</code> directory the classpath.
<br>
If you have 3rd party libraries that lookup resources from the classpath, put your files in here.
<br>
Logging libraries often have classpath lookup of their configuration files (eg: <code>log4j.properties</code>, <code>log4j.xml</code>, <code>logging.properties</code>, and <code>logback.xml</code>), so this would be the ideal setup for this sort of configuration demand.</p>
</dd>
</dl>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Both the <code>ext</code> and <code>resources</code> modules declare relative paths that follow <a href="#base-vs-home-resolution">Jetty Base and Jetty Home path resolution rules</a>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="sect3">
<h4 id="_interrogating-the-server-classpath"><a class="anchor" href="#_interrogating-the-server-classpath"></a><a class="link" href="#_interrogating-the-server-classpath">Interrogating the Server Classpath</a></h4>
<div class="paragraph">
<p>The Jetty <code>start.jar</code> has the ability to resolve the classpath from the command line, modules and configuration, and to list the classpath entries it will use to start jetty.</p>
</div>
<div class="paragraph">
<p>The <code>--list-classpath</code> command line option is used as such.</p>
</div>
<div class="paragraph">
<p>(Demonstrated with the <a href="#demo-base">demo-base from the Jetty Distribution</a>)</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --list-classpath
Jetty Server Classpath:
-----------------------
Version Information on 42 entries in the classpath.
Note: order presented here is how they would appear on the classpath.
changes to the --module=name command line options will be reflected here.
0: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-client-10.0.0-SNAPSHOT.jar
1: 1.4.1.v201005082020 | ${jetty.base}/lib/ext/javax.mail.glassfish-1.4.1.v201005082020.jar
2: 10.0.0-SNAPSHOT | ${jetty.base}/lib/ext/test-mock-resources-10.0.0-SNAPSHOT.jar
3: (dir) | ${jetty.home}/resources
4: 4.0.2 | ${jetty.home}/lib/jetty-servlet-api-4.0.2.jar
6: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-http-10.0.0-SNAPSHOT.jar
7: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-continuation-10.0.0-SNAPSHOT.jar
8: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-server-10.0.0-SNAPSHOT.jar
9: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-xml-10.0.0-SNAPSHOT.jar
10: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-util-10.0.0-SNAPSHOT.jar
11: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-io-10.0.0-SNAPSHOT.jar
12: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-jaas-10.0.0-SNAPSHOT.jar
13: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-jndi-10.0.0-SNAPSHOT.jar
14: 1.1.0.v201105071233 | ${jetty.home}/lib/jndi/javax.activation-1.1.0.v201105071233.jar
15: 1.4.1.v201005082020 | ${jetty.home}/lib/jndi/javax.mail.glassfish-1.4.1.v201005082020.jar
16: 1.3 | ${jetty.home}/lib/jndi/javax.transaction-api-1.3.jar
17: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-rewrite-10.0.0-SNAPSHOT.jar
18: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-security-10.0.0-SNAPSHOT.jar
19: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-servlet-10.0.0-SNAPSHOT.jar
20: 3.0.0 | ${jetty.home}/lib/jsp/javax.el-3.0.0.jar
21: 1.2.0.v201105211821 | ${jetty.home}/lib/jsp/javax.servlet.jsp.jstl-1.2.0.v201105211821.jar
22: 2.3.2 | ${jetty.home}/lib/jsp/javax.servlet.jsp-2.3.2.jar
23: 2.3.1 | ${jetty.home}/lib/jsp/javax.servlet.jsp-api-2.3.1.jar
24: 2.3.3 | ${jetty.home}/lib/jsp/jetty-jsp-jdt-2.3.3.jar
25: 1.2.0.v201112081803 | ${jetty.home}/lib/jsp/org.apache.taglibs.standard.glassfish-1.2.0.v201112081803.jar
26: 3.8.2.v20130121-145325 | ${jetty.home}/lib/jsp/org.eclipse.jdt.core-3.8.2.v20130121.jar
27: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-plus-10.0.0-SNAPSHOT.jar
28: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-webapp-10.0.0-SNAPSHOT.jar
29: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-annotations-10.0.0-SNAPSHOT.jar
30: 4.1 | ${jetty.home}/lib/annotations/asm-4.1.jar
31: 4.1 | ${jetty.home}/lib/annotations/asm-commons-4.1.jar
32: 1.2 | ${jetty.home}/lib/annotations/javax.annotation-api-1.2.jar
33: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-deploy-10.0.0-SNAPSHOT.jar
34: 1.0 | ${jetty.home}/lib/websocket/javax.websocket-api-1.0.jar
35: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-javax-client-10.0.0-SNAPSHOT.jar
36: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-javax-server-10.0.0-SNAPSHOT.jar
37: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-api-10.0.0-SNAPSHOT.jar
38: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-client-10.0.0-SNAPSHOT.jar
39: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-common-10.0.0-SNAPSHOT.jar
40: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-server-10.0.0-SNAPSHOT.jar
41: 10.0.0-SNAPSHOT | ${jetty.home}/lib/websocket/websocket-servlet-10.0.0-SNAPSHOT.jar</code></pre>
</div>
</div>
<div class="paragraph">
<p>Of note is that an attempt is made to list the internally declared version of each artifact on the Server Classpath, which can potentially help when diagnosing classpath issues.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="startup-modules"><a class="anchor" href="#startup-modules"></a><a class="link" href="#startup-modules">Managing Startup Modules</a></h3>
<div class="paragraph">
<p>The standard Jetty Distribution ships with several modules defined in <code>${jetty.home}/modules/</code>.
Modules interact with Jetty XML files to configure options and parameters for the server and are the primary configuration method for Jetty distributions.
Modules allow flexibility for implementations and their plug-and-play nature makes adding or removing server functionality virtually painless.</p>
</div>
<div class="sect3">
<h4 id="enabling-modules"><a class="anchor" href="#enabling-modules"></a><a class="link" href="#enabling-modules">Enabling Modules</a></h4>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
The default distribution has a co-mingled <code>${jetty.home}</code> and <code>${jetty.base}</code> where the directories for <code>${jetty.home}</code> and <code>${jetty.base}</code> point to the same location.
It is highly encouraged that you learn about the differences in <a href="#startup-base-and-home">Jetty Base vs Jetty Home</a> and take full advantage of this setup.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Enabling a module is a simple process: simply add the <code>--add-to-start=&lt;module-name1&gt;,&lt;module-name2&gt;,&#8230;&#8203;etc.</code> syntax on the command line.
Doing this will enable the specified module and any dependent modules.</p>
</div>
<div class="paragraph">
<p>An example of this with a new, empty, base directory:</p>
</div>
<div class="paragraph">
<p>If we try to start the Jetty server with no configuration or modules enabled, it will promptly exit:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[jetty]$ mkdir mybase
[jetty]$ cd mybase
[mybase]$ ls -la
total 0
drwxr-xr-x 2 staff staff 68 Jul 12 17:29 .
drwxr-xr-x 20 staff staff 680 Jul 12 17:29 ..
[my-base]$ java -jar /path/to/jetty-home/start.jar
WARNING: Nothing to start, exiting ...
Usage: java -jar start.jar [options] [properties] [configs]
java -jar start.jar --help # for more information</code></pre>
</div>
</div>
<div class="paragraph">
<p>By using the <code>--list-config</code> parameter to our startup command, we can see that there are no modules enabled and no Jetty XML files are active:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --list-config
Java Environment:
-----------------
java.home = /Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre
java.vm.vendor = Oracle Corporation
java.vm.version = 25.92-b14
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
java.vm.info = mixed mode
java.runtime.name = Java(TM) SE Runtime Environment
java.runtime.version = 1.8.0_92-b14
java.io.tmpdir = /var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/
user.dir = /Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT/mybase
user.language = en
user.country = US
Jetty Environment:
-----------------
jetty.version = 10.0.0-SNAPSHOT
jetty.tag.version = master
jetty.home = /Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT
jetty.base = /Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT/mybase
Config Search Order:
--------------------
&lt;command-line&gt;
${jetty.base} -&gt; /Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT/mybase
${jetty.home} -&gt; /Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT
JVM Arguments:
--------------
(no jvm args specified)
System Properties:
------------------
(no system properties specified)
Properties:
-----------
java.version = 1.8.0_92
Jetty Server Classpath:
-----------------------
No classpath entries and/or version information available show.
Jetty Active XMLs:
------------------
(no xml files specified)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Let&#8217;s try adding some basic support for webapps, with automatic deploy (hot deploy), and a single basic HTTP/1.1 connector.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=http,webapp,deploy
INFO : webapp initialized in ${jetty.base}/start.ini
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : security transitively enabled
INFO : servlet transitively enabled
INFO : http initialized in ${jetty.base}/start.ini
INFO : deploy initialized in ${jetty.base}/start.ini
MKDIR : ${jetty.base}/webapps
INFO : Base directory was modified</code></pre>
</div>
</div>
<div class="paragraph">
<p>This creates the webapps directory in our <code>mybase</code> directory and appended the <code>start.ini</code> file with the ini template arguments from the associated module files.
Additionally, where needed, Jetty enabled any module dependencies.</p>
</div>
<div class="paragraph">
<p>Now that we have added some modules to our server, let&#8217;s run <code>--list-config</code> again to review our new configuration.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --list-config
Java Environment:
-----------------
java.home = /Library/Java/JavaVirtualMachines/jdk1.8.0_92.jdk/Contents/Home/jre
java.vm.vendor = Oracle Corporation
java.vm.version = 25.92-b14
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
java.vm.info = mixed mode
java.runtime.name = Java(TM) SE Runtime Environment
java.runtime.version = 1.8.0_92-b14
java.io.tmpdir = /var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/
user.dir = /Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT/mybase
user.language = en
user.country = US
Jetty Environment:
-----------------
jetty.version = 10.0.0-SNAPSHOT
jetty.tag.version = master
jetty.home = /Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT
jetty.base = /Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT/mybase
Config Search Order:
--------------------
&lt;command-line&gt;
${jetty.base} -&gt; /Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT/mybase
${jetty.home} -&gt; /Users/staff/installs/repository/jetty-distribution-10.0.0-SNAPSHOT
JVM Arguments:
--------------
(no jvm args specified)
System Properties:
------------------
(no system properties specified)
Properties:
-----------
java.version = 1.8.0_92
Jetty Server Classpath:
-----------------------
Version Information on 11 entries in the classpath.
Note: order presented here is how they would appear on the classpath.
changes to the --module=name command line options will be reflected here.
0: 3.1.0 | ${jetty.home}/lib/jetty-servlet-api-4.0.2.jar
2: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-http-10.0.0-SNAPSHOT.jar
3: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-server-10.0.0-SNAPSHOT.jar
4: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-xml-10.0.0-SNAPSHOT.jar
5: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-util-10.0.0-SNAPSHOT.jar
6: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-io-10.0.0-SNAPSHOT.jar
7: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-security-10.0.0-SNAPSHOT.jar
8: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-servlet-10.0.0-SNAPSHOT.jar
9: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-webapp-10.0.0-SNAPSHOT.jar
10: 10.0.0-SNAPSHOT | ${jetty.home}/lib/jetty-deploy-10.0.0-SNAPSHOT.jar
Jetty Active XMLs:
------------------
${jetty.home}/etc/jetty.xml
${jetty.home}/etc/jetty-webapp.xml
${jetty.home}/etc/jetty-deploy.xml
${jetty.home}/etc/jetty-http.xml</code></pre>
</div>
</div>
<div class="paragraph">
<p>You now have a configured and functional server, albeit with no webapps deployed.
At this point you can place a webapp (war file) in the <code>mybase/webapps/</code> directory and and start Jetty.</p>
</div>
</div>
<div class="sect3">
<h4 id="start-vs-startd"><a class="anchor" href="#start-vs-startd"></a><a class="link" href="#start-vs-startd">Start.ini vs. Start.d</a></h4>
<div class="paragraph">
<p>In the above example, when a module is activated the contents of that module file are added in <code>${jetty.base}/start.ini</code>.
As additional modules are added, their contents are appended to this file.
This can be beneficial if you want all of your module configurations in a single file, but for large server instances with lots of modules it can pose a challenge to quickly find and make changes or to remove a module.</p>
</div>
<div class="paragraph">
<p>As an alternative to a single <code>start.ini</code> file you can opt to house modules in a <code>${jetty.base}/start.d</code> directory.
Modules activated when a <code>start.d</code> directory exists will be stored as a single file per module.
Below is an example of a fresh <code>${jetty.base}</code> that will create a <code>start.d</code> directory and activate several modules.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[jetty.home]$ mkdir mybase
[jetty.home]$ cd mybase/
[my-base]$ java -jar /path/to/jetty-home/start.jar --create-startd
INFO : Base directory was modified
[mybase]$ ls -all
total 0
drwxr-xr-x 3 staff staff 102 Aug 29 15:16 .
drwxr-xr-x@ 26 staff staff 884 Aug 29 15:16 ..
drwxr-xr-x 6 staff staff 204 Aug 29 15:19 start.d
[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=server,client,webapp,websocket
INFO : webapp initialised in ${jetty.base}/start.d/webapp.ini
INFO : server initialised in ${jetty.base}/start.d/server.ini
INFO : websocket initialised in ${jetty.base}/start.d/websocket.ini
INFO : client initialised in ${jetty.base}/start.d/client.ini
INFO : Base directory was modified
[mybase]$ cd start.d/
[mybase]$ ls -all
total 32
drwxr-xr-x 6 staff staff 204 Aug 29 15:19 .
drwxr-xr-x 3 staff staff 102 Aug 29 15:16 ..
-rw-r--r-- 1 staff staff 175 Aug 29 15:19 client.ini
-rw-r--r-- 1 staff staff 2250 Aug 29 15:19 server.ini
-rw-r--r-- 1 staff staff 265 Aug 29 15:19 webapp.ini
-rw-r--r-- 1 staff staff 177 Aug 29 15:19 websocket.ini</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the example, we first create a new <code>${jetty.base}</code> and then create the <code>start.d</code> directory with the <code>--create-startd</code> command.
Next, we use the <code>--add-to-start</code> command which activates the modules and creates their respective ini files in the <code>start.d</code> directory.</p>
</div>
<div class="paragraph">
<p>If you have an existing <code>start.ini</code> file but would like to use the <code>start.d</code> structure for additional modules, you can use the <code>--create-startd</code> command as well.
Doing this will create the <code>start.d</code> directory and copy your existing <code>start.ini</code> file in to it.
Any new modules added to the server will have their own <code>&lt;module name&gt;.ini</code> file created in the <code>start.d</code> directory.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=server,client,webapp,websocket
INFO : webapp initialised in ${jetty.base}/start.ini
INFO : server initialised in ${jetty.base}/start.ini
INFO : websocket initialised in ${jetty.base}/start.ini
INFO : client initialised in ${jetty.base}/start.ini
INFO : Base directory was modified
[my-base]$ java -jar /path/to/jetty-home/start.jar --create-startd
INFO : Base directory was modified
[mybase]$ tree
.
└── start.d
└── start.ini
[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=ssl
INFO : ssl initialised in ${jetty.base}/start.d/ssl.ini
INFO : Base directory was modified
[mybase]$ tree
.
├── etc
│   └── keystore
└── start.d
├── ssl.ini
└── start.ini</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>It is <strong>not</strong> recommended to use both a <code>${jetty.base}/start.ini</code> file and a <code>${jetty.base}/start.d</code> directory at the same time and doing so can cause issues.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="startup-configuring-modules"><a class="anchor" href="#startup-configuring-modules"></a><a class="link" href="#startup-configuring-modules">Configuring Modules</a></h4>
<div class="paragraph">
<p>Once a module has been enabled for the server, it can be further configured to meet your needs.
This is done by editing the associated ini file for the module.
If your server setup is using a centralized ini configuration, you will edit the <code>${jetty.base}/server.ini</code> file.
If you have elected to manage each module within it&#8217;s own ini file, you can find these files in the <code>${jetty.base}/start.d</code> directory.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
It is important that you <strong>do not</strong> modify the module files in the <code>$JETTY_HOME/modules</code> directory.
$JETTY_HOME should always remain a standard of truth.
If you want to make a change to an actual module file (not the values in its <code>ini-template</code>), either edit its associated <code>ini</code> file in the <code>$JETTY_BASE/start.d</code> directory or make a copy of the desired module file and copy it to the <code>$JETTY_BASE</code> directory and edit it there.
The start.jar reads local <code>$JETTY_BASE/modules</code> files (if they exist) before scanning <code>$JETTY_HOME</code>.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>When a module is activated, a number of properties are set by default.
To view these defaults, open up the associated ini file.
Listed in the ini file is the associated module file and any properties that can be set.</p>
</div>
<div class="paragraph">
<p>Below is an example of the <code>requestlog.ini</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># ---------------------------------------
# Module: requestlog
--module=requestlog
## Logging directory (relative to $jetty.base)
# jetty.requestlog.dir=logs
## File path
# jetty.requestlog.filePath=${jetty.requestlog.dir}/yyyy_mm_dd.request.log
## Date format for rollovered files (uses SimpleDateFormat syntax)
# jetty.requestlog.filenameDateFormat=yyyy_MM_dd
## How many days to retain old log files
# jetty.requestlog.retainDays=90
## Whether to append to existing file
# jetty.requestlog.append=true
## Whether to use the extended log output
# jetty.requestlog.extended=true
## Whether to log http cookie information
# jetty.requestlog.cookies=true
## Timezone of the log entries
# jetty.requestlog.timezone=GMT
## Whether to log LogLatency
# jetty.requestlog.loglatency=false</code></pre>
</div>
</div>
<div class="paragraph">
<p>The first lines name the module file being called (located in <code>{$jetty.home/modules}</code>).
Subsequent lines list properties that can be changed as well as a description for each property.
To edit a property, first un-comment the line by deleting the <code>#</code> at the start of the line, then make the change after <code>=</code> sign (such as changing a <code>true</code> value to <code>false</code>).</p>
</div>
</div>
<div class="sect3">
<h4 id="startup-disable-module"><a class="anchor" href="#startup-disable-module"></a><a class="link" href="#startup-disable-module">Disabling Modules</a></h4>
<div class="paragraph">
<p>Disabling a module is an easy process.
To disable a module, comment out the <code>--module=</code> line in the associated ini file.
Deleting the ini file associated with module is another option, but may not be practical in all situations.</p>
</div>
</div>
<div class="sect3">
<h4 id="startup-listing-modules"><a class="anchor" href="#startup-listing-modules"></a><a class="link" href="#startup-listing-modules">Listing Available and Active Modules</a></h4>
<div class="paragraph">
<p>To see which modules are <em>available</em>, use the <code>--list-modules</code> command line argument.
This command will also show you which modules are <em>enabled</em>.
Modules are sorted by the value in the <code>[tags]</code> section of the associated <code>.mod</code> file.
If there are multiple entries in the <code>[tags]</code> section, it sorts by the first tag in the list.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
By default, the <code>--list-modules</code> command line argument shows all modules that do not include <code>internal</code> in the <code>[tags]</code> section of the associated <code>.mod</code> file.
If you would like to see <strong>all</strong> modules, use <code>--list-all-modules</code>
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of the <code>--list-modules</code> command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --list-modules
Available Modules:
==================
tags: [-internal]
Modules for tag '*':
--------------------
Module: alpn
: Enables the ALPN (Application Layer Protocol Negotiation) TLS extension.
Depend: ssl, alpn-impl
LIB: lib/jetty-alpn-client-${jetty.version}.jar
LIB: lib/jetty-alpn-server-${jetty.version}.jar
XML: etc/jetty-alpn.xml
Module: alpn-impl
: Selects an ALPN (Application Layer Protocol Negotiation) implementation by java version.
Depend: alpn-impl/alpn-${java.version.platform}
Module: annotations
: Enables Annotation scanning for deployed webapplications.
Depend: plus
LIB: lib/jetty-annotations-${jetty.version}.jar
LIB: lib/annotations/*.jar
XML: etc/jetty-annotations.xml
Enabled: ${jetty.base}\start.d\annotations.ini
Module: apache-jsp
: Enables use of the apache implementation of JSP
LIB: lib/apache-jsp/*.jar
Enabled: transitive provider of apache-jsp for jsp
Module: apache-jstl
: Enables the apache version of JSTL
LIB: lib/apache-jstl/*.jar
Enabled: transitive provider of apache-jstl for jstl
Module: cdi2
: Jetty setup to support Weld/CDI2 with WELD inside the webapp
Depend: deploy
XML: etc/cdi2/jetty-cdi2.xml
Module: client
: Adds the Jetty HTTP client to the server classpath.
LIB: lib/jetty-client-${jetty.version}.jar
Enabled: ${jetty.base}\start.d\client.ini
Module: continuation
: Enables support for Continuation style asynchronous
: Servlets. Now deprecated in favour of Servlet 3.1
: API
LIB: lib/jetty-continuation-${jetty.version}.jar
Enabled: ${jetty.base}\start.d\continuation.ini
Module: deploy
: Enables webapplication deployment from the webapps directory.
Depend: webapp
LIB: lib/jetty-deploy-${jetty.version}.jar
XML: etc/jetty-deploy.xml
Enabled: ${jetty.base}\start.d\deploy.ini
Module: fcgi
: Adds the FastCGI implementation to the classpath.
Depend: servlet, client
LIB: lib/jetty-proxy-${jetty.version}.jar
LIB: lib/fcgi/*.jar
Module: flight-recorder
Depend: server
JVM: -XX:+UnlockCommercialFeatures
JVM: -XX:+FlightRecorder
Module: global-webapp-common
: Enables Deployer to apply common configuration to all webapp deployments
Depend: deploy
XML: etc/global-webapp-common.xml
Module: hazelcast-embedded-sessions
Depend: annotations, webapp
LIB: lib/hazelcast/*.jar
XML: etc/sessions/hazelcast/default.xml
Module: hazelcast-remote-sessions
Depend: annotations, webapp
LIB: lib/hazelcast/*.jar
XML: etc/sessions/hazelcast/remote.xml
Module: home-base-warning
: Generates a warning that server has been run from $JETTY_HOME
: rather than from a $JETTY_BASE.
XML: etc/home-base-warning.xml
Module: jaas
: Enable JAAS for deployed webapplications.
Depend: server
LIB: lib/jetty-jaas-${jetty.version}.jar
XML: etc/jetty-jaas.xml
Enabled: ${jetty.base}\start.d\demo.ini
Module: jaspi
: Enable JASPI authentication for deployed webapplications.
Depend: security
LIB: lib/jetty-jaspi-${jetty.version}.jar
LIB: lib/jaspi/*.jar
Module: jmx
: Enables JMX instrumentation for server beans and
: enables JMX agent.
Depend: server
LIB: lib/jetty-jmx-${jetty.version}.jar
XML: etc/jetty-jmx.xml
Module: jmx-remote
: Enables remote RMI access to JMX
Depend: jmx
XML: etc/jetty-jmx-remote.xml
Module: jndi
: Adds the Jetty JNDI implementation to the classpath.
Depend: server, mail
LIB: lib/jetty-jndi-${jetty.version}.jar
LIB: lib/jndi/*.jar
Enabled: ${jetty.base}\start.d\jndi.ini
Module: jsp
: Enables JSP for all webapplications deployed on the server.
Depend: servlet, annotations, apache-jsp
Enabled: ${jetty.base}\start.d\jsp.ini
Module: jstl
: Enables JSTL for all webapplications deployed on the server
Depend: jsp, apache-jstl
Enabled: ${jetty.base}\start.d\jstl.ini
Module: jvm
: A noop module that creates an ini template useful for
: setting JVM arguments (eg -Xmx )
Module: lowresources
: Enables a low resource monitor on the server
: that can take actions if threads and/or connections
: cross configured threshholds.
Depend: server
XML: etc/jetty-lowresources.xml
Module: mail
: Adds the javax.mail implementation to the classpath.
LIB: lib/mail/*.jar
Enabled: transitive provider of mail for jndi
Module: plus
: Enables JNDI and resource injection for webapplications
: and other servlet 3.x features not supported in the core
: jetty webapps module.
Depend: server, security, jndi, webapp, transactions
LIB: lib/jetty-plus-${jetty.version}.jar
XML: etc/jetty-plus.xml
Enabled: transitive provider of plus for annotations
Module: proxy
: Enable the Jetty Proxy, that allows the server to act
: as a non-transparent proxy for browsers.
Depend: servlet, client
LIB: lib/jetty-proxy-${jetty.version}.jar
XML: etc/jetty-proxy.xml
Module: proxy-protocol
: Enables the Proxy Protocol on the HTTP Connector.
: http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
: This allows a proxy operating in TCP mode to
: transport details of the proxied connection to
: the server.
: Both V1 and V2 versions of the protocol are supported.
Depend: http
XML: etc/jetty-proxy-protocol.xml
Module: quickstart
: Enables the Jetty Quickstart module for rapid
: deployment of preconfigured webapplications.
Depend: server, plus, annotations
LIB: lib/jetty-quickstart-${jetty.version}.jar
Module: rewrite
: Enables the jetty-rewrite handler. Specific rewrite
: rules must be added to either to etc/jetty-rewrite.xml or a custom xml/module
Depend: server
LIB: lib/jetty-rewrite-${jetty.version}.jar
XML: etc/jetty-rewrite.xml
Enabled: ${jetty.base}\start.d\demo.ini
Module: rewrite-compactpath
: Add a rule to the rewrite module to compact paths so that double slashes
: in the path are treated as a single slash.
Depend: rewrite
XML: etc/rewrite-compactpath.xml
Module: rewrite-customizer [rewrite]
: Enables a rewrite Rules container as a request customizer on
: the servers default HttpConfiguration instance
Depend: server
LIB: lib/jetty-rewrite-${jetty.version}.jar
XML: etc/jetty-rewrite-customizer.xml
Module: security
: Adds servlet standard security handling to the classpath.
Depend: server
LIB: lib/jetty-security-${jetty.version}.jar
Enabled: transitive provider of security for webapp
Enabled: transitive provider of security for plus
Module: server
: Enables the core Jetty server on the classpath.
Depend: threadpool
Optional: jvm, ext, resources, logging
LIB: lib/jetty-servlet-api-4.0.2.jar
LIB: lib/jetty-http-${jetty.version}.jar
LIB: lib/jetty-server-${jetty.version}.jar
LIB: lib/jetty-xml-${jetty.version}.jar
LIB: lib/jetty-util-${jetty.version}.jar
LIB: lib/jetty-io-${jetty.version}.jar
XML: etc/jetty.xml
Enabled: ${jetty.base}\start.d\server.ini
Module: servlet
: Enables standard Servlet handling.
Depend: server
LIB: lib/jetty-servlet-${jetty.version}.jar
Enabled: transitive provider of servlet for webapp
Enabled: transitive provider of servlet for servlets
Enabled: transitive provider of servlet for jsp
Module: servlets
: Puts a collection of jetty utility servlets and filters
: on the server classpath (CGI, CrossOriginFilter, DosFilter,
: MultiPartFilter, PushCacheFilter, QoSFilter, etc.) for
: use by all webapplications.
Depend: servlet
LIB: lib/jetty-servlets-${jetty.version}.jar
Enabled: ${jetty.base}\start.d\servlets.ini
Module: setuid
: Enables the unix setUID configuration so that the server
: may be started as root to open privileged ports/files before
: changing to a restricted user (eg jetty).
Depend: server
LIB: lib/setuid/jetty-setuid-java-1.0.3.jar
XML: etc/jetty-setuid.xml
Module: spring
: Enable spring configuration processing so all jetty style
: xml files can optionally be written as spring beans
Depend: server
LIB: lib/spring/*.jar
Module: stop
: This module causes jetty to stop immediately after starting. This is good for testing configuration and/or precompiling quickstart webapps
XML: etc/jetty-stop.xml
Module: threadpool
: Enables the Server thread pool.
XML: etc/jetty-threadpool.xml
Enabled: ${jetty.base}\start.d\threadpool.ini
Module: transactions
: Puts javax.transaction api on the classpath
LIB: lib/transactions/*.jar
Enabled: transitive provider of transactions for plus
Module: webapp
: Adds support for servlet specification webapplication to the server
: classpath. Without this, only Jetty specific handlers may be deployed.
Depend: servlet, security
LIB: lib/jetty-webapp-${jetty.version}.jar
XML: etc/jetty-webapp.xml
Enabled: transitive provider of webapp for plus
Enabled: transitive provider of webapp for deploy
Module: websocket
: Enable websockets for deployed web applications
Depend: client, annotations
LIB: lib/websocket/*.jar
Enabled: ${jetty.base}\start.d\demo.ini
Modules for tag '3rdparty':
---------------------------
Module: conscrypt [alpn-impl]
: Installs the Conscrypt JSSE provider
Tags: 3rdparty
Depend: ssl
LIB: lib/conscrypt/**.jar
LIB: lib/jetty-alpn-conscrypt-server-${jetty.version}.jar
XML: etc/conscrypt.xml
Module: gcloud
: Control GCloud API classpath
Tags: 3rdparty, gcloud
LIB: lib/gcloud/*.jar
Module: gcloud-datastore
: Enables GCloud Datastore API and implementation
Tags: 3rdparty, gcloud
Depend: gcloud, jcl-slf4j, jul-impl
Module: hawtio
: Deploys the Hawtio console as a webapplication.
Tags: 3rdparty
Depend: stats, deploy, jmx
XML: etc/hawtio.xml
Module: jamon
: Deploys the JAMon webapplication
Tags: 3rdparty
Depend: stats, deploy, jmx, jsp
LIB: lib/jamon/**.jar
XML: etc/jamon.xml
Module: jminix
: Deploys the Jminix JMX Console within the server
Tags: 3rdparty
Depend: stats, jmx, jcl-api, jcl-impl
LIB: lib/jminix/**.jar
XML: etc/jminix.xml
Module: jolokia
: Deploys the Jolokia console as a web application.
Tags: 3rdparty
Depend: stats, deploy, jmx
XML: etc/jolokia.xml
Modules for tag 'classpath':
----------------------------
Module: ext
: Adds all jar files discovered in $JETTY_HOME/lib/ext
: and $JETTY_BASE/lib/ext to the servers classpath.
Tags: classpath
LIB: lib/ext/**.jar
Enabled: ${jetty.base}\start.d\ext.ini
Module: resources
: Adds the $JETTY_HOME/resources and/or $JETTY_BASE/resources
: directory to the server classpath. Useful for configuration
: property files (eg jetty-logging.properties)
Tags: classpath
LIB: resources/
Enabled: ${jetty.base}\start.d\resources.ini
Modules for tag 'connector':
----------------------------
Module: acceptratelimit
: Enable a server wide accept rate limit
Tags: connector
Depend: server
XML: etc/jetty-acceptratelimit.xml
Module: connectionlimit
: Enable a server wide connection limit
Tags: connector
Depend: server
XML: etc/jetty-connectionlimit.xml
Module: http
: Enables a HTTP connector on the server.
: By default HTTP/1 is support, but HTTP2C can
: be added to the connector with the http2c module.
Tags: connector, http
Depend: server
XML: etc/jetty-http.xml
Enabled: ${jetty.base}\start.d\http.ini
Module: http-forwarded
: Adds a forwarded request customizer to the HTTP Connector
: to process forwarded-for style headers from a proxy.
Tags: connector
Depend: http
XML: etc/jetty-http-forwarded.xml
Module: http2
: Enables HTTP2 protocol support on the TLS(SSL) Connector,
: using the ALPN extension to select which protocol to use.
Tags: connector, http2, http, ssl
Depend: ssl, alpn
LIB: lib/http2/*.jar
XML: etc/jetty-http2.xml
Module: http2c
: Enables the HTTP2C protocol on the HTTP Connector
: The connector will accept both HTTP/1 and HTTP/2 connections.
Tags: connector, http2, http
Depend: http
LIB: lib/http2/*.jar
XML: etc/jetty-http2c.xml
Module: https
: Adds HTTPS protocol support to the TLS(SSL) Connector
Tags: connector, https, http, ssl
Depend: ssl
Optional: http-forwarded, http2
XML: etc/jetty-https.xml
Enabled: ${jetty.base}\start.d\https.ini
Module: proxy-protocol-ssl
: Enables the Proxy Protocol on the TLS(SSL) Connector.
: http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
: This allows a Proxy operating in TCP mode to transport
: details of the proxied connection to the server.
: Both V1 and V2 versions of the protocol are supported.
Tags: connector, ssl
Depend: ssl
XML: etc/jetty-proxy-protocol-ssl.xml
Module: ssl
: Enables a TLS(SSL) Connector on the server.
: This may be used for HTTPS and/or HTTP2 by enabling
: the associated support modules.
Tags: connector, ssl
Depend: server
XML: etc/jetty-ssl.xml
XML: etc/jetty-ssl-context.xml
Enabled: transitive provider of ssl for https
Module: unixsocket
: Enables a Unix Domain Socket Connector that can receive
: requests from a local proxy and/or SSL offloader (eg haproxy) in either
: HTTP or TCP mode. Unix Domain Sockets are more efficient than
: localhost TCP/IP connections as they reduce data copies, avoid
: needless fragmentation and have better dispatch behaviours.
: When enabled with corresponding support modules, the connector can
: accept HTTP, HTTPS or HTTP2C traffic.
Tags: connector
Depend: server
LIB: lib/jetty-unixsocket-${jetty.version}.jar
LIB: lib/jnr/*.jar
XML: etc/jetty-unixsocket.xml
Module: unixsocket-forwarded
: Adds a forwarded request customizer to the HTTP configuration used
: by the Unix Domain Socket connector, for use when behind a proxy operating
: in HTTP mode that adds forwarded-for style HTTP headers. Typically this
: is an alternate to the Proxy Protocol used mostly for TCP mode.
Tags: connector
Depend: unixsocket-http
XML: etc/jetty-unixsocket-forwarded.xml
Module: unixsocket-http
: Adds a HTTP protocol support to the Unix Domain Socket connector.
: It should be used when a proxy is forwarding either HTTP or decrypted
: HTTPS traffic to the connector and may be used with the
: unix-socket-http2c modules to upgrade to HTTP/2.
Tags: connector, http
Depend: unixsocket
XML: etc/jetty-unixsocket-http.xml
Module: unixsocket-http2c
: Adds a HTTP2C connetion factory to the Unix Domain Socket Connector
: It can be used when either the proxy forwards direct
: HTTP/2C (unecrypted) or decrypted HTTP/2 traffic.
Tags: connector, http2
Depend: unixsocket-http
LIB: lib/http2/*.jar
XML: etc/jetty-unixsocket-http2c.xml
Module: unixsocket-proxy-protocol
: Enables the proxy protocol on the Unix Domain Socket Connector
: http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
: This allows information about the proxied connection to be
: efficiently forwarded as the connection is accepted.
: Both V1 and V2 versions of the protocol are supported and any
: SSL properties may be interpreted by the unixsocket-secure
: module to indicate secure HTTPS traffic. Typically this
: is an alternate to the forwarded module.
Tags: connector
Depend: unixsocket
XML: etc/jetty-unixsocket-proxy-protocol.xml
Module: unixsocket-secure
: Enable a secure request customizer on the HTTP Configuration
: used by the Unix Domain Socket Connector.
: This looks for a secure scheme transported either by the
: unixsocket-forwarded, unixsocket-proxy-protocol or in a
: HTTP2 request.
Tags: connector
Depend: unixsocket-http
XML: etc/jetty-unixsocket-secure.xml
Modules for tag 'debug':
------------------------
Module: debug
: Enables the DebugListener to generate additional
: logging regarding detailed request handling events.
: Renames threads to include request URI.
Tags: debug
Depend: deploy
XML: etc/jetty-debug.xml
Module: debuglog
: Deprecated Debug Log using the DebugHandle.
: Replaced with the debug module.
Tags: debug
Depend: server
XML: etc/jetty-debuglog.xml
Modules for tag 'handler':
--------------------------
Module: gzip
: Enable GzipHandler for dynamic gzip compression
: for the entire server.
Tags: handler
Depend: server
XML: etc/jetty-gzip.xml
Module: ipaccess
: Enable the ipaccess handler to apply a white/black list
: control of the remote IP of requests.
Tags: handler
Depend: server
XML: etc/jetty-ipaccess.xml
Module: stats
: Enable detailed statistics collection for the server,
: available via JMX.
Tags: handler
Depend: server
XML: etc/jetty-stats.xml
Module: threadlimit
Tags: handler
Depend: server
XML: etc/jetty-threadlimit.xml
Modules for tag 'logging':
--------------------------
Module: console-capture
: Redirects JVMs console stderr and stdout to a log file,
: including output from Jetty's default StdErrLog logging.
Tags: logging
LIB: resources/
XML: etc/console-capture.xml
Module: logging-jetty [logging]
: Configure jetty logging mechanism.
: Provides a ${jetty.base}/resources/jetty-logging.properties.
Tags: logging
Depend: resources
Module: logging-jul [logging]
: Configure jetty logging to use Java Util Logging (jul)
: SLF4J is used as the core logging mechanism.
Tags: logging
Depend: slf4j-jul, jul-impl
JVM: -Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
Module: logging-log4j [logging]
: Configure jetty logging to use Log4j Logging
: SLF4J is used as the core logging mechanism.
Tags: logging
Depend: slf4j-log4j, log4j-impl
JVM: -Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
Module: logging-log4j2 [logging]
: Configure jetty logging to use log4j version 2
: SLF4J is used as the core logging mechanism.
Tags: logging
Depend: slf4j-log4j2, log4j2-impl
JVM: -Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
Module: logging-logback [logging]
: Configure jetty logging to use Logback Logging.
: SLF4J is used as the core logging mechanism.
Tags: logging
Depend: slf4j-logback, logback-impl
JVM: -Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
Module: logging-slf4j [logging]
: Configure jetty logging to use slf4j.
: Any slf4j-impl implementation is used
Tags: logging
Depend: slf4j-api, slf4j-impl
JVM: -Dorg.eclipse.jetty.util.log.class?=org.eclipse.jetty.util.log.Slf4jLog
Modules for tag 'requestlog':
-----------------------------
Module: logback-access [requestlog]
: Enables logback request log.
Tags: requestlog, logging, logback
Depend: server, logback-impl, resources
LIB: lib/logback/logback-access-${logback.version}.jar
XML: etc/jetty-logback-access.xml
Module: requestlog
: Enables a NCSA style request log.
Tags: requestlog
Depend: server
XML: etc/jetty-requestlog.xml
Modules for tag 'session':
--------------------------
Module: session-cache-hash [session-cache]
: Enable first level session cache in ConcurrentHashMap.
: If not enabled, sessions will use a HashSessionCache by default, so enabling
: via this module is only needed if the configuration properties need to be
: changed.
Tags: session
Depend: sessions
XML: etc/sessions/session-cache-hash.xml
Module: session-cache-null [session-cache]
: A trivial SessionCache that does not actually cache sessions.
Tags: session
Depend: sessions
XML: etc/sessions/session-cache-null.xml
Module: session-store-cache
: Enables caching of SessionData in front of a SessionDataStore.
Tags: session
Depend: session-store, sessions/session-data-cache/${session-data-cache}
XML: etc/sessions/session-data-cache/session-caching-store.xml
Module: session-store-file [session-store]
: Enables session persistent storage in files.
Tags: session
Depend: sessions
XML: etc/sessions/file/session-store.xml
Module: session-store-gcloud [session-store]
: Enables GCloudDatastore session management.
Tags: session, gcloud
Depend: gcloud-datastore, annotations, webapp, sessions
LIB: lib/jetty-gcloud-session-manager-${jetty.version}.jar
XML: etc/sessions/gcloud/session-store.xml
Module: session-store-hazelcast-embedded [session-store]
: Enables session data store in an embedded Hazelcast Map
Tags: session
Depend: sessions
LIB: lib/jetty-hazelcast-${jetty.version}.jar
LIB: lib/hazelcast/*.jar
XML: etc/sessions/hazelcast/default.xml
Module: session-store-hazelcast-remote [session-store]
: Enables session data store in a remote Hazelcast Map
Tags: session
Depend: sessions
LIB: lib/jetty-hazelcast-${jetty.version}.jar
LIB: lib/hazelcast/*.jar
XML: etc/sessions/hazelcast/remote.xml
Module: session-store-infinispan-embedded [session-store-infnispan-embedded, session-store]
: Enables session data store in a local Infinispan cache
Tags: session
Depend: sessions
LIB: lib/jetty-infinispan-${jetty.version}.jar
LIB: lib/infinispan/*.jar
XML: etc/sessions/infinispan/default.xml
Module: session-store-infinispan-embedded-910 [session-store-infinispan-embedded, session-store]
: Enables session data store in a local Infinispan cache
Tags: session
Depend: sessions
LIB: lib/jetty-infinispan-${jetty.version}.jar
LIB: lib/infinispan/*.jar
XML: etc/sessions/infinispan/default.xml
Module: session-store-infinispan-remote [session-store]
: Enables session data store in a remote Infinispan cache
Tags: session
Depend: sessions
LIB: lib/jetty-infinispan-${jetty.version}.jar
LIB: lib/infinispan/*.jar
XML: etc/sessions/infinispan/remote.xml
Module: session-store-infinispan-remote-910 [session-store-infinispan-remote, session-store]
: Enables session data store in a remote Infinispan cache
Tags: session
Depend: sessions
LIB: lib/jetty-infinispan-${jetty.version}.jar
LIB: lib/infinispan/*.jar
XML: etc/sessions/infinispan/remote.xml
Module: session-store-jdbc [session-store]
: Enables JDBC persistent/distributed session storage.
Tags: session
Depend: sessions, sessions/jdbc/${db-connection-type}
XML: etc/sessions/jdbc/session-store.xml
Module: session-store-mongo [session-store]
: Enables NoSql session management with a MongoDB driver.
Tags: session
Depend: sessions, sessions/mongo/${connection-type}
LIB: lib/jetty-nosql-${jetty.version}.jar
LIB: lib/nosql/*.jar
Module: sessions
: The session management. By enabling this module, it allows
: session management to be configured via the ini templates
: created or by enabling other session-cache or session-store
: modules. Without this module enabled, the server may still
: use sessions, but their management cannot be configured.
Tags: session
Depend: server
XML: etc/sessions/id-manager.xml</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_searching-modules"><a class="anchor" href="#_searching-modules"></a><a class="link" href="#_searching-modules">Searching Modules</a></h5>
<div class="paragraph">
<p>Since the introduction of the module system, many new modules have been added.
As a result, looking at the module list as a whole can be somewhat overwhelming.
To narrow down which modules you would like to choose from, you can search by values listed under the <code>[tags]</code> section.
Note that when you search this way, all modules that include your criteria in it&#8217;s <code>[tags]</code> section, including internal modules, will be shown.
To filter out internal modules when searching a specific module tag, simply add <code>-internal</code> to the command line.
For example, if you wanted to look at only the logging modules (excluding the internal implementation modules), you would use <code>--list-modules=logging,-internal</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --list-modules=logging,-internal
Available Modules:
==================
tags: [logging, -internal]
Modules for tag 'logging':
--------------------------
Module: console-capture
: Redirects JVMs console stderr and stdout to a log file,
: including output from Jetty's default StdErrLog logging.
Tags: logging
LIB: resources/
XML: etc/console-capture.xml
Module: logging-jcl [logging]
: Configure jetty logging to use Java Commons Logging (jcl)
: SLF4J is used as the core logging mechanism.
Tags: logging
Depend: jcl-impl, slf4j-jcl
JVM: -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog
Module: logging-jetty [logging]
: Configure jetty logging mechanism.
: Provides a ${jetty.base}/resources/jetty-logging.properties.
Tags: logging
Depend: console-capture, resources
Module: logging-jul [logging]
: Configure jetty logging to use Java Util Logging (jul)
: SLF4J is used as the core logging mechanism.
Tags: logging
Depend: jul-impl, slf4j-jul
JVM: -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog
Module: logging-log4j [logging]
: Configure jetty logging to use Log4j Logging
: SLF4J is used as the core logging mechanism.
Tags: logging
Depend: log4j-impl, slf4j-log4j
JVM: -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog
Module: logging-log4j2 [logging]
: Configure jetty logging to use log4j version 2
: SLF4J is used as the core logging mechanism.
Tags: logging
Depend: slf4j-log4j2, log4j2-impl
JVM: -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog
Module: logging-logback [logging]
: Configure jetty logging to use Logback Logging.
: SLF4J is used as the core logging mechanism.
Tags: logging
Depend: logback-impl, slf4j-logback
JVM: -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog
Module: logging-slf4j [logging]
: Configure jetty logging to use slf4j.
: Any slf4j-impl implementation is used
Tags: logging
Depend: slf4j-api, slf4j-impl
JVM: -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog
Modules for tag 'requestlog':
-----------------------------
Module: logback-access [requestlog]
: Enables logback request log.
Tags: requestlog, logging, logback
Depend: server, logback-core, resources
LIB: lib/logback/logback-access-${logback.version}.jar
XML: etc/jetty-logback-access.xml</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="custom-modules"><a class="anchor" href="#custom-modules"></a><a class="link" href="#custom-modules">Custom Modules</a></h3>
<div class="paragraph">
<p>In addition to the modules that come packaged with the Jetty distribution, users are able to create and define their own custom modules for use with their Jetty implementation.
Custom modules can be used for a number of reasons - they can extend features in Jetty, add new features, manage additional libraries available to the server&#8230;&#8203;etc.</p>
</div>
<div class="paragraph">
<p>At the heart of a Jetty module is the <code>{name}.mod</code> file itself.
A jetty <code>.mod</code> file defines the following:</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>It is important to note that when creating your own module, none of these sections are required - simply use those which are applicable to your implementation.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Module Description - <code>[description]</code></dt>
<dd>
<p>The description of the module.
This will be showing when viewing the <code>.mod</code> file itself or using the <code>--list-modules</code> command.</p>
</dd>
<dt class="hdlist1">List of Dependent Modules - <code>[depend]</code></dt>
<dd>
<p>All modules can declare that they depend on other modules with the <code>[depend]</code> section.
The list of dependencies is used to transitively resolve other modules that are deemed to be required based on the modules that you activate.
The order of modules defined in the graph of active modules is used to determine various execution order for configuration, such as Jetty IoC XML configurations, and to resolve conflicting property declarations.</p>
<div class="dlist">
<dl>
<dt class="hdlist1">Optional Modules - <code>[optional]</code></dt>
<dd>
<p>Of note: there is a special section <code>[optional]</code> used to describe structurally dependent modules that are not technically required, but might be of use to your specific configuration.</p>
</dd>
</dl>
</div>
</dd>
<dt class="hdlist1">List of Libraries - <code>[lib]</code></dt>
<dd>
<p>Modules can optionally declare that they have libraries that they need to function properly.
The <code>[lib]</code> section declares a set of pathnames that follow the <a href="#base-vs-home-resolution">Jetty Base and Jetty Home path resolution rules</a>.</p>
</dd>
<dt class="hdlist1">List of Jetty IoC XML Configurations - <code>[xml]</code></dt>
<dd>
<p>A Module can optionally declare a list of Jetty IoC XML configurations used to wire up the functionality that this module defines.
The <code>[xml]</code> section declares a set of pathnames that follow the <a href="#base-vs-home-resolution">Jetty Base and Jetty Home path resolution rules</a>.
Ideally, all XML files are parameterized to accept properties to configure the various elements of the standard configuration.
Allowing for a simplified configuration of Jetty for the vast majority of deployments.
The execution order of the Jetty IoC XML configurations is determined by the graph of active module dependencies resolved via the <code>[depend]</code> sections.
If the default XML is not sufficient to satisfy your needs, you can override this XML by making your own in the <code>${jetty.base}/etc/</code> directory, with the same name.
The resolution steps for Jetty Base and Jetty Home will ensure that your copy from <code>${jetty.base}</code> will be picked up over the default one in <code>${jetty.home}</code>.</p>
</dd>
<dt class="hdlist1">List of Module Tags - <code>[tags]</code></dt>
<dd>
<p>For ease of sorting, modules can be assigned tags.
When using the <code>--list-modules</code> command, modules will be groups by the first tag that exists in this section.
Modules can also be listed specifically by these tags using <code>--list-modules=&lt;tag name&gt;</code> on the command line.</p>
</dd>
<dt class="hdlist1">Ini Variables - <code>[ini]</code></dt>
<dd>
<p>The <code>[ini]</code> section is used to add or change server parameters at startup.
The <code>[ini]</code> section can also include a the path of a file or several files which should be made available to the <em>server</em> only.
This is helpful when you want to control what jars are available to deployed webapps.</p>
</dd>
<dt class="hdlist1">Jetty INI Template - <code>[ini-template]</code></dt>
<dd>
<p>Each module can optionally declare a startup ini template that is used to insert/append/inject sample configuration elements into the <code>start.ini</code> or <code>start.d/*.ini</code> files when using the <code>--add-to-start=&lt;name&gt;</code> command line argument in <code>start.jar</code>.
Commonly used to present some of the parameterized property options from the Jetty IoC XML configuration files also referenced in the same module.</p>
</dd>
<dt class="hdlist1">Required Files and Directories - <code>[files]</code></dt>
<dd>
<p>If the activation of a module requires some paths to exist, the <code>[files]</code> section defines them.
There are 2 modes of operation of the entries in this section.</p>
<div class="dlist">
<dl>
<dt class="hdlist1">Ensure Directory Exists</dt>
<dd>
<p>If you add a pathname that ends in <code>"/"</code> (slash), such as <code>"webapps/"</code>, then that directory will be created if it does not yet exist in <code>${jetty.base}/&lt;pathname&gt;</code> (eg: <code>"webapps/"</code> will result in <code>${jetty.base}/webapps/</code> being created).</p>
</dd>
<dt class="hdlist1">Download File</dt>
<dd>
<p>There is a special syntax to allow you to download a file into a specific location if it doesn&#8217;t exist yet: <code>&lt;url&gt;:&lt;pathname&gt;</code>.
Currently, the <code>&lt;url&gt;</code> must be a <code>http://</code> scheme URL.
The <code>&lt;pathname&gt;</code> portion follows the <a href="#base-vs-home-resolution">Jetty Base and Jetty Home path resolution rules</a>.
Example: <code><a href="http://repo.corp.com/maven/corp-security-policy-1.0.jar:lib/corp-security-policy.jar" class="bare">http://repo.corp.com/maven/corp-security-policy-1.0.jar:lib/corp-security-policy.jar</a></code>
This will check for the existence of <code>lib/corp-security-policy.jar</code>, and if it doesn&#8217;t exist, it will download the jar file from <code><a href="http://repo.corp.com/maven/corp-security-policy-1.0.jar" class="bare">http://repo.corp.com/maven/corp-security-policy-1.0.jar</a></code></p>
</dd>
</dl>
</div>
</dd>
<dt class="hdlist1">Licenses - <code>[license]</code></dt>
<dd>
<p>If you are implementing a software/technology that has a license, it&#8217;s text can be placed here.
When a user attempts to activate the module they will be asked if they accept the license agreement.
If a user does not accept the license agreement, the module will not be activated.</p>
</dd>
<dt class="hdlist1">Additional Startup Commands - <code>[exec]</code></dt>
<dd>
<p>The <code>[exec]</code> section is used to define additional parameters specific to the module.
These commands are added to the server startup.</p>
</dd>
<dt class="hdlist1">JPMS Module-Path Definitions - <code>[jpms]</code></dt>
<dd>
<p>The <code>[jpms]</code> section is used to add <a href="#startup-jpms">JPMS modules</a> to the module-path for startup when using the <code>--jpms</code> command.</p>
</dd>
</dl>
</div>
<div class="sect3">
<h4 id="custom-module-properties"><a class="anchor" href="#custom-module-properties"></a><a class="link" href="#custom-module-properties">Module Properties</a></h4>
<div class="paragraph">
<p>Properties are used to parameterize:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>XML files using the <code>&lt;Property name="pname"/&gt;</code> element</p>
</li>
<li>
<p>Module files using the <code>${pname}</code> syntax</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Properties and System Properties may be set on the command line, in a ini file or in a <code>[ini]</code> section of a module using the following syntax.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>name=value</code></dt>
<dd>
<p>Set a property that can be expanded in XML files with the &lt;Property&gt; element.</p>
</dd>
<dt class="hdlist1"><code>name+=value</code></dt>
<dd>
<p>Append value to an existing property value.</p>
</dd>
<dt class="hdlist1"><code>name+=,value</code></dt>
<dd>
<p>Append value to an existing property value, using a comma separator if needed.</p>
</dd>
<dt class="hdlist1"><code>name?=value</code></dt>
<dd>
<p>Set a property only if it is not already set.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>If any of the previous formats is preceded by <code>-D</code>, then a system property is set as well as a start property.</p>
</div>
</div>
<div class="sect3">
<h4 id="custom-module-location"><a class="anchor" href="#custom-module-location"></a><a class="link" href="#custom-module-location">Location of Modules</a></h4>
<div class="paragraph">
<p>Jetty comes with dozens of modules as part of the distribution package.
By default these are located in the <code>${JETTY_HOME}/modules</code> directory.
These modules should not be modified.
In the unlikely circumstance you need to make changes to a stock module, copy it to your <code>${JETTY_BASE}</code> in a <code>modules</code> directory.</p>
</div>
<div class="paragraph">
<p>Custom modules should also be maintained separately as part of the <code>${JETTY_BASE}/modules</code> directory, though you can optionally place them in <code>${JETTY_HOME}/modules</code> for convenience if you have several <code>{$JETTY_BASE}</code> locations in your implementation.</p>
</div>
</div>
<div class="sect3">
<h4 id="custom-module-examples"><a class="anchor" href="#custom-module-examples"></a><a class="link" href="#custom-module-examples">Creating Custom Modules</a></h4>
<div class="paragraph">
<p>As shown above, there are several options that can be utilized when creating custom module files.
This may seem daunting, but the good news is that creating custom modules is actually quite easy.</p>
</div>
<div class="paragraph">
<p>For example, here is a look at the <code>http.mod</code> file which defines parameters for enabling HTTP features for the server:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
[description]
Enables an HTTP connector on the server.
By default HTTP/1 is support, but HTTP2C can be added to the connector by enabling the http2c module.
[tags]
connector
http
[depend]
server
[xml]
etc/jetty-http.xml
[ini-template]
### HTTP Connector Configuration
## Connector host/address to bind to
# jetty.http.host=0.0.0.0
## Connector port to listen on
# jetty.http.port=8080
## Connector idle timeout in milliseconds
# jetty.http.idleTimeout=30000
## Number of acceptors (-1 picks default based on number of cores)
# jetty.http.acceptors=-1
## Number of selectors (-1 picks default based on number of cores)
# jetty.http.selectors=-1
## ServerSocketChannel backlog (0 picks platform default)
# jetty.http.acceptQueueSize=0
## Thread priority delta to give to acceptor threads
# jetty.http.acceptorPriorityDelta=0
## The requested maximum length of the queue of incoming connections.
# jetty.http.acceptQueueSize=0
## Enable/disable the SO_REUSEADDR socket option.
# jetty.http.reuseAddress=true
## Enable/disable TCP_NODELAY on accepted sockets.
# jetty.http.acceptedTcpNoDelay=true
## The SO_RCVBUF option to set on accepted sockets. A value of -1 indicates that it is left to its default value.
# jetty.http.acceptedReceiveBufferSize=-1
## The SO_SNDBUF option to set on accepted sockets. A value of -1 indicates that it is left to its default value.
# jetty.http.acceptedSendBufferSize=-1
## Connect Timeout in milliseconds
# jetty.http.connectTimeout=15000</code></pre>
</div>
</div>
<div class="paragraph">
<p>You&#8217;ll notice that the <code>http.mod</code> file only includes a handful of the possible sections available - <code>[description]</code>, <code>[tags]</code>, <code>[depend]</code>, <code>[xml]</code>, and <code>[ini-template]</code>.
When configuring your own modules, you are free to pick and choose what you include.</p>
</div>
<div class="paragraph">
<p>As an example, below is a module file that defines a custom XML and lib, and activates a number of additional modules.
A module like this could be used to enable a set of standard modules and resources for a new JETTY_BASE without having to define them all manually.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[description]
Enables the standard set of modules and resources for ACME Corp servers.
[tags]
core
[depend]
server
client
http
http2
jsp
console-capture
requestlog
stats
gzip
deploy
jmx
[files]
basehome:modules/acme/acme.xml|etc/acme.xml
[lib]
lib/acme/ACMECustom.jar</code></pre>
</div>
</div>
<div class="paragraph">
<p>Activating this module will activate all the dependent modules, create any required directories and copy in any required files:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=acme
ALERT: There are enabled module(s) with licenses.
The following 1 module(s):
+ contains software not provided by the Eclipse Foundation!
+ contains software not covered by the Eclipse Public License!
+ has not been audited for compliance with its license
Module: alpn-impl/alpn-8
+ ALPN is a hosted at github under the GPL v2 with ClassPath Exception.
+ ALPN replaces/modifies OpenJDK classes in the sun.security.ssl package.
+ http://github.com/jetty-project/jetty-alpn
+ http://openjdk.java.net/legal/gplv2+ce.html
Proceed (y/N)? y
INFO : webapp transitively enabled, ini template available with --add-to-start=webapp
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : requestlog transitively enabled, ini template available with --add-to-start=requestlog
INFO : alpn transitively enabled, ini template available with --add-to-start=alpn
INFO : jsp transitively enabled
INFO : servlet transitively enabled
INFO : alpn-impl/alpn-8 dynamic dependency of alpn
INFO : annotations transitively enabled
INFO : gzip transitively enabled, ini template available with --add-to-start=gzip
INFO : ssl transitively enabled, ini template available with --add-to-start=ssl
INFO : plus transitively enabled
INFO : deploy transitively enabled, ini template available with --add-to-start=deploy
INFO : alpn-impl/alpn-1.8.0_92 dynamic dependency of alpn-impl/alpn-8
INFO : security transitively enabled
INFO : jmx transitively enabled
INFO : apache-jsp transitively enabled
INFO : stats transitively enabled, ini template available with --add-to-start=stats
INFO : acme initialized in ${jetty.base}/start.d/acme.ini
INFO : jndi transitively enabled
INFO : console-capture transitively enabled, ini template available with --add-to-start=console-capture
INFO : client transitively enabled
INFO : http transitively enabled, ini template available with --add-to-start=http
INFO : http2 transitively enabled, ini template available with --add-to-start=http2
MKDIR : ${jetty.base}/logs
MKDIR : ${jetty.base}/lib
MKDIR : ${jetty.base}/lib/alpn
MKDIR : ${jetty.base}/etc
COPY : ${jetty.home}/modules/ssl/keystore to ${jetty.base}/etc/keystore
MKDIR : ${jetty.base}/webapps
DOWNLD: https://repo1.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.8.v20160420/alpn-boot-8.1.8.v20160420.jar to ${jetty.base}/lib/alpn/alpn-boot-8.1.8.v20160420.jar
COPY : ${jetty.home}/modules/acme/acme.xml to ${jetty.base}/etc/acme.xml
INFO : Base directory was modified</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_dependencies"><a class="anchor" href="#_dependencies"></a><a class="link" href="#_dependencies">Dependencies</a></h4>
<div class="paragraph">
<p>When dependent modules are enabled, they are done so <strong>transitively</strong> by default.
This means that any <code>ini</code> files for dependent modules are not created in the <code>${JETTY_BASE}/start.d</code> directory (or added to <code>${JETTY_BASE}/start.ini</code>) and are as such not configurable.</p>
</div>
<div class="paragraph">
<p>For Jetty to create/add the <code>ini-template</code> parameters to <code>start.d</code> or <code>start.ini</code> the associated module must be enabled explicitly.</p>
</div>
<div class="paragraph">
<p>For example, if I activate the <code>http</code> module, it will be enabled, and the <code>server</code> module will be enabled transitively:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=http
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : http initialized in ${jetty.base}/start.d/http.ini
INFO : Base directory was modified</code></pre>
</div>
</div>
<div class="paragraph">
<p>You&#8217;ll notice that Jetty informs you of what modules were enabled, and where there associated ini files are located (when applicable).
It also tells the user what command they would need to run to enable any missing or desired ini files for the selected modules, in this case <code>--add-to-start=server</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[my-base]$ java -jar /path/to/jetty-home/start.jar --add-to-start=server
INFO : server initialized in ${jetty.base}/start.d/server.ini
INFO : Base directory was modified</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
It is important to keep in mind that when activating a dependency, Jetty does not just go one layer down.
If a dependent module also has dependencies they too will be enabled.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
</div>
<div class="sect2">
<h3 id="startup-xml-config"><a class="anchor" href="#startup-xml-config"></a><a class="link" href="#startup-xml-config">Managing XML Based Startup Configuration</a></h3>
<div class="paragraph">
<p>When you see XML files on the command line for startup of Jetty, they are always part of the Jetty IoC Configuration mechanism.</p>
</div>
<div class="paragraph">
<p>Internally, Jetty uses these XML files to build up Jetty with the features that you wan to use.</p>
</div>
<div class="paragraph">
<p>The module mechanism present in Jetty determines the load order of the XML files.
The Jetty Base and Jetty Home resolution logic also applies, which allows you to override a XML file declared by a module with your XML by simply having the same named XML in your <code>${jetty.base}/etc</code> directory location.</p>
</div>
</div>
<div class="sect2">
<h3 id="startup-unix-service"><a class="anchor" href="#startup-unix-service"></a><a class="link" href="#startup-unix-service">Startup a Unix Service using jetty.sh</a></h3>
<div class="paragraph">
<p>The standalone Jetty distribution ships with a <code>bin/jetty.sh</code> script that can be used by various Unix distros (including OSX) to manage Jetty as a startup service.</p>
</div>
<div class="paragraph">
<p>This script is suitable for setting up Jetty as a service in Unix.</p>
</div>
<div class="sect3">
<h4 id="_quick-start-a-jetty-service"><a class="anchor" href="#_quick-start-a-jetty-service"></a><a class="link" href="#_quick-start-a-jetty-service">Quick-Start a Jetty Service</a></h4>
<div class="paragraph">
<p>The minimum steps to get Jetty to run as a Service include:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[/opt/jetty]# tar -zxf /home/user/downloads/jetty-distribution-10.0.0-SNAPSHOT.tar.gz
[/opt/jetty]# cd jetty-distribution-10.0.0-SNAPSHOT/
[/opt/jetty/jetty-distribution-10.0.0-SNAPSHOT]# ls
bin lib modules resources start.jar
demo-base license-eplv10-aslv20.html notice.html start.d VERSION.txt
etc logs README.TXT start.ini webapps
[/opt/jetty/jetty-distribution-10.0.0-SNAPSHOT]# cp bin/jetty.sh /etc/init.d/jetty
[/opt/jetty/jetty-distribution-10.0.0-SNAPSHOT]# echo JETTY_HOME=`pwd` &gt; /etc/default/jetty
[/opt/jetty/jetty-distribution-10.0.0-SNAPSHOT]# cat /etc/default/jetty
JETTY_HOME=/opt/jetty/jetty-distribution-10.0.0-SNAPSHOT
[/opt/jetty/jetty-distribution-10.0.0-SNAPSHOT]# service jetty start
Starting Jetty: OK Wed Nov 20 10:26:53 MST 2013</code></pre>
</div>
</div>
<div class="paragraph">
<p>From this demonstration we can see that Jetty started successfully as a Unix Service from the <code>/opt/jetty/jetty-distribution-10.0.0-SNAPSHOT</code> directory.</p>
</div>
<div class="paragraph">
<p>This configuration works well but it is running Jetty as the root user.</p>
</div>
</div>
<div class="sect3">
<h4 id="_practical-setup-of-a-jetty-service"><a class="anchor" href="#_practical-setup-of-a-jetty-service"></a><a class="link" href="#_practical-setup-of-a-jetty-service">Practical Setup of a Jetty Service</a></h4>
<div class="paragraph">
<p>There are various ways this can be accomplished, mostly depending on your Unix environment (and possibly corporate policies).</p>
</div>
<div class="paragraph">
<p>The techniques outlined here assume an installation on Linux (demonstrated on Ubuntu 12.04.3 LTS).</p>
</div>
<div class="paragraph">
<p>Prepare some empty directories to work with.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># mkdir -p /opt/jetty
# mkdir -p /opt/web/mybase
# mkdir -p /opt/jetty/temp</code></pre>
</div>
</div>
<div class="paragraph">
<p>The directory purposes are as follows:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">/opt/jetty</dt>
<dd>
<p>Where the Jetty Distribution will be unpacked into</p>
</dd>
<dt class="hdlist1">/opt/web/mybase</dt>
<dd>
<p>Where your specific set of webapps will be located, including all of the configuration required of the server to make them operational.</p>
</dd>
<dt class="hdlist1">/opt/jetty/temp</dt>
<dd>
<p>This is the temporary directory assigned to Java by the Service Layer (this is what Java sees as the <code>java.io.tmpdir</code> System Property).</p>
<div class="paragraph">
<p>This is intentionally kept separate from the standard temp directory of <code>/tmp</code>, as this location doubles as the Servlet Spec work directory.
It is our experience that the standard temp directory is often managed by various cleanup scripts that wreak havoc on a long running Jetty server.</p>
</div>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Jetty 9.3 requires Java 8 (or greater) to run.
Make sure you have it installed.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># apt-get install openjdk-8-jdk</code></pre>
</div>
</div>
<div class="paragraph">
<p>Or download Java 8 from: <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" class="bare">http://www.oracle.com/technetwork/java/javase/downloads/index.html</a></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># java -version
java version "1.6.0_27"
OpenJDK Runtime Environment (IcedTea6 1.12.6) (6b27-1.12.6-1ubuntu0.12.04.2)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
# update-alternatives --list java
/usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java
/usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java
# update-alternatives --config java
There are 2 choices for the alternative java (providing /usr/bin/java).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java 1061 auto mode
1 /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java 1061 manual mode
2 /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java 1051 manual mode
Press enter to keep the current choice[*], or type selection number: 2
update-alternatives: using /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java to provide /usr/bin/java (java) in manual mode.
# java -version
java version "1.7.0_25"
OpenJDK Runtime Environment (IcedTea 2.3.10) (7u25-2.3.10-1ubuntu0.12.04.2)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is recommended that you create a user to specifically run Jetty.
This user should have the minimum set of privileges needed to run Jetty.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># useradd --user-group --shell /bin/false --home-dir /opt/jetty/temp jetty</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will create a user called <code>jetty</code>, belonging to the group called <code>jetty</code>, with no shell access (aka <code>/bin/false</code>), and home directory at <code>/opt/jetty/temp</code>.</p>
</div>
<div class="paragraph">
<p>Download a copy of the Jetty distribution from the <a href="#jetty-downloading">Official Eclipse Download Site</a></p>
</div>
<div class="paragraph">
<p>Unpack it into place.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[/opt/jetty]# tar -zxf /home/user/Downloads/jetty-distribution-10.0.0-SNAPSHOT.tar.gz
[/opt/jetty]# ls -F
jetty-distribution-10.0.0-SNAPSHOT/
[/opt/jetty]# mkdir /opt/jetty/temp</code></pre>
</div>
</div>
<div class="paragraph">
<p>It might seem strange or undesirable to unpack the first portion of the jetty-distribution directory name too.
But starting with Jetty 9 the split between <code>${jetty.home}</code> and <code>${jetty.base}</code> allows for easier upgrades of Jetty itself while isolating your webapp specific configuration.
For more information on the Jetty home and base concepts see the section on managing a Jetty installation <a href="#startup-base-and-home">earlier in this Chapter.</a></p>
</div>
<div class="paragraph">
<p>The <code>/opt/jetty/temp</code> directory is created as a durable place for Jetty to use for temp and working directories.
Many Unix systems will periodically clean out the /tmp directory, this behavior is undesired in a Servlet container and has been known to cause problems.
This durable directory at <code>/opt/jetty/temp</code> solves for that behavior.</p>
</div>
<div class="paragraph">
<p>The directory at <code>/opt/web/mybase</code> is going to be a <code>${jetty.base}</code>, so lets configure it to hold your webapp and its configuration.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>In past versions of Jetty, you would configure / modify / add to the <code>jetty-distribution</code> directory directly.
While this is still supported, we encourage you to setup a proper <code>${jetty.base}</code> directory, as it will benefit you with easier <code>jetty-distribution</code> upgrades in the future.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># cd /opt/web/mybase/
[/opt/web/mybase]# ls
[/opt/web/mybase]# java -jar /opt/jetty/jetty-distribution-10.0.0-SNAPSHOT/start.jar \
--add-to-start=deploy,http,console-capture
INFO : webapp transitively enabled, ini template available with --add-to-start=webapp
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : security transitively enabled
INFO : servlet transitively enabled
INFO : console-capture initialized in ${jetty.base}/start.ini
INFO : http initialized in ${jetty.base}/start.ini
INFO : deploy initialized in ${jetty.base}/start.ini
MKDIR : ${jetty.base}/logs
MKDIR : ${jetty.base}/webapps
INFO : Base directory was modified
[/opt/web/mybase]# ls -F
start.ini webapps/</code></pre>
</div>
</div>
<div class="paragraph">
<p>At this point you have configured your <code>/opt/web/mybase</code> to enable the following modules:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">deploy</dt>
<dd>
<p>This is the module that will perform deployment of web applications (WAR files or exploded directories), or Jetty IoC XML context deployables, from the <code>/opt/web/mybase/webapps</code> directory.</p>
</dd>
<dt class="hdlist1">http</dt>
<dd>
<p>This sets up a single Connector that listens for basic HTTP requests.</p>
<div class="paragraph">
<p>See the created <code>start.ini</code> for configuring this connector.</p>
</div>
</dd>
<dt class="hdlist1">console-capture</dt>
<dd>
<p>When running Jetty as a service it is very important to have logging enabled.
This module will enable the basic STDOUT and STDERR capture logging to the <code>/opt/web/mybase/logs/</code> directory.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Additionally, the <code>webapp</code>, <code>server</code>, <code>security</code> and <code>servlet</code> modules were enabled as they are dependencies for other modules.</p>
</div>
<div class="paragraph">
<p>See <a href="#start-jar">[start-jar]</a> for more details and options on setting up and configuring a <code>${jetty.base}</code> directory.</p>
</div>
<div class="paragraph">
<p>Copy your war file into place.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># cp /home/user/projects/mywebsite.war /opt/web/mybase/webapps/</code></pre>
</div>
</div>
<div class="paragraph">
<p>Most service installations will want Jetty to run on port 80, now is the opportunity to change this from the default value of <code>8080</code> to <code>80</code>.</p>
</div>
<div class="paragraph">
<p>Edit the <code>/opt/web/mybase/start.ini</code> and change the <code>jetty.http.port</code> value.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># grep jetty.http.port /opt/web/mybase/start.ini
jetty.port=80</code></pre>
</div>
</div>
<div class="paragraph">
<p>Change the permissions on the Jetty distribution and webapp directories so that the user you created can access it.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># chown --recursive jetty /opt/jetty
# chown --recursive jetty /opt/web/mybase</code></pre>
</div>
</div>
<div class="paragraph">
<p>Next we need to make the Unix System aware that we have a new Jetty Service that can be managed by the standard <code>service</code> calls.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># cp /opt/jetty/jetty-distribution-10.0.0-SNAPSHOT/bin/jetty.sh /etc/init.d/jetty
# echo "JETTY_HOME=/opt/jetty/jetty-distribution-10.0.0-SNAPSHOT" &gt; /etc/default/jetty
# echo "JETTY_BASE=/opt/web/mybase" &gt;&gt; /etc/default/jetty
# echo "TMPDIR=/opt/jetty/temp" &gt;&gt; /etc/default/jetty</code></pre>
</div>
</div>
<div class="paragraph">
<p>Test out the configuration:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># service jetty status
Checking arguments to Jetty:
START_INI = /opt/web/mybase/start.ini
JETTY_HOME = /opt/jetty/jetty-distribution-10.0.0-SNAPSHOT
JETTY_BASE = /opt/web/mybase
JETTY_CONF = /opt/jetty/jetty-distribution-10.0.0-SNAPSHOT/etc/jetty.conf
JETTY_PID = /var/run/jetty.pid
JETTY_START = /opt/jetty/jetty-distribution-10.0.0-SNAPSHOT/start.jar
CLASSPATH =
JAVA = /usr/bin/java
JAVA_OPTIONS = -Djetty.state=/opt/web/mybase/jetty.state
-Djetty.logs=/opt/web/mybase/logs
-Djetty.home=/opt/jetty/jetty-distribution-10.0.0-SNAPSHOT
-Djetty.base=/opt/web/mybase
-Djava.io.tmpdir=/opt/jetty/temp
JETTY_ARGS = console-capture.xml jetty-started.xml
RUN_CMD = /usr/bin/java
-Djetty.state=/opt/web/mybase/jetty.state
-Djetty.logs=/opt/web/mybase/logs
-Djetty.home=/opt/jetty/jetty-distribution-10.0.0-SNAPSHOT
-Djetty.base=/opt/web/mybase
-Djava.io.tmpdir=/opt/jetty/temp
-jar /opt/jetty/jetty-distribution-10.0.0-SNAPSHOT/start.jar
console-capture.xml
jetty-started.xml</code></pre>
</div>
</div>
<div class="paragraph">
<p>You now have a configured <code>${jetty.base}</code> in <code>/opt/web/mybase</code> and a <code>${jetty.home}</code> in <code>/opt/jetty/jetty-distribution-10.0.0-SNAPSHOT</code>, along with the service level files necessary to start the service.</p>
</div>
<div class="paragraph">
<p>Test the service to make sure it starts up and runs successfully.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"># service jetty start
Starting Jetty: OK Wed Nov 20 12:35:28 MST 2013
# service jetty check
..(snip)..
Jetty running pid=2958
[/opt/web/mybase]# ps u 2958
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
jetty 2958 5.3 0.1 11179176 53984 ? Sl 12:46 0:00 /usr/bin/java -Djetty...</code></pre>
</div>
</div>
<div class="paragraph">
<p>You should now have your server running.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="startup-windows-service"><a class="anchor" href="#startup-windows-service"></a><a class="link" href="#startup-windows-service">Startup via Windows Service</a></h3>
<div class="paragraph">
<p>There are no components that ship with the Jetty Distribution to make it a formal Windows Service.</p>
</div>
<div class="paragraph">
<p>However, we recommend the use of <a href="https://commons.apache.org/proper/commons-daemon/procrun.html">Apache ProcRun&#8217;s Daemon</a>.</p>
</div>
<div class="paragraph">
<p>The techniques outlined here are based on Windows 7 (64-bit), using JDK 8 (64-bit), running on an Intel i7 architecture machine.</p>
</div>
<div class="paragraph">
<p>Prepare some empty directories to work with.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">C:\&gt; mkdir opt
C:\&gt; cd opt
C:\opt&gt; mkdir jetty
C:\opt&gt; mkdir logs
C:\opt&gt; mkdir myappbase
C:\opt&gt; mkdir temp
C:\opt&gt; dir
Volume in drive C has no label.
Volume Serial Number is DEAD-BEEF
Directory of C:\opt
11/21/2013 04:06 PM &lt;DIR&gt; .
11/21/2013 04:06 PM &lt;DIR&gt; ..
11/21/2013 04:06 PM &lt;DIR&gt; jetty
11/21/2013 04:06 PM &lt;DIR&gt; logs
11/21/2013 04:06 PM &lt;DIR&gt; myappbase
11/21/2013 04:06 PM &lt;DIR&gt; temp
0 File(s) 0 bytes</code></pre>
</div>
</div>
<div class="paragraph">
<p>The directory purposes are as follows:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">C:\opt</dt>
<dd>
<p>Where the service layer utilities, scripts, and binaries will eventually be.</p>
</dd>
<dt class="hdlist1">C:\opt\logs</dt>
<dd>
<p>Where the logs for the service layer will put its own logs.</p>
<div class="paragraph">
<p>Typically you will see the audit logs (install/update/delete), StdOutput, and StdError logs here.</p>
</div>
</dd>
<dt class="hdlist1">C:\opt\jetty</dt>
<dd>
<p>Where the Jetty Distribution will be unpacked into.</p>
</dd>
<dt class="hdlist1">C:\opt\myappbase</dt>
<dd>
<p>Where your specific set of webapps will be located, including all of the configuration required of the server to make them operational.</p>
</dd>
<dt class="hdlist1">C:\opt\temp</dt>
<dd>
<p>This is the temporary directory assigned to Java by the Service Layer (this is what Java sees as the <code>java.io.tmpdir</code> System Property).</p>
<div class="paragraph">
<p>This is intentionally kept separate from the standard temp directories of Windows, as this location doubles as the Servlet Spec work directory.</p>
</div>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Or download Java 8 from: <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" class="bare">http://www.oracle.com/technetwork/java/javase/downloads/index.html</a></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">C:\opt&gt;java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Download a copy of the ZIP distribution from the <a href="#jetty-downloading">Official Eclipse Download Site</a></p>
</div>
<div class="paragraph">
<p>Extract the contents of the <code>jetty-distribution-10.0.0-SNAPSHOT</code> directory to <code>C:\opt\jetty</code></p>
</div>
<div class="paragraph">
<p>Once complete, the contents of the <code>C:\opt\jetty</code> directory should look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">C:\opt\jetty&gt;dir
Volume in drive C has no label.
Volume Serial Number is C8CF-820B
Directory of C:\opt\jetty
11/21/2013 12:13 PM &lt;DIR&gt; .
11/21/2013 12:13 PM &lt;DIR&gt; ..
11/21/2013 12:13 PM &lt;DIR&gt; bin
11/21/2013 12:13 PM &lt;DIR&gt; demo-base
11/21/2013 12:13 PM &lt;DIR&gt; etc
11/21/2013 12:13 PM &lt;DIR&gt; lib
11/21/2013 12:13 PM 30,012 license-eplv10-aslv20.html
11/21/2013 12:13 PM &lt;DIR&gt; logs
11/21/2013 12:13 PM &lt;DIR&gt; modules
11/21/2013 12:13 PM 6,262 notice.html
11/21/2013 12:13 PM 1,249 README.TXT
11/21/2013 12:13 PM &lt;DIR&gt; resources
11/21/2013 12:13 PM &lt;DIR&gt; start.d
11/21/2013 12:13 PM 2,126 start.ini
11/21/2013 12:13 PM 72,226 start.jar
11/21/2013 12:13 PM 341,784 VERSION.txt
11/21/2013 12:13 PM &lt;DIR&gt; webapps
6 File(s) 453,659 bytes
11 Dir(s) 306,711,420,928 bytes free</code></pre>
</div>
</div>
<div class="paragraph">
<p>Download a copy of the <a href="https://commons.apache.org/proper/commons-daemon/binaries.html">Apache ProcRun</a> native binaries.</p>
</div>
<div class="paragraph">
<p>You should have downloaded a file named <code>commons-daemon-1.0.15-bin-windows.zip</code> (the version might be different).
Open the ZIP file and extract the <code>prunmgr.exe</code> and <code>prunsrv.exe</code> files into the <code>C:\opt</code> directory.</p>
</div>
<div class="paragraph">
<p>Make sure to get the right version of <code>prunsrv.exe</code> for your environment.
The ZIP file has both 32 bit and 64 bit versions of this file.</p>
</div>
<div class="paragraph">
<p>Once you are complete, the contents of <code>C:\opt</code> directory should look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">C:\opt&gt; dir
Volume in drive C has no label.
Volume Serial Number is DEAD-BEEF
Directory of C:\opt
11/21/2013 04:06 PM &lt;DIR&gt; .
11/21/2013 04:06 PM &lt;DIR&gt; ..
11/21/2013 04:06 PM &lt;DIR&gt; jetty
11/21/2013 04:06 PM &lt;DIR&gt; logs
11/21/2013 04:06 PM &lt;DIR&gt; myappbase
11/21/2013 04:06 PM &lt;DIR&gt; temp
11/21/2013 04:11 PM 104,448 prunmgr.exe
11/21/2013 04:11 PM 80,896 prunsrv.exe
2 File(s) 185,344 bytes</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now it&#8217;s time to setup your new <code>${jetty.base}</code> directory to have all of your WebApps and the configurations that they need.</p>
</div>
<div class="paragraph">
<p>We&#8217;ll start by specifying which modules we want to use (this will create a start.ini file and also create a few empty directories for you)</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">C:\opt\myappbase&gt;java -jar ..\jetty\start.jar --add-to-start=deploy,http,console-capture
WARNING: deploy initialised in ${jetty.base}\start.ini (appended)
WARNING: deploy enabled in ${jetty.base}\start.ini
MKDIR: ${jetty.base}\webapps
WARNING: server initialised in ${jetty.base}\start.ini (appended)
WARNING: server enabled in ${jetty.base}\start.ini
WARNING: http initialised in ${jetty.base}\start.ini (appended)
WARNING: http enabled in ${jetty.base}\start.ini
WARNING: server enabled in ${jetty.base}\start.ini
WARNING: logging initialised in ${jetty.base}\start.ini (appended)
WARNING: logging enabled in ${jetty.base}\start.ini
MKDIR: ${jetty.base}\logs
C:\opt\myappbase&gt;dir
Volume in drive C has no label.
Volume Serial Number is C8CF-820B
Directory of C:\opt\myappbase
11/21/2013 12:49 PM &lt;DIR&gt; .
11/21/2013 12:49 PM &lt;DIR&gt; ..
11/21/2013 12:49 PM &lt;DIR&gt; logs
11/21/2013 12:49 PM 1,355 start.ini
11/21/2013 12:49 PM &lt;DIR&gt; webapps
1 File(s) 1,355 bytes
4 Dir(s) 306,711,064,576 bytes free</code></pre>
</div>
</div>
<div class="paragraph">
<p>At this point you have configured your <code>C:\opt\myappbase</code> to enable the following modules:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">deploy</dt>
<dd>
<p>This is the module that will perform deployment of web applications (WAR files or exploded directories), or Jetty IoC XML context deployables, from the <code>C:\opt\myappbase\webapps</code> directory.</p>
</dd>
<dt class="hdlist1">http</dt>
<dd>
<p>This sets up a single Connector that listens for basic HTTP requests.</p>
<div class="paragraph">
<p>See the created <code>start.ini</code> for configuring this connector.</p>
</div>
</dd>
<dt class="hdlist1">logging</dt>
<dd>
<p>When running Jetty as a service it is very important to have logging enabled.
This module will enable the basic STDOUT and STDERR capture logging to the <code>C:\opt\myappbase\logs</code> directory.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>See the section on <a href="#start-jar">[start-jar]</a> for more details and options on setting up and configuring a <code>${jetty.base}</code> directory.</p>
</div>
<div class="paragraph">
<p>At this point you merely have to copy your WAR files into the <code>{$jetty.base}/webapps</code> directory.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">C:\opt\myappbase&gt; copy C:\projects\mywebsite.war webapps\</code></pre>
</div>
</div>
<div class="paragraph">
<p>At this point you should have your directories, Java, the Jetty distribution, and your webapp specifics setup and ready for operation.</p>
</div>
<div class="paragraph">
<p>We will use the <a href="https://commons.apache.org/proper/commons-daemon/binaries.html">Apache ProcRun&#8217;s prunsrv.exe</a> to install a Jetty Service.</p>
</div>
<div class="paragraph">
<p>The basic command line syntax is outlined in the link above.</p>
</div>
<div class="paragraph">
<p>A example <code>install-jetty-service.bat</code> is provided here as an example, based on the above directories.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bat" data-lang="bat">@echo off
set SERVICE_NAME=JettyService
set JETTY_HOME=C:\opt\jetty
set JETTY_BASE=C:\opt\myappbase
set STOPKEY=secret
set STOPPORT=50001
set PR_INSTALL=C:\opt\prunsrv.exe
@REM Service Log Configuration
set PR_LOGPREFIX=%SERVICE_NAME%
set PR_LOGPATH=C:\opt\logs
set PR_STDOUTPUT=auto
set PR_STDERROR=auto
set PR_LOGLEVEL=Debug
@REM Path to Java Installation
set JAVA_HOME=C:\Program Files\Java\jdk1.7.0_45
set PR_JVM=%JAVA_HOME%\jre\bin\server\jvm.dll
set PR_CLASSPATH=%JETTY_HOME%\start.jar;%JAVA_HOME%\lib\tools.jar
@REM JVM Configuration
set PR_JVMMS=128
set PR_JVMMX=512
set PR_JVMSS=4000
set PR_JVMOPTIONS=-Duser.dir="%JETTY_BASE%";-Djava.io.tmpdir="C:\opt\temp";-Djetty.home="%JETTY_HOME%";-Djetty.base="%JETTY_BASE%"
@REM Startup Configuration
set JETTY_START_CLASS=org.eclipse.jetty.start.Main
set PR_STARTUP=auto
set PR_STARTMODE=java
set PR_STARTCLASS=%JETTY_START_CLASS%
set PR_STARTPARAMS=STOP.KEY="%STOPKEY%";STOP.PORT=%STOPPORT%
@REM Shutdown Configuration
set PR_STOPMODE=java
set PR_STOPCLASS=%JETTY_START_CLASS%
set PR_STOPPARAMS=--stop;STOP.KEY="%STOPKEY%";STOP.PORT=%STOPPORT%;STOP.WAIT=10
"%PR_INSTALL%" //IS/%SERVICE_NAME% ^
--DisplayName="%SERVICE_NAME%" ^
--Install="%PR_INSTALL%" ^
--Startup="%PR_STARTUP%" ^
--LogPath="%PR_LOGPATH%" ^
--LogPrefix="%PR_LOGPREFIX%" ^
--LogLevel="%PR_LOGLEVEL%" ^
--StdOutput="%PR_STDOUTPUT%" ^
--StdError="%PR_STDERROR%" ^
--JavaHome="%JAVA_HOME%" ^
--Jvm="%PR_JVM%" ^
--JvmMs="%PR_JVMMS%" ^
--JvmMx="%PR_JVMMX%" ^
--JvmSs="%PR_JVMSS%" ^
--JvmOptions=%PR_JVMOPTIONS% ^
--Classpath="%PR_CLASSPATH%" ^
--StartMode="%PR_STARTMODE%" ^
--StartClass="%JETTY_START_CLASS%" ^
--StartParams="%PR_STARTPARAMS%" ^
--StopMode="%PR_STOPMODE%" ^
--StopClass="%PR_STOPCLASS%" ^
--StopParams="%PR_STOPPARAMS%"
if not errorlevel 1 goto installed
echo Failed to install "%SERVICE_NAME%" service. Refer to log in %PR_LOGPATH%
goto end
:installed
echo The Service "%SERVICE_NAME%" has been installed
:end</code></pre>
</div>
</div>
<div class="paragraph">
<p>Configuration&#8217;s of note in this batch file:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">SERVICE_NAME</dt>
<dd>
<p>This is the name of the service that Windows sees.
The name in the Services window will show this name.</p>
</dd>
<dt class="hdlist1">STOPKEY</dt>
<dd>
<p>This is the secret key (password) for the ShutdownMonitor, used to issue a formal command to stop the server.</p>
</dd>
<dt class="hdlist1">STOPPORT</dt>
<dd>
<p>The port that the Shutdown Monitor listens on for the stop command.</p>
<div class="paragraph">
<p>If you have multiple Jetty servers on the same machine, this port will need to be different for each Service.</p>
</div>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Once you have run <code>prunsrv.exe //IS/&lt;service-name&gt;</code> (done for you in the above batch file) to install the service, you can use the standard Windows utilities to manage (start/stop/restart) the Jetty service.</p>
</div>
<div class="paragraph">
<p>Open the Service View and start your service.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="windows-service-jetty.png" alt="image" width="576"></span></p>
</div>
</div>
<div class="sect2">
<h3 id="startup-jpms"><a class="anchor" href="#startup-jpms"></a><a class="link" href="#startup-jpms">Startup using the Java Platform Module System (JPMS)</a></h3>
<div class="paragraph">
<p>Jetty modules also act as automatic <a href="https://en.wikipedia.org/wiki/Java_Platform_Module_System">JPMS</a> modules via the <code>Automatic-Module-Name</code> attribute in the jar&#8217;s <code>MANIFEST.MF</code> file.</p>
</div>
<div class="paragraph">
<p>This makes possible to run Jetty from the module-path, rather than the class-path.</p>
</div>
<div class="paragraph">
<p>We recommend using JDK 11 or greater due to the fact that JDK 11 removed all the "enterprise" modules from the JDK,
and therefore it guarantees a more stable platform to base your application&#8217;s dependencies on.
The classes in these "enterprise" modules were bundled with JDK 8, and present in "enterprise" modules in JDK 9 and JDK 10.
With JDK 11, these "enterprise" classes are either not available in the JDK (because their corresponding module was removed), or they are present in a different module.</p>
</div>
<div class="paragraph">
<p>Because some of these "enterprise" classes are required by Jetty or by applications running in Jetty, it is better to use a stable source for those classes - in this case by using JDK 11
or greater, and explicitly referencing the "enterprise" classes as dependencies, rather than assuming they are bundled with the JDK.</p>
</div>
<div class="sect3">
<h4 id="jpms-module-path"><a class="anchor" href="#jpms-module-path"></a><a class="link" href="#jpms-module-path">Starting Jetty on the module-path</a></h4>
<div class="paragraph">
<p>To start Jetty on the module-path rather than the class-path, it is enough to add the <code>--jpms</code> option to the command line, for example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ mkdir my-jetty-base
$ cd my-jetty-base
$ java -jar $JETTY_HOME/start.jar --add-to-start=http
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : http initialized in ${jetty.base}/start.ini
INFO : threadpool transitively enabled, ini template available with --add-to-start=threadpool
INFO : Base directory was modified
$ java -jar $JETTY_HOME/start.jar --jpms</code></pre>
</div>
</div>
<div class="paragraph">
<p>The example above creates a <a href="#startup-base-and-home">Jetty base directory</a> and enables the <code>http</code> module using the <code>--add-to-start</code> command.
The server then starts Jetty on the module-path using the <code>--jpms</code> option.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>[NOTE]
When running on the module-path using the `--jpms` option, the Jetty start mechanism will fork a second JVM passing it the right JVM options to run on the module-path.
You will have two JVMs running: one that runs `start.jar` and one that runs Jetty on the module-path.</pre>
</div>
</div>
<div class="paragraph">
<p>If you are interested in the details of how the command line to run Jetty on the module-path looks like, you can add the <code>--dry-run</code> option:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ java -jar $JETTY_HOME/start.jar --jpms --dry-run</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will give an output looking something like this (broken in sections for clarity):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">/opt/openjdk-11+28/bin/java
--module-path /opt/jetty/lib/jetty-servlet-api-4.0.2.jar:/opt/jetty/lib/jetty-http-10.0.0-SNAPSHOT.jar:...
--module org.eclipse.jetty.xml/org.eclipse.jetty.xml.XmlConfiguration /opt/jetty/etc/jetty-threadpool.xml /opt/jetty/etc/jetty.xml ...</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>--module-path</code> option specifies the list of Jetty jars.
This list depends on the Jetty modules that have been enabled via the <a href="#startup-modules"><code>--add-to-start</code></a> command.</p>
</div>
<div class="paragraph">
<p>The <code>--module</code> option tells the JVM to run main class <code>XmlConfiguration</code> from the <code>org.eclipse.jetty.xml</code> module, with the given XML files as program arguments.</p>
</div>
<div class="paragraph">
<p>When the JVM starts, module <code>org.eclipse.jetty.xml</code> is added to the set of JPMS <em>root modules</em>; all other Jetty modules, being automatic, will be resolved and added to the module graph.
JAR files that are not modules, such as <code>jetty-servlet-api-4.0.2.jar</code>, are on the module-path and therefore will be made automatic modules by the JVM (hence the derived module name <code>servlet.api</code> for this jar, referenced by the <code>--patch-module</code> command line option above).</p>
</div>
</div>
<div class="sect3">
<h4 id="jpms-advanced-config"><a class="anchor" href="#jpms-advanced-config"></a><a class="link" href="#jpms-advanced-config">Advanced JPMS Configuration</a></h4>
<div class="paragraph">
<p>Web applications may need additional services from the Servlet Container, such as JDBC <code>DataSource</code> references or JTA <code>UserTransaction</code> references.</p>
</div>
<div class="paragraph">
<p>For example, for JDBC it is typical to store, in JNDI, a reference to the connection pool&#8217;s <code>DataSource</code> (such as <code>com.zaxxer.hikari.HikariDataSource</code>) or a reference directly to the JDBC driver&#8217;s <code>DataSource</code> (<code>com.mysql.jdbc.jdbc2.optional.MysqlDataSource</code>).
Jetty needs to be able to instantiate those classes and therefore needs to be able to load those classes and all their super-classes, among which includes <code>javax.sql.DataSource</code>.</p>
</div>
<div class="paragraph">
<p>When Jetty runs on the class-path, this is easily achieved by using a <a href="#custom-modules">custom module</a>:</p>
</div>
<div class="listingblock">
<div class="title">mysql.mod</div>
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[description]
MySQL module
[lib]
lib/mysql/mysql-connector-java-*.jar</code></pre>
</div>
</div>
<div class="paragraph">
<p>However, when running on the module-path, things are quite different.</p>
</div>
<div class="paragraph">
<p>Class <code>javax.sql.DataSource</code> is in a JDK bundled module named <code>java.sql</code>, which is not automatic (it&#8217;s a proper JPMS module) and it is not in the <em>root modules</em> set.
Because it is not an automatic module, it is not added to the module graph, and therefore needs to be added explicitly using the JVM command line <code>--add-modules</code>.</p>
</div>
<div class="paragraph">
<p>To add the JPMS module <code>java.sql</code> to the module graph, you need to modify your custom module in the following way, using our <code>mysql.mod</code> as an example:</p>
</div>
<div class="listingblock">
<div class="title">mysql.mod</div>
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[description]
MySQL module
[lib]
lib/mysql/mysql-connector-java-*.jar
[jpms]
add-modules: java.sql</code></pre>
</div>
</div>
<div class="paragraph">
<p>The new <code>[jpms]</code> section is only used when Jetty is started on the module-path via the <code>--jpms</code> command line option.</p>
</div>
<div class="paragraph">
<p>Assuming that <code>mysql-connector-java-<strong>.jar</code> is a non JPMS modular jar, or an automatic JPMS modular jar, the Jetty start mechanism will add <code>mysql-connector-java-</strong>.jar</code> to the module-path, and will add the JVM command line option <code>--add-modules java.sql</code>.</p>
</div>
<div class="paragraph">
<p>If <code>mysql-connector-java-*.jar</code> were a proper JPMS modular jar with name (for example) <code>com.mysql.jdbc</code>, then it would need to be explicitly added to the module graph, in this way:</p>
</div>
<div class="listingblock">
<div class="title">mysql.mod</div>
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[description]
MySQL module
[lib]
lib/mysql/mysql-connector-java-*.jar
[jpms]
add-modules: com.mysql.jdbc</code></pre>
</div>
</div>
<div class="paragraph">
<p>The JPMS module <code>java.sql</code> does not need to be explicitly added because it would be a dependency of the <code>com.mysql.jdbc</code> module and therefore automatically added to the module graph.</p>
</div>
<div class="paragraph">
<p>The <code>[jpms]</code> section has the following format:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[jpms]
add-modules: &lt;module name&gt;(,&lt;module name&gt;)*
patch-module: &lt;module&gt;=&lt;file&gt;(:&lt;file&gt;)*
add-opens: &lt;module&gt;/&lt;package&gt;=&lt;target-module&gt;(,&lt;target-module&gt;)*
add-exports: &lt;module&gt;/&lt;package&gt;=&lt;target-module&gt;(,&lt;target-module&gt;)*
add-reads: &lt;module&gt;=&lt;target-module&gt;(,&lt;target-module&gt;)*</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="jpms-module-path-alternative"><a class="anchor" href="#jpms-module-path-alternative"></a><a class="link" href="#jpms-module-path-alternative">Alternative way to start Jetty on the module-path</a></h4>
<div class="paragraph">
<p>The section above uses the <code>--jpms</code> command line option to start Jetty on the module-path.
An alternative way of achieving the same result is to use a Jetty module, <code>$JETTY_BASE/modules/jpms.mod</code>,
that specifies that you want to run using JPMS (and possibly add some JPMS specific configuration).</p>
</div>
<div class="listingblock">
<div class="title">jpms.mod</div>
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">[ini]
--jpms
[jpms]
# Additional JPMS configuration.</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>[ini]</code> section is equivalent to passing the <code>--jpms</code> option to the command line.
The <code>[jpms]</code> section (see also the <a href="#jpms-advanced-config">advanced JPMS configuration section</a>)
allows you specify additional JPMS configuration.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ mkdir jetty-base-jpms
$ cd jetty-base-jpms
$ mkdir modules
# Copy the jpms.mod file above into the $JETTY_BASE/modules/ directory.
$ cp /tmp/jpms.mod modules/
# Add both the http and the jpms modules.
$ java -jar $JETTY_HOME/start.jar --add-to-start=http,jpms
# Jetty will start on the module-path.
$ java -jar $JETTY_HOME/start.jar</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="troubleshooting"><a class="anchor" href="#troubleshooting"></a><a class="link" href="#troubleshooting">Troubleshooting</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>This is a collection of helpful tricks and tips that we have come across to address odd issues that might arise.</p>
</div>
<div class="sect2">
<h3 id="troubleshooting-zip-exceptions"><a class="anchor" href="#troubleshooting-zip-exceptions"></a><a class="link" href="#troubleshooting-zip-exceptions">Troubleshooting Zip Exceptions</a></h3>
<div class="paragraph">
<p>A Zip exception occurs when Jetty rereads a Jar or WAR file.</p>
</div>
<div class="paragraph">
<p>The JVM maintains a cache of zip file indexes, and does not support hot replacement of zip files.
Thus if you redeploy a web application using the same WAR or Jar files, exceptions occur when Jetty rereads the jars.
See <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4774421">Oracle Bug 4774421</a> for more information.</p>
</div>
<div class="sect3">
<h4 id="remedy"><a class="anchor" href="#remedy"></a><a class="link" href="#remedy">Remedy</a></h4>
<div class="paragraph">
<p>The remedy is to avoid hot replacing Jar or WAR files, which can be difficult if you are using the
<a href="#configuring-specific-webapp-deployment">Webapp Provider</a>.
You can use the following techniques to reduce exposure to this issue:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Deploy unpacked classes in the <code>WEB-INF/classes</code> directory rather than as a Jar file under <code>WEB-INF/lib</code>.</p>
</li>
<li>
<p>Deploy all WAR and Jar files with a version number in their filename or path.
If the code changes, a new version number applies, avoiding the cache problem.</p>
</li>
<li>
<p>Deploy a packed WAR file with the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#setExtractWAR(boolean)">setExtractWAR</a> option set to true.
This causes the WAR to be extracted to a <a href="#ref-temporary-directories">temporary directory</a> and thus to a new location.
This might not be sufficient if you want to hot-replace and re-extract the WAR, so you might also need to use <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#setCopyWebInf(boolean)">WebAppContext.setCopyWebInf(true)</a>, which (re)copies just the WEB-INF directory to a different location.</p>
</li>
<li>
<p>Deploy an unpacked WAR file with the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#setCopyWebDir(boolean)">setCopyWebDir</a> option set to true.
This causes the directory to be extracted to a new location.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If you have problems with <a href="#troubleshooting-locked-files-on-windows">Windows file-locking</a> preventing static file editing (such as JSP or HTML), use the <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/webapp/WebAppContext.html#setCopyWebDir(boolean)">WebAppContext .setCopyWebDir(true)</a> option.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="troubleshooting-locked-files-on-windows"><a class="anchor" href="#troubleshooting-locked-files-on-windows"></a><a class="link" href="#troubleshooting-locked-files-on-windows">Troubleshooting Locked Files on Windows</a></h3>
<div class="paragraph">
<p>Jetty buffers static content for webapps such as HTML files, CSS files, images, etc.
If you are using NIO connectors, Jetty uses memory-mapped files to do this.
The problem is that on Windows, memory mapping a file causes the file to lock, so that you cannot update or replace the file.
Effectively this means that you have to stop Jetty to update a file.</p>
</div>
<div class="sect3">
<h4 id="_remedy"><a class="anchor" href="#_remedy"></a><a class="link" href="#_remedy">Remedy</a></h4>
<div class="paragraph">
<p>Jetty provides a configuration switch for the <code>DefaultServlet</code> that enables or disables the use of memory-mapped files.
If you are running on Windows and are having file-locking problems, you should set this switch to disable memory-mapped file buffers.
Use one of the following options to configure the switch.</p>
</div>
<div class="sect4">
<h5 id="_using-override-web-xml"><a class="anchor" href="#_using-override-web-xml"></a><a class="link" href="#_using-override-web-xml">Using override-web.xml</a></h5>
<div class="paragraph">
<p>An <a href="#override-web-xml">override-web.xml</a> file can be placed in your webapp&#8217;s <code>WEB-INF</code> directory to change the default setting of the <code>DefaultServlet</code> for memory-mapped file buffers.
Create an <code>override-web.xml</code> file with appropriate headers for your version of the servlet specification, and place the following inside the <code>&lt;web-app&gt;</code> element:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;servlet&gt;
&lt;servlet-name&gt;default&lt;/servlet-name&gt;
&lt;init-param&gt;
&lt;param-name&gt;useFileMappedBuffer&lt;/param-name&gt;
&lt;param-value&gt;false&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;/servlet&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_using-a-context-xml-file"><a class="anchor" href="#_using-a-context-xml-file"></a><a class="link" href="#_using-a-context-xml-file">Using a Context XML File</a></h5>
<div class="paragraph">
<p>You can create or update a context xml file that configures your webapp to apply the setting to disable memory-mapped file buffers.
Add the following to your context xml file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;Call name="setInitParameter"&gt;
&lt;Arg&gt;org.eclipse.jetty.servlet.Default.useFileMappedBuffer&lt;/Arg&gt;
&lt;Arg&gt;false&lt;/Arg&gt;
&lt;/Call&gt;</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_using-the-jetty-maven-plugin"><a class="anchor" href="#_using-the-jetty-maven-plugin"></a><a class="link" href="#_using-the-jetty-maven-plugin">Using the Jetty Maven Plugin</a></h5>
<div class="paragraph">
<p>If you don&#8217;t want to use either of the other two solutions, you can configure the plugin directly to disable memory-mapped file buffers.
Add the following to the plugin&#8217;s configuration under the <code>&lt;webApp&gt;</code> element:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml"> &lt;_initParams&gt;
&lt;org.eclipse.jetty.servlet.Default.useFileMappedBuffer&gt;false&lt;/org.eclipse.jetty.servlet.Default.useFileMappedBuffer&gt;
&lt;/_initParams&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_alternate-remedy"><a class="anchor" href="#_alternate-remedy"></a><a class="link" href="#_alternate-remedy">Alternate Remedy</a></h4>
<div class="paragraph">
<p>You can force a <code>WebAppContext</code> to always copy a web app directory on deployment.
The base directory of your web app (i.e. the root directory where your static content exists) will be copied to the <a href="#ref-temporary-directories">temp directory</a>.
Configure this in an xml file like so:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;New id="myWebAppContext" class="org.eclipse.jetty.webapp.WebAppContext"&gt;
&lt;Set name="contextPath"&gt;/&lt;/Set&gt;
&lt;Set name="war"&gt;./webapps/fredapp&lt;/Set&gt;
&lt;Set name="copyWebDir"&gt;true&lt;/Set&gt;
.
.
&lt;/New&gt;</code></pre>
</div>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Be careful with this option when using an explicitly set<a href="#ref-temp-directories">temp directory</a> name - as the name of the temp directory will not unique across redeployments, copying the static content into the same directory name each time may not avoid the locking problem.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
</div>
</div>
<div class="sect2">
<h3 id="preventing-memory-leaks"><a class="anchor" href="#preventing-memory-leaks"></a><a class="link" href="#preventing-memory-leaks">Preventing Memory Leaks</a></h3>
<div class="paragraph">
<p>If you have memory leaks, and you have thoroughly investigated tools like jconsole, yourkit, jprofiler, jvisualvm or any of the other profiling and analysis tools, and you can eliminate your code as the source of the problem, read the following sections about how to prevent memory leaks in your application.</p>
</div>
<div class="sect3">
<h4 id="preventing-webapp-classloader-pinning"><a class="anchor" href="#preventing-webapp-classloader-pinning"></a><a class="link" href="#preventing-webapp-classloader-pinning">Preventing WebApp Classloader Pinning</a></h4>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
This feature is available for Jetty 7.6.6 and later.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Code that keeps references to a webapp classloader can cause memory leaks.
These leaks fall generally into two categories: static fields and daemon threads.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A static field is initialized with the value of the classloader, which happens to be a webapp classloader; as Jetty undeploys and redeploys the webapp, the static reference lives on, meaning garbage collecting cannot occur for the webapp classloader.</p>
</li>
<li>
<p>When Jetty starts as a daemon thread and is outside the lifecycle of the webapp, threads have references to the context classloader that created them, leading to a memory leak if that classloader belongs to a webapp.
For a good discussion of the issue see <a href="http://cdivilly.wordpress.com/tag/sun-awt-appcontext/">Anatomy of a PermGen Memory Leak.</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>We provide a number of <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT//org/eclipse/jetty/util/preventers/package-summary.html">workaround classes</a> that preemptively invoke the problematic code with the Jetty classloader, thereby ensuring the webapp classloader is not pinned.
Be aware that since some of the problematic code creates threads, you should be selective about which preventers you enable, and use only those that are specific to your application.</p>
</div>
<div class="sect4">
<h5 id="preventers-table"><a class="anchor" href="#preventers-table"></a><a class="link" href="#preventers-table">Preventers</a></h5>
<div class="paragraph">
<p>Jetty includes the following preventers.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Preventer Name</th>
<th class="tableblock halign-left valign-top">Problem Addressed</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">AppContextLeakPreventer</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The call to <code>AppContext.getAppContext()</code> keeps a static reference to the context classloader. The JRE can invoke AppContext in many different places.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">AWTLeakPreventer</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The <code>java.awt.Toolkit</code> class has a static field that is the default toolkit.
Creating the default toolkit causes the creation of an <code>EventQueue</code>, which has a classloader field initialized with the thread context class loader.
See <a href="https://issues.jboss.org/browse/AS7-3733">JBoss bug AS7-3733.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">DOMLeakPreventer</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">DOM parsing can cause the webapp classloader to be pinned, due to the static field ` RuntimeException` of <code>com.sun.org.apache.xerces.internal.parsers.AbstractDOMParser.</code> <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6916498">Oracle bug 6916498</a> specifically mentions that a heap dump might not identify the GCRoot as the uncollected loader, making it difficult to identify the cause of the leak.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">DriverManagerLeakPreventer</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The number of threads dedicated to accepting incoming connections.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">GCThreadLeakPreventer</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Calls to <code>sun.misc.GC.requestLatency</code> create a daemon thread that keeps a reference to the context classloader.
A known caller of this method is the RMI impl. See <a href="http://stackoverflow.com/questions/6626680/does-java-garbage-collection-log-entry-full-gc-system-mean-some-class-called">Stackoverflow: Does java garbage collection log entry 'Full GC system' mean some class
called System.gc()?</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java2DLeakPreventer</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sun.java2d.Disposer</code> keeps a reference to the classloader.
See <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=51687">ASF bug 51687.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">LDAPLeakPreventer</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">If <code>com.sun.jndi.LdapPoolManager</code> class is loaded and the system property ` com.sun.jndi.ldap.connect.pool.timeout` is set to a nonzero value, a daemon thread starts and keeps a reference to the context classloader.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">LoginConfigurationLeakPreventer</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The <code>javax.security.auth.login.Configuration</code> class keeps a static reference to the thread context classloader.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">SecurityProviderLeakPreventer</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Some security providers, such as <code>sun.security.pkcs11.SunPKCS11</code> start a deamon thread that traps the thread context classloader.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect4">
<h5 id="configuring-preventers"><a class="anchor" href="#configuring-preventers"></a><a class="link" href="#configuring-preventers">Configuring Preventers</a></h5>
<div class="paragraph">
<p>You can individually enable each preventer by adding an instance to a Server with the ` addBean(Object)` call. Here&#8217;s an example of how to do it in code with the <code>org.eclipse.jetty.util.preventers.AppContextLeakPreventer</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Server server = new Server();
server.addBean(new AppContextLeakPreventer());</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can add the equivalent in code to the <code>$JETTY_HOME/etc/jetty.xml</code> file or any jetty xml file that is configuring a Server instance.
Be aware that if you have more than one Server instance in your JVM, you should configure these preventers on just <em>one</em> of them.
Here&#8217;s the example from code put into xml:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;Call name="addBean"&gt;
&lt;Arg&gt;
&lt;New class="org.eclipse.jetty.util.preventers.AppContextLeakPreventer"/&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="jsp-bugs"><a class="anchor" href="#jsp-bugs"></a><a class="link" href="#jsp-bugs">JSP Bugs: Permgen Problems</a></h4>
<div class="paragraph">
<p>The JSP engine in Jetty is Jasper.
This was originally developed under the Apache Tomcat project, but over time many different project have forked it.
All Jetty versions up to 6 used Apache-based Jasper exclusively, with Jetty 6 using Apache Jasper only for JSP 2.0.
With the advent of JSP 2.1, Jetty 6 switched to using Jasper from Sun&#8217;s <a href="https://glassfish.java.net/">Glassfish</a> project, which is now the reference implementation.</p>
</div>
<div class="paragraph">
<p>All forks of Jasper suffer from a problem whereby using JSP tag files puts the permgen space under pressure.
This is because of the classloading architecture of the JSP implementation.
Each JSP file is effectively compiled and its class loaded in its own classloader to allow for hot replacement.
Each JSP that contains references to a tag file compiles the tag if necessary and then loads it using its own classloader.
If you have many JSPs that refer to the same tag file, the tag&#8217;s class is loaded over and over again into permgen space, once for each JSP.
See <a href="http://java.net/jira/browse/GLASSFISH-3963">Glassfish bug 3963</a> and <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=43878">Apache bug 43878.</a>
The Apache Tomcat project has already closed this bug with status WON&#8217;T FIX, however the Glassfish folks still have the bug open and have scheduled it to be fixed.
When the fix becomes available, the Jetty project will pick it up and incorporate into our release program.</p>
</div>
</div>
<div class="sect3">
<h4 id="jvm-bugs"><a class="anchor" href="#jvm-bugs"></a><a class="link" href="#jvm-bugs">JVM Bugs</a></h4>
<div class="paragraph">
<p>This section describes garbage collection and direct ByteBuffer problems.</p>
</div>
<div class="sect4">
<h5 id="jvm-garbage-collection-problems"><a class="anchor" href="#jvm-garbage-collection-problems"></a><a class="link" href="#jvm-garbage-collection-problems">Garbage Collection Problems</a></h5>
<div class="paragraph">
<p>One symptom of a cluster of JVM related memory issues is the OOM exception accompanied by a message such as <code>java.lang.OutOfMemoryError: requested xxxx bytes for xxx.
Out of swap space?</code></p>
</div>
<div class="paragraph">
<p><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4697804">Oracle bug 4697804</a> describes how this can happen in the scenario when the garbage collector needs to allocate a bit more space during its run and tries to resize the heap, but fails because the machine is out of swap space.
One suggested work around is to ensure that the JVM never tries to resize the heap, by setting min heap size to max heap size:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-text" data-lang="text">java -Xmx1024m -Xms1024m</code></pre>
</div>
</div>
<div class="paragraph">
<p>Another workaround is to ensure you have configured sufficient swap space on your device to accommodate all programs you are running concurrently.</p>
</div>
</div>
<div class="sect4">
<h5 id="direct-byte-buffers"><a class="anchor" href="#direct-byte-buffers"></a><a class="link" href="#direct-byte-buffers">Direct ByteBuffers</a></h5>
<div class="paragraph">
<p>Exhausting native memory is another issue related to JVM bugs.
The symptoms to look out for are the process size growing, but heap use remaining relatively constant.
Both the JIT compiler and nio ByteBuffers can consume native memory.
<a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6210541">Oracle bug 6210541</a> discusses a still-unsolved problem whereby the JVM itself allocates a direct ByteBuffer in some circumstances while the system never garbage collects, effectively eating native memory.
Guy Korland&#8217;s blog discusses this problem <a href="http://www.jroller.com/gkorland/entry/java_s_memory_isn_t">here</a> and <a href="http://www.jroller.com/gkorland/entry/java_s_memory_managment_is">here.</a>
As the JIT compiler consumes native memory, the lack of available memory may manifest itself in the JIT as OutOfMemory exceptions such as <code>Exception in thread "CompilerThread0" java.lang.OutOfMemoryError: requested xxx bytes for ChunkPool::allocate. Out of swap
space?</code></p>
</div>
<div class="paragraph">
<p>By default, Jetty allocates and manages its own pool of direct ByteBuffers for io if you configure the nio SelectChannelConnector.
It also allocates MappedByteBuffers to memory-map static files via the DefaultServlet settings.
However, you could be vulnerable to this JVM ByteBuffer allocation problem if you have disabled either of these options.
For example, if you&#8217;re on Windows, you may have disabled the use of memory-mapped buffers for the static file cache on the DefaultServlet to avoid the file-locking problem.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="troubleshooting-slow-deployment"><a class="anchor" href="#troubleshooting-slow-deployment"></a><a class="link" href="#troubleshooting-slow-deployment">Troubleshooting Slow Deployment</a></h3>
<div class="paragraph">
<p>After upgrading to a version of Jetty that supports Servlet Spec 3.0 or above, enabling some new modules, or introducing some new jars to your webapp, you notice that your deployment time is increased.
This could be due to scanning for classes caused by a ServletContainerInitializer.</p>
</div>
<div class="paragraph">
<p>As documented in the section on <a href="#using-annotations">Using Annotations</a>, even if your webapp has set <code>metadata-complete=true</code> in web.xml, all jars within your webapp may still be scanned due to one or more ServletContainerInitializers that have a <a href="http://docs.oracle.com/javaee/6/api/javax/servlet/annotation/HandlesTypes.html">&#64;HandlesTypes</a> annotation listing the names of classes in which it is interested.</p>
</div>
<div class="paragraph">
<p>There are 3 ways to speed up deployment time:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>limit which ServletContainerInitializers to include</p>
</li>
<li>
<p>limit which jars to scan</p>
</li>
<li>
<p>limit the scan to the first deployment only</p>
</li>
</ul>
</div>
<div class="sect3">
<h4 id="_remedies"><a class="anchor" href="#_remedies"></a><a class="link" href="#_remedies">Remedies</a></h4>
<div class="sect4">
<h5 id="_limit-which-servletcontainerinitializers-to-execute"><a class="anchor" href="#_limit-which-servletcontainerinitializers-to-execute"></a><a class="link" href="#_limit-which-servletcontainerinitializers-to-execute">Limit Which ServletContainerInitializers to Execute</a></h5>
<div class="paragraph">
<p>As documented in the section <a href="#excluding-scis">Excluding ServletContainerInitializers</a>, you can provide a context attribute that defines a pattern of ServletContainerInitializer (SCI) class names to ignore.
These SCIs will not be examined for <a href="http://docs.oracle.com/javaee/6/api/javax/servlet/annotation/HandlesTypes.html">&#64;HandlesTypes</a> and will not be executed.
This is useful if you have included a 3rd party jar that has a SCI on which your code does not rely.</p>
</div>
</div>
<div class="sect4">
<h5 id="_limit-which-jars-to-scan"><a class="anchor" href="#_limit-which-jars-to-scan"></a><a class="link" href="#_limit-which-jars-to-scan">Limit Which Jars to Scan</a></h5>
<div class="paragraph">
<p>As documented in the section <a href="#jars-scanned-for-annotations">Jars Scanned for Annotations</a>, you can explicitly define which jars to include in the scanning process.
This is helpful if you have a lot of jars in your webapp, and you know that they do not contain any classes referenced by an @HandlesTypes annotation on a ServletContainerInitializer that will be executed.</p>
</div>
</div>
<div class="sect4">
<h5 id="_limit-scanning-to-first-deployment-only-quickstart"><a class="anchor" href="#_limit-scanning-to-first-deployment-only-quickstart"></a><a class="link" href="#_limit-scanning-to-first-deployment-only-quickstart">Limit Scanning to First Deployment Only (Quickstart)</a></h5>
<div class="paragraph">
<p>The <a href="#quickstart-webapp">quickstart mechanism</a> will do a normal deployment - obeying any limits on SCIs and jars to scan as documented here - the first time the webapp is deployed only.
Subsequent deployments will re-use the information discovered during the first deployment.
This is useful if you cannot limit the scan significantly by using any of the mechanisms described here, but you don&#8217;t want to incur the cost of scanning on every redeployment.
The <a href="#quickstart-webapp">quickstart mechanism</a> and how to use it is described <a href="#quickstart-webapp">here</a>.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="security-reports"><a class="anchor" href="#security-reports"></a><a class="link" href="#security-reports">Jetty Security Reports</a></h3>
<div class="paragraph">
<p>The following sections provide information about Jetty security issues.</p>
</div>
<div class="paragraph">
<p>If you would like to report a security issue please follow these <a href="#security-reporting">instructions</a>.</p>
</div>
<table class="tableblock frame-all grid-all" style="width: 99%;">
<caption class="title">Table 21. Resolved Issues</caption>
<colgroup>
<col style="width: 11%;">
<col style="width: 19%;">
<col style="width: 14%;">
<col style="width: 9%;">
<col style="width: 14%;">
<col style="width: 14%;">
<col style="width: 19%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">yyyy/mm/dd</th>
<th class="tableblock halign-left valign-top">ID</th>
<th class="tableblock halign-left valign-top">Exploitable</th>
<th class="tableblock halign-left valign-top">Severity</th>
<th class="tableblock halign-left valign-top">Affects</th>
<th class="tableblock halign-left valign-top">Fixed Version</th>
<th class="tableblock halign-left valign-top">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2019/08/13</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2019-9518</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Med</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Med</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 9.4.20</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.4.21</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9518">Some HTTP/2 implementations are vulnerable to a flood of empty frames, potentially leading to a denial of service.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2019/08/13</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2019-9516</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Med</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Med</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 9.4.20</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.4.21</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9516">Some HTTP/2 implementations are vulnerable to a header leak, potentially leading to a denial of service.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2019/08/13</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2019-9515</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Med</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Med</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 9.4.20</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.4.21</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9515">Some HTTP/2 implementations are vulnerable to a settings flood, potentially leading to a denial of service when an attacker sent a stream of SETTINGS frames to the peer.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2019/08/13</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2019-9514</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Med</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Med</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 9.4.20</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.4.21</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9514">Some HTTP/2 implementations are vulnerable to a reset flood, potentially leading to a denial of service.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2019/08/13</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2019-9512</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 9.4.20</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.4.21</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9512">Some HTTP/2 implementations are vulnerable to ping floods which could lead to a denial of service.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2019/08/13</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2019-9511</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Low</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 9.4.20</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.4.21</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9511">Some HTTP/2 implementations are vulnerable to window size manipulation and stream prioritization manipulation which could lead to a denial of service.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2019/04/11</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2019-10247</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Med</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Med</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 9.4.16</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.2.28, 9.3.27, 9.4.17</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10247">If no webapp was mounted to the root namespace and a 404 was encountered, an HTML page would be generated displaying the fully qualified base resource location for each context.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2019/04/11</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2019-10246</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 9.4.16</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.2.28, 9.3.27, 9.4.17</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10246">Use of <code>DefaultServlet</code> or <code>ResourceHandler</code> with indexing was vulnerable to XSS behaviors to expose the directory listing on Windows operating systems.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2019/04/11</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2019-10241</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 9.4.15</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.2.27, 9.3.26, 9.4.16</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10241">Use of <code>DefaultServlet</code> or <code>ResourceHandler</code> with indexing was vulnerable to XSS behaviors to expose the directory listing.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2018/06/25</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2018-12538</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&gt;= 9.4.0, &lt; = 9.4.8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.4.9</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12538"><code>HttpSessions</code> present specifically in the FileSystem’s storage could be hijacked/accessed by an unauthorized user.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2018/06/25</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2018-12536</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">High</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">See <a href="https://cwe.mitre.org/data/definitions/209.html">CWE-202</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 9.4.10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.2.25, 9.3.24, 9.4.11</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-12536"><code>InvalidPathException</code> Message reveals webapp system path.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2018/06/25</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2017-7658</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">See <a href="https://cwe.mitre.org/data/definitions/444.html">CWE-444</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">See <a href="https://cwe.mitre.org/data/definitions/444.html">CWE-444</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 9.4.10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.2.25, 9.3.24, 9.4.11</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-7658">Too Tolerant Parser, Double Content-Length + Transfer-Encoding + Whitespace.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2018/06/25</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2017-7657</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">See <a href="https://cwe.mitre.org/data/definitions/444.html">CWE-444</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">See <a href="https://cwe.mitre.org/data/definitions/444.html">CWE-444</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 9.4.10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.2.25, 9.3.24, 9.4.11</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7657">HTTP/1.1 Request smuggling with carefully crafted body content (Does not apply to HTTP/1.0 or HTTP/2).</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2018/06/25</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2017-7656</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">See <a href="https://cwe.mitre.org/data/definitions/444.html">CWE-444</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">See <a href="https://cwe.mitre.org/data/definitions/444.html">CWE-444</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 9.4.10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.2.25, 9.3.24, 9.4.11</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=2017-7656">HTTP Request Smuggling when used with invalid request headers (for HTTP/0.9).</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2016/05/31</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CVE-2016-4800</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&gt;= 9.3.0, &lt; = 9.3.8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.3.9</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.ocert.org/advisories/ocert-2016-001.html">Alias vulnerability allowing access to protected resources within a webapp on Windows.</a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2015/02/24</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://blog.gdssecurity.com/labs/2015/2/25/jetleak-vulnerability-remote-leakage-of-shared-buffers-in-je.html">CVE-2015-2080</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&gt;=9.2.3 &lt;9.2.9</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.2.9</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">JetLeak exposure of past buffers during HttpParser error</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2013/11/27</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://en.securitylab.ru/lab/PT-2013-65">PT-2013-65</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&gt;=9.0.0 &lt;9.0.5</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">9.0.6
<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=418014">418014</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Alias checking disabled by NTFS errors on Windows.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2013/07/24</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=413684">413684</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">low</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&gt;=7.6.9 &lt;9.0.5</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">7.6.13,8.1.13,9.0.5
<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=413684">413684</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Constraints bypassed if Unix symlink alias checker used on Windows.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2011/12/29</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.ocert.org/advisories/ocert-2011-003.html">CERT2011-003</a> <a href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2011-4461">CVE-2011-4461</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All versions</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">7.6.0.RCO
<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=367638">Jetty-367638</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Added ContextHandler.setMaxFormKeys (intkeys) to limit the number of parameters (default 1000).</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2009/11/05</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.kb.cert.org/vuls/id/120541">CERT2011-003</a> <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3555">CERT2011-003</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">JVM&lt;1.6u19</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">jetty-7.01.v20091125, jetty-6.1.22</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Work
around by turning off SSL renegotiation in Jetty. If using JVM &gt; 1.6u19
setAllowRenegotiate(true) may be called on connectors.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2009/06/18</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Jetty-1042</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">low</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 6.1.18, &lt; = 7.0.0.M4</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">6.1.19, 7.0.0.Rc0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Cookie leak between
requests sharing a connection.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2009/04/30</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.kb.cert.org/vuls/id/402580">CERT402580</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt; = 6.1.16, &lt; = 7.0.0.M2</p></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>5.1.15, 6.1.18, 7.0.0.M2</p>
</div>
<div class="paragraph">
<p>Jetty-1004</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">View arbitrary disk content in some specific configurations.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2007/12/22</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.kb.cert.org/vuls/id/553235">CERT553235</a> <a href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2007-6672">CVE-2007-6672</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">6.1.rrc0-6.1.6</p></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>6.1.7</p>
</div>
<div class="paragraph">
<p>CERT553235</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Static content visible in WEB-INF and past security constraints.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2007/11/05</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.kb.cert.org/vuls/id/438616">CERT438616</a> <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-5614">CVE-2007-5614</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">low</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">low</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;6.1.6</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">6.1.6rc1 (patch in CVS for jetty5)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Single quote in
cookie name.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2007/11/05</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.kb.cert.org/vuls/id/237888">CERT237888&gt;</a> <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-5613">CVE-2007-5613</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">low</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">low</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;6.1.6</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">6.1.6rc0 (patch in CVS for jetty5)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">XSS in demo dup
servlet.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2007/11/03</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.kb.cert.org/vuls/id/212984">CERT212984
&gt;</a> <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-5615">CVE-2007-5615</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;6.1.6</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">6.1.6rc0 (patch in CVS for jetty5)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CRLF
Response splitting.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2006/11/22</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-6969">CVE-2006-6969</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">low</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;6.1.0, &lt;6.0.2, &lt;5.1.12, &lt;4.2.27</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">6.1.0pre3, 6.0.2, 5.1.12,
4.2.27</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Session ID predictability.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2006/06/01</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-2759">CVE-2006-2759</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;6.0.*, &lt;6.0.0Beta17</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">6.0.0Beta17</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">JSP source
visibility.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2006/01/05</p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;5.1.10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">5.1.10</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Fixed //security
constraint bypass on Windows.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2005/11/18</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-2758">CVE-2006-2758</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;5.1.6</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">5.1.6, 6.0.0Beta4</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">JSP source visibility.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2004/02/04</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">JSSE 1.0.3_01</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;4.2.7</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4.2.7</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Upgraded JSSE
to obtain downstream security fix.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2002/09/22</p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;4.1.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4.1.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Fixed CGI servlet remove
exploit.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2002/03/12</p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;3.1.7</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">4.0.RC2, 3.1.7</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Fixed // security
constraint bypass.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">2001/10/21</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">medium</p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">high</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">&lt;3.1.3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.1.3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Fixed trailing null security
constraint bypass.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="watchservice"><a class="anchor" href="#watchservice"></a><a class="link" href="#watchservice">Java WatchService</a></h3>
<div class="paragraph">
<p>The JVM <a href="https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html"><code>WatchService</code></a> is in place to monitor objects like a directory for changes, and then update it&#8217;s contents and notify the application of those changes.
This service is useful for features like <a href="#hot-deployment">Hot Deployment</a>.
When a change is detected, the <code>WatchService</code> will enter a "quiet time" where it is waiting for the change (or changes) to be made and completed before notifying the application of the change.</p>
</div>
<div class="paragraph">
<p>Example:
A new war file is copied into <code>/webapps</code>.
The <code>WatchService</code> can (depending on implementation) see that the file was created (which is registered as an event!, and that its growing in size (another event).
With the quiet time, each of the events are gated behind that timeout before the aggregated events are sent to the application.</p>
</div>
<div class="paragraph">
<p>While some operating systems such as Windows have a native value for this quiet time, not all do, notably OSX.
At the core this is a limitation of the JVM&#8217;s FileSystem-specific implementation, but one that has been raised to the <a href="https://bugs.openjdk.java.net/browse/JDK-7133447">attention of the project.</a></p>
</div>
<div class="sect3">
<h4 id="_remedy-2"><a class="anchor" href="#_remedy-2"></a><a class="link" href="#_remedy-2">Remedy</a></h4>
<div class="paragraph">
<p>To help offset the delay in systems like OSX, Jetty defaults the value for non-native implementations to a <a href="https://github.com/eclipse/jetty.project/tree/master/jetty-util/src/main/java/org/eclipse/jetty/util/PathWatcher.java#L1431">time of 5000ms.</a>
Using values lower than 5000ms is not recommended and has shown to frequently fail.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="optimizing"><a class="anchor" href="#optimizing"></a><a class="link" href="#optimizing">Optimizing Jetty</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>There are many ways to optimize Jetty which vary depending on the situation.
Are you trying to optimize for number of requests within a given amount of time?
Are you trying to optimize the serving of static content?
Do you have a large bit of hardware that you want to give entirely over to Jetty to use to its heart&#8217;s delight?
This chapter examines a few of the many different ways to optimize Jetty.</p>
</div>
<div class="sect2">
<h3 id="garbage-collection"><a class="anchor" href="#garbage-collection"></a><a class="link" href="#garbage-collection">Garbage Collection</a></h3>
<div class="paragraph">
<p>Tuning the JVM garbage collection (GC) can greatly improve the performance of the JVM where Jetty and your application are running.
Optimal tuning of the GC depends on the behavior of the application(s) and requires detailed analysis, but there are general recommendations to follow to at least obtain comprehensive GC logs that can be later analyzed.</p>
</div>
<div class="paragraph">
<p>See official <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/">Java 8</a> and <a href="https://docs.oracle.com/javase/9/gctuning/introduction-garbage-collection-tuning.htm">Java 9</a> Garbage Collection documentation for further assistance.</p>
</div>
<div class="sect3">
<h4 id="garbage-collection-logging-configuration"><a class="anchor" href="#garbage-collection-logging-configuration"></a><a class="link" href="#garbage-collection-logging-configuration">Garbage Collection Logging Configuration</a></h4>
<div class="paragraph">
<p>These options are general to OpenJDK (and therefore also for the Oracle JVM).
They provide good information about the GC activity of your JVM, producing logs that can later be analyzed to perform finer tuning.</p>
</div>
<div class="listingblock">
<div class="title">JDK 8 Garbage Collection Logging Configuration</div>
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">-Xloggc:/path/to/myjettybase/logs/gc.log
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-XX:+ParallelRefProcEnabled
-XX:+PrintReferenceGC
-XX:+PrintTenuringDistribution
-XX:+PrintAdaptiveSizePolicy</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">JDK 9 Garbage Collection Logging Configuration</div>
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">Xlog:gc*,ergo*=trace,ref*=debug,age*=trace:file=/path/to/myjettybase/logs/gc.log:time,level,tags</code></pre>
</div>
</div>
<div class="paragraph">
<p>There are not many recommended options for GC that can apply to all users.
However, the most obvious one is to disable explicit GC (this is performed regularly by RMI and can introduce an abnormal amount of GC pauses).</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">-XX:+DisableExplicitGC</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="high-load"><a class="anchor" href="#high-load"></a><a class="link" href="#high-load">High Load</a></h3>
<div class="paragraph">
<p>Configuring Jetty for high load, whether for load testing or for production, requires that the operating system, the JVM, Jetty, the application, the network and the load generation all be tuned.</p>
</div>
<div class="sect3">
<h4 id="_load-generation-for-load-testing"><a class="anchor" href="#_load-generation-for-load-testing"></a><a class="link" href="#_load-generation-for-load-testing">Load Generation for Load Testing</a></h4>
<div class="paragraph">
<p>Machines handling load generation must have their OS, JVM, etc., tuned just as much as the server machines.</p>
</div>
<div class="paragraph">
<p>The load generation should not be over the local network on the server machine, as this has unrealistic performance and latency as well as different packet sizes and transport characteristics.</p>
</div>
<div class="paragraph">
<p>The load generator should generate a realistic load.
Avoid the following pitfalls:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A common mistake is that load generators often open relatively few connections that are extremely busy sending as many requests as possible over each connection.
This causes the measured throughput to be limited by request latency (see <a href="http://blogs.webtide.com/gregw/entry/lies_damned_lies_and_benchmarks">Lies, Damned Lies and Benchmarks</a> for an analysis of such an issue).</p>
</li>
<li>
<p>Another common mistake is to use TCP/IP for a single request, and to open many, many short-lived connections.
This often results in accept queues filling and limitations due to file descriptor and/or port starvation.</p>
</li>
<li>
<p>A load generator should model the traffic profile from the normal clients of the server.
For browsers, this is often between two and six connections that are mostly idle and that are used in sporadic bursts with read times in between.
The connections are typically long held HTTP/1.1 connections.</p>
</li>
<li>
<p>Load generators should be written in asynchronously so that a limited number of threads does not restrict the maximum number of users that can be simulated.
If the generator is not asynchronous, a thread pool of 2000 may only be able to simulate 500 or fewer users.
The Jetty <code>HttpClient</code> is an ideal choice for building a load generator as it is asynchronous and can simulate many thousands of connections (see the CometD Load Tester for a good example of a realistic load generator).</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_operating-system-tuning"><a class="anchor" href="#_operating-system-tuning"></a><a class="link" href="#_operating-system-tuning">Operating System Tuning</a></h4>
<div class="paragraph">
<p>Both the server machine and any load generating machines need to be tuned to support many TCP/IP connections and high throughput.</p>
</div>
<div class="sect4">
<h5 id="_linux"><a class="anchor" href="#_linux"></a><a class="link" href="#_linux">Linux</a></h5>
<div class="paragraph">
<p>Linux does a reasonable job of self-configuring TCP/IP, but there are a few limits and defaults that you should increase.
You can configure most of these in <code>/etc/security/limits.conf</code> or via <code>sysctl</code>.</p>
</div>
<div class="sect5">
<h6 id="_tcp-buffer-sizes"><a class="anchor" href="#_tcp-buffer-sizes"></a><a class="link" href="#_tcp-buffer-sizes">TCP Buffer Sizes</a></h6>
<div class="paragraph">
<p>You should increase TCP buffer sizes to at least 16MB for 10G paths and tune the auto-tuning (keep in mind that you need to consider buffer bloat).</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ sysctl -w net.core.rmem_max=16777216
$ sysctl -w net.core.wmem_max=16777216
$ sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
$ sysctl -w net.ipv4.tcp_wmem="4096 16384 16777216"</code></pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="_queue-sizes"><a class="anchor" href="#_queue-sizes"></a><a class="link" href="#_queue-sizes">Queue Sizes</a></h6>
<div class="paragraph">
<p><code>net.core.somaxconn</code> controls the size of the connection listening queue.
The default value is 128.
If you are running a high-volume server and connections are getting refused at a TCP level, you need to increase this value.
This setting can take a bit of finesse to get correct: if you set it too high, resource problems occur as it tries to notify a server of a large number of connections, and many remain pending, but if you set it too low, refused connections occur.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen"> $ sysctl -w net.core.somaxconn=4096</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>net.core.netdev_max_backlog</code> controls the size of the incoming packet queue for upper-layer (Java) processing.
The default (2048) may be increased and other related parameters adjusted with:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ sysctl -w net.core.netdev_max_backlog=16384
$ sysctl -w net.ipv4.tcp_max_syn_backlog=8192
$ sysctl -w net.ipv4.tcp_syncookies=1</code></pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="_ports"><a class="anchor" href="#_ports"></a><a class="link" href="#_ports">Ports</a></h6>
<div class="paragraph">
<p>If many outgoing connections are made (for example, on load generators), the operating system might run low on ports.
Thus it is best to increase the port range, and allow reuse of sockets in <code>TIME_WAIT</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ sysctl -w net.ipv4.ip_local_port_range="1024 65535"
$ sysctl -w net.ipv4.tcp_tw_recycle=1</code></pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="_file-descriptors"><a class="anchor" href="#_file-descriptors"></a><a class="link" href="#_file-descriptors">File Descriptors</a></h6>
<div class="paragraph">
<p>Busy servers and load generators may run out of file descriptors as the system defaults are normally low.
These can be increased for a specific user in <code>/etc/security/limits.conf</code>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>theusername hard nofile 40000
theusername soft nofile 40000</pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="_congestion-control"><a class="anchor" href="#_congestion-control"></a><a class="link" href="#_congestion-control">Congestion Control</a></h6>
<div class="paragraph">
<p>Linux supports pluggable congestion control algorithms.
To get a list of congestion control algorithms that are available in your kernel run:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ sysctl net.ipv4.tcp_available_congestion_control</code></pre>
</div>
</div>
<div class="paragraph">
<p>If cubic and/or htcp are not listed, you need to research the control algorithms for your kernel.
You can try setting the control to cubic with:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-screen" data-lang="screen">$ sysctl -w net.ipv4.tcp_congestion_control=cubic</code></pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="_mac-os"><a class="anchor" href="#_mac-os"></a><a class="link" href="#_mac-os">Mac OS</a></h6>
<div class="paragraph">
<p>Tips welcome.</p>
</div>
</div>
<div class="sect5">
<h6 id="_windows"><a class="anchor" href="#_windows"></a><a class="link" href="#_windows">Windows</a></h6>
<div class="paragraph">
<p>Tips welcome.</p>
</div>
</div>
<div class="sect5">
<h6 id="_network-tuning"><a class="anchor" href="#_network-tuning"></a><a class="link" href="#_network-tuning">Network Tuning</a></h6>
<div class="paragraph">
<p>Intermediaries such as nginx can use a non-persistent HTTP/1.0 connection.
Make sure to use persistent HTTP/1.1 connections.</p>
</div>
</div>
<div class="sect5">
<h6 id="_jvm-tuning"><a class="anchor" href="#_jvm-tuning"></a><a class="link" href="#_jvm-tuning">JVM Tuning</a></h6>
<div class="ulist">
<ul>
<li>
<p>Tune the <a href="#tuning-examples">Garbage Collection</a></p>
</li>
<li>
<p>Allocate sufficient memory</p>
</li>
<li>
<p>Use the -server option</p>
</li>
<li>
<p>Jetty Tuning</p>
</li>
</ul>
</div>
</div>
<div class="sect5">
<h6 id="_acceptors"><a class="anchor" href="#_acceptors"></a><a class="link" href="#_acceptors">Acceptors</a></h6>
<div class="paragraph">
<p>The standard rule of thumb for the number of Accepters to configure is one per CPU on a given machine.</p>
</div>
</div>
<div class="sect5">
<h6 id="_low-resource-limits"><a class="anchor" href="#_low-resource-limits"></a><a class="link" href="#_low-resource-limits">Low Resource Limits</a></h6>
<div class="paragraph">
<p>Must not be configured for less than the number of expected connections.</p>
</div>
</div>
<div class="sect5">
<h6 id="_thread-pool"><a class="anchor" href="#_thread-pool"></a><a class="link" href="#_thread-pool">Thread Pool</a></h6>
<div class="paragraph">
<p>Configure with goal of limiting memory usage maximum available.
Typically this is &gt;50 and &lt;500</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="limit-load"><a class="anchor" href="#limit-load"></a><a class="link" href="#limit-load">Limiting Load</a></h3>
<div class="paragraph">
<p>To achieve optimal fair handling for all users of a server, it can be necessary to limit the resources that each user/connection can utilize so as to maximize throughput for the server or to ensure that the entire server runs within the limitations of it&#8217;s runtime.</p>
</div>
<div class="sect3">
<h4 id="_low-resources-monitor"><a class="anchor" href="#_low-resources-monitor"></a><a class="link" href="#_low-resources-monitor">Low Resources Monitor</a></h4>
<div class="paragraph">
<p>An instance of <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/server/LowResourcesMonitor.html">LowResourcesMonitor</a> may be added to a Jetty server to monitor for low resources situations and to take action to limit the number of idle connections on the server.
To configure the low resources monitor, you can enable the the <code>lowresources.mod</code> on the command line, which has the effect of including the following XML configuration:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd"&gt;
&lt;!-- =============================================================== --&gt;
&lt;!-- Mixin the Low Resources Monitor --&gt;
&lt;!-- =============================================================== --&gt;
&lt;Configure id="Server" class="org.eclipse.jetty.server.Server"&gt;
&lt;Call name="addBean"&gt;
&lt;Arg&gt;
&lt;New id="lowResourceMonitor" class="org.eclipse.jetty.server.LowResourceMonitor"&gt;
&lt;Arg name="server"&gt;&lt;Ref refid='Server'/&gt;&lt;/Arg&gt;
&lt;Set name="period" property="jetty.lowresources.period"/&gt;
&lt;Set name="lowResourcesIdleTimeout" property="jetty.lowresources.idleTimeout"/&gt;
&lt;Set name="monitorThreads" property="jetty.lowresources.monitorThreads"/&gt;
&lt;Set name="maxConnections" property="jetty.lowresources.maxConnections"/&gt;
&lt;Set name="maxMemory" property="jetty.lowresources.maxMemory"/&gt;
&lt;Set name="maxLowResourcesTime" property="jetty.lowresources.maxLowResourcesTime"/&gt;
&lt;Set name="acceptingInLowResources" property="jetty.lowresources.accepting"/&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
&lt;/Configure&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The monitor is configured with a period in milliseconds at which it will scan the server looking for a low resources condition, which may be one of:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>If <code>monitorThreads</code> is configured as true and a connectors Executor is an instance of <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/util/thread/ThreadPool.html">ThreadPool</a>, then its <code>isLowOnThreads()</code> method is used to detect low resources.</p>
</li>
<li>
<p>If <code>maxConnections</code> is configured to a number &gt;0 then if the total number of connections from all monitored connectors exceeds this value, then low resources state is entered.</p>
</li>
<li>
<p>If the <code>maxMemory</code> field is configured to a number of bytes &gt;0 then if the JVMs total memory minus its idle memory exceeds this value, then low resources state is entered.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Once low resources state is detected, then the monitor will iterate over all existing connections and set their <code>IdleTimeout</code> to its configured <code>lowResourcesIdleTimeout</code> in milliseconds.
This allows the idle time of existing connections to be reduced so that the connection is quickly closed if no further request are received.</p>
</div>
<div class="paragraph">
<p>If the low resources state persists longer than the time in milliseconds configured for the <code>maxLowResourcesTime</code> field, the the <code>lowResourcesIdleTimeout</code> is repeatedly applied so that new connections as well as existing connections will be limited.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="websocket-intro"><a class="anchor" href="#websocket-intro"></a><a class="link" href="#websocket-intro">WebSocket Introduction</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>WebSocket is a new protocol for bidirectional communications initiated via HTTP/1.1 upgrade and providing basic message framing, layered over TCP.
It is based on a low-level framing protocol that delivers messages in either UTF-8 TEXT or BINARY format.</p>
</div>
<div class="paragraph">
<p>A single message in WebSocket can be of any size (the underlying framing however does have a single frame limit of <a href="http://en.wikipedia.org/wiki/9223372036854775807">63-bits</a>).
There can be an unlimited number of messages sent.
Messages are sent sequentially, the base protocol does not support interleaved messages.</p>
</div>
<div class="paragraph">
<p>A WebSocket connection goes through some basic state changes:</p>
</div>
<table class="tableblock frame-all grid-all" style="width: 50%;">
<caption class="title">Table 22. WebSocket connection states</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">State</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">CONNECTING</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A HTTP Upgrade to WebSocket is in progress</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">OPEN</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The HTTP Upgrade succeeded and the socket is now open and ready to read / write</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">CLOSING</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A WebSocket Close Handshake has been started</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">CLOSED</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">WebSocket is now closed, no more read/write possible</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>When a WebSocket is closed, a <a href="http://www.eclipse.org/jetty/javadoc/10.0.0-SNAPSHOT/org/eclipse/jetty/websocket/api/StatusCode.html">status code</a> and short reason string is provided.</p>
</div>
<div class="sect2">
<h3 id="ws-intro-provides"><a class="anchor" href="#ws-intro-provides"></a><a class="link" href="#ws-intro-provides">What Jetty provides</a></h3>
<div class="paragraph">
<p>Jetty provides an implementation of the following standards and specs.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><a href="http://tools.ietf.org/html/rfc6455">RFC-6455</a></dt>
<dd>
<p>The WebSocket Protocol</p>
<div class="paragraph">
<p>We support the version 13 of the released and final spec.</p>
</div>
<div class="paragraph">
<p>Jetty tests its WebSocket protocol implementation using the <a href="http://autobahn.ws/testsuite">autobahn testsuite</a>.</p>
</div>
</dd>
</dl>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
The early drafts of WebSocket were supported in Jetty 7 and Jetty 8, but this support has been removed in Jetty 9.
This means that Jetty 9 will not support the old browsers that implemented the early drafts of WebSocket. (such as Safari 5.0 or Opera 12)
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="quoteblock">
<blockquote>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
Want to know if the browser you are targeting supports WebSocket?
Use <a href="http://caniuse.com/websockets">caniuse.com/websockets</a> to find out.
</td>
</tr>
</table>
</div>
</blockquote>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><a href="http://www.jcp.org/en/jsr/detail?id=356">JSR-356</a></dt>
<dd>
<p>The Java WebSocket API (<code>javax.websocket</code>)</p>
<div class="paragraph">
<p>This is the official Java API for working with WebSockets.</p>
</div>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Unstable standards and specs:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><a href="https://datatracker.ietf.org/doc/draft-ietf-hybi-websocket-perframe-compression/">perframe-compression</a></dt>
<dd>
<p>Per Frame Compression Extension.</p>
<div class="paragraph">
<p>An early extension draft from the Google/Chromium team that would provide WebSocket frame compression.
perframe-compression using deflate algorithm is present on many versions of Chrome/Chromium.</p>
</div>
<div class="paragraph">
<p>Jetty&#8217;s support for perframe-compression is based on the draft-04 spec.
This standard is being replaced with permessage-compression.</p>
</div>
</dd>
<dt class="hdlist1"><a href="https://datatracker.ietf.org/doc/draft-tyoshino-hybi-permessage-compression/">permessage-compression</a></dt>
<dd>
<p>Per Frame Compression Extension.</p>
<div class="paragraph">
<p>This is the replacement for perframe-compression, switching the compression to being based on the entire message, not the individual frames.</p>
</div>
</dd>
</dl>
</div>
</div>
<div class="sect2">
<h3 id="ws-intro-api"><a class="anchor" href="#ws-intro-api"></a><a class="link" href="#ws-intro-api">WebSocket APIs</a></h3>
<div class="paragraph">
<p>APIs and libraries to implement your WebSockets using Jetty.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Jetty WebSocket API</dt>
<dd>
<p>The basic common API for creating and working with WebSockets using Jetty.</p>
</dd>
<dt class="hdlist1">Jetty WebSocket Server API</dt>
<dd>
<p>Write WebSocket Server Endpoints for Jetty.</p>
</dd>
<dt class="hdlist1">Jetty WebSocket Client API</dt>
<dd>
<p>Connect to WebSocket servers with Jetty.</p>
</dd>
<dt class="hdlist1">Java WebSocket Client API</dt>
<dd>
<p>The new standard Java WebSocket Client API (<code>javax.websocket</code>) [JSR-356]</p>
</dd>
<dt class="hdlist1">Java WebSocket Server API</dt>
<dd>
<p>The new standard Java WebSocket Server API (<code>javax.websocket.server</code>) [JSR-356]</p>
</dd>
</dl>
</div>
</div>
<div class="sect2">
<h3 id="_enabling-websocket"><a class="anchor" href="#_enabling-websocket"></a><a class="link" href="#_enabling-websocket">Enabling WebSocket</a></h3>
<div class="paragraph">
<p>To enable Websocket, you need to enable the <code>websocket</code> <a href="#enabling-modules">module</a>.</p>
</div>
<div class="paragraph">
<p>Once this module is enabled for your Jetty base, it will apply to all webapps deployed to that base. If you want to be more selective about which webapps use Websocket, then you can:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Disable Websocket for a particular webapp</dt>
<dd>
<p>You can disable jsr-356 for a particular webapp by setting the <a href="#context_attributes">context attribute</a> <code>org.eclipse.jetty.websocket.javax</code> to <code>false</code>.
This will mean that websockets are not available to your webapp, however deployment time scanning for websocket-related classes such as endpoints will still occur.
This can be a significant impost if your webapp contains a lot of classes and/or jar files.
To completely disable websockets and avoid all setup costs associated with it for a particular webapp, use instead the context attribute <code>org.eclipse.jetty.containerInitializerExclusionPattern</code>, described next, which allows you to exclude the websocket ServletContainerInitializer that causes the scanning.</p>
</dd>
<dt class="hdlist1">Completely disable Websocket for a particular webapp</dt>
<dd>
<p>Set the <code>org.eclipse.jetty.containerInitializerExclusionPattern</code> <a href="#context_attributes">context attribute</a> to include <code>org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer</code>.
Here&#8217;s an example of doing this in code, although you can do the <a href="#intro-jetty-configuration-webapps">same in xml</a>:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">WebAppContext context = new WebAppContext();
context.setAttribute("org.eclipse.jetty.containerInitializerExclusionPattern",
"org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer|com.acme.*");</code></pre>
</div>
</div>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="websocket-jetty"><a class="anchor" href="#websocket-jetty"></a><a class="link" href="#websocket-jetty">Jetty Websocket API</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>These pages are works in progress that have not been moved to their respective sections yet.</p>
</div>
<div class="paragraph">
<p>Unresolved directive in websockets/jetty/chapter.adoc - include::websocket-jetty-api.adoc[]
Unresolved directive in websockets/jetty/chapter.adoc - include::websocket-jetty-api-events.adoc[]
Unresolved directive in websockets/jetty/chapter.adoc - include::websocket-jetty-api-session.adoc[]
Unresolved directive in websockets/jetty/chapter.adoc - include::websocket-jetty-api-send-message.adoc[]
Unresolved directive in websockets/jetty/chapter.adoc - include::websocket-jetty-api-annotations.adoc[]
Unresolved directive in websockets/jetty/chapter.adoc - include::websocket-jetty-api-listener.adoc[]
Unresolved directive in websockets/jetty/chapter.adoc - include::websocket-jetty-api-adapter.adoc[]
Unresolved directive in websockets/jetty/chapter.adoc - include::websocket-jetty-server-api.adoc[]
Unresolved directive in websockets/jetty/chapter.adoc - include::websocket-jetty-client-api.adoc[]</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="websocket-java"><a class="anchor" href="#websocket-java"></a><a class="link" href="#websocket-java">Java Websocket API</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>JSR-356 These pages are works in progress that have not been moved to
their respective sections yet.</p>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Version 10.0.0-SNAPSHOT<br>
Last updated 2020-10-01 02:22:39 UTC
</div>
</div>
</body>
</html>