A Bite of SpringBoot

The journey to migrate dotnet experiences to springboot and build a demo app from scratch, deploy it to kubernetes with explanation on technical points and the cloud native practice notes.

Background

As a pythonist on system level, I built several my experience with Java Web Frameworks are mostly on structs MVC as an UI backend to interact with JQuery to present the status and management from message security gateway products. However, according to the reality of circumstance, framework seems much more impressive than computer science and ways of thoughts.

It's the time to take a bite on Springboot and see what's inside.

1 Environment

In brief, Jetbrain IntelliJ community version on Mac. I used to program Python on PyCharm and IntelliJ shares similar features on Java IDE.

Java toolchain will be organized in Gradle. Maven is an alternative which I used in previous test automation tools. However, gradle is graceful and brief.

Eventually the service will be wrapped in kubernetes pod but it is not the first step.

2 Create A New Springboot App

Springboot web site offers curl interface to generate a demo project to start from. Visit https://start.spring.io on cli tool curl will show the manual on how to generate springboot scaffold.

curl https://start.spring.io
# The response shows a manual page with below samples.
Examples:

To create a default demo.zip:
$ curl https://start.spring.io/starter.zip -o demo.zip

To create a web project using Java 11:
$ curl https://start.spring.io/starter.zip -d dependencies=web \\
-d javaVersion=11 -o demo.zip

To create a web/data-jpa gradle project unpacked:
$ curl https://start.spring.io/starter.tgz -d dependencies=web,data-jpa \\
-d type=gradle-project -d baseDir=my-dir | tar -xzvf -

To generate a Maven POM with war packaging:
$ curl https://start.spring.io/pom.xml -d packaging=war -o pom.xml

I chose a demo web project using Java 8. Which means, a wrapped dependency of spring-boot-starter-web. Springboo will interrepte it to real dependencies.

curl https://start.spring.io/starter.zip -d dependencies=web -d javaVersion=8 -d type=gradle-project -o demo.zip

Alternatively, open IntelliJ menu to "New Project" will also provide options to visit start.spring.io within the IDE UI to create project scaffold.

3 Launch Springboot Demo

When importing the scaffold project to IntelliJ, a run configuration with main class on the DemoApplication , where the annotation @SpringBootApplication is applied, will be created. Run the configuration "DemoApplication" will launch Springboo web app in couple of seconds. However, visiting localhost:8080 will still return an error page since there is nothing to respond.

For the gradle configured project, the IntelliJ would spend a bit while to download gradle dependencies.

A simple controller class is added to respond string content to path /. Thanks to IntelliJ, the annotations are auto-completed. Key points here are "GetMapping" annotation to specify the path of / and "RespenseBody" annotation t

package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MainController {

@GetMapping("/")
@ResponseBody
public String home(){
return "Home";
}
}

Like npm run but more verbose than the node.js cmd, luanch ./gradlew tasks or directly run gradle tasks in root folder of project would print out a task list which can be run by gradle plugin. If it is the first time running gradle, the gradle daemon shall be luanched and basic environment/dependencies checks would be performed first.

gradlew and gradle.bat are artifacts generated by gradle warpper task which empower environments with gradle preinstalled to run gradle toolchain commands.

After updating the above controller class, run gradle bootRun would also run the springboot application to server localhost:8080. In the browser, the simple content "Home" is fetched and rendered.

4 Build Docker Image for Springboot App

As usual there are multiple ways to build docker images as first step to containerize the app. Thanks to the gradle community com.palantir.docker plugin is picked up in this demo project.

The gradle pluin could be applied in build.script DSL or plugin DSL. This experiment applies the plugin DSL and build docker image with Dockerfile rather than docker plugin DSL to reuse author's existing Dockerfile experiences for now.

4.1 Add Plugin

Insert this plugin reference to build.gradle id 'com.palantir.docker' version '0.22.1'.

4.2 Introduce docker Task

The task is defined as below:

docker {
dependsOn build
name "${project.group}/${bootJar.baseName}"
files bootJar.archivePath
buildArgs(['JAR_FILE': "${bootJar.archiveName}"])
}

4.3 Create the Dockerfile

To keep the image slim, alpine jdk8 image is picked as base image.

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

4.4 Launch Container Locally

With above Dockerfile and the docker task inserted to gradle.build script, run gradle docker would (re)build the app image with dependencies. Quickly test the docker image by launching it locally, docker run -p 8080:8080 -t com.example/demo. Then open browser on URL http://localhost:8080/ the same contents are responded "Home".

5 Deploy to Kubernetes

(To be continued)

Change Log

Sep 22, 2019: Configuration and start a new springboot app. Sep 28, 2019: