|  | [//]: # " Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved. " | 
|  | [//]: # " " | 
|  | [//]: # " This program and the accompanying materials are made available under the " | 
|  | [//]: # " terms of the Eclipse Distribution License v. 1.0, which is available at " | 
|  | [//]: # " http://www.eclipse.org/org/documents/edl-v10.php. " | 
|  | [//]: # " " | 
|  | [//]: # " SPDX-License-Identifier: BSD-3-Clause " | 
|  |  | 
|  | Hello World JMH Example | 
|  | ======================= | 
|  |  | 
|  | ### *How to write JAX-RS Micro-Benchmarks* | 
|  |  | 
|  | This example demonstrates how to write simple micro-benchmarks, based on | 
|  | JMH, for JAX-RS application. This particular example shows how to obtain | 
|  | throughput of a simple 'Hello World' application. | 
|  |  | 
|  | The application consists of one resource, `HelloWorldResource` with | 
|  | three resource methods (one method per HTTP GET, POST and PUT methods). | 
|  | To make it more interesting the resource also acts like sub-resource | 
|  | locator which allows us to measure the difference between processing of | 
|  | normal resource methods and sub-resource locators. | 
|  |  | 
|  | This application is solely focused on showing how to write benchmarks | 
|  | and it doesn't start any server that would allow one to send request to | 
|  | the `HelloWorldResource`. | 
|  |  | 
|  | Main class that illustrates writing benchmarks for JAX-RS applications | 
|  | is `HelloWorldBenchmark`. Measurements are not based on any container | 
|  | such as Servlet or Grizzly container. Requests are directly invoked on | 
|  | `ApplicationHandler` class from Jersey Server module to eliminate any | 
|  | network influences. Still, all JAX-RS features, like filters and | 
|  | interceptors, are taken into consideration when the benchmark is | 
|  | executed. | 
|  |  | 
|  | It's also possible to run the benchmark on older versions of Jersey, | 
|  | e.g. 2.15, which had known performance issues with sub-resource | 
|  | locators. The recommended approach is to run the benchmarks without any | 
|  | changes at first and then modify the `pom.xml` to switch version of | 
|  | Jersey to 2.15 and run the benchmarks again to see the (big) difference. | 
|  | Look for `jersey-bom` artifact in `pom.xml` to see how the switch should | 
|  | be done. | 
|  |  | 
|  | Sample Results | 
|  | -------------- | 
|  |  | 
|  | The execution takes around 2 minutes and you can see partial results | 
|  | (for each combination of parameters) of every iteration. At the end JMH | 
|  | gives you whole summary. For example, Jersey 2.16 gives the following | 
|  | results: | 
|  |  | 
|  | # Run complete. Total time: 00:01:41 | 
|  |  | 
|  | Benchmark                    (method)              (path)   Mode  Cnt      Score      Error  Units | 
|  | HelloWorldBenchmark.measure       GET          helloworld  thrpt    8  74343.864 ± 4814.979  ops/s | 
|  | HelloWorldBenchmark.measure       GET  helloworld/locator  thrpt    8  54137.102 ± 8996.766  ops/s | 
|  | HelloWorldBenchmark.measure      POST          helloworld  thrpt    8  45173.853 ± 5349.363  ops/s | 
|  | HelloWorldBenchmark.measure      POST  helloworld/locator  thrpt    8  37144.797 ± 4699.782  ops/s | 
|  | HelloWorldBenchmark.measure       PUT          helloworld  thrpt    8  45945.974 ± 4116.752  ops/s | 
|  | HelloWorldBenchmark.measure       PUT  helloworld/locator  thrpt    8  36345.667 ± 5929.480  ops/s | 
|  |  | 
|  | Running the Example | 
|  | ------------------- | 
|  |  | 
|  | There are two ways how to run the micro-benchmark. Either via Maven | 
|  | `exec:exec` | 
|  |  | 
|  | >     mvn clean install exec:exec | 
|  |  | 
|  | or you can build the benchmark JAR at first | 
|  |  | 
|  | >     mvn clean install | 
|  |  | 
|  | and then invoking it using `java` command | 
|  |  | 
|  | >     java -jar target/benchmark.jar | 
|  |  | 
|  | Resources | 
|  | --------- | 
|  |  | 
|  | JMH has excellent overview of it's features presented as list of | 
|  | different samples. You can find them on [JMH | 
|  | Samples](http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/). | 
|  | The general overview of JMH is available at their [home | 
|  | page](http://openjdk.java.net/projects/code-tools/jmh/). |