|
| 1 | +--- |
| 2 | +title: Install the JDK and build an application |
| 3 | +weight: 4 |
| 4 | + |
| 5 | +### FIXED, DO NOT MODIFY |
| 6 | +layout: learningpathall |
| 7 | +--- |
| 8 | + |
| 9 | + |
| 10 | +### Platform Overview |
| 11 | +Whether you're using an Azure Linux 3.0 Docker container or a VM created from a custom Azure Linux 3.0 image, the deployment and benchmarking steps remain the same. |
| 12 | + |
| 13 | +### Working inside Azure Linux 3.0 Docker container |
| 14 | +The Azure Linux Container Host is an operating system image that's optimized for running container workloads on Azure Kubernetes Service (AKS). Microsoft maintains the Azure Linux Container Host and based it on CBL-Mariner, an open-source Linux |
| 15 | +distribution created by Microsoft. |
| 16 | +To know more about Azure Linux 3.0, kindly refer [What is Azure Linux Container Host for AKS](https://learn.microsoft.com/en-us/azure/azure-linux/intro-azure-linux). Azure Linux 3.0 offers support for Aarch64. However, the standalone VM image for Azure Linux 3.0 or CBL Mariner 3.0 is not available for Arm. |
| 17 | + |
| 18 | +Hence, to use the default software stack provided by the Microsoft team, this guide will focus on creating a docker container with Azure Linux 3.0 as a base image and will build |
| 19 | +and run the Java application inside the container, with the default JDK provided by the Microsoft team via Azure Linux 3.0 environment. |
| 20 | + |
| 21 | +### Create Azure Linux 3.0 Docker Container |
| 22 | +The [Microsoft Artifact Registry](https://mcr.microsoft.com/en-us/artifact/mar/azurelinux/base/core/about) offers updated docker image for the Azure Linux 3.0. |
| 23 | + |
| 24 | +To create a docker container, install docker, and then follow the below instructions: |
| 25 | + |
| 26 | +```console |
| 27 | +$ sudo docker run -it --rm mcr.microsoft.com/azurelinux/base/core:3.0 |
| 28 | +``` |
| 29 | + |
| 30 | +The default container startup command is bash. tdnf and dnf are the default package managers. |
| 31 | + |
| 32 | +### Install Java |
| 33 | + |
| 34 | +This Azure Linux 3.0 image does not include Java, so you need to install it. |
| 35 | + |
| 36 | +First update tdnf: |
| 37 | + |
| 38 | +```console |
| 39 | +$ tdnf update -y |
| 40 | +``` |
| 41 | +Then install java-devel: |
| 42 | + |
| 43 | +```console |
| 44 | +$ tdnf install -y java-devel |
| 45 | +``` |
| 46 | + |
| 47 | +Java-devel installs both the default JRE and JDK provided by Azure Linux 3.0. |
| 48 | + |
| 49 | +Check to ensure that the JRE is properly installed: |
| 50 | + |
| 51 | +```console |
| 52 | +$ java -version |
| 53 | +``` |
| 54 | + |
| 55 | +**Your output will look like this:** |
| 56 | + |
| 57 | +```output |
| 58 | +openjdk version "11.0.27" 2025-04-15 LTS |
| 59 | +OpenJDK Runtime Environment Microsoft-11371464 (build 11.0.27+6-LTS) |
| 60 | +OpenJDK 64-Bit Server VM Microsoft-11371464 (build 11.0.27+6-LTS, mixed mode, |
| 61 | +sharing) |
| 62 | +``` |
| 63 | + |
| 64 | +**Check to ensure that the JDK is properly installed:** |
| 65 | + |
| 66 | +```console |
| 67 | +$ javac -version |
| 68 | +``` |
| 69 | +Your output will look like this: |
| 70 | + |
| 71 | +```output |
| 72 | +javac 11.0.27 |
| 73 | +``` |
| 74 | + |
| 75 | +Set Java Environment Variable for Arm: |
| 76 | + |
| 77 | +```console |
| 78 | +$ export JAVA_HOME=/usr/lib/jvm/msopenjdk-11 |
| 79 | +$ export PATH=$JAVA_HOME/bin:$PATH |
| 80 | +``` |
| 81 | + |
| 82 | +{{% notice Note %}} |
| 83 | +Azure Linux 3.0 offers the default JDK version 11.0.27. It’s important to ensure that your version of OpenJDK for Arm is at least 11.0.9, or above. There is a large performance gap between OpenJDK-11.0.8 and OpenJDK 11.0.9. A patch added in 11.0.9 reduces false-sharing cache contention. |
| 84 | +For more information, you can view this [Arm community blog](https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/java-performance-on-neoverse-n1). |
| 85 | + |
| 86 | +The [Arm Ecosystem Dashboard](https://developer.arm.com/ecosystem-dashboard/) also recommends Java/OpenJDK version 11.0.9 as minimum recommended on the Arm platforms. |
| 87 | +{{% /notice %}} |
| 88 | + |
| 89 | +### Deploy a Java application with Tomcat-like operation |
| 90 | +Apache Tomcat is a Java-based web application server (technically, a Servlet container) that executes Java web applications. It's widely used to host Java servlets, JSP (JavaServer Pages), |
| 91 | +and RESTful APIs written in Java. |
| 92 | +The below Java class simulates the generation of a basic HTTP response and measures the time taken to construct it, mimicking a lightweight Tomcat-like operation. It measures how long it |
| 93 | +takes to build the response string, helping evaluate raw Java execution efficiency before deploying heavier frameworks like Tomcat. |
| 94 | +Create a file named `HttpSingleRequestTest.java`, and add the below content to it: |
| 95 | + |
| 96 | +```java |
| 97 | +public class HttpSingleRequestTest { |
| 98 | + public static void main(String[] args) { |
| 99 | + long startTime = System.nanoTime(); |
| 100 | + String response = generateHttpResponse("Tomcat baseline test on Arm64"); |
| 101 | + long endTime = System.nanoTime(); |
| 102 | + double durationInMicros = (endTime - startTime) / 1_000.0; |
| 103 | + System.out.println("Response Generated:\n" + response); |
| 104 | + System.out.printf("Response generation took %.2f microseconds.%n", durationInMicros); |
| 105 | + } |
| 106 | + private static String generateHttpResponse(String body) { |
| 107 | + return "HTTP/1.1 200 OK\r\n" + |
| 108 | + "Content-Type: text/plain\r\n" + |
| 109 | + "Content-Length: " + body.length() + "\r\n\r\n" + |
| 110 | + body; |
| 111 | + } |
| 112 | +} |
| 113 | +``` |
| 114 | +Compile and Run Java program : |
| 115 | + |
| 116 | +```console |
| 117 | +$ javac HttpSingleRequestTest.java |
| 118 | +$ java -Xms128m -Xmx256m -XX:+UseG1GC HttpSingleRequestTest |
| 119 | +``` |
| 120 | + |
| 121 | +- -Xms128m sets the initial heap size for the Java Virtual Machine to 128 MB. |
| 122 | +- -Xmx256m sets the maximum heap size for the JVM to 256 MB. |
| 123 | +- -XX:+UseG1GC enables the G1 Garbage Collector (Garbage First GC), designed for low pause times and better performance in large heaps. |
| 124 | + |
| 125 | +Output of java program on the Arm VM: |
| 126 | +```output |
| 127 | +
|
| 128 | +$ javac HttpSingleRequestTest.java |
| 129 | +$ java -Xms128m -Xmx256m -XX:+UseG1GC HttpSingleRequestTest |
| 130 | +Response Generated: |
| 131 | +HTTP/1.1 200 OK |
| 132 | +Content-Type: text/plain |
| 133 | +Content-Length: 29 |
| 134 | +
|
| 135 | +Tomcat baseline test on Arm64 |
| 136 | +Response generation took 22125.79 microseconds. |
| 137 | +``` |
| 138 | +Output summary: |
| 139 | + |
| 140 | +- The program generated a fake HTTP 200 OK response with a custom message. |
| 141 | +- It then measured and printed the time taken to generate that response (22125.79 microseconds). |
| 142 | +- This serves as a basic baseline performance test of string formatting and memory handling on the JVM running on an Azure Arm64 instance. |
0 commit comments