{{announcement.body}}
{{announcement.title}}
Refcard #349

Introduction to Cloud-Native Java

Cloud-native solutions are not a novelty thing. Writing, deploying, and managing applications outside of local machines opens countless opportunities for businesses around the world. And those that use Java are major beneficiaries of this approach thanks to containers, JVM optimizations, multi-purpose frameworks, and native image technology. In this Refcard, we go through the basic explanations of cloud-native development on Java and explore everything you need to make your project cloud-native.

Published: Mar. 31, 2021    |    Modified: Apr. 12, 2021
1,314
Free PDF for easy Reference

Brought to you by

BellSoft
refcard cover

Written by

author avatar Aleksei Voitylov CTO, BellSoft
asset cover
Refcard #349

Introduction to Cloud-Native Java

Cloud-native solutions are not a novelty thing. Writing, deploying, and managing applications outside of local machines opens countless opportunities for businesses around the world. And those that use Java are major beneficiaries of this approach thanks to containers, JVM optimizations, multi-purpose frameworks, and native image technology. In this Refcard, we go through the basic explanations of cloud-native development on Java and explore everything you need to make your project cloud-native.

Published: Mar. 31, 2021    |    Modified: Apr. 12, 2021
1,314
Free PDF for easy Reference

Written by

author avatar Aleksei Voitylov CTO, BellSoft

Brought to you by

BellSoft
Table of Contents

Introduction

What Is Cloud-Native Java?

Cloud-Native Features in OpenJDK

Key Components and Approaches to Cloud-Native Java

Setting Up Your Cloud-Native Java Environment

Conclusion

Section 1

Introduction

Cloud-native solutions are not a novelty thing. Ever since the first virtualized services emerged in the 90s, it was only a matter of time before the software development process in its entirety moved to the cloud. Writing, deploying, and managing applications outside of local machines opens countless opportunities for businesses around the world. And those that use Java, one of the most popular programming languages, are major beneficiaries of this approach thanks to containers, JVM optimizations, multi-purpose frameworks, and native image technology. 

In this Refcard, we go through the basic explanations of cloud-native development on Java and see the scope of capabilities brought by multiple utilities. You’ll get everything that is required to make your project cloud-native: tools, an assessment of advantages and limitations, a detailed user guide, and a walkthrough example to get you started right away. 


This is a preview of the Introduction to Cloud-Native Java Refcard. To read the entire Refcard, please download the PDF from the link above.

Section 2

What Is Cloud-Native Java?

To understand the concept, first we need to look into its constituent parts. As VMware puts it, the cloud-native methodology rests upon four pillars: microservices, containers, CI/CD, and DevOps. 

microservice bears several characteristics. It’s a small, individual application component with a high degree of autonomy in terms of deployment and scalability. Microservice architecture represents a set of loosely coupled elements that run independently, each executing its own functionality and communicating with the others via APIs. An alternative to monoliths, microservices are lightweight and great for building clear interfaces. 

The wide adoption of microservices makes Docker containers indispensable. They are often opposed to virtual machines since they leverage a separate, more lightweight type of virtualization based on OS instances. A container image is layered and includes everything an application needs to run in the cloud: its code with dependencies, framework, OS packages and the operating system itself, runtime environment, system tools, and libraries. Container size depends on various parameters but always on the base OS image and runtime.  

Continuous integration (CI) and continuous delivery (CD) make your application’s release cycle fast, frequent, and reliable. These practices are based on the Agile methodology and depend on automation to push updates into production in small chunks rather than in bulk. 

An acronym from “software development” and “IT operations,” DevOps is an overarching concept. It is defined as the union of people, processes, and end-results to ensure automated software delivery. When an organization applies DevOps, every procedure is set toward readying code for deployment at any time: It works within a production-first mindset and a live-site culture. Developers and operations collaborate so that their customers get the highest-quality product. 

So, in its purest sense, cloud-native Java development is an approach to building Java and JVM-based applications geared initially toward cloud frameworks instead of being adapted ex-post. Such piece of software should be written with technology native to cloud computing and exhibit at least some of the following features: 

  • Microservices packaged in containers 
  • Well-defined APIs for communication 
  • Support for different user interfaces and devices 
  • Built-in DevOps practices and CI/CD pipelines 
  • Low requirements for manual management 
  • Dynamic horizontal and vertical scalability 
  • Various datastore paradigms 

Why Java?

In 2020, Java celebrated its 25th anniversary. While many other technologies have emerged and disappeared during that time, this language is still moving forward. This is due to the Java Community Process (JCP) that helps optimize Java standards for any progressive needs and its six-month release cadence. 

Thanks to Java’s long history, the industry has plenty of Java-based systems, services, and applications. It is competing with Python and JS as the most popular programming language for the Enterprise year after year. Not to mention numerous accompanying tools that simplify Java development: Spring, IntelliJ IDEA, Eclipse, NetBeans, JUnit, and more.  

Java remains vibrant in the cloud era thanks to multiple efforts by a number of companies in the OpenJDK and GraalVM projects led by Oracle. GraalVM aids developers in building microservices that satisfy most of the modern cloud requirements. 


This is a preview of the Introduction to Cloud-Native Java Refcard. To read the entire Refcard, please download the PDF from the link above.

Section 3

Cloud-Native Features in OpenJDK

You might still be wondering if Java is the right choice for cloud-native applications. Being in the industry for as long as it has, Java is an advanced language that evolves with its users. Over the years, it has accumulated lots of features that have made it lighter on the memory and in every way faster. Let us consider Java's path toward becoming cloud-oriented. 

JDK 9 introduced compact strings, saving the JVM heap space which optimizes memory consumption. A brand-new HTTP client API also appeared in JDK 9 to implement HTTP/2 and WebSocket. Not to mention container limits awareness that was then also backported to JDK 8, still one of the most popular distributions. 

The next step for the OpenJDK community was to teach garbage collectors how to return unused buffer memory back to the operating system. It was implemented in JDK 12 for the default G1. Then, two new low-latency GCs, scalable ZGC (first integrated into JDK 11) and low-time-pause Shenandoah GC (first integrated into JDK 12) changed from experimental features to product features in JDK 15. These collectors attempt to tackle the common problem of too long full GC pauses and increase the overall responsiveness in the cloud. 

Finally, the notorious metaspace collecting HotSpot class metadata had its elasticity improved in JDK 16, the most recent as of writing this Refcard. It means returning unused memory to the OS even more promptly, reducing footprint and cutting down on maintenance costs. 

To sum it up, language developers are always looking ahead. They make every effort so that Java users can seamlessly migrate to the cloud and gain from increased performance. 


This is a preview of the Introduction to Cloud-Native Java Refcard. To read the entire Refcard, please download the PDF from the link above.

Section 4

Key Components and Approaches to Cloud-Native Java

So you have a Java app and are ready to deploy it to the cloud. It might be public or private, no difference here. In any case, a cloud is represented with a set of virtual instances, where we should have a separate system to automatically manage (add, update, scale, and delete) software delivered in containers. Kubernetes would probably be your first and best choice for container orchestration. 

To access Kubernetes and expose containerized apps to the users, you will then pick an ingress controller. Among other uses, it integrates load balancers and proxies smoothly. We recommend the open-source NGINX implementation produced by the Kubernetes community, although there are plenty of others. Now it’s time to build the microservice containers. 

While DevOps is an essential cloud-native ingredient, there is a difference between DevOps and pure developers’ processes for building software. DevOps orbits around automation and release management; devs specialize in coding and deploying specifically.  

In this Refcard, we will present various cloud-native Java development approaches but focus more on the latter (referencing other Refcards that bring out the former). Let’s look into the following three methods to increase performance efficiently cloud-native-style: 

Approach 1. Easy: JVM in Linux Containers 

Docker containers, another critical cloud-native component, are not hard to comprehend. Back in the day, WAR files were deployed on web servers, which acted as isolated systems. It might be considered early containerization, albeit lacking structured configuration of services that the cloud-native ideology demands. Now, Linux containers based on cgroups functionality have taken the lead, along with the operating-system-level virtualization method.  

Today’s containers are an excellent tool to facilitate the deployment of complex Java applications. Here’s a possible setup:  

  1. A hypervisor host OS running on a server in the cloud provider’s datacenter 
  2. A guest OS running on a virtual machine provided by the hypervisor 
  3. Docker running in the guest OS and providing a container runtime 
  4. JVM inside the container — both a type of VM and a simulator of sorts — running Java bytecode on the host CPU architecture. 

This is a preview of the Introduction to Cloud-Native Java Refcard. To read the entire Refcard, please download the PDF from the link above.

Section 5

Setting Up Your Cloud-Native Java Environment

We would love to cover every single approach in great detail. Unfortunately, there’s only so much space in one Refcard. Instead of trying to bite more than one can chew, this section will focus on the third approach, Spring and native images, as the newest, least covered in the space, as well as the most convenient for developers who don’t want to revamp their entire project. 

The process of building your cloud-native Java environment doesn’t require much effort. Let’s set up the toolkit: 

  1. Kubernetes 
  2. NGINX ingress controller 
  3. Spring Boot 
  4. Apache Maven 
  5. Liberica Native Image Kit 

We won’t spend too much time on the first two pieces of software, Kubernetes with NGINX. There are many different tutorials for setting up Kubernetes and its associated tools.

The last three products here are fully compatible with one another. When building a standard Docker container in Spring with the Maven plugin, it automatically picks Liberica JDK as a base runtime image. Also, the Java Buildpack downloads BellSoft’s Liberica JRE from the Liberica GitHub releases by default with Paketo, a Cloud Foundry project. The Spring framework and Liberica are a perfect combination for making your project cloud-native. 


This is a preview of the Introduction to Cloud-Native Java Refcard. To read the entire Refcard, please download the PDF from the link above.

Section 6

Conclusion

We’ve been able to explain the very foundations of cloud-native Java, touch upon the three approaches to it, and demonstrate the use of a full-fledged tool to facilitate the switch, Liberica Native Image Kit with Spring Native. With this introduction Refcard, you can start exploring on your own and take your projects to a whole new level. 


This is a preview of the Introduction to Cloud-Native Java Refcard. To read the entire Refcard, please download the PDF from the link above.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}