| <?xml version="1.0"?> | 
 | <!-- | 
 |  | 
 |     Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved. | 
 |  | 
 |     This program and the accompanying materials are made available under the | 
 |     terms of the Eclipse Public License v. 2.0, which is available at | 
 |     http://www.eclipse.org/legal/epl-2.0. | 
 |  | 
 |     This Source Code may also be made available under the following Secondary | 
 |     Licenses when the conditions for such availability set forth in the | 
 |     Eclipse Public License v. 2.0 are satisfied: GNU General Public License, | 
 |     version 2 with the GNU Classpath Exception, which is available at | 
 |     https://www.gnu.org/software/classpath/license.html. | 
 |  | 
 |     SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | 
 |  | 
 | --> | 
 |  | 
 | <!DOCTYPE chapter [<!ENTITY % ents SYSTEM "jersey.ent" > %ents; | 
 |     <!ENTITY jersey.github.osgi.webapp.example.link "<link xlink:href='&jersey.github.examples.uri;/osgi-helloworld-webapp'>WAB Example</link>"> | 
 |     <!ENTITY jersey.github.osgi.httpservice.example.link "<link xlink:href='&jersey.github.examples.uri;/osgi-http-service'>HTTP Service example</link>"> | 
 | ]> | 
 | <chapter xmlns="http://docbook.org/ns/docbook" | 
 |          version="5.0" | 
 |          xml:lang="en" | 
 |          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | 
 |          xmlns:xlink="http://www.w3.org/1999/xlink" | 
 |          xsi:schemaLocation="http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd" | 
 |          xml:id="deployment"> | 
 |     <title>Application Deployment and Runtime Environments</title> | 
 |     <section xml:id="deployment.intro"> | 
 |         <title>Introduction</title> | 
 |         <para> | 
 |             This chapter is an overview of various server-side environments currently capable of running JAX-RS applications | 
 |             on top of Jersey server runtime. Jersey supports wide range of server environments from lightweight http containers | 
 |             up to full-fledged Java/Jakarta EE servers. Jersey applications can also run in an OSGi runtime. | 
 |             The way how the application is published depends on whether the application shall run in a Java SE environment or | 
 |             within a container. | 
 |         </para> | 
 |         <note> | 
 |             <para> | 
 |                 This chapter is focused on server-side Jersey deployment models. The | 
 |                 <link linkend="client">Jersey client runtime</link> does | 
 |                 not have any specific container requirements and runs in plain Java SE 8 or higher runtime. | 
 |             </para> | 
 |         </note> | 
 |     </section> | 
 |     <section xml:id="environmenmt.appmodel"> | 
 |         <title>JAX-RS Application Model</title> | 
 |         <para> | 
 |             JAX-RS provides a deployment agnostic abstract class &jaxrs.core.Application; | 
 |             for declaring root resource and provider classes, and root resource and provider singleton instances. | 
 |             A Web service may extend this class to declare root resource and provider classes. For example, | 
 |             <example> | 
 |                 <title>Deployment agnostic application model</title> | 
 |                 <programlisting language="java" linenumbering="numbered">public class MyApplication extends Application { | 
 |     @Override | 
 |     public Set<Class<?>> getClasses() { | 
 |         Set<Class<?>> s = new HashSet<Class<?>>(); | 
 |         s.add(HelloWorldResource.class); | 
 |         return s; | 
 |     } | 
 | }</programlisting> | 
 |             </example> | 
 |         </para> | 
 |         <para> | 
 |             Alternatively it is possible to reuse &jersey.server.ResourceConfig; - Jersey's own implementations | 
 |             of &lit.jaxrs.core.Application; class. This class can either be directly instantiated and then configured | 
 |             or it can be extended and the configuration code placed into the constructor of the extending class. The | 
 |             approach typically depends on the chosen deployment runtime. | 
 |         </para> | 
 |         <para> | 
 |             Compared to &lit.jaxrs.core.Application;, the &lit.jersey.server.ResourceConfig; provides advanced capabilities | 
 |             to simplify registration of JAX-RS components, such as scanning for root resource and provider classes in a provided | 
 |             classpath or a set of package names etc. All JAX-RS component classes that are either manually registered or | 
 |             found during scanning are automatically added to the set of classes that are returned by | 
 |             <literal>getClasses</literal>. For example, the following application class that extends from | 
 |             &lit.jersey.server.ResourceConfig; scans during deployment for JAX-RS components in packages | 
 |             <literal>org.foo.rest</literal> and <literal>org.bar.rest</literal>: | 
 |             <note> | 
 |                 <para> | 
 |                     <emphasis>Package scanning</emphasis> ignores an inheritance and therefore &lit.jaxrs.Path; annotation | 
 |                     on parent classes and interfaces will be ignored. These classes won't be registered as the JAX-RS component | 
 |                     classes. | 
 |                 </para> | 
 |             </note> | 
 |             <example> | 
 |                 <title>Reusing Jersey implementation in your custom application model</title> | 
 |                 <programlisting language="java" linenumbering="numbered">public class MyApplication extends ResourceConfig { | 
 |     public MyApplication() { | 
 |         packages("org.foo.rest;org.bar.rest"); | 
 |     } | 
 | }</programlisting> | 
 |             </example> | 
 |         </para> | 
 |         <note> | 
 |             <para> | 
 |                 Later in this chapter, the term <emphasis>&lit.jaxrs.core.Application; subclass</emphasis> is frequently used. | 
 |                 Whenever used, this term refers to the JAX-RS Application Model explained above. | 
 |             </para> | 
 |         </note> | 
 |     </section> | 
 |  | 
 |     <section xml:id="deployment.autodiscoverable"> | 
 |         <title>Auto-Discoverable Features</title> | 
 |  | 
 |         <para> | 
 |             By default Jersey 3.x does not implicitly register any extension features from the modules available on the | 
 |             classpath, unless explicitly stated otherwise in the documentation of each particular extension. | 
 |             Users are expected to explicitly register the extension &jaxrs.core.Feature;s using their | 
 |             &lit.jaxrs.core.Application; subclass. | 
 |             For a few Jersey provided modules however there is no need to explicitly register their extension | 
 |             &lit.jaxrs.core.Feature;s as these are discovered and registered in the &jaxrs.core.Configuration; (on client/server) | 
 |             automatically by Jersey runtime whenever the modules implementing these features are present on the classpath | 
 |             of the deployed JAX-RS application. The modules that are automatically discovered include: | 
 |  | 
 |             <itemizedlist> | 
 |                 <listitem> | 
 |                     <para>JSON binding feature from <literal>jersey-media-moxy</literal></para> | 
 |                 </listitem> | 
 |                 <listitem> | 
 |                     <para><literal>jersey-media-json-processing</literal></para> | 
 |                 </listitem> | 
 |                 <listitem> | 
 |                     <para><literal>jersey-bean-validation</literal></para> | 
 |                 </listitem> | 
 |             </itemizedlist> | 
 |         </para> | 
 |         <para> | 
 |             Besides these modules there are also few features/providers present in <literal>jersey-server</literal> module that | 
 |             are discovered by this mechanism and their availability is affected by Jersey auto-discovery support configuration | 
 |             (see <xref linkend="deployment.autodiscovery.config" />), namely: | 
 |  | 
 |             <itemizedlist> | 
 |                 <listitem> | 
 |                     <para>&jersey.server.WadlFeature; - enables WADL processing.</para> | 
 |                 </listitem> | 
 |                 <listitem> | 
 |                     <para>&jersey.server.UriConnegFilter; - a URI-based content negotiation filter.</para> | 
 |                 </listitem> | 
 |             </itemizedlist> | 
 |  | 
 |             Almost all Jersey auto-discovery implementations have <code>AutoDiscoverable.DEFAULT_PRIORITY</code> | 
 |             <literal>@Priority</literal> set. | 
 |         </para> | 
 |  | 
 |         <note> | 
 |             <para> | 
 |                 Auto discovery functionality is in Jersey supported by implementing an internal | 
 |                 <literal>AutoDiscoverable</literal> Jersey SPI. This interface is not public at the moment, | 
 |                 and is subject to change in the future, so be careful when trying to use it. | 
 |             </para> | 
 |         </note> | 
 |  | 
 |         <section xml:id="deployment.autodiscovery.config"> | 
 |             <title>Configuring Feature Auto-discovery Mechanism</title> | 
 |  | 
 |             <para> | 
 |                 The mechanism of feature auto-discovery in Jersey that described above is enabled by default. It can be | 
 |                 disabled by using special (common/server/client) properties: | 
 |  | 
 |                 <itemizedlist> | 
 |                     <title>Common auto discovery properties</title> | 
 |  | 
 |                     <listitem> | 
 |                         <para>&jersey.common.CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE;</para> | 
 |                         <para>When set, disables auto discovery globally on client/server.</para> | 
 |                     </listitem> | 
 |                     <listitem> | 
 |                         <para>&jersey.common.CommonProperties.JSON_PROCESSING_FEATURE_DISABLE;</para> | 
 |                         <para>When set, disables configuration of Json Processing (JSR-353) feature.</para> | 
 |                     </listitem> | 
 |                     <listitem> | 
 |                         <para>&jersey.common.CommonProperties.MOXY_JSON_FEATURE_DISABLE;</para> | 
 |                         <para>When set, disables configuration of MOXy Json feature.</para> | 
 |                     </listitem> | 
 |                 </itemizedlist> | 
 |  | 
 |                 For each of these properties there is a client/server counter-part that is only honored by the Jersey | 
 |                 client or server runtime respectively (see &jersey.client.ClientProperties;/&jersey.server.ServerProperties;). | 
 |                 When set, each of these client/server specific auto-discovery related properties overrides the value of the | 
 |                 related common property. | 
 |             </para> | 
 |  | 
 |             <note> | 
 |                 <para> | 
 |                     In case an auto-discoverable mechanism (in general or for a specific feature) is disabled, then all the | 
 |                     features, components and/or properties, registered by default using the auto-discovery mechanism have | 
 |                     to be registered manually. | 
 |                 </para> | 
 |             </note> | 
 |         </section> | 
 |  | 
 |     </section> | 
 |  | 
 |     <section xml:id="deployment.classpath-scanning"> | 
 |         <title>Configuring the Classpath Scanning</title> | 
 |  | 
 |         <para> | 
 |             Jersey uses a common Java Service Provider mechanism to obtain all service implementations. It means that Jersey | 
 |             scans the whole class path to find appropriate <literal>META-INF/services/</literal> files. The class path scanning | 
 |             may be time consuming. The more jar or war files on the classpath the longer the scanning time. | 
 |             In use cases where you need to save every millisecond of application bootstrap time, | 
 |             you may typically want to disable the services provider lookup in Jersey. | 
 |  | 
 |             <itemizedlist> | 
 |                 <title>List of SPIs recognized by Jersey</title> | 
 |                 <listitem> | 
 |                     <para><literal>AutoDiscoverable</literal> (server, client) - | 
 |                         it means if you disable service loading the AutoDiscoverable feature is automatically disabled too</para> | 
 |                 </listitem> | 
 |                 <listitem> | 
 |                     <para><literal>ForcedAutoDiscoverable</literal> (server, client) - | 
 |                         Jersey always looks for these auto discoverable features even if the service loading is disabled</para> | 
 |                 </listitem> | 
 |                 <listitem> | 
 |                     <para><literal>HeaderDelegateProvider</literal> (server, client)</para> | 
 |                 </listitem> | 
 |                 <listitem> | 
 |                     <para><literal>ComponentProvider</literal> (server)</para> | 
 |                 </listitem> | 
 |                 <listitem> | 
 |                     <para><literal>ContainerProvider</literal> (server)</para> | 
 |                 </listitem> | 
 |                 <listitem> | 
 |                     <para><literal>AsyncContextDelegateProvider</literal> (server/Servlet)</para> | 
 |                 </listitem> | 
 |             </itemizedlist> | 
 |  | 
 |             <itemizedlist> | 
 |                 <title>List of additional SPIs recognized by Jersey in case the <literal>metainf-services</literal> module is on the classpath</title> | 
 |                 <listitem> | 
 |                     <para><literal>MessageBodyReader</literal> (server, client)</para> | 
 |                 </listitem> | 
 |                 <listitem> | 
 |                     <para><literal>MessageBodyWriter</literal> (server, client)</para> | 
 |                 </listitem> | 
 |                 <listitem> | 
 |                     <para><literal>ExceptionMapper</literal> (server, client)</para> | 
 |                 </listitem> | 
 |             </itemizedlist> | 
 |  | 
 |             Since it is possible to configure all SPI implementation classes or instances manually in your | 
 |             &lit.jaxrs.core.Application; subclass, disabling services lookup in Jersey does not affect any | 
 |             functionality of Jersey core modules and extensions and can save dozens of ms during application | 
 |             initialization in exchange for a more verbose application configuration code. | 
 |         </para> | 
 |  | 
 |         <para> | 
 |             The services lookup in Jersey (enabled by default) can be disabled via a dedicated | 
 |             &jersey.common.CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE; property. | 
 |             There is a client/server counter-part that only disables the feature on the client or server respectively: | 
 |             &jersey.client.ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE;/&jersey.server.ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE;. | 
 |             As in all other cases, the client/server specific properties overrides the value of the related common property, | 
 |             when set. | 
 |         </para> | 
 |  | 
 |         <para> | 
 |             For example, following code snippet disables service provider lookup and manually registers implementations | 
 |             of different JAX-RS and Jersey provider types | 
 |             (&jaxrs.container.ContainerRequestFilter;, &jaxrs.core.Feature;, &jersey.server.spi.ComponentProvider; | 
 |             and &jersey.server.spi.ContainerProvider;): | 
 |             <example> | 
 |                 <title>Registering SPI implementations using ResourceConfig</title> | 
 |                 <programlisting language="java" linenumbering="numbered">ResourceConfig resourceConfig = new ResourceConfig(MyResource.class); | 
 | resourceConfig.register(org.glassfish.jersey.server.filter.UriConnegFilter.class); | 
 | resourceConfig.register(org.glassfish.jersey.server.validation.ValidationFeature.class); | 
 | resourceConfig.register(org.glassfish.jersey.server.spring.SpringComponentProvider.class); | 
 | resourceConfig.register(org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainerProvider.class); | 
 | resourceConfig.property(ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE, true);</programlisting> | 
 |             </example> | 
 |  | 
 |             Similarly, in scenarios where the deployment model requires extending the &lit.jaxrs.core.Application; subclass | 
 |             (e.g. in all Servlet container deployments), the following code could be used to achieve the same application | 
 |             configuration: | 
 |  | 
 |             <example> | 
 |                 <title>Registering SPI implementations using &lit.jersey.server.ResourceConfig; subclass</title> | 
 |                 <programlisting language="java" linenumbering="numbered">public class MyApplication extends ResourceConfig { | 
 |     public MyApplication() { | 
 |         register(org.glassfish.jersey.server.filter.UriConnegFilter.class); | 
 |         register(org.glassfish.jersey.server.validation.ValidationFeature.class); | 
 |         register(org.glassfish.jersey.server.spring.SpringComponentProvider.class); | 
 |         register(org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainerProvider.class); | 
 |         property(ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE, true); | 
 |     } | 
 | }</programlisting> | 
 |             </example> | 
 |         </para> | 
 |     </section> | 
 |  | 
 |     <section xml:id="deployment.javase"> | 
 |         <title>Java SE Deployment Environments</title> | 
 |  | 
 |         <section xml:id="deployment.http"> | 
 |             <title>HTTP servers</title> | 
 |             <para> | 
 |                 Java based HTTP servers represent a minimalistic and flexible way of deploying Jersey application. | 
 |                 The HTTP servers are usually embedded in the application and configured and started programmatically. | 
 |                 In general, Jersey container for a specific HTTP server provides a custom factory method that returns | 
 |                 a correctly initialized HTTP server instance. | 
 |             </para> | 
 |  | 
 |             <section xml:id="deployment.http.jdk"> | 
 |                 <title>JDK Http Server</title> | 
 |                 <para> | 
 |                     Starting with Java SE 6, Java runtime ships with a built-in lightweight HTTP server. Jersey offers | 
 |                     integration with this Java SE HTTP server through the <literal>jersey-container-jdk-http</literal> | 
 |                     container extension module. | 
 |                     Instead of creating the <literal>&jdk6.HttpServer;</literal> instance directly, use the | 
 |                     <literal>createHttpServer()</literal> method of <literal>&jersey.jdkhttp.JdkHttpServerFactory;</literal>, | 
 |                     which creates the <literal>HttpServer</literal> instance configured as a Jersey container and | 
 |                     initialized with the supplied &lit.jaxrs.core.Application; subclass. | 
 |                 </para> | 
 |                 <para> | 
 |                     Creating new Jersey-enabled jdk http server is as easy as: | 
 |  | 
 |                     <example> | 
 |                         <title>Using Jersey with JDK HTTP Server</title> | 
 |                         <programlisting language="java" linenumbering="numbered"> URI baseUri = UriBuilder.fromUri("http://localhost/").port(9998).build(); | 
 | ResourceConfig config = new ResourceConfig(MyResource.class); | 
 | HttpServer server = JdkHttpServerFactory.createHttpServer(baseUri, config);</programlisting> | 
 |  | 
 |                         A JDK HTTP Container dependency needs to be added: | 
 |  | 
 |                         <programlisting language="xml"><dependency> | 
 |     <groupId>org.glassfish.jersey.containers</groupId> | 
 |     <artifactId>jersey-container-jdk-http</artifactId> | 
 |     <version>&version;</version> | 
 | </dependency></programlisting> | 
 |                     </example> | 
 |                 </para> | 
 |             </section> | 
 |  | 
 |             <section xml:id="deployment.http.grizzly"> | 
 |                 <title>Grizzly HTTP Server</title> | 
 |                 <para>&grizzly.link; is a multi-protocol framework built on top of Java &jdk6.NIO;. Grizzly aims to simplify | 
 |                     development of robust and scalable servers. | 
 |                     Jersey provides a container extension module that enables support for using Grizzly as a plain vanilla | 
 |                     HTTP container that runs JAX-RS applications. Starting a Grizzly server to run | 
 |                     a JAX-RS or Jersey application is one of the most lightweight and easy ways how to expose a functional | 
 |                     RESTful services application. | 
 |                 </para> | 
 |                 <para> | 
 |                     Grizzly HTTP container supports injection of Grizzly-specific | 
 |                     <literal>org.glassfish.grizzly.http.server.Request</literal> and | 
 |                     <literal>org.glassfish.grizzly.http.server.Response</literal> instances into JAX-RS and Jersey | 
 |                     application resources and providers. However, since Grizzly <literal>Request</literal> is not proxiable, | 
 |                     the injection of Grizzly <literal>Request</literal> into singleton (by default) JAX-RS / Jersey providers | 
 |                     is only possible via <literal>jakarta.inject.Provider</literal> instance. (Grizzly <literal>Response</literal> | 
 |                     does not suffer the same restriction.) | 
 |                 </para> | 
 |  | 
 |                 <example> | 
 |                     <title>Using Jersey with Grizzly HTTP Server</title> | 
 |                     <programlisting language="java" linenumbering="numbered">URI baseUri = UriBuilder.fromUri("http://localhost/").port(9998).build(); | 
 |     ResourceConfig config = new ResourceConfig(MyResource.class); | 
 |     HttpServer server = GrizzlyHttpServerFactory.createHttpServer(baseUri, config);</programlisting> | 
 |  | 
 |                     The container extension module dependency to be added is: | 
 |  | 
 |                     <programlisting language="xml"><dependency> | 
 |     <groupId>org.glassfish.jersey.containers</groupId> | 
 |     <artifactId>jersey-container-grizzly2-http</artifactId> | 
 |     <version>&version;</version> | 
 | </dependency></programlisting> | 
 |                 </example> | 
 |                 <note> | 
 |                     <para> | 
 |                         Jersey uses Grizzly extensively in the project unit and end-to-end tests via | 
 |                         <link linkend="test-framework">test framework</link>. | 
 |                     </para> | 
 |                 </note> | 
 |             </section> | 
 |  | 
 |             <section xml:id="deployment.http.simple"> | 
 |                 <title>Simple server</title> | 
 |                 <para> | 
 |                     <link xlink:href='http://www.simpleframework.org/'>Simple</link> is a framework which allows developers | 
 |                     to create a HTTP server instance and embed it within | 
 |                     an application. Again, creating the server instance is achieved by calling a factory method from the | 
 |                     <literal>jersey-container-simple-http</literal> container extension module. | 
 |                 </para> | 
 |                 <para> | 
 |                     Simple framework HTTP container supports injection of Simple framework-specific | 
 |                     <literal>org.simpleframework.http.Request</literal> and | 
 |                     <literal>org.simpleframework.http.Response</literal> instances into JAX-RS and Jersey | 
 |                     application resources and providers. | 
 |                 </para> | 
 |  | 
 |                 <example> | 
 |                     <title>Using Jersey with the Simple framework</title> | 
 |                     <programlisting language="java" linenumbering="numbered">URI baseUri = UriBuilder.fromUri("http://localhost/").port(9998).build(); | 
 |     ResourceConfig config = new ResourceConfig(MyResource.class); | 
 |     SimpleContainer server = SimpleContainerFactory.create(baseUri, config);</programlisting> | 
 |  | 
 |                     The necessary container extension module dependency in this case is: | 
 |  | 
 |                     <programlisting language="xml"><dependency> | 
 |     <groupId>org.glassfish.jersey.containers</groupId> | 
 |     <artifactId>jersey-container-simple-http</artifactId> | 
 |     <version>&version;</version> | 
 | </dependency></programlisting> | 
 |                 </example> | 
 |                 <note> | 
 |                     <para> | 
 |                         Simple framework HTTP container does not support deployment on context paths other than | 
 |                         root path ("<literal>/</literal>"). Non-root context path is ignored during deployment. | 
 |                     </para> | 
 |                 </note> | 
 |             </section> | 
 |  | 
 |             <section xml:id="deployment.http.jetty"> | 
 |                 <title>Jetty HTTP Server</title> | 
 |                 <para> | 
 |                     Jetty is a popular Servlet container and HTTP server. We will not look into Jetty's capabilities as a | 
 |                     Servlet container (although we are using it in our tests and examples), because there is nothing specific | 
 |                     to Jetty when using a Servlet-based deployment model, which is extensively described later in our | 
 |                     <xref linkend="deployment.servlet"/> section. We will here only focus on describing how to use | 
 |                     Jetty's HTTP server. | 
 |                 </para> | 
 |                 <para> | 
 |                     Jetty HTTP container supports injection of Jetty-specific | 
 |                     <literal>org.eclipse.jetty.server.Request</literal> and | 
 |                     <literal>org.eclipse.jetty.server.Response</literal> instances into JAX-RS and Jersey | 
 |                     application resources and providers. However, since Jetty HTTP <literal>Request</literal> is not proxiable, | 
 |                     the injection of Jetty <literal>Request</literal> into singleton (by default) JAX-RS / Jersey providers | 
 |                     is only possible via <literal>jakarta.inject.Provider</literal> instance. (Jetty <literal>Response</literal> | 
 |                     does not suffer the same restriction.) | 
 |                 </para> | 
 |  | 
 |                 <example> | 
 |                     <title>Using Jersey with Jetty HTTP Server</title> | 
 |  | 
 |                     <programlisting language="java" linenumbering="numbered">URI baseUri = UriBuilder.fromUri("http://localhost/").port(9998).build(); | 
 | ResourceConfig config = new ResourceConfig(MyResource.class); | 
 | Server server = JettyHttpContainerFactory.createServer(baseUri, config);</programlisting> | 
 |  | 
 |                     And, of course, we add the necessary container extension module dependency: | 
 |  | 
 |                     <programlisting language="xml" linenumbering="numbered"><dependency> | 
 |     <groupId>org.glassfish.jersey.containers</groupId> | 
 |     <artifactId>jersey-container-jetty-http</artifactId> | 
 |     <version>&version;</version> | 
 | </dependency></programlisting> | 
 |                 </example> | 
 |                 <note> | 
 |                     <para> | 
 |                         Jetty HTTP container does not support deployment on context paths other than | 
 |                         root path ("<literal>/</literal>"). Non-root context path is ignored during deployment. | 
 |                     </para> | 
 |                 </note> | 
 |             </section> | 
 |  | 
 |             <section xml:id="deployment.http.netty"> | 
 |                 <title>Netty HTTP Server</title> | 
 |                 <para> | 
 |                     Netty is a NIO client server framework which enables quick and easy development of network | 
 |                     applications such as protocol servers and clients. Jersey supports Netty as a container and | 
 |                     as a client connector - this chapter will present how to use the container. | 
 |                 </para> | 
 |  | 
 |                 <example> | 
 |                     <title>Using Jersey with Netty HTTP Server</title> | 
 |  | 
 |                     <programlisting language="java" linenumbering="numbered">URI baseUri = UriBuilder.fromUri("http://localhost/").port(9998).build(); | 
 | ResourceConfig resourceConfig = new ResourceConfig(HelloWorldResource.class); | 
 | Channel server = NettyHttpContainerProvider.createServer(baseUri, resourceConfig, false);</programlisting> | 
 |  | 
 |                     And, of course, we add the necessary container extension module dependency: | 
 |  | 
 |                     <programlisting language="xml" linenumbering="numbered"><dependency> | 
 |     <groupId>org.glassfish.jersey.containers</groupId> | 
 |     <artifactId>jersey-container-netty-http</artifactId> | 
 |     <version>&version;</version> | 
 | </dependency></programlisting> | 
 |                 </example> | 
 |                 <note> | 
 |                     <para> | 
 |                         Netty HTTP container does not support deployment on context paths other than | 
 |                         root path ("<literal>/</literal>"). Non-root context path is ignored during deployment. | 
 |                     </para> | 
 |                 </note> | 
 |             </section> | 
 |         </section> | 
 |     </section> | 
 |  | 
 |     <section xml:id="deployment.jaxrs.endpoint"> | 
 |         <title>Creating programmatic JAX-RS endpoint</title> | 
 |         <para> | 
 |             JAX-RS specification also defines the ability to programmatically create a JAX-RS application endpoint | 
 |             (i.e. container) for any instance of a &lit.jaxrs.core.Application; subclass. For example, Jersey supports | 
 |             creation of <link xlink:href="http://grizzly.java.net/">Grizzly</link> <literal>HttpHandler</literal> instance | 
 |             as follows: | 
 |  | 
 |             <programlisting language="java">HttpHandler endpoint = RuntimeDelegate.getInstance() | 
 |         .createEndpoint(new MyApplication(), HttpHandler.class);</programlisting> | 
 |  | 
 |             Once the Grizzly <literal>HttpHandler</literal> endpoint is created, it can be used for in-process deployment | 
 |             to a specific base URL. | 
 |         </para> | 
 |     </section> | 
 |  | 
 |     <section xml:id="deployment.servlet"> | 
 |         <title>Servlet-based Deployment</title> | 
 |  | 
 |         <para> | 
 |             In a Servlet container, JAX-RS defines multiple deployment options depending on the Servlet API version supported by | 
 |             the Servlet container. Following sections describe these options in detail. | 
 |         </para> | 
 |  | 
 |         <section xml:id="deployment.servlet.2"> | 
 |             <title>Servlet 2.x way</title> | 
 |             <para> | 
 |                 Jersey integrates with any Servlet containers supporting at least Servlet 2.5 specification. Running on a | 
 |                 Servlet container that supports Servlet API 5.0 it's required to adjust this approach to jakartified Servlet API. | 
 |                 This includes Jakarta EE 9 namespaces which is applied since the 5.x Servlet API version. | 
 |                 In this section we will focus on the basic deployment models available in any Servlet 2.5 container. | 
 |             </para> | 
 |             <para> | 
 |                 Using Servlet 2.x way, you have to explicitly declare the Jersey container Servlet in your Web application's | 
 |                 <literal>web.xml</literal> deployment descriptor file. | 
 |  | 
 |                 <example> | 
 |                     <title>Hooking up Jersey as a Servlet</title> | 
 |                     <programlisting language="xml" linenumbering="numbered"><web-app> | 
 |                         <servlet> | 
 |                         <servlet-name>MyApplication</servlet-name> | 
 |                         <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> | 
 |                         <init-param> | 
 |                         ... | 
 |                         </init-param> | 
 |                         </servlet> | 
 |                         ... | 
 |                         <servlet-mapping> | 
 |                         <servlet-name>MyApplication</servlet-name> | 
 |                         <url-pattern>/myApp/*</url-pattern> | 
 |                         </servlet-mapping> | 
 |                         ... | 
 |                         </web-app></programlisting> | 
 |                 </example> | 
 |  | 
 |                 Alternatively, you can register Jersey container as a <emphasis>filter</emphasis>: | 
 |  | 
 |                 <example> | 
 |                     <title>Hooking up Jersey as a Servlet Filter</title> | 
 |                     <programlisting language="xml" linenumbering="numbered"><web-app> | 
 |                         <filter> | 
 |                         <filter-name>MyApplication</filter-name> | 
 |                         <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class> | 
 |                         <init-param> | 
 |                         ... | 
 |                         </init-param> | 
 |                         </filter> | 
 |                         ... | 
 |                         <filter-mapping> | 
 |                         <filter-name>MyApplication</filter-name> | 
 |                         <url-pattern>/myApp/*</url-pattern> | 
 |                         </filter-mapping> | 
 |                         ... | 
 |                         </web-app></programlisting> | 
 |                 </example> | 
 |             </para> | 
 |  | 
 |             <important> | 
 |                 <para> | 
 |                     Since pure Servlet 2.x way deployment does not provide a way how to programmatically read the filter | 
 |                     mappings in order to make application with filter work correctly, the context path of the app needs | 
 |                     to be defined using init parameter <literal>jersey.config.servlet.filter.contextPath</literal> for | 
 |                     <literal>jersey-container-servlet-core</literal>. | 
 |                     Or <literal>jersey-container-servlet</literal> shall be used. | 
 |                 </para> | 
 |             </important> | 
 |  | 
 |             <para> | 
 |                 The content of the <literal><init-param></literal> element will vary depending on the way you decide to | 
 |                 configure Jersey resources. | 
 |             </para> | 
 |  | 
 |             <section xml:id="deployment.servlet.2.application"> | 
 |                 <title>Custom &lit.jaxrs.core.Application; subclass</title> | 
 |                 <para> | 
 |                     If you extend the &jaxrs.core.Application; class to provide the list of relevant root resource | 
 |                     classes (<literal>getClasses()</literal>) and singletons (<literal>getSingletons()</literal>), | 
 |                     i.e. your JAX-RS application model, you then need to register it in your web application | 
 |                     <literal>web.xml</literal> deployment descriptor using a Servlet or Servlet filter initialization | 
 |                     parameter with a name of  <literal>jakarta.ws.rs.Application</literal> [<emphasis>sic</emphasis>] as follows: | 
 |  | 
 |                     <example> | 
 |                         <title> | 
 |                             Configuring Jersey container Servlet or Filter to use custom &lit.jaxrs.core.Application; subclass | 
 |                         </title> | 
 |                         <programlisting language="xml" linenumbering="numbered"><init-param> | 
 |                             <param-name>jakarta.ws.rs.Application</param-name> | 
 |                             <param-value>org.foo.MyApplication</param-value> | 
 |                             </init-param></programlisting> | 
 |                     </example> | 
 |  | 
 |                     Jersey will consider all the classes returned by <literal>getClasses()</literal> and | 
 |                     <literal>getSingletons()</literal> methods of your &lit.jaxrs.core.Application; implementation. | 
 |                 </para> | 
 |  | 
 |                 <note> | 
 |                     <para> | 
 |                         The name of the configuration property as defined by JAX-RS specification is indeed | 
 |                         <literal>jakarta.ws.rs.Application</literal> and not <literal>jakarta.ws.rs.core.Application</literal> | 
 |                         as one might expect. | 
 |                     </para> | 
 |                 </note> | 
 |             </section> | 
 |  | 
 |             <section xml:id="deployment.servlet.2.package"> | 
 |                 <title>Jersey package scanning</title> | 
 |                 <para> | 
 |                     If there is no configuration properties to be set and deployed application consists only from resources | 
 |                     and providers stored in particular packages, you can instruct Jersey to scan these packages | 
 |                     and register any found resources and providers automatically: | 
 |  | 
 |                     <example> | 
 |                         <title>Configuring Jersey container Servlet or Filter to use package scanning</title> | 
 |                         <programlisting language="xml" linenumbering="numbered"><init-param> | 
 |                             <param-name>jersey.config.server.provider.packages</param-name> | 
 |                             <param-value> | 
 |                             org.foo.myresources,org.bar.otherresources | 
 |                             </param-value> | 
 |                             </init-param> | 
 |                             <init-param> | 
 |                             <param-name>jersey.config.server.provider.scanning.recursive</param-name> | 
 |                             <param-value>false</param-value> | 
 |                             </init-param></programlisting> | 
 |                     </example> | 
 |  | 
 |                     Jersey will automatically discover the resources and providers in the selected packages. | 
 |                     You can also decide whether Jersey should recursively scan also sub-packages by setting the | 
 |                     <literal>jersey.config.server.provider.scanning.recursive</literal> property. | 
 |                     The default value is <literal>true</literal>, i.e. the recursive scanning of sub-packages is enabled. | 
 |                 </para> | 
 |             </section> | 
 |  | 
 |             <section xml:id="deployment.servlet.2.classes"> | 
 |                 <title>Selecting concrete resource and provider classes</title> | 
 |  | 
 |                 <para> | 
 |                     While the above-mentioned package scanning is useful esp. for development and testing, you may want to | 
 |                     have a little bit more control when it comes to production deployment in terms of being able to enumerate | 
 |                     specific resource and provider classes. In Jersey it is possible to achieve this even without a need to | 
 |                     implement a custom &lit.jaxrs.core.Application; subclass. The specific resource and provider | 
 |                     fully-qualified class names can be provided in a comma-separated value of | 
 |                     <literal>jersey.config.server.provider.classnames</literal> initialization parameter. | 
 |                 </para> | 
 |                 <example> | 
 |                     <title>Configuring Jersey container Servlet or Filter to use a list of classes</title> | 
 |                     <programlisting language="xml" linenumbering="numbered"><init-param> | 
 |                         <param-name>jersey.config.server.provider.classnames</param-name> | 
 |                         <param-value> | 
 |                         org.foo.myresources.MyDogResource, | 
 |                         org.bar.otherresources.MyCatResource | 
 |                         </param-value> | 
 |                         </init-param></programlisting> | 
 |                 </example> | 
 |             </section> | 
 |  | 
 |             <note> | 
 |                 <para> | 
 |                     All of the techniques that have been described in this section also apply to Servlet containers that | 
 |                     support Servlet API 5.0 with jakartified adjustments. Newer Servlet specifications only give you additional | 
 |                     features, deployment options and more flexibility. | 
 |                 </para> | 
 |             </note> | 
 |         </section> | 
 |  | 
 |         <section xml:id="deployment.servlet.5"> | 
 |             <title>Servlet 5.x Container</title> | 
 |  | 
 |             <section xml:id="deployment.servlet.5.no.descriptor"> | 
 |                 <title>Descriptor-less deployment</title> | 
 |                 <para> | 
 |                     There are multiple deployment options in the Servlet 5.0 container for a JAX-RS application defined | 
 |                     by implementing a custom &jaxrs.core.Application; subclass. For simple deployments, no | 
 |                     <literal>web.xml</literal> is necessary at all. Instead, an &jaxrs.ApplicationPath; annotation can be used | 
 |                     to annotate the custom &jaxrs.core.Application; subclass and define the base application URI for all | 
 |                     JAX-RS resources configured in the application: | 
 |  | 
 |                     <example> | 
 |                         <title>Deployment of a JAX-RS application using &lit.jaxrs.ApplicationPath; with Servlet 5.0</title> | 
 |                         <programlisting language="java" linenumbering="numbered">@ApplicationPath("resources") | 
 | public class MyApplication extends ResourceConfig { | 
 |     public MyApplication() { | 
 |         packages("org.foo.rest;org.bar.rest"); | 
 |     } | 
 | }</programlisting> | 
 |                     </example> | 
 |                 </para> | 
 |  | 
 |                 <note> | 
 |                     <para> | 
 |                         There are many other convenience methods in the &lit.jersey.server.ResourceConfig; that can be used | 
 |                         in the constructor of your custom subclass to configure your JAX-RS application, | 
 |                         see &jersey.server.ResourceConfig; API documentation for more details. | 
 |                     </para> | 
 |                 </note> | 
 |  | 
 |                 <para> | 
 |                     In case you are not providing <literal>web.xml</literal> deployment descriptor for your maven-based web | 
 |                     application project, you need to configure your <literal>maven-war-plugin</literal> to ignore the missing | 
 |                     <literal>web.xml</literal> file by setting | 
 |                     <link xlink:href="http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html#failOnMissingWebXml">failOnMissingWebXml</link> | 
 |                     configuration property to &lit.false; in your project <literal>pom.xml</literal> file: | 
 |  | 
 |                     <example> | 
 |                         <title>Configuration of maven-war-plugin to ignore missing <literal>web.xml</literal></title> | 
 |                         <programlisting language="xml" linenumbering="numbered"><plugins> | 
 |     ... | 
 |     <plugin> | 
 |         <groupId>org.apache.maven.plugins</groupId> | 
 |         <artifactId>maven-war-plugin</artifactId> | 
 |         <version>2.3</version> | 
 |         <configuration> | 
 |             <failOnMissingWebXml>false</failOnMissingWebXml> | 
 |         </configuration> | 
 |     </plugin> | 
 |     ... | 
 | </plugins></programlisting> | 
 |                     </example> | 
 |                 </para> | 
 |             </section> | 
 |             <section xml:id="deployment.servlet.5.descriptor"> | 
 |                 <title>Deployment using <literal>web.xml</literal> descriptor</title> | 
 |  | 
 |                 <para> | 
 |                     Another Servlet 5.x container deployment model is to declare the JAX-RS application details in the | 
 |                     <literal>web.xml</literal>. | 
 |                     This is typically suitable for more complex deployments, e.g. when security model needs to be | 
 |                     properly defined or when additional initialization parameters have to be passed to Jersey runtime. | 
 |                     JAX-RS 1.1 and later specifies that a fully qualified name of the class that implements | 
 |                     &jaxrs.core.Application; may be used in the definition of a <literal><servlet-name></literal> | 
 |                     element as part of your application's <literal>web.xml</literal> deployment descriptor. | 
 |                 </para> | 
 |  | 
 |                 <para> | 
 |                     Following example illustrates this approach: | 
 |  | 
 |                     <example> | 
 |                         <title>Deployment of a JAX-RS application using <literal>web.xml</literal> with Servlet 5.0 | 
 |                         </title> | 
 |                         <programlisting language="xml" linenumbering="numbered"><web-app> | 
 |     <servlet> | 
 |         <servlet-name>org.foo.rest.MyApplication</servlet-name> | 
 |     </servlet> | 
 |     ... | 
 |     <servlet-mapping> | 
 |         <servlet-name>org.foo.rest.MyApplication</servlet-name> | 
 |         <url-pattern>/resources</url-pattern> | 
 |     </servlet-mapping> | 
 |     ... | 
 | </web-app></programlisting> | 
 |                     </example> | 
 |  | 
 |                     Note that the <literal><servlet-class></literal> element is omitted from the Servlet declaration. | 
 |                     This is a correct declaration utilizing the Servlet 5.0 extension mechanism described in detail in the | 
 |                     <xref linkend="deployment.servlet.5.pluggability"/> section. Also note that | 
 |                     <literal><servlet-mapping></literal> is used in the example to define the base resource URI. | 
 |                 </para> | 
 |  | 
 |             </section> | 
 |  | 
 |             <section xml:id="deployment.servlet.5.pluggability"> | 
 |                 <title>Servlet Pluggability Mechanism</title> | 
 |                 <para> | 
 |                     Servlet framework pluggability mechanism is a feature introduced with Servlet 3.0 specification. It | 
 |                     simplifies the configuration of various frameworks built on top of Servlets. Instead of having one | 
 |                     <literal>web.xml</literal> file working as a central point for all the configuration options, it is possible | 
 |                     to modularize the deployment descriptor by using the concept of so-called web fragments - several specific | 
 |                     and focused <literal>web.xml</literal> files. A set of web fragments basically builds up the final | 
 |                     deployment descriptor. This mechanism also provides SPI hooks that enable web frameworks to register | 
 |                     themselves in the Servlet container or customize the Servlet container deployment process in some other way. | 
 |                     This section describes how JAX-RS and Jersey leverage the Servlet pluggability mechanism. | 
 |                 </para> | 
 |  | 
 |                 <section xml:id="deployment.servlet.5.pluggability.noapp"> | 
 |                     <title>JAX-RS application without an &lit.jaxrs.core.Application; subclass</title> | 
 |  | 
 |                     If no &lit.jaxrs.core.Application; (or &lit.jersey.server.ResourceConfig;) subclass is present, | 
 |                     Jersey will dynamically add a Jersey container Servlet and set its name to | 
 |                     <literal>jakarta.ws.rs.core.Application</literal>. The web application path will be scanned and all the | 
 |                     root resource classes (the classes annotated with &jaxrs.Path; annotation) as well as any providers that are | 
 |                     annotated with &jaxrs.ext.Provider; annotation packaged with the application will be automatically registered | 
 |                     in the JAX-RS application. The web application has to be packaged with a deployment descriptor specifying | 
 |                     at least the mapping for the added <literal>jakarta.ws.rs.core.Application</literal> Servlet: | 
 |  | 
 |                     <example> | 
 |                         <title> | 
 |                             <literal>web.xml</literal> of a JAX-RS application without an &lit.jaxrs.core.Application; subclass | 
 |                         </title> | 
 |                         <programlisting language="xml" linenumbering="numbered"><web-app version="5.0" | 
 |     xmlns="https://jakarta.ee/xml/ns/jakartaee" | 
 |     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | 
 |  | 
 |     <!-- Servlet declaration can be omitted in which case | 
 |          it would be automatically added by Jersey --> | 
 |     <servlet> | 
 |         <servlet-name>jakarta.ws.rs.core.Application</servlet-name> | 
 |     </servlet> | 
 |  | 
 |     <servlet-mapping> | 
 |         <servlet-name>jakarta.ws.rs.core.Application</servlet-name> | 
 |         <url-pattern>/myresources/*</url-pattern> | 
 |     </servlet-mapping> | 
 | </web-app></programlisting> | 
 |                     </example> | 
 |                 </section> | 
 |  | 
 |                 <section xml:id="deployment.servlet.5.pluggability.app"> | 
 |                     <title>JAX-RS application with a custom &lit.jaxrs.core.Application; subclass</title> | 
 |  | 
 |                     <para> | 
 |                         When a custom &lit.jaxrs.core.Application; subclass is provided, in such case the Jersey server runtime | 
 |                         behavior depends od whether or not there is a Servlet defined to handle the application subclass. | 
 |                     </para> | 
 |  | 
 |                     <para> | 
 |                         If the <literal>web.xml</literal> contains a Servlet definition, that has an initialization parameter | 
 |                         <literal>jakarta.ws.rs.Application</literal> whose value is the fully qualified name of the | 
 |                         &lit.jaxrs.core.Application; subclass, Jersey does not perform any additional steps in such case. | 
 |                     </para> | 
 |  | 
 |                     <para> | 
 |                         If no such Servlet is defined to handle the custom &lit.jaxrs.core.Application; subclass, Jersey | 
 |                         dynamically adds a Servlet with a fully qualified name equal to the name of the provided | 
 |                         &lit.jaxrs.core.Application; subclass. To define the mapping for the added Servlet, you can either | 
 |                         annotate the custom &lit.jaxrs.core.Application; subclass with an &jaxrs.ApplicationPath; annotation | 
 |                         (Jersey will use the annotation value appended with <literal>/*</literal> to automatically define | 
 |                         the mapping for the Servlet), or specify the mapping for the Servlet in the | 
 |                         <literal>web.xml</literal> descriptor directly. | 
 |                     </para> | 
 |  | 
 |                     <para> | 
 |                         In the following example, let's assume that the JAX-RS application is defined using a custom | 
 |                         &lit.jaxrs.core.Application; subclass named <literal>org.example.MyApplication</literal>. | 
 |                         Then the <literal>web.xml</literal> file could have the following structure: | 
 |                         <example> | 
 |                             <programlisting language="xml" linenumbering="numbered"><web-app version="5.0" | 
 |     xmlns="https://jakarta.ee/xml/ns/jakartaee" | 
 |     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | 
 |  | 
 |     <!-- Servlet declaration can be omitted in which case | 
 |          it would be automatically added by Jersey --> | 
 |     <servlet> | 
 |         <servlet-name>org.example.MyApplication</servlet-name> | 
 |     </servlet> | 
 |  | 
 |     <!-- Servlet mapping can be omitted in case the Application subclass | 
 |          is annotated with @ApplicationPath annotation; in such case | 
 |          the mapping would be automatically added by Jersey --> | 
 |     <servlet-mapping> | 
 |         <servlet-name>org.example.MyApplication</servlet-name> | 
 |         <url-pattern>/myresources/*</url-pattern> | 
 |     </servlet-mapping> | 
 | </web-app></programlisting> | 
 |                         </example> | 
 |                     </para> | 
 |  | 
 |                     <note> | 
 |                         <para> | 
 |                             If your custom &lit.jaxrs.core.Application; subclass is packaged in the <literal>war</literal>, it defines | 
 |                             which resources will be taken into account. | 
 |                             <itemizedlist> | 
 |                                 <listitem> | 
 |                                     If both <literal>getClasses()</literal> and <literal>getSingletons()</literal> methods return | 
 |                                     an empty collection, then ALL the root resource classes and providers packaged in the web | 
 |                                     application archive will be used, Jersey will automatically discover them by scanning the | 
 |                                     <literal>.war</literal> file. | 
 |                                 </listitem> | 
 |                                 <listitem> | 
 |                                     If any of the two mentioned methods - <literal>getClasses()</literal> or | 
 |                                     <literal>getSingletons()</literal> returns a non-empty collection, only those classes and/or | 
 |                                     singletons will be published in the JAX-RS application. | 
 |                                 </listitem> | 
 |                             </itemizedlist> | 
 |                         </para> | 
 |                     </note> | 
 |  | 
 |                     <table pgwide="1" frame='all' xml:id="environment-table-pluggability"> | 
 |                         <title>Servlet 3 Pluggability Overview</title> | 
 |                         <tgroup cols='4' align='left' colsep='1' rowsep='1'> | 
 |                             <thead> | 
 |                                 <row> | 
 |                                     <entry>Condition</entry> | 
 |                                     <entry>Jersey action</entry> | 
 |                                     <entry>Servlet Name</entry> | 
 |                                     <entry><literal>web.xml</literal></entry> | 
 |                                 </row> | 
 |                             </thead> | 
 |                             <tbody> | 
 |                                 <row> | 
 |                                     <entry>No &lit.jaxrs.core.Application; subclass</entry> | 
 |                                     <entry>Adds Servlet</entry> | 
 |                                     <entry><literal>jakarta.ws.rs.core.Application</literal></entry> | 
 |                                     <entry>Servlet mapping is required</entry> | 
 |                                 </row> | 
 |                                 <row> | 
 |                                     <entry>&lit.jaxrs.core.Application; subclass handled by existing Servlet</entry> | 
 |                                     <entry>No action</entry> | 
 |                                     <entry>Already defined</entry> | 
 |                                     <entry>Not required</entry> | 
 |                                 </row> | 
 |                                 <row> | 
 |                                     <entry>&lit.jaxrs.core.Application; subclass NOT handled by existing Servlet</entry> | 
 |                                     <entry>Adds Servlet</entry> | 
 |                                     <entry>FQN of the &lit.jaxrs.core.Application; subclass</entry> | 
 |                                     <entry> | 
 |                                         if no &lit.jaxrs.ApplicationPath; on the &lit.jaxrs.core.Application; | 
 |                                         subclass, then Servlet mapping is required | 
 |                                     </entry> | 
 |                                 </row> | 
 |                             </tbody> | 
 |                         </tgroup> | 
 |                     </table> | 
 |                 </section> | 
 |             </section> | 
 |         </section> | 
 |  | 
 |         <section xml:id="deployment.servlet.containers"> | 
 |             <title>Jersey Servlet container modules</title> | 
 |  | 
 |             <para> | 
 |                 Jersey uses its own <literal>&jersey.servlet.ServletContainer;</literal> implementation of Servlet and | 
 |                 Servlet Filter API to integrate with Servlet containers. As any Jakartified JAX-RS runtime (JAX-RS spec 3.0), | 
 |                 Jersey provides support for Servlet containers that support Servlet specification version 5.0 or higher | 
 |                 is required. | 
 |             </para> | 
 |  | 
 |             <para> | 
 |                 When deploying to a Servlet container, Jersey application is typically packaged as a <literal>.war</literal> file. | 
 |                 As with any other Servlet application, JAX-RS application classes are packaged in | 
 |                 <literal>WEB-INF/classes</literal> or <literal>WEB-INF/lib</literal> and required application libraries are | 
 |                 located in <literal>WEB-INF/lib</literal>. | 
 |                 For more details, please refer to the Servlet Specification (&servlet5.link;). | 
 |             </para> | 
 |  | 
 |             <para> | 
 |                 Jersey provides two Servlet modules. The first module is the Jersey core Servlet module that provides | 
 |                 the core Servlet integration support and is required in any Servlet 5 or higher container: | 
 |  | 
 |                 <programlisting language="xml"><dependency> | 
 |     <groupId>org.glassfish.jersey.containers</groupId> | 
 |     <artifactId>jersey-container-servlet-core</artifactId> | 
 | </dependency></programlisting> | 
 |  | 
 |                 To support additional Servlet 5.x deployment modes and asynchronous JAX-RS resource programming model, | 
 |                 an additional Jersey module is required: | 
 |  | 
 |                 <programlisting language="xml"><dependency> | 
 |     <groupId>org.glassfish.jersey.containers</groupId> | 
 |     <artifactId>jersey-container-servlet</artifactId> | 
 | </dependency></programlisting> | 
 |  | 
 |                 The <literal>jersey-container-servlet</literal> module depends on | 
 |                 <literal>jersey-container-servlet-core</literal> module, therefore when it is used, it is not necessary to | 
 |                 explicitly declare the <literal>jersey-container-servlet-core</literal> dependency. | 
 |             </para> | 
 |  | 
 |             <para> | 
 |                 Note that in simple cases, you don't need to provide the deployment descriptor (<literal>web.xml</literal>) | 
 |                 and can use the <literal>@ApplicationPath</literal> annotation, as described in | 
 |                 <xref linkend="deployment.servlet.3.pluggability.noapp"/> section. | 
 |             </para> | 
 |         </section> | 
 |     </section> | 
 |  | 
 |     <section xml:id="deployment.javaee"> | 
 |         <title>Jakarta EE Platform</title> | 
 |         <para> | 
 |             This section describes, how you can publish Jersey JAX-RS resources as various Jakarta EE platform elements. | 
 |             JAX-RS and Jersey give you wide choice of possibilities and it is up to your taste (and design of your application), | 
 |             what Jakarta EE technology you decide to use for the management of your resources. | 
 |         </para> | 
 |  | 
 |         <section xml:id="deployment.javaee.managed"> | 
 |             <title>Managed Beans</title> | 
 |  | 
 |             <para> | 
 |                 Jersey supports the use of Jakarta EE Managed beans as root resource classes, providers as well as | 
 |                 &lit.jaxrs.core.Application; subclasses. | 
 |             </para> | 
 |  | 
 |             <para> | 
 |                 In the code below, you can find an example of a bean, that uses a managed-bean interceptor defined as a JAX-RS | 
 |                 bean. The bean is used to intercept calls to the resource method <literal>getIt()</literal>: | 
 |  | 
 |                 <programlisting language="java" linenumbering="numbered">@ManagedBean | 
 | @Path("/managedbean") | 
 | public class ManagedBeanResource { | 
 |  | 
 |     public static class MyInterceptor { | 
 |         @AroundInvoke | 
 |         public String around(InvocationContext ctx) throws Exception { | 
 |             System.out.println("around() called"); | 
 |             return (String) ctx.proceed(); | 
 |         } | 
 |     } | 
 |  | 
 |     @GET | 
 |     @Produces("text/plain") | 
 |     @Interceptors(MyInterceptor.class) | 
 |     public String getIt() { | 
 |         return "Hi managed bean!"; | 
 |     } | 
 | }</programlisting> | 
 |             </para> | 
 |         </section> | 
 |  | 
 |         <section xml:id="deployment.javaee.cdi"> | 
 |             <title>Context and Dependency Injection (CDI)</title> | 
 |  | 
 |             <para> | 
 |                 CDI beans can be used as Jersey root resource classes, providers as well as &lit.jaxrs.core.Application; | 
 |                 subclasses. Providers and &lit.jaxrs.core.Application; subclasses have to be singleton or application scoped. | 
 |             </para> | 
 |  | 
 |             <para> | 
 |                 The next example shows a usage of a CDI bean as a JAX-RS root resource class. We assume, that CDI has been | 
 |                 enabled. The code snipped uses the type-safe dependency injection provided in CDI by using another bean | 
 |                 (<literal>MyOtherCdiBean</literal>): | 
 |  | 
 |                 <programlisting language="java" linenumbering="numbered">@Path("/cdibean") | 
 | public class CdiBeanResource { | 
 |     @Inject MyOtherCdiBean bean;  // CDI injected bean | 
 |  | 
 |     @GET | 
 |     @Produces("text/plain") | 
 |     public String getIt() { | 
 |         return bean.getIt(); | 
 |     } | 
 | }</programlisting> | 
 |             </para> | 
 |             <para> | 
 |               The above works naturally inside any Java/Jakarta EE compliant AS container. In Jersey version 2.15, container agnostic CDI support was introduced. | 
 |               This feature allows you to publish CDI based JAX-RS resources also in other containers. Jersey cdi-webapp example shows Jersey/CDI integration | 
 |               in Grizzly HTTP and Apache Tomcat server. Detailed description of Jersey CDI support outside of a fully fledged Java/Jakarta EE application container | 
 |               could be found in <xref linkend="cdi.support"/>. | 
 |             </para> | 
 |         </section> | 
 |  | 
 |         <section xml:id="deployment.javaee.ejb"> | 
 |             <title>Enterprise Java Beans (EJB)</title> | 
 |             <para> | 
 |                 Stateless and Singleton Session beans can be used as Jersey root resource classes, providers and/or | 
 |                 &lit.jaxrs.core.Application; subclasses. You can choose from annotating the methods in the EJB's local | 
 |                 interface or directly the method in an interface-less EJB POJO. JAX-RS specifications requires its | 
 |                 implementors to discover EJBs by inspecting annotations on classes (or local interfaces), | 
 |                 but not in the deployment descriptors (<literal>ejb-jar.xml</literal>). As such, to keep your JAX-RS | 
 |                 application portable, do not override EJB annotations or provide any additional meta-data in the deployment | 
 |                 descriptor file. | 
 |             </para> | 
 |  | 
 |             <para> | 
 |                 Following example consists of a stateless EJB and a local interface used in Jersey: | 
 |                 <programlisting language="java" linenumbering="numbered">@Local | 
 | public interface LocalEjb { | 
 |     @GET | 
 |     @Produces("text/plain") | 
 |    public String getIt(); | 
 | } | 
 |  | 
 | @Stateless | 
 | @Path("/stateless") | 
 | public class StatelessEjbResource implements LocalEjb { | 
 |     @Override | 
 |     public String getIt() { | 
 |         return "Hi Stateless!"; | 
 |     } | 
 | }</programlisting> | 
 |             </para> | 
 |  | 
 |             <note> | 
 |                 <para> | 
 |                     Please note that Jersey currently does not support deployment of JAX-RS applications packaged as standalone | 
 |                     EJB modules (ejb-jars). To use EJBs as JAX-RS resources, the EJBs need to be packaged either directly in a | 
 |                     WAR or in an EAR that contains at least one WAR. This is to ensure Servlet container initialization that is | 
 |                     necessary for bootstrapping of the Jersey runtime. | 
 |                 </para> | 
 |             </note> | 
 |         </section> | 
 |  | 
 |         <section xml:id="deployment.appservers"> | 
 |             <title>Jakarta EE Servers</title> | 
 |  | 
 |             <section xml:id="deployment.appservers.glassfish"> | 
 |                 <title>GlassFish Application Server</title> | 
 |  | 
 |                 <para> | 
 |                     As explained in <link linkend="servlet-app-glassfish">2.3.1</link> , you don't need to add any specific | 
 |                     dependencies on GlassFish, Jersey is already packaged within GlassFish. You only need to add the | 
 |                     <literal>provided</literal>-scoped dependencies to your project to be able to compile it. At runtime, | 
 |                     GlassFish will make sure that your application has access to the Jersey libraries. | 
 |                 </para> | 
 |  | 
 |                 <para> | 
 |                   Started with version 2.7, Jersey allows injecting Jersey specific types into CDI enabled JAX-RS components | 
 |                   using the <literal>@jakarta.inject.Inject</literal> annotation. This covers also custom HK2 bindings, that are configured | 
 |                   as part of Jersey application. The feature specifically enables usage of Jersey monitoring statistics (provided that the statistic feature is turned on) | 
 |                   in CDI environment, where injection is the only mean to get access to monitoring data. | 
 |                 </para> | 
 |                 <para> | 
 |                   Since both CDI and HK2 use the same injection annotation, Jersey could get confused in certain | 
 |                   cases, which could lead to nasty runtime issues. The get better control over what Jersey evaluates | 
 |                   as HK2 injection, end-users could take advantage of newly introduced, &jersey.ext.cdi1x.spi.Hk2CustomBoundTypesProvider;, SPI. | 
 |                   Please see the linked javadoc to get detailed information on how to use the SPI in your application. | 
 |                 </para> | 
 |             </section> | 
 |  | 
 |             <section xml:id="deployment.appservers.weblogic"> | 
 |                 <title>Oracle WebLogic Server</title> | 
 |  | 
 |                 <para> | 
 |                     For now Oracle WebLogic Server does not support Jakartified Jersey 3.x deployment (for deployment of prior | 
 |                     versions of Jersey please refer to corresponding manual/user guide) | 
 |                 </para> | 
 |                 <para> | 
 |                     In 10.3.x, a set of pre-built shared libraries were delivered with WebLogic Server to support | 
 |                     Jersey 1.9 and 1.1.5.1 Java API for RESTful Web Services (JAX-RS) Reference Implementations (RIs). | 
 |                     In 12.2.x, WebLogic Server supports Jersey 2.21.x (JAX-RS 2.0 RI) by default. To use the pre-built | 
 |                     shared libraries of 10.3.x, you needed to register them with the WebLogic Server instance, and | 
 |                     modify the web.xml and weblogic.xml deployment descriptors to use the Jersey servlet and reference | 
 |                     the shared libraries, respectively. | 
 |                     In 12.2.x, as WebLogic Server supports Jersey 2.21.x (JAX-RS 2.0 RI) by default, registration as a | 
 |                     shared library with WebLogic Server is no longer required. | 
 |                     Please read through | 
 |                     the <link xlink:href="https://docs.oracle.com/middleware/12213/wls/WLUPG/upgrade_ws.htm#WLUPG331"> | 
 |                     Upgrading a 10.3.x RESTful Web Service (JAX-RS) to 12.2.x</link> | 
 |                 </para> | 
 |             </section> | 
 |  | 
 |             <section xml:id="deployment.appservers.other"> | 
 |                 <title>Other Application Servers</title> | 
 |  | 
 |                 <para> | 
 |                     Third party Java/Jakarta EE application servers usually ship with a JAX-RS implementation. If you want to | 
 |                     use Jersey instead of the default JAX-RS provider, you need to add Jersey libraries to your classpath and | 
 |                     disable the default JAX-RS provider in the container. | 
 |                 </para> | 
 |                 <para> | 
 |                     In general, Jersey will be deployed as a Servlet and the resources can be deployed in various ways, | 
 |                     as described in this section. However, the exact steps will vary from vendor to vendor.</para> | 
 |             </section> | 
 |         </section> | 
 |     </section> | 
 |  | 
 |     <section xml:id="deployment.osgi"> | 
 |         <title>OSGi</title> | 
 |         <para> | 
 |             OSGi support has been added to the Jersey version 1.2. Since then, you should be able to utilize standard OSGi | 
 |             means to run Jersey based web applications in OSGi runtime as described in the OSGi Service Platform Enterprise | 
 |             Specification. Jersey is currently compatible with OSGi 4.2.0, the specification could be downloaded from the | 
 |             <link xlink:href='http://www.osgi.org/Download/Release4V42'>OSGi 4.2.0 Download Site</link>. | 
 |         </para> | 
 |         <para> | 
 |             The two supported ways of running an OSGi web application are: | 
 |  | 
 |             <itemizedlist> | 
 |                 <listitem>WAB (Web Application Bundle)</listitem> | 
 |                 <listitem>HTTP Service</listitem> | 
 |             </itemizedlist> | 
 |  | 
 |             WAB is in fact just an OSGified WAR archive. HTTP Service feature allows you to publish Jakarta EE Servlets in | 
 |             the OSGi runtime. | 
 |         </para> | 
 |         <para> | 
 |             Two examples were added to the Jersey distribution to depict the above mentioned features and show how to use | 
 |             them with Jersey: | 
 |  | 
 |             <itemizedlist> | 
 |                 <listitem>&jersey.github.osgi.webapp.example.link;</listitem> | 
 |                 <listitem>&jersey.github.osgi.httpservice.example.link;</listitem> | 
 |             </itemizedlist> | 
 |  | 
 |             Both examples are multi-module maven projects and both consist of an application OSGi bundle module and a test module. | 
 |             The tests are based on the <link xlink:href='http://ops4j1.jira.com/wiki/display/PAXEXAM3/Pax+Exam'>PAX Exam</link> | 
 |             framework. Both OSGi examples also include a readme file containing instructions | 
 |             how to manually run the example applications using &felix.link; framework. | 
 |         </para> | 
 |  | 
 |         <para> | 
 |             The rest of the chapter describes how to run the above mentioned examples on GlassFish 6 application server. | 
 |         </para> | 
 |  | 
 |         <section xml:id="osgi.shell"> | 
 |             <title>Enabling the OSGi shell in Glassfish</title> | 
 |             <para> | 
 |                 Since GlassFish utilizes Apache Felix, an OSGi runtime comes out of the box with GlassFish. | 
 |                 However, for security reasons, the OSGi shell has been turned off. You can however explicitly enable it | 
 |                 either by starting GlassFish the <literal>asadmin</literal> console and creating a Java system property | 
 |                 <literal>glassfish.osgi.start.level.final</literal> and setting its value to <literal>3</literal>: | 
 |  | 
 |                 <example> | 
 |                     Start the admin console: | 
 |  | 
 |                     <programlisting language="bash shell" linenumbering="numbered" continuation="restarts"> | 
 | ~/glassfish/bin$ ./asadmin | 
 | Use "exit" to exit and "help" for online help. | 
 | asadmin></programlisting> | 
 |  | 
 |                     You can check the actual value of the java property (loaded from the configuration file): | 
 |  | 
 |                     <programlisting language="bash shell" linenumbering="numbered" continuation="continues"> | 
 | asadmin>  list-jvm-options | 
 | ... | 
 | -Dglassfish.osgi.start.level.final=2 | 
 | ...</programlisting> | 
 |  | 
 |                     And change the value by typing: | 
 |  | 
 |                     <programlisting language="bash shell" linenumbering="numbered" continuation="continues"> | 
 | asadmin>  create-jvm-options --target server -Dglassfish.osgi.start.level.final=3</programlisting> | 
 |                 </example> | 
 |             </para> | 
 |  | 
 |             <para> | 
 |                 The second option is to change the value in the <literal>osgi.properties</literal> configuration file: | 
 |                 <programlisting language="bash shell" linenumbering="numbered"> | 
 | # Final start level of OSGi framework. This is used by GlassFish launcher code | 
 | # to set the start level of the OSGi framework once server is up and running so that | 
 | # optional services can start. The initial start level of framework is controlled using | 
 | # the standard framework property called org.osgi.framework.startlevel.beginning | 
 | glassfish.osgi.start.level.final=3</programlisting> | 
 |  | 
 |                 You can then execute the Felix shell commands by typing <literal>osgi <felix_command></literal> in | 
 |                 the <literal>asadmin</literal> console. For example: | 
 |  | 
 |                 <programlisting language="bash shell" linenumbering="numbered"> | 
 | asadmin> osgi lb | 
 | ... list of bundles ...</programlisting> | 
 |  | 
 |                 or launching the shell using <literal>osgi-shell</literal> command in the admin console (the domain must be | 
 |                 started, otherwise the osgi shell won't launch): | 
 |  | 
 |                 <programlisting language="bash shell" linenumbering="numbered"> | 
 | asadmin> osgi-shell | 
 | Use "exit" to exit and "help" for online help. | 
 | gogo$</programlisting> | 
 |  | 
 |                 and execute the osgi commands directly (without the "<literal>osgi</literal>" prefix): | 
 |  | 
 | <programlisting language="bash shell" linenumbering="numbered"> | 
 | gogo$ lb | 
 | ... list of bundles ...</programlisting> | 
 |             </para> | 
 |         </section> | 
 |  | 
 |         <section xml:id="osgi.wab"> | 
 |             <title>WAB Example</title> | 
 |  | 
 |             <para> | 
 |                 As mentioned above, WAB is just an OSGi-fied WAR archive. Besides the usual OSGi headers it must | 
 |                 in addition contain a special header, Web-ContextPath, specifying the web application context path. | 
 |                 Our WAB has (beside some other) the following headers present in the manifest: | 
 |  | 
 |                 <programlisting language="text" linenumbering="numbered">Web-ContextPath: helloworld | 
 | Webapp-Context: helloworld | 
 | Bundle-ClassPath: WEB-INF/classese</programlisting> | 
 |  | 
 |                 Here, the second header is ignored by GlassFish, but may be required by other containers not fully | 
 |                 compliant with the OSGi Enterprise Specification mentioned above. The third manifest header | 
 |                 worth mentioning is the Bundle-ClassPath specifying where to find the application | 
 |                 Java classes within the bundle archive. | 
 |                 More about manifest headers in OSGi can be found in the | 
 |                 <link xlink:href='http://wiki.osgi.org/wiki/Category:Manifest_Header'>OSGi Wiki</link>. | 
 |             </para> | 
 |  | 
 |             <para> | 
 |                 For more detailed information on the example please see the &jersey.github.osgi.webapp.example.link; source code. This | 
 |                 example does not package into a single <literal>war</literal> file. Instead a <literal>war</literal> and a | 
 |                 set of additional <literal>jar</literal>s is produced during the build. See the next example to see how to deploy OSGi | 
 |                 based Jersey application to GlassFish. | 
 |             </para> | 
 |         </section> | 
 |  | 
 |         <section xml:id="osgi.httpservice"> | 
 |             <title>HTTP Service Example</title> | 
 |  | 
 |             <note> | 
 |                 <para> | 
 |                     When deploying an OSGi HTTP Service example to GlassFish, please make sure the OSGi HTTP Service bundle is | 
 |                     installed on your GlassFish instance. | 
 |                 </para> | 
 |             </note> | 
 |  | 
 |             <para> | 
 |                 You can directly install and activate the Jersey application bundle. In case of our example, you can either | 
 |                 install the example bundle stored locally (and alternatively build from Jersey sources): | 
 |             </para> | 
 |             <para> | 
 |                 1) Build (optional) | 
 |  | 
 |                 <programlisting language="bash" linenumbering="numbered"> | 
 | examples$ cd osgi-http-service/bundle | 
 | bundle$ mvn clean package</programlisting> | 
 |  | 
 |                 You can also get the binary readily compiled from | 
 |                 <link xlink:href='&maven.java.net.releases.link;org/glassfish/jersey/examples/osgi-http-service/bundle/&version;'>Java.net Maven Repository</link>. | 
 |             </para> | 
 |             <para> | 
 |                 2) Install into OSGi runtime: | 
 |                 <programlisting language="bash shell" linenumbering="numbered"> | 
 | gogo$ install file:///path/to/file/bundle.jar | 
 | Bundle ID: 303</programlisting> | 
 |  | 
 |                 or install it directly from the maven repository: | 
 |  | 
 |                 <programlisting language="bash shell" linenumbering="numbered"> | 
 | gogo$ install https://repo1.maven.org/maven2/org/glassfish/jersey/examples/osgi-http-service/bundle/<version>/bundle-<version>.jar | 
 | Bundle ID: 303</programlisting> | 
 |             </para> | 
 |  | 
 |             <para> | 
 |                 Make sure to replace <literal><version></literal> with an appropriate version number. Which one is | 
 |                 appropriate depends on the specific GlassFish 6.x version you are using. The version of the bundle cannot | 
 |                 be higher than the version of Jersey integrated in your GlassFish 6.x server. Jersey bundles declare | 
 |                 dependencies on other bundles at the OSGi level and those dependencies are version-sensitive. If you use | 
 |                 example bundle from let's say version 3.0.0-RC2, but Glassfish has Jersey 3.0.0-M1, dependencies will not be satisfied | 
 |                 and bundle will not start. If this happens, the error will look something like this: | 
 |  | 
 |                 <programlisting language="bash" linenumbering="numbered">gogo$ lb | 
 | ... | 
 | 303 | Installed  |    1| jersey-examples-osgi-http-service-bundle (2.5.0.SNAPSHOT) | 
 | gogo$ start 303 | 
 |  | 
 | org.osgi.framework.BundleException: Unresolved constraint in bundle | 
 | org.glassfish.jersey.examples.osgi-http-service.bundle [303]: Unable to resolve 308.0: missing requirement | 
 | [303.0] osgi.wiring.package; (&(osgi.wiring.package=org.glassfish.jersey.servlet) | 
 | (version>=3.0.0.RC2)) | 
 |  | 
 | gogo$</programlisting> | 
 |  | 
 |                 In the opposite scenario (example bundle version 3.0.0-M1 and Glassfish Jersey version higher), everything should | 
 |                 work fine. | 
 |             </para> | 
 |  | 
 |             <para> | 
 |                 Also, if you build GlassFish from the main trunk sources and use the example from most recent | 
 |                 Jersey release, you will most likely be able to run the examples from the latest Jersey release, as Jersey | 
 |                 team typically integrates all newly released versions of Jersey immediately into GlassFish. | 
 |             </para> | 
 |  | 
 |             <para> | 
 |                 As a final step, start the bundle: | 
 |  | 
 |                 <programlisting language="bash" linenumbering="numbered">gogo$ start 303</programlisting> | 
 |  | 
 |                 Again, the Bundle ID (in our case 303) has to be replaced by the correct one returned from the | 
 |                 <literal>install</literal> command. | 
 |             </para> | 
 |  | 
 |             <para> | 
 |                 The example app should now be up and running. You can access it on | 
 |                 <link xlink:href='http://localhost:8080/osgi/jersey-http-service/status'> | 
 |                     http://localhost:8080/osgi/jersey-http-service/status | 
 |                 </link>. Please see &jersey.github.osgi.httpservice.example.link; source code for more details on the example. | 
 |             </para> | 
 |         </section> | 
 |     </section> | 
 |  | 
 |     <section xml:id="deployment.other"> | 
 |         <title>Other Environments</title> | 
 |  | 
 |         <section xml:id="deployment.other.cloud"> | 
 |             <title>Oracle Java Cloud Service</title> | 
 |  | 
 |             <para> | 
 |                 As Oracle Public Cloud is based on WebLogic server, the same applies as in the paragraph about WebLogic | 
 |                 deployment (see <xref linkend="deployment.appservers.weblogic" />). More on developing applications for | 
 |                 Oracle Java Cloud Service can be found in this &cloud.guide;. | 
 |             </para> | 
 |         </section> | 
 |     </section> | 
 | </chapter> |