<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Thomas Vitale</title>
    <description>The latest articles on Forem by Thomas Vitale (@thomasvitale).</description>
    <link>https://forem.com/thomasvitale</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F274574%2Fa7860a65-b553-43b1-85b8-a7604e8851bb.jpeg</url>
      <title>Forem: Thomas Vitale</title>
      <link>https://forem.com/thomasvitale</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/thomasvitale"/>
    <language>en</language>
    <item>
      <title>Spring Native: Getting started with GraalVM native images</title>
      <dc:creator>Thomas Vitale</dc:creator>
      <pubDate>Wed, 12 May 2021 17:49:38 +0000</pubDate>
      <link>https://forem.com/thomasvitale/spring-native-getting-started-with-graalvm-native-images-457b</link>
      <guid>https://forem.com/thomasvitale/spring-native-getting-started-with-graalvm-native-images-457b</guid>
      <description>&lt;p&gt;The Spring Native project provides support for packaging Spring applications as native images using GraalVM.&lt;/p&gt;

&lt;p&gt;Compared to JVM executables, native images have faster startup times (&amp;lt; 100 ms) and lower memory consumption. However, building a native image requires more time than a JVM-based one.&lt;/p&gt;

&lt;p&gt;The project is still in beta but already supports most of the Spring portfolio modules, including Spring Framework, Spring Boot, Spring Security, and Spring Cloud.&lt;/p&gt;

&lt;p&gt;Its features make it a good fit for building serverless applications with Spring Cloud Function and deploying them to a platform like Azure Functions, AWS Lambda, or Knative.&lt;/p&gt;

&lt;p&gt;This article will guide you through the building of a Spring Boot application compiled to a native executable with Spring Native. You can find the &lt;a href="https://github.com/ThomasVitale/spring-tutorials/tree/master/spring-native-graalvm"&gt;source code&lt;/a&gt; on GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bootstrapping an application with Spring Native
&lt;/h2&gt;

&lt;p&gt;You can add Spring Native to your application when bootstrapping the project from &lt;a href="https://start.spring.io/"&gt;Spring Initializr&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iorcP9vE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uk70r57v293moc3uqcd7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iorcP9vE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uk70r57v293moc3uqcd7.png" alt="Bootstrap a Spring Boot application with Spring Reactive Web and Spring Native"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The generated project will contain a dependency on the Spring Native project and the Spring AOT plugin used to compile your application source code to native executable while improving compatibility and footprint.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;build.gradle&lt;/code&gt; file looks as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;plugins&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework.boot'&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s1"&gt;'2.4.3'&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="s1"&gt;'io.spring.dependency-management'&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s1"&gt;'1.0.11.RELEASE'&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="s1"&gt;'java'&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework.experimental.aot'&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s1"&gt;'0.9.0'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'com.thomasvitale'&lt;/span&gt;
&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'0.0.1-SNAPSHOT'&lt;/span&gt;
&lt;span class="n"&gt;sourceCompatibility&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'11'&lt;/span&gt;

&lt;span class="n"&gt;repositories&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;maven&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="s1"&gt;'https://repo.spring.io/release'&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;mavenCentral&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework.boot:spring-boot-starter-webflux'&lt;/span&gt;
    &lt;span class="n"&gt;testImplementation&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework.boot:spring-boot-starter-test'&lt;/span&gt;
    &lt;span class="n"&gt;testImplementation&lt;/span&gt; &lt;span class="s1"&gt;'io.projectreactor:reactor-test'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;useJUnitPlatform&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;bootBuildImage&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'paketobuildpacks/builder:tiny'&lt;/span&gt;
    &lt;span class="n"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'BP_NATIVE_IMAGE'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'true'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can build a native image out of your application using the familiar Spring Boot plugin (Gradle or Maven) and its embedded Cloud Native Buildpacks support. The choice between JVM and GraalVM images is defined by the &lt;code&gt;BP_NATIVE_IMAGE&lt;/code&gt; property in the &lt;code&gt;bootBuildImage&lt;/code&gt; task, which comes pre-configured when you use Spring Initialzr.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining a REST endpoint with Spring WebFlux
&lt;/h2&gt;

&lt;p&gt;Let's define a REST endpoint with Spring WebFlux so that we can test the application.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;SpringNativeGraalvmApplication&lt;/code&gt; class generated by the Initializr, you can add a REST endpoint using a router function or a &lt;code&gt;@RestController&lt;/code&gt;-annotated class. Let's go with the former option.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.thomasvitale.demo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;reactor.core.publisher.Mono&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.SpringApplication&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.autoconfigure.SpringBootApplication&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.Bean&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.reactive.function.server.RouterFunction&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.reactive.function.server.ServerResponse&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;springframework&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reactive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RouterFunctions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;route&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;springframework&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reactive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ServerResponse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@SpringBootApplication&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SpringNativeGraalvmApplication&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringNativeGraalvmApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="nc"&gt;RouterFunction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ServerResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;routes&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GET&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Mono&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;just&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Spring Native and Beyond!"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, in the &lt;code&gt;SpringNativeGraalvmApplicationTests&lt;/code&gt; class generated by the Initializr, you can add an integration test for the REST endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.thomasvitale.demo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.test.context.SpringBootTest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.test.web.reactive.server.WebTestClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;webEnvironment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SpringBootTest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;WebEnvironment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RANDOM_PORT&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@AutoConfigureWebTestClient&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SpringNativeGraalvmApplicationTests&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;WebTestClient&lt;/span&gt; &lt;span class="n"&gt;webClient&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;whenGetBooksThenReturn&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;webClient&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exchange&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;expectStatus&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;is2xxSuccessful&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;expectBody&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;isEqualTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Spring Native and Beyond!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Running the application as an executable JAR
&lt;/h2&gt;

&lt;p&gt;The Spring Native dependency in your project will optimize the application startup time and memory consumption, thanks to the Spring AOT plugin, even when running it as an executable JAR. Let's try it out.&lt;/p&gt;

&lt;p&gt;First, open a Terminal window, navigate to the root folder of your project, and run the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;./gradlew bootRun
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application will start up faster than its corresponding version without Spring AOT. Let's try calling the REST endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl http://localhost:8080
Spring Native and Beyond!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Running the application as a native image
&lt;/h2&gt;

&lt;p&gt;Now, let's try building and running a native image leveraging Spring Native with GraalVM.&lt;/p&gt;

&lt;p&gt;Building a native image is very straightforward with the Spring Boot plugin. Make sure your Docker Engine is running, and then execute the following command. Be aware that it will take a few minutes, very much depending on your laptop CPU and memory characteristics.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;./gradlew bootBuildImage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result will be a &lt;code&gt;spring-native-graalvm:0.0.1-SNAPSHOT&lt;/code&gt; image that you can run with Docker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; spring-native-graalvm &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 spring-native-graalvm:0.0.1-SNAPSHOT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Applications with Spring Native typically start in less than 100 ms, depending on your machine's available resources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bjNMFlYX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l0mqi39u9vcaw73twnoa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bjNMFlYX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l0mqi39u9vcaw73twnoa.png" alt="A Spring Native application typically starts in less than 100ms"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once again, let's call the REST endpoint to ensure the application is still working when run as a native image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl http://localhost:8080
Spring Native and Beyond!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It does. Good job!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, I went through how to quickly bootstrap a Spring Boot application and compile it to a native executable using Spring Native and GraalVM.&lt;/p&gt;

&lt;p&gt;For more information on the Spring Native project and to follow its roadmap, you can refer to the &lt;a href="https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're interested in cloud native development with Spring Boot and Kubernetes, check out my book &lt;a href="https://www.manning.com/books/cloud-native-spring-in-action"&gt;Cloud Native Spring in Action&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Did you like this article? Check out my personal blog for more: &lt;a href="https://www.thomasvitale.com"&gt;thomasvitale.com&lt;/a&gt;. I write about Enterprise Java, Spring, Keycloak and Application Security.&lt;/p&gt;

</description>
      <category>java</category>
      <category>docker</category>
      <category>cloud</category>
      <category>spring</category>
    </item>
    <item>
      <title>New Book: Cloud Native Spring in Action - With Spring Boot and Kubernetes</title>
      <dc:creator>Thomas Vitale</dc:creator>
      <pubDate>Sun, 06 Sep 2020 14:25:44 +0000</pubDate>
      <link>https://forem.com/thomasvitale/new-book-cloud-native-spring-in-action-with-spring-boot-and-kubernetes-12b8</link>
      <guid>https://forem.com/thomasvitale/new-book-cloud-native-spring-in-action-with-spring-boot-and-kubernetes-12b8</guid>
      <description>&lt;p&gt;I'm thrilled to announce that my new book, &lt;a href="https://www.manning.com/books/cloud-native-spring-in-action?utm_source=affiliate&amp;amp;utm_medium=affiliate&amp;amp;a_aid=thomas&amp;amp;a_bid=3dda43a8"&gt;Cloud Native Spring in Action&lt;/a&gt; (Manning Publishing), is now available in early access.&lt;/p&gt;

&lt;p&gt;In the last few years, it has become clear that many organizations had to choose the cloud to keep the business alive. A traditional approach based on application servers and on-premise “snowflake” infrastructure can hardly ensure the requirements of modern applications: scalability, resilience, zero-downtime, reliability, short feedback cycles, and frequent releases. To fully leverage the cloud capabilities, it wasn’t enough to move traditional applications to the new infrastructure. Something else was needed. Applications had to become cloud native.&lt;/p&gt;

&lt;p&gt;This book will take you on an exciting journey in the cloud native world from development to production using the latest features from Spring, Docker, and Kubernetes. You’ll have the chance to apply every new idea along the journey by progressively building a full cloud native system for an online bookshop. By the end of the book, you’ll have it deployed to a Kubernetes cluster in a public cloud.&lt;/p&gt;

&lt;p&gt;The book is divided into four parts. Part 1 will guide you through the cloud native landscape, defining what it means for an application to be cloud native, and establishing tools, technologies, and patterns you’ll bring on your journey.&lt;/p&gt;

&lt;p&gt;Part 2 will get you started with the fundamentals of cloud native development. You’ll work with RESTful Spring application services and data persistence, understand how to manage configuration across environments, define automation for your continuous integration process, learn how the Docker containerization works, and finally deploy your apps to a local Kubernetes cluster.&lt;/p&gt;

&lt;p&gt;In Part 3, your journey gets to a whole new level. You’ll move from a single app to a distributed system in the cloud. You’ll learn about service discovery, load balancing, scalability, and resilience. You’ll then explore the features of event-driven architecture and secure your system with authentication, authorization, and encryption.&lt;/p&gt;

&lt;p&gt;In Part 4, you’ll ensure the observability of your applications, dealing with logging, tracing, and monitoring. Finally, you’ll get to the long wished for destination: production. You’ll learn how to deploy your application to a Kubernetes cluster in a public cloud, and automate the delivery and deployment process. A new journey starts in production. You’ll get familiar with the next steps in your cloud native adventure and learn some tips on migrating your existing applications.&lt;/p&gt;

&lt;p&gt;If you start reading the book, please let me know your thoughts on &lt;a href="https://twitter.com/vitalethomas"&gt;Twitter&lt;/a&gt; or in the &lt;a href="https://livebook.manning.com/book/cloud-native-spring-in-action/chapter-1/v-1/"&gt;Manning liveBook discussion forum&lt;/a&gt; about what's been written so far and what you'd like to see in the rest of the book. Your feedback will be invaluable in improving &lt;em&gt;Cloud Native Spring in Action&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>kubernetes</category>
      <category>cloud</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Quarkus - Develop Your First Supersonic Enterprise Java Application</title>
      <dc:creator>Thomas Vitale</dc:creator>
      <pubDate>Mon, 18 Nov 2019 21:47:26 +0000</pubDate>
      <link>https://forem.com/thomasvitale/quarkus-develop-your-first-supersonic-enterprise-java-application-4c9f</link>
      <guid>https://forem.com/thomasvitale/quarkus-develop-your-first-supersonic-enterprise-java-application-4c9f</guid>
      <description>&lt;p&gt;In this article, we're going to getting started with our first supersonic Quarkus application. We will develop a RESTful application using the familiar JAX-RS and CDI APIs, learn how to run it in a Quarkus environment and see how to test it.&lt;/p&gt;

&lt;p&gt;Recently, &lt;a href="https://quarkus.io/blog/announcing-quarkus-1-0/"&gt;Quarkus 1.0 has been announced&lt;/a&gt;, an important milestone for the Java community.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://quarkus.io/"&gt;Quarkus&lt;/a&gt;&lt;/strong&gt; is an Open Source stack to write Java applications offering unparalleled startup time, memory footprint and developer experience. It offers familiar programming models and APIs (Hibernate, JAX-RS, Eclipse Vert.x, Apache Camel, Eclipse MicroProfile, Spring API compatibility and more).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, we're going to getting started with our first Quarkus application, more specifically a &lt;strong&gt;RESTful application&lt;/strong&gt; using the familiar JAX-RS and CDI APIs from &lt;a href="https://www.thomasvitale.com/getting-started-jakarta-ee-first-look/"&gt;Jakarta EE&lt;/a&gt;. We will also see how to test our application. You can find the &lt;a href="https://github.com/ThomasVitale/quarkus-tutorials/tree/master/quarkus-getting-started"&gt;source code&lt;/a&gt; on my GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow along with this tutorial, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JDK 8 or 11+&lt;/li&gt;
&lt;li&gt;an IDE&lt;/li&gt;
&lt;li&gt;Apache Maven 3.5.3+&lt;/li&gt;
&lt;li&gt;Gradle 5.5.0+&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will use Gradle to build the application, but you're free to use Maven. Be aware that using Gradle with Quarkus is preview functionality. It might not support all the possible scenarios, but it works well enough for the application we are going to build in this tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Bootstrapping a Quarkus Application
&lt;/h2&gt;

&lt;p&gt;The application that we are going to develop is a fictitious RESTful application for a library, which exposes an endpoint to fetch all the available books.&lt;/p&gt;

&lt;p&gt;We can quickly bootstrap a Quarkus application in two ways: leveraging Maven from the command line or using the convenient UI-based application generator.&lt;/p&gt;

&lt;p&gt;In both cases, we need to provide some important information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;group and artifact ids&lt;/li&gt;
&lt;li&gt;build tool (Maven or Gradle)&lt;/li&gt;
&lt;li&gt;extensions (i.e. dependencies).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;em&gt;RESTeasy JAX-RS&lt;/em&gt; extension is included by default, while we need to include the &lt;em&gt;RESTeasy JSON-B&lt;/em&gt; extension explicitly.&lt;/p&gt;

&lt;p&gt;Using the Maven generator, we can also specify a resource class to be automatically generated and configured for JAX-RS and an optional path.&lt;/p&gt;

&lt;p&gt;Let's have a look at both the options.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Maven to generate a Quarkus application
&lt;/h3&gt;

&lt;p&gt;Let's open a Terminal window and run the following command to generate an application which will use Maven as a built tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR1:create &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-DprojectGroupId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;com.thomasvitale &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-DprojectArtifactId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;quarkus-getting-started &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-DclassName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"com.thomasvitale.library.BookResource"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-Dpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/books"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-Dextensions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"resteasy-jsonb"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Should we prefer to use Gradle as the tool to build our application, we can do so in this way (notice the extra &lt;code&gt;buildTool&lt;/code&gt; parameter):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR1:create &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-DprojectGroupId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;com.thomasvitale &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-DprojectArtifactId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;quarkus-getting-started &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-DclassName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"com.thomasvitale.library.BookResource"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-Dpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/books"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-Dextensions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"resteasy-jsonb"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-DbuildTool&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gradle
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Using the UI-based initializer to generate a Quarkus application
&lt;/h3&gt;

&lt;p&gt;In alternative to Maven, we can go to &lt;a href="https://code.quarkus.io/"&gt;code.quarkus.io&lt;/a&gt; and create our Quarkus application from a convenient user interface where to insert all the details about the project, the build tool and the extensions we need. Are you familiar with the &lt;a href="https://start.spring.io/"&gt;Spring Initializr&lt;/a&gt;? This tool works in the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The Structure of a Quarkus Application
&lt;/h2&gt;

&lt;p&gt;The basic structure of the generated Quarkus application follows the Maven standard. On top of that, there are some extra features.&lt;/p&gt;

&lt;p&gt;As defined in the previous section, we can notice that the &lt;code&gt;BookResource&lt;/code&gt; class has been generated in &lt;code&gt;src/main/java&lt;/code&gt;, together with test classes in &lt;code&gt;src/test/java&lt;/code&gt; and &lt;code&gt;src/native-test/java&lt;/code&gt;. The first tests are run in JVM mode, the second in native mode. The &lt;code&gt;BookResource&lt;/code&gt; is exposed to the &lt;code&gt;/books&lt;/code&gt; endpoint and accessible by default on &lt;code&gt;http://localhost:8080&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;src/main/docker&lt;/code&gt;, we can find example &lt;code&gt;Dockerfile&lt;/code&gt; files to run our application in a container, either in JVM or native mode.&lt;/p&gt;

&lt;p&gt;To easily build the application, a Quarkus plugin is applied (either for Maven or Gradle), and a Quarkus BOM is imported to define which version we want to use throughout the application.&lt;/p&gt;

&lt;p&gt;In the dependencies section of our &lt;code&gt;gradle.build&lt;/code&gt; file (or &lt;code&gt;pom.xml&lt;/code&gt; if using Maven), we can find the RESTeasy extensions that we defined for the generator, plus JUnit5 and RestAssured to test our application both in JVM and native mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'io.quarkus:quarkus-resteasy-jsonb'&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'io.quarkus:quarkus-resteasy'&lt;/span&gt;

    &lt;span class="n"&gt;testImplementation&lt;/span&gt; &lt;span class="s1"&gt;'io.quarkus:quarkus-junit5'&lt;/span&gt;
    &lt;span class="n"&gt;testImplementation&lt;/span&gt; &lt;span class="s1"&gt;'io.rest-assured:rest-assured'&lt;/span&gt;

    &lt;span class="n"&gt;nativeTestImplementation&lt;/span&gt; &lt;span class="s1"&gt;'io.quarkus:quarkus-junit5'&lt;/span&gt;
    &lt;span class="n"&gt;nativeTestImplementation&lt;/span&gt; &lt;span class="s1"&gt;'io.rest-assured:rest-assured'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  4. JVM vs Native Mode
&lt;/h2&gt;

&lt;p&gt;In the previous section, we mentioned a few times JVM and native modes. Some clarification is in order.&lt;/p&gt;

&lt;p&gt;The JVM mode exploits the standard JVM. It tailors the runtime such that it includes only what the application actually needs, removing all the extra dynamics of a standard enterprise runtime. This results in lower memory consumption, and a faster boot phase and first response time comparing to a traditional enterprise application.&lt;/p&gt;

&lt;p&gt;The Quarkus JVM mode is already a significant advantage over the traditional enterprise Java application. In reality, what makes Quarkus shines is its native mode. Quarkus has been designed around a &lt;a href="https://quarkus.io/vision/container-first"&gt;container first&lt;/a&gt; philosophy, with native support for GraalVM and SubstrateVM. When using this mode, our applications are pre-built and compiled to native executables which start up almost immediately and are incredibly well-performant both in terms of time and memory consumption.&lt;/p&gt;

&lt;p&gt;In this tutorial, we're going to run the application and its tests in JVM mode. In a future article, instead, we will see how the native mode works.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Implementing the REST API
&lt;/h2&gt;

&lt;p&gt;Now, let's get started with the actual development phase. A &lt;code&gt;BookResource&lt;/code&gt; class has been generated for us. It's time to implement some endpoints.&lt;/p&gt;

&lt;p&gt;We're going to expose two endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/books&lt;/code&gt; returns the list of books available in the library;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/books/{id}&lt;/code&gt; returns the book having the specified id.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/books"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookResource&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Inject&lt;/span&gt;
    &lt;span class="nc"&gt;BookService&lt;/span&gt; &lt;span class="n"&gt;bookService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@GET&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getBooks&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;bookService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBooks&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@GET&lt;/span&gt;
    &lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{id}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="nf"&gt;getBookById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;bookService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBookById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's interesting to notice that, differently from vanilla JAX-RS as used in Jakarta EE, in Quarkus we don't need to define an &lt;code&gt;Application&lt;/code&gt; class annotated with &lt;code&gt;@ApplicationPath&lt;/code&gt; to enable the REST API. Also, by default, the resource class is configured as &lt;code&gt;@ApplicationScoped&lt;/code&gt;. You can change the configuration by using the familiar annotations from CDI to define the scope of a class.&lt;/p&gt;

&lt;p&gt;The functionality to retrieve books is delegated to the &lt;code&gt;BookService&lt;/code&gt; class, which is injected as a CDI bean in &lt;code&gt;BookResource&lt;/code&gt;. The service defines a static map to simulate a book repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ApplicationScoped&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bookRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ConcurrentHashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;bookRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1L&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1L&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Harry Potter"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;bookRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2L&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2L&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"The Lord of The Rings"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;bookRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3L&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3L&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"The Golden Compass"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getBooks&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;bookRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="nf"&gt;getBookById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;bookRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally, the &lt;code&gt;Book&lt;/code&gt; class is a POJO.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="nf"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getTitle&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setTitle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Running the Quarkus Application
&lt;/h2&gt;

&lt;p&gt;It's time to run our Quarkus application for the first time. Ready for some &lt;em&gt;supersonic subatomic&lt;/em&gt; deployment? &lt;/p&gt;

&lt;p&gt;Let's open a Terminal window and run the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew assemble quarkusDev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If using Maven, we can run the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;./mvnw compile quarkus:dev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;quarkusDev&lt;/code&gt; task (or &lt;code&gt;quarkus:dev&lt;/code&gt; when using Maven) runs Quarkus in development mode. The main feature of this mode is the hot deployment with background compilation, which means we can modify our source files (both Java classes and resources) while the application is running and the changes will automatically take effect.&lt;/p&gt;

&lt;p&gt;When running Quarkus in development mode, the debug mode is enabled by default, listening to port &lt;code&gt;5005&lt;/code&gt; without suspending the JVM.&lt;/p&gt;

&lt;p&gt;Now, let's verify if it's working. From the Terminal, let's call our brand new REST API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8080/books/1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;:1,&lt;span class="s2"&gt;"title"&lt;/span&gt;:&lt;span class="s2"&gt;"Harry Potter"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Great, it's working!&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Testing
&lt;/h2&gt;

&lt;p&gt;We manually verified that our REST endpoints are correctly exposed to our Quarkus application, but it's better to write some autotests.&lt;/p&gt;

&lt;p&gt;Let's use the &lt;code&gt;BookResourceTest&lt;/code&gt; class in &lt;code&gt;src/test/java&lt;/code&gt; that has been already generated for us and let's write a couple of tests for the two endpoints exposed by the &lt;code&gt;BookResource&lt;/code&gt; class. As mentioned before, we're going to use &lt;a href="https://junit.org/junit5/"&gt;JUnit5&lt;/a&gt; and &lt;a href="http://rest-assured.io/"&gt;RestAssured&lt;/a&gt; to write our tests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@QuarkusTest&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookResourceTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testGetBooks&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;given&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/books"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;then&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hasItems&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testGetBookById&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;given&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pathParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/books/{id}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;then&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
             &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
             &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;@QuarkusTest&lt;/code&gt; annotation makes sure that the application is running before starting the tests.&lt;/p&gt;

&lt;p&gt;Tests can be run either directly from our IDE or our build tool. If we use Gradle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With Maven, instead, we run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;./mvnw &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Super! We now also have autotests ensuring that our application works as intended.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we have had a first look at Quarkus. We have explored the different ways to generate a basic Quarkus project and went through its structure to identify all the main parts of the application. Then, we have implemented a simple RESTful application leveraging the familiar JAX-RS and CDI APIs for enterprise Java and learned how to run a Quarkus application in development mode. Finally, we have ensured that the application has been implemented correctly by writing some autotests and learned how to run them.&lt;/p&gt;

&lt;p&gt;Quarkus is definitely here to stay, and I'm looking forward to seeing how it will change the enterprise Java application landscape. And you? Let me know what you think about Quarkus and if you're considering starting using it for your future projects.&lt;/p&gt;




&lt;p&gt;Did you like this article? Check out my personal blog for more: &lt;a href="https://www.thomasvitale.com"&gt;thomasvitale.com&lt;/a&gt;. I write about Enterprise Java, Spring, Keycloak and Application Security.&lt;/p&gt;

</description>
      <category>quarkus</category>
      <category>java</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
