Skip to content

Upgrade frameworks for jChampions Conference presentation #58

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ rm -rf {micronaut,quarkus,spring-boot}/build
rm -rf helidon/target

source ~/.sdkman/bin/sdkman-init.sh
sdk use java 21-graalce
sdk use java 21.0.1-graalce

echo "Building Micronaut..."
cd micronaut && ./gradlew nativeCompile
Expand Down
95 changes: 29 additions & 66 deletions demo.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ toc::[]

Use SDKMAN to install Java 21 with GraalVM

sdk install java 21-graalce
sdk install java 21.0.1-graalce

== Generate an OAuth 2.0 Access Token

Expand All @@ -32,7 +32,7 @@ Use SDKMAN to install Java 21 with GraalVM
+
[source,shell]
----
auth0 test token -a https://<your-auth0-domain>/api/v2/
auth0 test token -a https://<your-auth0-domain>/api/v2/ -s openid
----

. Set the access token as a `TOKEN` environment variable in a terminal window.
Expand Down Expand Up @@ -222,9 +222,11 @@ public class HelloResourceTest {
[source,shell]
----
sdk install springboot
spring init -d=web,oauth2-resource-server,native \
spring init -d=web,oauth2-resource-server,native -b=3.2.0 \
--group-id=com.okta.rest --package-name=com.okta.rest spring-boot
----
+
CAUTION: Spring Boot 3.2.1 https://github.com/oktadev/auth0-java-rest-api-examples/pull/58#issuecomment-1877844650[does not work with GraalVM].

. Add a `HelloController` class that returns the user's information: [`sb-hello`]
+
Expand Down Expand Up @@ -383,7 +385,8 @@ mp.jwt.verify.publickey.location=${mp.jwt.verify.issuer}.well-known/jwks.json
----
Args=--initialize-at-build-time=com.okta.rest \
--initialize-at-run-time=io.helidon.openapi.ExpandedTypeDescription \
--report-unsupported-elements-at-runtime
--report-unsupported-elements-at-runtime \
-H:+AddAllCharsets
----

. Compile your Helidon app into a native executable using the `native-image` profile:
Expand All @@ -401,72 +404,32 @@ Args=--initialize-at-build-time=com.okta.rest \
== Startup Time Comparison

. Run each image three times before recording the numbers, then each command five times.
+
TIP: Use the link:start.sh[`start.sh`] script to get the real time, not what each framework prints to the console.

. Write each time down, add them up, and divide by five for the average. For example:
+
----
Micronaut: (19 + 18 + 17 + 12 + 19) / 5 = 17
Micronaut (optimized): (18 + 15 + 19 + 20 + 17) / 5 = 17.8
Quarkus: (29 + 26 + 27 + 29 + 25) / 5 = 27.2
Spring Boot: (42 + 43 + 37 + 44 + 36) / 5 = 40.4
Helidon*: (50 + 52 + 42 + 53 + 55) / 5 = 50.4
Helidon (optimized): (33 + 34 + 38 + 37 + 36) / 5 = 35.6
Micronaut: (51 + 50 + 51 + 47 + 47) / 5 = 49.2
Micronaut (optimized): (49 + 50 + 48 + 52 + 57) / 5 = 51.2
Quarkus: (48 + 44 + 46 + 49 + 54) / 5 = 48.2
Spring Boot: (70 + 70 + 75 + 73 + 69) / 5 = 71.4
Helidon: (66 + 68 + 62 + 64 + 73) / 5 = 66.6
Helidon (optimized): (42 + 44 +68 + 49 + 66) / 5 = 53.8
----
+
NOTE: Helidon https://github.com/helidon-io/helidon/issues/7784[requires Java 20].

.Native Java startup times in milliseconds
|===
|Framework | Command executed | Milliseconds to start

|Micronaut | `./micronaut/build/native/nativeCompile/app` | 17
|Micronaut (optimized) | `./micronaut/build/native/nativeOptimizedCompile/app` | 17.8
|Quarkus | `./quarkus/build/quarkus-1.0.0-SNAPSHOT-runner` | 27.2
|Spring Boot | `./spring-boot/build/native/nativeCompile/spring-boot` | 40.4
|Helidon | `./helidon/target/helidon` | 50.4
|Helidon (optimized) | https://github.com/oktadev/auth0-java-rest-api-examples/pull/2[auth0-java-rest-api-examples/pull/2] | 35.6
|Micronaut | `./micronaut/build/native/nativeCompile/app` | 49.2
|Micronaut (optimized) | `./micronaut/build/native/nativeOptimizedCompile/app` | 51.2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the optimised version slower?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's what I'm seeing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@melix any idea why that could be?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, doesn't really make sense to me. However, I see that the most impactful optimizations are disabled. Not sure if disabling them is still required (optimize service loading).

|Quarkus | `./quarkus/build/quarkus-1.0.0-SNAPSHOT-runner` | 48.2
|Spring Boot | `./spring-boot/build/native/nativeCompile/spring-boot` | 71.4
|Helidon | `./helidon/target/helidon` | 66.6
|Helidon (optimized) | https://github.com/oktadev/auth0-java-rest-api-examples/pull/2[auth0-java-rest-api-examples/pull/2] | 53.8
|===

////
October 19, 2023:
- Micronaut: 17
- Micronaut (optimized): 17.8
- Quarkus: 27.2
- Spring Boot: 40.4
- Helidon: 50.4
- Helidon (optimized): 35.6

October 17, 2023:
- Micronaut: 16.2
- Micronaut (optimized): 16
- Quarkus: 27.8
- Spring Boot: 38.4
- Helidon: 49.2
- Helidon (optimized): 23.8

August 2023:
- Micronaut: 15.6
- Micronaut (optimized): 14
- Quarkus: 36.8
- Spring Boot: 38.2
- Helidon: 48.4
- Helidon (optimized): 30.8

June 2023:
- Micronaut: 33.4
- Micronaut (optimized): 23.8
- Quarkus: 25.8
- Spring Boot: 39.8
- Helidon: 47.6
- Helidon (optimized): 33.2

October 2022:
- Micronaut was 18
- Quarkus was 20.6
- Spring Boot was 39
- Helidon was 43.2
////

== Memory Usage Comparison

Test the memory usage in MB of each app using the command below. Make sure to send an HTTP request to each one before measuring.
Expand All @@ -480,14 +443,14 @@ Substitute `<executable>` as follows:

.Native Java memory used in megabytes
|===
|Framework | Executable | Megabytes after startup | Megabytes after 1 request| Megabytes after 5 requests

|Micronaut | `app` | 53 | 63 | 64
|Micronaut (optimized) | `app` | 45 | 65 | 67
|Quarkus | `quarkus` | 41 | 51 | 53
|Spring Boot | `spring-boot` | 74 | 84 | 84
|Helidon | `helidon` | 83 | 99 | 117
|Helidon (optimized) | `helidon` | 72 | 89 | 123
|Framework | Executable | Megabytes after startup | Megabytes after 1 request| Megabytes after 10 requests

|Micronaut | `app` | 53 | 62 | 66
|Micronaut (optimized) | `app` | 53 | 63 | 67
|Quarkus | `quarkus` | 37 | 48 | 52
|Spring Boot | `spring-boot` | 76 | 86 | 87
|Helidon | `helidon` | 82 | 92 | 93
|Helidon (optimized) | `helidon` | 62 | 72 | 73
|===

IMPORTANT: If you disagree with these numbers and think X framework should be faster, I encourage you to clone https://github.com/oktadev/auth0-java-rest-api-examples[this repo] and run these tests yourself.
Expand Down
8 changes: 4 additions & 4 deletions helidon/.helidon

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions helidon/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@
<parent>
<groupId>io.helidon.applications</groupId>
<artifactId>helidon-mp</artifactId>
<version>4.0.1</version>
<version>4.0.2</version>
<relativePath/>
</parent>
<groupId>com.okta.rest</groupId>
<artifactId>helidon</artifactId>
<version>1.0-SNAPSHOT</version>


<dependencies>
<dependency>
<groupId>io.helidon.microprofile.bundles</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Args=--initialize-at-build-time=com.okta.rest \
--initialize-at-run-time=io.helidon.openapi.ExpandedTypeDescription \
--report-unsupported-elements-at-runtime
--report-unsupported-elements-at-runtime \
-H:+AddAllCharsets
11 changes: 6 additions & 5 deletions memory.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ memory() {
kill_cmd="fuser -k -n tcp 8080"

if [[ "$OSTYPE" == "darwin"* ]]; then
kill_cmd="kill -9 $(lsof -i:8080 -t)"
fkill --version || echo "fkill is missing. Install it using 'npm i -g fkill-cli'."
kill_cmd="fkill :8080"
fi

# Start the app in the background
Expand All @@ -66,13 +67,13 @@ while true; do
echo -e "\n---- Memory usage after the first request:"
memory $executable

# Make four more curl requests with an access token
for ((i=1; i<=4; i++)); do
# Make 9 more curl requests with an access token
for ((i=1; i<=9; i++)); do
curl -s -o /dev/null localhost:8080/hello -i --header "Authorization: Bearer $access_token"
done

# Print out memory usage after five requests
echo -e "\n---- Memory usage after five requests:"
# Print out memory usage after 10 requests
echo -e "\n---- Memory usage after 10 requests:"
memory $executable

# Kill the app
Expand Down
18 changes: 9 additions & 9 deletions micronaut/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
## Micronaut 4.1.4 Documentation
## Micronaut 4.2.3 Documentation

- [User Guide](https://docs.micronaut.io/4.1.4/guide/index.html)
- [API Reference](https://docs.micronaut.io/4.1.4/api/index.html)
- [Configuration Reference](https://docs.micronaut.io/4.1.4/guide/configurationreference.html)
- [User Guide](https://docs.micronaut.io/4.2.3/guide/index.html)
- [API Reference](https://docs.micronaut.io/4.2.3/api/index.html)
- [Configuration Reference](https://docs.micronaut.io/4.2.3/guide/configurationreference.html)
- [Micronaut Guides](https://guides.micronaut.io/index.html)
---

- [Shadow Gradle Plugin](https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow)
- [Micronaut Gradle Plugin documentation](https://micronaut-projects.github.io/micronaut-gradle-plugin/latest/)
- [GraalVM Gradle Plugin documentation](https://graalvm.github.io/native-build-tools/latest/gradle-plugin.html)
## Feature security-jwt documentation

- [Micronaut Security JWT documentation](https://micronaut-projects.github.io/micronaut-security/latest/guide/index.html)


## Feature serialization-jackson documentation

- [Micronaut Serialization Jackson Core documentation](https://micronaut-projects.github.io/micronaut-serialization/latest/guide/)
Expand All @@ -19,8 +24,3 @@
- [Micronaut AOT documentation](https://micronaut-projects.github.io/micronaut-aot/latest/guide/)


## Feature security-jwt documentation

- [Micronaut Security JWT documentation](https://micronaut-projects.github.io/micronaut-security/latest/guide/index.html)


24 changes: 13 additions & 11 deletions micronaut/build.gradle → micronaut/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugins {
id("com.github.johnrengelman.shadow") version "8.1.1"
id("io.micronaut.application") version "4.1.2"
id("io.micronaut.aot") version "4.1.2"
id("io.micronaut.application") version "4.2.1"
id("io.micronaut.aot") version "4.2.1"
}

version = "0.1"
Expand All @@ -20,10 +20,11 @@ dependencies {
compileOnly("io.micronaut:micronaut-http-client")
runtimeOnly("ch.qos.logback:logback-classic")
testImplementation("io.micronaut:micronaut-http-client")
aotPlugins platform("io.micronaut.platform:micronaut-platform:4.1.6")
aotPlugins(platform("io.micronaut.platform:micronaut-platform:4.2.3"))
aotPlugins("io.micronaut.security:micronaut-security-aot")
}


application {
mainClass.set("com.okta.rest.Application")
}
Expand All @@ -32,7 +33,8 @@ java {
targetCompatibility = JavaVersion.toVersion("17")
}

graalvmNative.toolchainDetection = false

graalvmNative.toolchainDetection.set(false)
micronaut {
runtime("netty")
testRuntime("junit5")
Expand All @@ -43,13 +45,13 @@ micronaut {
aot {
// Please review carefully the optimizations enabled below
// Check https://micronaut-projects.github.io/micronaut-aot/latest/guide/ for more details
optimizeServiceLoading = false
convertYamlToJava = false
precomputeOperations = true
cacheEnvironment = true
optimizeClassLoading = true
deduceEnvironment = true
optimizeNetty = true
optimizeServiceLoading.set(false)
convertYamlToJava.set(false)
precomputeOperations.set(true)
cacheEnvironment.set(true)
optimizeClassLoading.set(true)
deduceEnvironment.set(true)
optimizeNetty.set(true)
configurationProperties.put("micronaut.security.jwks.enabled","false")
}
}
Expand Down
2 changes: 1 addition & 1 deletion micronaut/gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
micronautVersion=4.1.4
micronautVersion=4.2.3
Binary file modified micronaut/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion micronaut/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
17 changes: 9 additions & 8 deletions micronaut/gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
Expand Down Expand Up @@ -144,15 +145,15 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
Expand Down Expand Up @@ -201,11 +202,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.

set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
Expand Down
2 changes: 1 addition & 1 deletion micronaut/micronaut-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ applicationType: default
defaultPackage: com.okta.rest
testFramework: junit
sourceLanguage: java
buildTool: gradle
buildTool: gradle_kotlin
features: [app-name, gradle, http-client-test, java, java-application, junit, logback, micronaut-aot, micronaut-build, micronaut-http-validation, netty-server, properties, readme, security-annotations, security-jwt, serialization-jackson, shade]
File renamed without changes.
4 changes: 2 additions & 2 deletions quarkus/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ group 'com.okta.rest'
version '1.0.0-SNAPSHOT'

java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}

test {
Expand Down
4 changes: 2 additions & 2 deletions quarkus/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Gradle properties
quarkusPluginId=io.quarkus
quarkusPluginVersion=3.4.3
quarkusPluginVersion=3.6.4
quarkusPlatformGroupId=io.quarkus.platform
quarkusPlatformArtifactId=quarkus-bom
quarkusPlatformVersion=3.4.3
quarkusPlatformVersion=3.6.4
2 changes: 1 addition & 1 deletion quarkus/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading