Share
Embed
Quarkus で FizzBuzz する CLI を作ってみた / FizzBuzz with Quarkus
kota2and3kan
March 05, 2026
Transcript
52 slides
-
2026/03/05 シネマ de LT会#2 〜Back to the Screen〜 Quarkus で
FizzBuzz する CLI を 作ってみた #CinemaDeLT -
Name: こたつ&&みかん Account: @kota2and3kan Company: Name: Scalar, Inc. Product: -
ScalarDB (Distributed Transaction Manager) - ScalarDL (Byzantine Fault Detection Middleware) Job: [Technical Support, Infra Engineer] Like: DB: [PostgreSQL, CockroachDB] Bouldering: 5Q Dislike: Real Cockroach Who am I. -
1 から順に数字を出力するプログラム。 ただし、 • 3の倍数の時は Fizz • 5の倍数の時は Buzz •
15の倍数の時は FizzBuzz と出力する。 FizzBuzz とは... -
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz
FizzBuzz とは... (例) Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz -
※補足※ Quarkus は Java の Distro ではなく、 Framework 的なもの。 Spring
Framework とかと同じ立ち位 置のイメージ。 -
Native Image を build するコマンド $ quarkus build --native $
./mvnw install -Dnative $ ./gradlew build -Dquarkus.native.enabled=true quarkus コマンドを使う場合 ./mvnw コマンドを使う場合 ./gradlew コマンドを使う場合 -
$ quarkus build --native jdk-25: Pulling from quarkus/ubi9-quarkus-mandrel-builder-image Digest: sha256:f78109a604797780ae1b80fee6860e3017a77da1a1cb0152d601f48e3b1e69d2
Status: Image is up to date for quay.io/quarkus/ubi9-quarkus-mandrel-builder-image:jdk-25 quay.io/quarkus/ubi9-quarkus-mandrel-builder-image:jdk-25 Warning: Option 'DynamicProxyConfigurationResources' is deprecated and might be removed in a future release: This can be caused by a proxy-config.json file in your META-INF directory. Consider including proxy configuration in the reflection section of reachability-metadata.md instead.. Please refer to the GraalVM release notes. ======================================================================================================================== GraalVM Native Image: Generating 'fizzbuzz' (executable)... ======================================================================================================================== For detailed information and explanations on the build output, visit: https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md ------------------------------------------------------------------------------------------------------------------------ [1/8] Initializing... (6.0s @ 0.13GB) Java version: 25.0.2+10-LTS, vendor version: Mandrel-25.0.2.0-Final Graal compiler: optimization level: 2, target machine: x86-64-v3 C compiler: gcc (redhat, x86_64, 11.5.0) Garbage collector: Serial GC (max heap size: 80% of RAM) 5 user-specific feature(s): - com.oracle.svm.thirdparty.gson.GsonFeature - io.quarkus.runner.Feature: Auto-generated class by Quarkus from the existing extensions - io.quarkus.runtime.graal.DisableLoggingFeature: Adapts logging during the analysis phase - io.quarkus.runtime.graal.JVMChecksFeature - io.quarkus.runtime.graal.SkipConsoleServiceProvidersFeature: Skip unsupported console service providers when quarkus.native.auto-service-loader-registration is false ------------------------------------------------------------------------------------------------------------------------ 5 experimental option(s) unlocked: - '-H:+AllowFoldMethods' (origin(s): command line) - '-H:BuildOutputJSONFile' (origin(s): command line) - '-H:-UseServiceLoaderFeature' (origin(s): command line) - '-H:+GenerateBuildArtifactsFile' (origin(s): command line) - '-H:AddOpens' (alternative API option(s): --add-opens java.base/java.lang=ALL-UNNAMED; origin(s): command line) ------------------------------------------------------------------------------------------------------------------------ Build resources: - 28.45GB of memory (56.3% of system memory, in container) - 14 thread(s) (100.0% of 14 available processor(s), determined at start) [2/8] Performing analysis... [*****] (34.4s @ 0.80GB) 7,800 types, 9,916 fields, and 37,796 methods found reachable 2,570 types, 78 fields, and 2,925 methods registered for reflection 62 types, 68 fields, and 55 methods registered for JNI access 0 downcalls and 0 upcalls registered for foreign access 4 native libraries: dl, pthread, rt, z [3/8] Building universe... (3.6s @ 0.92GB) [4/8] Parsing methods... [**] (2.9s @ 0.98GB) [5/8] Inlining methods... [***] (2.3s @ 1.09GB) [6/8] Compiling methods... [*****] (32.0s @ 1.41GB) [7/8] Laying out methods... [**] (3.9s @ 1.66GB) [8/8] Creating image... [**] (4.7s @ 0.80GB) 17.37MB (43.93%) for code area: 24,822 compilation units 19.46MB (49.23%) for image heap: 230,591 objects and 60 resources 2.70MB ( 6.84%) for other data 39.54MB in total image size, 37.21MB in total file size ------------------------------------------------------------------------------------------------------------------------ Top 10 origins of code area: Top 10 object types in image heap: 12.07MB java.base 4.72MB byte[] for code metadata 1.66MB svm.jar (Native Image) 2.80MB byte[] for java.lang.String 870.63kB info.picocli.picocli-4.7.7.jar 1.99MB java.lang.String 324.69kB fizzbuzz.jar 1.56MB com.oracle.svm.core.hub.DynamicHubCompanion 322.20kB io.smallrye.config.smallrye-config-core-3.15.1.jar 1.11MB byte[] for general heap data 307.13kB o.j.logmanager.jboss-logmanager-3.2.1.Final.jar 1.08MB java.lang.Class 227.89kB jdk.zipfs 505.68kB java.util.HashMap$Node 167.60kB io.quarkus.arc.arc-3.31.4.jar 458.28kB java.lang.Object[] 163.81kB io.quarkus.quarkus-core-3.31.4.jar 369.31kB java.util.concurrent.ConcurrentHashMap$Node 145.62kB jdk.proxy4 334.34kB java.lang.String[] 735.03kB for 32 more packages 4.54MB for 2234 more object types ------------------------------------------------------------------------------------------------------------------------ Recommendations: FUTR: Use '--future-defaults=all' to prepare for future releases. HEAP: Set max heap for improved and more predictable memory usage. CPU: Enable more CPU features with '-march=native' for improved performance. ------------------------------------------------------------------------------------------------------------------------ 6.9s (7.4% of total time) in 610 GCs | Peak RSS: 2.55GB | CPU load: 10.92 ------------------------------------------------------------------------------------------------------------------------ Build artifacts: /project/build-artifacts.json (build_info) /project/fizzbuzz (executable) /project/fizzbuzz-build-output-stats.json (build_info) ======================================================================================================================== Finished generating 'fizzbuzz' in 1m 32s. BUILD SUCCESSFUL in 1m 50s 13 actionable tasks: 13 executed Consider enabling configuration cache to speed up this build: https://docs.gradle.org/9.3.1/userguide/configuration_cache_enabling.html 映画館の巨大スクリーンなら文字が小さくても (ry -
Build された Native Image $ file ./build/fizzbuzz ./build/fizzbuzz: ELF 64-bit
LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=1572e96d1a6169e9629ea0609ec1d24c98e46b0c, for GNU/Linux 3.2.0, stripped $ ldd ./build/fizzbuzz linux-vdso.so.1 (0x00007ffc3b7f9000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007eaf530d6000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007eaf52e00000) /lib64/ld-linux-x86-64.so.2 (0x00007eaf530fa000) -
Native Image なのでそのまま実行できる $ ./build/fizzbuzz --start 1 --end 15 1
2 Buzz 4 Fizz Buzz 7 8 Buzz Fizz 11 Buzz 13 14 BuzzFizz -
普通に .jar も build できる $ ./gradlew build \ -Dquarkus.native.enabled=false
\ -Dquarkus.package.jar.enabled=true \ -Dquarkus.package.jar.type=uber-jar $ ls -l ./build/fizzbuzz.jar -rw-r--r-- 1 ubuntu ubuntu 5235424 Mar 1 14:40 ./build/fizzbuzz.jar $ file ./build/fizzbuzz.jar ./build/fizzbuzz.jar: Zip archive data, at least v2.0 to extract, compression method=deflate -
Uber Jar $ java -jar ./build/fizzbuzz.jar --start 1 --end 15
1 2 Buzz 4 Fizz Buzz 7 8 Buzz Fizz 11 Buzz 13 14 BuzzFizz -
Uber Jar (time -v の実行結果抜粋) $ /usr/bin/time -v java -jar
./build/fizzbuzz.jar --start 1 --end 10 1 2 Buzz 4 Fizz Buzz 7 8 Buzz Fizz Command being timed: "java -jar ./build/fizzbuzz.jar --start 1 --end 10" User time (seconds): 0.79 System time (seconds): 0.13 Percent of CPU this job got: 198% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.46 Maximum resident set size (kbytes): 92672 -
Native Image (time -v の実行結果抜粋) $ /usr/bin/time -v ./build/fizzbuzz --start
1 --end 10 1 2 Buzz 4 Fizz Buzz 7 8 Buzz Fizz Command being timed: "./build/fizzbuzz --start 1 --end 10" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 112% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00 Maximum resident set size (kbytes): 26752 -
比較 (time -v の実行結果抜粋) Command being timed: "./build/fizzbuzz --start 1
--end 10" User time (seconds): 0.00 System time (seconds): 0.00 Percent of CPU this job got: 112% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00 Maximum resident set size (kbytes): 26752 Command being timed: "java -jar ./build/fizzbuzz.jar --start 1 --end 10" User time (seconds): 0.79 System time (seconds): 0.13 Percent of CPU this job got: 198% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.46 Maximum resident set size (kbytes): 92672 Uber Jar Native Image (速すぎて実行時間が “0.00” になっている) -
Fizz… Buzz… ??? $ ./build/fizzbuzz --start 1 --end 15
1 2 Buzz <- 4 Fizz <- Buzz <- 7 8 Buzz <- Fizz <- 11 Buzz <- 13 14 BuzzFizz <- -
quarkus dev コマンドで Dev Mode を起動 $ quarkus dev (omit)
BUILD SUCCESSFUL in 6s 10 actionable tasks: 10 executed Listening for transport dt_socket at address: 5005 1 2 Buzz (omit) 98 Buzz Fizz -- Tests paused Press [space] to restart, [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options> -
TUI っぽいものでいい感じに操作できる $ quarkus dev (omit) BUILD SUCCESSFUL in 6s
10 actionable tasks: 10 executed Listening for transport dt_socket at address: 5005 1 2 Buzz (omit) 98 Buzz Fizz -- Tests paused Press [space] to restart, [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options> -
[e] を押して引数を変更し... -- Tests paused Press [space] to restart, [e]
to edit command line args (currently '--start 1 --end 10') , [r] to resume testing, [o] Toggle test output> -- Tests paused --start 1 --end 10 -- Tests paused Press [space] to restart, [e] to edit command line args (currently '') , [r] to resume testing, [o] Toggle test output> -
スペースを押すと新しい引数で実行してくれる 1 2 Buzz 4 Fizz Buzz 7 8 Buzz
Fizz -- Tests paused Press [space] to restart , [e] to edit command line args (currently '--start 1 --end 10'), [r] to resume testing, [o] Toggle test output> -
ソースコードを修正し保存した上で... $ git diff (omit) @@ -22,13 +22,13 @@ public
class FizzBuzzOptions { names = {"-f", "--fizz"}, description = "Output for multiples of 3", required = false, - defaultValue = "Buzz") + defaultValue = "Fizz") String fizz; @CommandLine.Option( names = {"-b", "--buzz"}, description = "Output for multiples of 5", required = false, - defaultValue = "Fizz") + defaultValue = "Buzz") String buzz; } -
スペースを押すと修正後のコードを実行できる! 1 2 Fizz 4 Buzz Fizz 7 8 Fizz
Buzz -- Tests paused Press [space] to restart , [e] to edit command line args (currently '--start 1 --end 10'), [r] to resume testing, [o] Toggle test output> -
まとめ • SUPERSONIC (超音速) で SUBATOMIC (亜原子) な Java Framework!
• Java App を Native Image (実行可能ファイル) に Build することができる! • Dev Mode を使うと、ソースコードの修正を (Rebuild 無し で) シュッ と確認できる!