| <?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> |