|  | <?xml version="1.0"?> | 
|  | <!-- | 
|  |  | 
|  | Copyright (c) 2010, 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; ]> | 
|  | <chapter xmlns="http://docbook.org/ns/docbook" | 
|  | version="5.0" | 
|  | xml:lang="en" | 
|  | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | 
|  | xmlns:xi="http://www.w3.org/2001/XInclude" | 
|  | xmlns:xlink="http://www.w3.org/1999/xlink" | 
|  | xsi:schemaLocation="http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd | 
|  | http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd" | 
|  | xml:id="getting-started"> | 
|  | <title>Getting Started</title> | 
|  |  | 
|  | <para> | 
|  | This chapter provides a quick introduction on how to get started building RESTful services using Jersey. | 
|  | The example described here uses the lightweight Grizzly HTTP server. At the end of this chapter you will | 
|  | see how to implement equivalent functionality as a JavaEE web application you can deploy on any servlet | 
|  | container supporting Servlet 5 and higher. | 
|  | </para> | 
|  |  | 
|  | <section xml:id="new-from-archetype"> | 
|  | <title>Creating a New Project from Maven Archetype</title> | 
|  |  | 
|  | <para> | 
|  | Jersey project is built using &maven.link; software project build and management tool. All modules produced as | 
|  | part of Jersey project build are pushed to the &maven.central.repo.link;. Therefore it is very convenient to work | 
|  | with Jersey for any Maven-based project as all the released (non-SNAPSHOT) Jersey dependencies are readily | 
|  | available without a need to configure a special maven repository to consume the Jersey modules. | 
|  |  | 
|  | <note> | 
|  | <para> | 
|  | In case you want to depend on the latest SNAPSHOT versions of Jersey modules, the following repository | 
|  | configuration needs to be added to your Maven project pom: | 
|  |  | 
|  | <programlisting language="xml" linenumbering="unnumbered"><snapshotRepository> | 
|  | <id>ossrh</id> | 
|  | <name>Sonatype Nexus Snapshots</name> | 
|  | <url>https://jakarta.oss.sonatype.org/content/repositories/snapshots/</url> | 
|  | </snapshotRepository></programlisting> | 
|  | </para> | 
|  | </note> | 
|  | </para> | 
|  | <para> | 
|  | Since starting from a Maven project is the most convenient way for working with Jersey, let's now have a look | 
|  | at this approach. We will now create a new Jersey project that runs on top of a &grizzly.link; container. We will | 
|  | use a Jersey-provided maven archetype. To create the project, execute the following Maven command in the directory | 
|  | where the new project should reside: | 
|  |  | 
|  | <programlisting language="bash" linenumbering="unnumbered">mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-grizzly2 \ | 
|  | -DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false \ | 
|  | -DgroupId=com.example -DartifactId=simple-service -Dpackage=com.example \ | 
|  | -DarchetypeVersion=&version;</programlisting> | 
|  |  | 
|  | Feel free to adjust the <literal>groupId</literal>, <literal>package</literal> and/or <literal>artifactId</literal> | 
|  | of your new project. Alternatively, you can change it by updating the new project pom.xml once it gets generated. | 
|  | </para> | 
|  | </section> | 
|  | <section xml:id="new-project-structure"> | 
|  | <title>Exploring the Newly Created Project</title> | 
|  |  | 
|  | <para> | 
|  | Once the project generation from a Jersey maven archetype is successfully finished, you should see the new | 
|  | <literal>simple-service</literal> project directory created in your current location. The directory contains | 
|  | a standard Maven project structure: | 
|  |  | 
|  | <simplelist> | 
|  | <member> | 
|  | Project build and management configuration is described in the <literal>pom.xml</literal> located | 
|  | in the project root directory. | 
|  | </member> | 
|  | <member>Project sources are located under <literal>src/main/java</literal>.</member> | 
|  | <member>Project test sources are located under <literal>src/test/java</literal>.</member> | 
|  | </simplelist> | 
|  |  | 
|  | There are 2 classes in the project source directory in the <literal>com.example</literal> package. | 
|  | The <literal>Main</literal> class is responsible for bootstrapping the Grizzly container as well as configuring | 
|  | and deploying the project's JAX-RS application to the container. Another class in the same package | 
|  | is <literal>MyResource</literal> class, that contains implementation of a simple JAX-RS resource. | 
|  | It looks like this: | 
|  |  | 
|  | <programlisting language="java" linenumbering="numbered">package com.example; | 
|  |  | 
|  | import jakarta.ws.rs.GET; | 
|  | import jakarta.ws.rs.Path; | 
|  | import jakarta.ws.rs.Produces; | 
|  | import jakarta.ws.rs.core.MediaType; | 
|  |  | 
|  | /** | 
|  | * Root resource (exposed at "myresource" path) | 
|  | */ | 
|  | @Path("myresource") | 
|  | public class MyResource { | 
|  |  | 
|  | /** | 
|  | * Method handling HTTP GET requests. The returned object will be sent | 
|  | * to the client as "text/plain" media type. | 
|  | * | 
|  | * @return String that will be returned as a text/plain response. | 
|  | */ | 
|  | @GET | 
|  | @Produces(MediaType.TEXT_PLAIN) | 
|  | public String getIt() { | 
|  | return "Got it!"; | 
|  | } | 
|  | }</programlisting> | 
|  |  | 
|  | A JAX-RS resource is an annotated POJO that provides so-called <emphasis>resource methods</emphasis> that | 
|  | are able to handle HTTP requests for URI paths that the resource is bound to. See | 
|  | <xref linkend="jaxrs-resources" /> for a complete guide to JAX-RS resources. In our case, the resource | 
|  | exposes a single resource method that is able to handle HTTP &lit.http.GET; requests, is bound to | 
|  | <literal>/myresource</literal> URI path and can produce responses with response message content represented | 
|  | in <literal>"text/plain"</literal> media type. In this version, the resource returns the same | 
|  | <literal>"Got it!"</literal> response to all client requests. | 
|  | </para> | 
|  | <para> | 
|  | The last piece of code that has been generated in this skeleton project is a <literal>MyResourceTest</literal> | 
|  | unit test class that is located in the same <literal>com.example</literal> package as the | 
|  | <literal>MyResource</literal> class, however, this unit test class is placed into the maven project test source | 
|  | directory <literal>src/test/java</literal> (certain code comments and JUnit imports have been excluded for brevity): | 
|  |  | 
|  | <programlisting language="java" linenumbering="numbered">package com.example; | 
|  |  | 
|  | import jakarta.ws.rs.client.Client; | 
|  | import jakarta.ws.rs.client.ClientBuilder; | 
|  | import jakarta.ws.rs.client.WebTarget; | 
|  |  | 
|  | import org.glassfish.grizzly.http.server.HttpServer; | 
|  |  | 
|  | ... | 
|  |  | 
|  | public class MyResourceTest { | 
|  |  | 
|  | private HttpServer server; | 
|  | private WebTarget target; | 
|  |  | 
|  | @BeforeEach | 
|  | public void setUp() throws Exception { | 
|  | server = Main.startServer(); | 
|  |  | 
|  | Client c = ClientBuilder.newClient(); | 
|  | target = c.target(Main.BASE_URI); | 
|  | } | 
|  |  | 
|  | @AfterEach | 
|  | public void tearDown() throws Exception { | 
|  | server.stop(); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Test to see that the message "Got it!" is sent in the response. | 
|  | */ | 
|  | @Test | 
|  | public void testGetIt() { | 
|  | String responseMsg = target.path("myresource").request().get(String.class); | 
|  | assertEquals("Got it!", responseMsg); | 
|  | } | 
|  | }</programlisting> | 
|  |  | 
|  | In this unit test, a Grizzly container is first started and server application is deployed in the | 
|  | test <literal>setUp()</literal> method by a static call to <literal>Main.startServer()</literal>. | 
|  | Next, JAX-RS client components are created in the same test set-up method. First a new JAX-RS client | 
|  | instance <literal>c</literal> is built and then a JAX-RS web target component pointing to the context root of our | 
|  | application deployed at <literal>http://localhost:8080/myapp/</literal> (a value of | 
|  | <literal>Main.BASE_URI</literal> constant) is stored into a <literal>target</literal> field of the unit test class. | 
|  | This field is then used in the actual unit test method (<literal>testGetIt()</literal>). | 
|  | </para> | 
|  | <para> | 
|  | In the <literal>testGetIt()</literal> method a fluent JAX-RS Client API is used to connect to and send | 
|  | a HTTP &lit.http.GET; request to the <literal>MyResource</literal> JAX-RS resource class listening on | 
|  | <literal>/myresource</literal> URI. As part of the same fluent JAX-RS API method invocation chain, a response is | 
|  | read as a Java <literal>String</literal> type. On the second line in the test method, the response content string | 
|  | returned from the server is compared with the expected phrase in the test assertion. To learn more about using | 
|  | JAX-RS Client API, please see the <xref linkend="client" /> chapter. | 
|  | </para> | 
|  | </section> | 
|  |  | 
|  | <section xml:id="running-project"> | 
|  | <title>Running the Project</title> | 
|  | <para> | 
|  | Now that we have seen the content of the project, let's try to test-run it. To do this, we need to invoke following | 
|  | command on the command line: | 
|  |  | 
|  | <programlisting language="bash" linenumbering="unnumbered">mvn clean test</programlisting> | 
|  |  | 
|  | This will compile the project and run the project unit tests. We should see a similar output that informs about a | 
|  | successful build once the build is finished: | 
|  |  | 
|  | <screen linenumbering="unnumbered">Results : | 
|  |  | 
|  | Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 | 
|  |  | 
|  | [INFO] ------------------------------------------------------------------------ | 
|  | [INFO] BUILD SUCCESS | 
|  | [INFO] ------------------------------------------------------------------------ | 
|  | [INFO] Total time: 34.527s | 
|  | [INFO] Finished at: Sun May 26 19:26:24 CEST 2020 | 
|  | [INFO] Final Memory: 17M/490M | 
|  | [INFO] ------------------------------------------------------------------------</screen> | 
|  |  | 
|  | Now that we have verified that the project compiles and that the unit test passes, we can execute the application | 
|  | in a standalone mode. To do this, run the following maven command: | 
|  |  | 
|  | <programlisting language="bash" linenumbering="unnumbered">mvn exec:java</programlisting> | 
|  |  | 
|  | The application starts and you should soon see the following notification in your console: | 
|  |  | 
|  | <screen linenumbering="unnumbered">May 26, 2020 8:08:45 PM org.glassfish.grizzly.http.server.NetworkListener start | 
|  | INFO: Started listener bound to [localhost:8080] | 
|  | May 26, 2020 8:08:45 PM org.glassfish.grizzly.http.server.HttpServer start | 
|  | INFO: [HttpServer] Started. | 
|  | Jersey app started with WADL available at http://localhost:8080/myapp/application.wadl | 
|  | Hit enter to stop it...</screen> | 
|  |  | 
|  | This informs you that the application has been started and it's WADL descriptor is available at | 
|  | <literal>http://localhost:8080/myapp/application.wadl</literal> URL. You can retrieve the WADL content by | 
|  | executing a <literal>curl http://localhost:8080/myapp/application.wadl</literal> command in your console | 
|  | or by typing the WADL URL into your favorite browser. You should get back an XML document in describing | 
|  | your deployed RESTful application in a WADL format. To learn more about working with WADL, check the | 
|  | <xref linkend="wadl" /> chapter. | 
|  | </para> | 
|  | <para> | 
|  | The last thing we should try before concluding this section is to see if we can communicate with our | 
|  | resource deployed at <literal>/myresource</literal> path. We can again either type the resource URL | 
|  | in the browser or we can use <literal>curl</literal>: | 
|  |  | 
|  | <screen language="bash" linenumbering="unnumbered">$ curl http://localhost:8080/myapp/myresource | 
|  | Got it!</screen> | 
|  |  | 
|  | As we can see, the <literal>curl</literal> command returned with the <literal>Got it!</literal> message that | 
|  | was sent by our resource. We can also ask <literal>curl</literal> to provide more information about the response, | 
|  | for example we can let it display all response headers by using the <literal>-i</literal> switch: | 
|  |  | 
|  | <screen language="bash" linenumbering="unnumbered">curl -i http://localhost:8080/myapp/myresource | 
|  | HTTP/1.1 200 OK | 
|  | Content-Type: text/plain | 
|  | Date: Sun, 26 May 2020 18:27:19 GMT | 
|  | Content-Length: 7 | 
|  |  | 
|  | Got it!</screen> | 
|  |  | 
|  | Here we see the whole content of the response message that our Jersey/JAX-RS application returned, including all | 
|  | the HTTP headers. Notice the <literal>Content-Type: text/plain</literal> header that was derived from the | 
|  | value of &jaxrs.Produces; annotation attached to the <literal>MyResource</literal> class. | 
|  | </para> | 
|  | <para> | 
|  | In case you want to see even more details about the communication between our <literal>curl</literal> client | 
|  | and our resource running on Jersey in a Grizzly I/O container, feel free to try other various options and switches | 
|  | that <literal>curl</literal> provides. For example, this last command will make <literal>curl</literal> output | 
|  | a lot of additional information about the whole communication: | 
|  |  | 
|  | <screen language="bash" linenumbering="unnumbered"><![CDATA[$ curl -v http://localhost:8080/myapp/myresource | 
|  | *   Trying 127.0.0.1:8080... | 
|  | * TCP_NODELAY set | 
|  | * Connected to localhost (127.0.0.1) port 8080 (#0) | 
|  | > GET /myapp/myresource HTTP/1.1 | 
|  | > Host: localhost:8080 | 
|  | > User-Agent: curl/7.68.0 | 
|  | > Accept: */* | 
|  | > | 
|  | * Mark bundle as not supporting multiuse | 
|  | < HTTP/1.1 200 OK | 
|  | < Content-Type: text/plain | 
|  | < Date: Sun, 26 May 2020 18:29:18 GMT | 
|  | < Content-Length: 7 | 
|  | < | 
|  | * Connection #0 to host localhost left intact | 
|  | Got it!]]></screen> | 
|  | </para> | 
|  | </section> | 
|  |  | 
|  | <section xml:id="new-webapp"> | 
|  | <title>Creating a JavaEE Web Application</title> | 
|  | <para> | 
|  | To create a Web Application that can be packaged as WAR and deployed in a Servlet container follow a similar process | 
|  | to the one described in <xref linkend="new-from-archetype" />. | 
|  | In addition to the Grizzly-based archetype, Jersey provides also a Maven archetype for creating web application | 
|  | skeletons. To create the new web application skeleton project, execute the following Maven command in the directory | 
|  | where the new project should reside: | 
|  |  | 
|  | <programlisting language="bash" linenumbering="unnumbered">mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-webapp \ | 
|  | -DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false \ | 
|  | -DgroupId=com.example -DartifactId=simple-service-webapp -Dpackage=com.example \ | 
|  | -DarchetypeVersion=&version;</programlisting> | 
|  |  | 
|  | As with the Grizzly based project, feel free to adjust the <literal>groupId</literal>, <literal>package</literal> | 
|  | and/or <literal>artifactId</literal> of your new web application project. Alternatively, you can change it by updating | 
|  | the new project &lit.pom.xml; once it gets generated. | 
|  | </para> | 
|  | <para> | 
|  | Once the project generation from a Jersey maven archetype is successfully finished, you should see the new | 
|  | <literal>simple-service-webapp</literal> project directory created in your current location. The directory contains | 
|  | a standard Maven project structure, similar to the <literal>simple-service</literal> project content we have seen | 
|  | earlier, except it is extended with an additional web application specific content: | 
|  |  | 
|  | <simplelist> | 
|  | <member> | 
|  | Project build and management configuration is described in the <literal>pom.xml</literal> located | 
|  | in the project root directory. | 
|  | </member> | 
|  | <member>Project sources are located under <literal>src/main/java</literal>.</member> | 
|  | <member>Project resources are located under <literal>src/main/resources</literal>.</member> | 
|  | <member>Project web application files are located under <literal>src/main/webapp</literal>.</member> | 
|  | </simplelist> | 
|  |  | 
|  | The project contains the same <literal>MyResouce</literal> JAX-RS resource class. It does not contain any unit tests | 
|  | as well as it does not contain a <literal>Main</literal> class that was used to setup Grizzly container in the | 
|  | previous project. Instead, it contains the standard Java/Jakarta EE web application <literal>web.xml</literal> deployment | 
|  | descriptor under <literal>src/main/webapp/WEB-INF</literal>. | 
|  | The last component in the project is an <literal>index.jsp</literal> page that serves as a client for the | 
|  | <literal>MyResource</literal> resource class that is packaged and deployed with the application. | 
|  | </para> | 
|  | <para> | 
|  | To compile and package the application into a WAR, invoke the following maven command in your console: | 
|  |  | 
|  | <programlisting language="bash" linenumbering="unnumbered">mvn clean package</programlisting> | 
|  |  | 
|  | A successful build output will produce an output similar to the one below: | 
|  |  | 
|  | <screen linenumbering="unnumbered">Results : | 
|  |  | 
|  | Tests run: 0, Failures: 0, Errors: 0, Skipped: 0 | 
|  |  | 
|  | [INFO] | 
|  | [INFO] --- maven-war-plugin:2.2:war (default-war) @ simple-service-webapp --- | 
|  | [INFO] Packaging webapp | 
|  | [INFO] Assembling webapp [simple-service-webapp] in | 
|  | [.../simple-service-webapp/target/simple-service-webapp] | 
|  | [INFO] Processing war project | 
|  | [INFO] Copying webapp resources [.../simple-service-webapp/src/main/webapp] | 
|  | [INFO] Webapp assembled in [117 msecs] | 
|  | [INFO] Building war: .../simple-service-webapp/target/simple-service-webapp.war | 
|  | [INFO] WEB-INF/web.xml already added, skipping | 
|  | [INFO] ------------------------------------------------------------------------ | 
|  | [INFO] BUILD SUCCESS | 
|  | [INFO] ------------------------------------------------------------------------ | 
|  | [INFO] Total time: 3.419 s | 
|  | [INFO] Finished at: 2020-11-25T09:34:59+01:00 | 
|  | [INFO] ------------------------------------------------------------------------ | 
|  | </screen> | 
|  |  | 
|  | Now you are ready to take the packaged WAR (located under <literal>./target/simple-service-webapp.war</literal>) | 
|  | and deploy it to a Servlet container of your choice. | 
|  | <important> | 
|  | <para> | 
|  | To deploy a Jersey application, with full set of advanced features (such as JAX-RS 2.0 Async Support) | 
|  | you will need a Servlet 5.0 or later  compliant container. | 
|  | </para> | 
|  | </important> | 
|  | </para> | 
|  | </section> | 
|  |  | 
|  | <section xml:id="heroku-webapp"> | 
|  | <title>Creating a Web Application that can be deployed on Heroku</title> | 
|  | <para> | 
|  | To create a Web Application that can be either packaged as WAR and deployed in a Servlet container or that can be | 
|  | pushed and deployed on &heroku.link; the process is very similar to the one described in <xref linkend="new-webapp" />. | 
|  | To create the new web application skeleton project, execute the following Maven command in the directory | 
|  | where the new project should reside: | 
|  |  | 
|  | <programlisting language="bash" linenumbering="unnumbered">mvn archetype:generate -DarchetypeArtifactId=jersey-heroku-webapp \ | 
|  | -DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false \ | 
|  | -DgroupId=com.example -DartifactId=simple-heroku-webapp -Dpackage=com.example \ | 
|  | -DarchetypeVersion=&version;</programlisting> | 
|  |  | 
|  | Adjust the <literal>groupId</literal>, <literal>package</literal> and/or <literal>artifactId</literal> of your new web | 
|  | application project to your needs or, alternatively, you can change it by updating the new project &lit.pom.xml; once it | 
|  | gets generated. | 
|  | </para> | 
|  | <para> | 
|  | Once the project generation from a Jersey maven archetype is successfully finished, you should see the new | 
|  | <literal>simple-heroku-webapp</literal> project directory created in your current location. The directory contains | 
|  | a standard Maven project structure: | 
|  |  | 
|  | <simplelist> | 
|  | <member> | 
|  | Project build and management configuration is described in the &lit.pom.xml; located | 
|  | in the project root directory. | 
|  | </member> | 
|  | <member>Project sources are located under <literal>src/main/java</literal>.</member> | 
|  | <member>Project resources are located under <literal>src/main/resources</literal>.</member> | 
|  | <member>Project web application files are located under <literal>src/main/webapp</literal>.</member> | 
|  | <member>Project test-sources (based on &jersey.test.JerseyTest;) are located under <literal>src/test/java</literal>.</member> | 
|  | <member>Heroku system properties (OpenJDK version) are defined in <literal>system.properties</literal>.</member> | 
|  | <member>Lists of the process types in an application for Heroku is in <literal>Procfile</literal>.</member> | 
|  | </simplelist> | 
|  |  | 
|  | The project contains one JAX-RS resource class, <literal>MyResouce</literal>, and one resource method which returns | 
|  | simple text message. To make sure the resource is properly tested there is also a end-to-end test-case | 
|  | in <literal>MyResourceTest</literal> (the test is based on &jersey.test.JerseyTest; from our <xref linkend="test-framework" />). | 
|  | Similarly to <literal>simple-service-webapp</literal>, the project contains the standard Java/Jakarta EE web application | 
|  | <literal>web.xml</literal> deployment descriptor under <literal>src/main/webapp/WEB-INF</literal> since the goal is to | 
|  | deploy the application in a Servlet container (the application will run in Jetty on Heroku). | 
|  | </para> | 
|  | <para> | 
|  | To compile and package the application into a WAR, invoke the following maven command in your console: | 
|  |  | 
|  | <programlisting language="bash" linenumbering="unnumbered">mvn clean package</programlisting> | 
|  |  | 
|  | A successful build output will produce an output similar to the one below: | 
|  |  | 
|  | <screen linenumbering="unnumbered">    Results : | 
|  |  | 
|  | Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 | 
|  |  | 
|  | [INFO] | 
|  | [INFO] --- maven-war-plugin:2.2:war (default-war) @ simple-heroku-webapp --- | 
|  | [INFO] Packaging webapp | 
|  | [INFO] Assembling webapp [simple-heroku-webapp] in [.../simple-heroku-webapp/target/simple-heroku-webapp] | 
|  | [INFO] Processing war project | 
|  | [INFO] Copying webapp resources [.../simple-heroku-webapp/src/main/webapp] | 
|  | [INFO] Webapp assembled in [109 msecs] | 
|  | [INFO] Building war: .../simple-heroku-webapp/target/simple-heroku-webapp.war | 
|  | [INFO] WEB-INF/web.xml already added, skipping | 
|  | [INFO] | 
|  | [INFO] --- maven-dependency-plugin:2.8:copy-dependencies (copy-dependencies) @ simple-heroku-webapp --- | 
|  | [INFO] Copying jakarta.validation-api-3.0.0.jar to ../simple-heroku-webapp/target/dependency/jakarta.validation-api-3.0.0.jar | 
|  | [INFO] Copying javassist-3.25.0-GA.jar to ../simple-heroku-webapp/target/dependency/javassist-3.25.0-GA.jar | 
|  | [INFO] Copying jersey-client-3.0.0.jar to ../simple-heroku-webapp/target/dependency/jersey-client-3.1.0-SNAPSHOT.jar | 
|  | [INFO] Copying jersey-hk2-3.0.0.jar to ../simple-heroku-webapp/target/dependency/jersey-hk2-3.1.0-SNAPSHOT.jar | 
|  | [INFO] Copying jetty-util-11.0.0.beta3.jar to ../simple-heroku-webapp/target/dependency/jetty-util-11.0.0.beta3.jar | 
|  | [INFO] Copying jakarta.annotation-api-2.0.0.jar to ../simple-heroku-webapp/target/dependency/jakarta.annotation-api-2.0.0.jar | 
|  | [INFO] Copying jersey-common-3.0.0.jar to ../simple-heroku-webapp/target/dependency/jersey-common-3.1.0-SNAPSHOT.jar | 
|  | [INFO] Copying jersey-container-servlet-core-3.0.0.jar to ../simple-heroku-webapp/target/dependency/jersey-container-servlet-core-3.1.0-SNAPSHOT.jar | 
|  | [INFO] Copying jakarta.activation-2.0.0.jar to ../simple-heroku-webapp/target/dependency/jakarta.activation-2.0.0.jar | 
|  | [INFO] Copying jetty-webapp-11.0.0.beta3.jar to ../simple-heroku-webapp/target/dependency/jetty-webapp-11.0.0.beta3.jar | 
|  | [INFO] Copying osgi-resource-locator-1.0.3.jar to ../simple-heroku-webapp/target/dependency/osgi-resource-locator-1.0.3.jar | 
|  | [INFO] Copying jersey-container-servlet-3.0.0.jar to ../simple-heroku-webapp/target/dependency/jersey-container-servlet-3.1.0-SNAPSHOT.jar | 
|  | [INFO] Copying jetty-io-11.0.0.beta3.jar to ../simple-heroku-webapp/target/dependency/jetty-io-11.0.0.beta3.jar | 
|  | [INFO] Copying slf4j-api-2.0.0-alpha1.jar to ../simple-heroku-webapp/target/dependency/slf4j-api-2.0.0-alpha1.jar | 
|  | [INFO] Copying jetty-server-11.0.0.beta3.jar to ../simple-heroku-webapp/target/dependency/jetty-server-11.0.0.beta3.jar | 
|  | [INFO] Copying jakarta.ws.rs-api-3.0.0.jar to ../simple-heroku-webapp/target/dependency/jakarta.ws.rs-api-3.0.0.jar | 
|  | [INFO] Copying jetty-servlet-11.0.0.beta3.jar to ../simple-heroku-webapp/target/dependency/jetty-servlet-11.0.0.beta3.jar | 
|  | [INFO] Copying hk2-locator-3.0.0-RC1.jar to ../simple-heroku-webapp/target/dependency/hk2-locator-3.0.0-RC1.jar | 
|  | [INFO] Copying hk2-utils-3.0.0-RC1.jar to ../simple-heroku-webapp/target/dependency/hk2-utils-3.0.0-RC1.jar | 
|  | [INFO] Copying jetty-xml-11.0.0.beta3.jar to ../simple-heroku-webapp/target/dependency/jetty-xml-11.0.0.beta3.jar | 
|  | [INFO] Copying hk2-api-3.0.0-RC1.jar to ../simple-heroku-webapp/target/dependency/hk2-api-3.0.0-RC1.jar | 
|  | [INFO] Copying jetty-security-11.0.0.beta3.jar to ../simple-heroku-webapp/target/dependency/jetty-security-11.0.0.beta3.jar | 
|  | [INFO] Copying jetty-http-11.0.0.beta3.jar to ../simple-heroku-webapp/target/dependency/jetty-http-11.0.0.beta3.jar | 
|  | [INFO] Copying jersey-server-3.0.0.jar to ../simple-heroku-webapp/target/dependency/jersey-server-3.1.0-SNAPSHOT.jar | 
|  | [INFO] Copying jakarta.inject-api-2.0.0.jar to ../simple-heroku-webapp/target/dependency/jakarta.inject-api-2.0.0.jar | 
|  | [INFO] Copying jetty-jakarta-servlet-api-5.0.1.jar to ../simple-heroku-webapp/target/dependency/jetty-jakarta-servlet-api-5.0.1.jar | 
|  | [INFO] Copying aopalliance-repackaged-3.0.0-RC1.jar to ../simple-heroku-webapp/target/dependency/aopalliance-repackaged-3.0.0-RC1.jar | 
|  | [INFO] ------------------------------------------------------------------------ | 
|  | [INFO] BUILD SUCCESS | 
|  | [INFO] ------------------------------------------------------------------------ | 
|  | [INFO] Total time:  12.567 s | 
|  | [INFO] Finished at: 2021-01-05T15:16:05+01:00 | 
|  | [INFO] ------------------------------------------------------------------------</screen> | 
|  |  | 
|  | Now that you know everything went as expected you are ready to: | 
|  |  | 
|  | <itemizedlist> | 
|  | <listitem><simpara> | 
|  | make some changes in your project, | 
|  | </simpara></listitem> | 
|  | <listitem><simpara> | 
|  | take the packaged WAR (located under <literal>./target/simple-service-webapp.war</literal>) and deploy it to a | 
|  | Servlet container of your choice, or | 
|  | </simpara></listitem> | 
|  | <listitem><simpara> | 
|  | <xref linkend="deploy-it-on-heroku" /> | 
|  | </simpara></listitem> | 
|  | </itemizedlist> | 
|  |  | 
|  | <tip> | 
|  | <para> | 
|  | If you want to make some changes to your application you can run the application locally by simply running | 
|  | <code>mvn clean package jetty:run</code> (which starts the embedded Jetty server) or by | 
|  | <code>java -cp target/classes:target/dependency/* com.example.heroku.Main</code> (this is how Jetty is | 
|  | started on Heroku). | 
|  | </para> | 
|  | </tip> | 
|  | </para> | 
|  | <section xml:id="deploy-it-on-heroku"> | 
|  | <title>Deploy it on Heroku</title> | 
|  | <para> | 
|  | We won't go into details how to create an account on &heroku.link; and setup the <literal>Heroku</literal> tools | 
|  | on your machine. You can find a lot of information in this article: <link xlink:href='https://devcenter.heroku.com/articles/getting-started-with-java'>Getting Started with Java on Heroku</link>. | 
|  | Instead, we'll take a look at the steps needed after your environment is ready. | 
|  | </para> | 
|  | <para> | 
|  | The first step is to create a Git repository from your project: | 
|  | <screen linenumbering="unnumbered">    $ git init | 
|  | Initialized empty Git repository in /.../simple-heroku-webapp/.git/</screen> | 
|  | </para> | 
|  | <para> | 
|  | Then, create a &heroku.link; instance and add a remote reference to your Git repository: | 
|  | <screen linenumbering="unnumbered">    $ heroku create | 
|  | Creating simple-heroku-webapp... done, stack is cedar | 
|  | http://simple-heroku-webapp.herokuapp.com/ | git@heroku.com:simple-heroku-webapp.git | 
|  | Git remote heroku added</screen> | 
|  |  | 
|  | <note> | 
|  | <para> | 
|  | The name of the instance is changed in the output to <literal>simple-heroku-webapp</literal>. Your will be | 
|  | named more like <literal>tranquil-basin-4744</literal>. | 
|  | </para> | 
|  | </note> | 
|  | </para> | 
|  | <para> | 
|  | Add and commit files to your Git repository: | 
|  | <screen linenumbering="unnumbered">    $ git add src/ pom.xml Procfile system.properties</screen> | 
|  | <screen linenumbering="unnumbered">    $ git commit -a -m "initial commit" | 
|  | [master (root-commit) e2b58e3] initial commit | 
|  | 7 files changed, 221 insertions(+) | 
|  | create mode 100644 Procfile | 
|  | create mode 100644 pom.xml | 
|  | create mode 100644 src/main/java/com/example/MyResource.java | 
|  | create mode 100644 src/main/java/com/example/heroku/Main.java | 
|  | create mode 100644 src/main/webapp/WEB-INF/web.xml | 
|  | create mode 100644 src/test/java/com/example/MyResourceTest.java | 
|  | create mode 100644 system.properties</screen> | 
|  | </para> | 
|  | <para> | 
|  | Push changes to Heroku: | 
|  | <screen linenumbering="unnumbered">    $ git push heroku master | 
|  | Counting objects: 21, done. | 
|  | Delta compression using up to 8 threads. | 
|  | Compressing objects: 100% (11/11), done. | 
|  | Writing objects: 100% (21/21), 3.73 KiB | 0 bytes/s, done. | 
|  | Total 21 (delta 0), reused 0 (delta 0) | 
|  |  | 
|  | -----> Java app detected | 
|  | -----> Installing OpenJDK 1.8... done | 
|  | -----> Installing Maven 3.6.3... done | 
|  | -----> Installing settings.xml... done | 
|  | -----> executing /app/tmp/cache/.maven/bin/mvn -B -Duser.home=/tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd -Dmaven.repo.local=/app/tmp/cache/.m2/repository -s /app/tmp/cache/.m2/settings.xml -DskipTests=true clean install | 
|  | [INFO] Scanning for projects... | 
|  | [INFO] | 
|  | [INFO] ------------------------------------------------------------------------ | 
|  | [INFO] Building simple-heroku-webapp 1.0-SNAPSHOT | 
|  | [INFO] ------------------------------------------------------------------------ | 
|  | [INFO] | 
|  | [INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ simple-heroku-webapp --- | 
|  | [INFO] | 
|  | [INFO] --- maven-resources-plugin:2.4.3:resources (default-resources) @ simple-heroku-webapp --- | 
|  | [INFO] Using 'UTF-8' encoding to copy filtered resources. | 
|  | [INFO] skip non existing resourceDirectory /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/src/main/resources | 
|  | [INFO] | 
|  | [INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ simple-heroku-webapp --- | 
|  | [INFO] Compiling 2 source files to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/classes | 
|  | [INFO] | 
|  | [INFO] --- maven-resources-plugin:2.4.3:testResources (default-testResources) @ simple-heroku-webapp --- | 
|  | [INFO] Using 'UTF-8' encoding to copy filtered resources. | 
|  | [INFO] skip non existing resourceDirectory /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/src/test/resources | 
|  | [INFO] | 
|  | [INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) @ simple-heroku-webapp --- | 
|  | [INFO] Compiling 1 source file to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/test-classes | 
|  | [INFO] | 
|  | [INFO] --- maven-surefire-plugin:2.7.2:test (default-test) @ simple-heroku-webapp --- | 
|  | [INFO] Tests are skipped. | 
|  | [INFO] | 
|  | [INFO] --- maven-war-plugin:2.1.1:war (default-war) @ simple-heroku-webapp --- | 
|  | [INFO] Packaging webapp | 
|  | [INFO] Assembling webapp [simple-heroku-webapp] in [/tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/simple-heroku-webapp] | 
|  | [INFO] Processing war project | 
|  | [INFO] Copying webapp resources [/tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/src/main/webapp] | 
|  | [INFO] Webapp assembled in [88 msecs] | 
|  | [INFO] Building war: /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/simple-heroku-webapp.war | 
|  | [INFO] WEB-INF/web.xml already added, skipping | 
|  | [INFO] | 
|  | [INFO] --- maven-dependency-plugin:2.1:copy-dependencies (copy-dependencies) @ simple-heroku-webapp --- | 
|  | [INFO] Copying guava-14.0.1.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/guava-14.0.1.jar | 
|  | [INFO] Copying jakarta.annotation-api-1.2.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jakarta.annotation-api-1.2.jar | 
|  | [INFO] Copying validation-api-1.1.0.Final.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/validation-api-1.1.0.Final.jar | 
|  | [INFO] Copying jakarta.ws.rs-api-2.0.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jakarta.ws.rs-api-2.0.jar | 
|  | [INFO] Copying jetty-http-9.0.6.v20130930.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jetty-http-9.0.6.v20130930.jar | 
|  | [INFO] Copying jetty-io-9.0.6.v20130930.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jetty-io-9.0.6.v20130930.jar | 
|  | [INFO] Copying jetty-security-9.0.6.v20130930.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jetty-security-9.0.6.v20130930.jar | 
|  | [INFO] Copying jetty-server-9.0.6.v20130930.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jetty-server-9.0.6.v20130930.jar | 
|  | [INFO] Copying jetty-servlet-9.0.6.v20130930.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jetty-servlet-9.0.6.v20130930.jar | 
|  | [INFO] Copying jetty-util-9.0.6.v20130930.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jetty-util-9.0.6.v20130930.jar | 
|  | [INFO] Copying jetty-webapp-9.0.6.v20130930.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jetty-webapp-9.0.6.v20130930.jar | 
|  | [INFO] Copying jetty-xml-9.0.6.v20130930.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jetty-xml-9.0.6.v20130930.jar | 
|  | [INFO] Copying jakarta.servlet-3.0.0.v201112011016.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jakarta.servlet-3.0.0.v201112011016.jar | 
|  | [INFO] Copying hk2-api-2.2.0-b21.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/hk2-api-2.2.0-b21.jar | 
|  | [INFO] Copying hk2-locator-2.2.0-b21.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/hk2-locator-2.2.0-b21.jar | 
|  | [INFO] Copying hk2-utils-2.2.0-b21.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/hk2-utils-2.2.0-b21.jar | 
|  | [INFO] Copying osgi-resource-locator-1.0.1.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/osgi-resource-locator-1.0.1.jar | 
|  | [INFO] Copying asm-all-repackaged-2.2.0-b21.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/asm-all-repackaged-2.2.0-b21.jar | 
|  | [INFO] Copying cglib-2.2.0-b21.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/cglib-2.2.0-b21.jar | 
|  | [INFO] Copying jakarta.inject-2.2.0-b21.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jakarta.inject-2.2.0-b21.jar | 
|  | [INFO] Copying jersey-container-servlet-2.5.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jersey-container-servlet-2.5.jar | 
|  | [INFO] Copying jersey-container-servlet-core-2.5.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jersey-container-servlet-core-2.5.jar | 
|  | [INFO] Copying jersey-client-2.5.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jersey-client-2.5.jar | 
|  | [INFO] Copying jersey-common-2.5.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jersey-common-2.5.jar | 
|  | [INFO] Copying jersey-server-2.5.jar to /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/dependency/jersey-server-2.5.jar | 
|  | [INFO] | 
|  | [INFO] --- maven-install-plugin:2.3.1:install (default-install) @ simple-heroku-webapp --- | 
|  | [INFO] Installing /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/target/simple-heroku-webapp.war to /app/tmp/cache/.m2/repository/com/example/simple-heroku-webapp/1.0-SNAPSHOT/simple-heroku-webapp-1.0-SNAPSHOT.war | 
|  | [INFO] Installing /tmp/build_992cc747-26d6-4800-bdb1-add47b9583cd/pom.xml to /app/tmp/cache/.m2/repository/com/example/simple-heroku-webapp/1.0-SNAPSHOT/simple-heroku-webapp-1.0-SNAPSHOT.pom | 
|  | [INFO] ------------------------------------------------------------------------ | 
|  | [INFO] BUILD SUCCESS | 
|  | [INFO] ------------------------------------------------------------------------ | 
|  | [INFO] Total time: 45.861s | 
|  | [INFO] Finished at: Mon Dec 09 19:51:34 UTC 2013 | 
|  | [INFO] Final Memory: 17M/514M | 
|  | [INFO] ------------------------------------------------------------------------ | 
|  | -----> Discovering process types | 
|  | Procfile declares types -> web | 
|  |  | 
|  | -----> Compiled slug size: 75.9MB | 
|  | -----> Launching... done, v6 | 
|  | http://simple-heroku-webapp.herokuapp.com deployed to Heroku | 
|  |  | 
|  | To git@heroku.com:simple-heroku-webapp.git | 
|  | * [new branch]      master -> master</screen> | 
|  | </para> | 
|  | <para> | 
|  | Now you can access your application at, for example: <link xlink:href='http://simple-heroku-webapp.herokuapp.com/myresource'>http://simple-heroku-webapp.herokuapp.com/myresource</link> | 
|  | </para> | 
|  | </section> | 
|  | </section> | 
|  |  | 
|  | <section xml:id="exploring-jersey-examples"> | 
|  | <title>Exploring Other Jersey Examples</title> | 
|  | <para> | 
|  | In the sections above, we have covered an approach how to get dirty with Jersey quickly. Please consult the other | 
|  | sections of the Jersey User Guide to learn more about Jersey and JAX-RS. | 
|  | Even though we try our best to cover as much as possible in the User Guide, there is always a chance that you would | 
|  | not be able to get a full answer to the problem you are solving. In that case, consider diving in our examples that | 
|  | provide additional tips and hints to the features you may want to use in your projects. | 
|  | </para> | 
|  | <para> | 
|  | Jersey codebase contains a number of useful examples on how to use various JAX-RS and Jersey features. | 
|  | Feel free to browse through the code of individual | 
|  | <link xlink:href="&jersey.github.examples.uri;">Jersey Examples</link> in the Jersey source repository. | 
|  | For off-line browsing, you can also download a bundle with all the examples from | 
|  | <link xlink:href="https://repo1.maven.org/maven2/org/glassfish/jersey/bundles/jersey-examples/&version;/">here</link>. | 
|  | </para> | 
|  | </section> | 
|  | </chapter> |