From f7d81e9eb5cbd9813b966f7c1ef808834e1ca631 Mon Sep 17 00:00:00 2001 From: 5803024019 Date: Tue, 19 May 2026 17:38:24 +0700 Subject: [PATCH 1/4] gitignore --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 1257a15..3d03636 100644 --- a/.gitignore +++ b/.gitignore @@ -41,8 +41,7 @@ build/ .env *.env -# JVM crash dumps -hs_err_pid*.log +walkguide-backend/demo/hs_err_pid*.log # Android SDK path (generated by Android Studio) android/local.properties From 5f3423537c56f72be81f1e09ed6320b070e2bbb9 Mon Sep 17 00:00:00 2001 From: 5803024019 Date: Tue, 19 May 2026 17:40:27 +0700 Subject: [PATCH 2/4] chore: remove tracked JVM crash logs --- walkguide-backend/demo/hs_err_pid29532.log | 819 --------------------- 1 file changed, 819 deletions(-) delete mode 100644 walkguide-backend/demo/hs_err_pid29532.log diff --git a/walkguide-backend/demo/hs_err_pid29532.log b/walkguide-backend/demo/hs_err_pid29532.log deleted file mode 100644 index 8992057..0000000 --- a/walkguide-backend/demo/hs_err_pid29532.log +++ /dev/null @@ -1,819 +0,0 @@ -# -# There is insufficient memory for the Java Runtime Environment to continue. -# Native memory allocation (malloc) failed to allocate 1048576 bytes. Error detail: AllocateHeap -# Possible reasons: -# The system is out of physical RAM or swap space -# This process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap -# Possible solutions: -# Reduce memory load on the system -# Increase physical memory or swap space -# Check if swap backing store is full -# Decrease Java heap size (-Xmx/-Xms) -# Decrease number of Java threads -# Decrease Java thread stack sizes (-Xss) -# Set larger code cache with -XX:ReservedCodeCacheSize= -# JVM is running with Unscaled Compressed Oops mode in which the Java heap is -# placed in the first 4GB address space. The Java Heap base address is the -# maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress -# to set the Java Heap base and to place the Java Heap above 4GB virtual address. -# This output file may be truncated or incomplete. -# -# Out of Memory Error (allocation.cpp:44), pid=29532, tid=23756 -# -# JRE version: OpenJDK Runtime Environment Temurin-21.0.10+7 (21.0.10+7) (build 21.0.10+7-LTS) -# Java VM: OpenJDK 64-Bit Server VM Temurin-21.0.10+7 (21.0.10+7-LTS, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, parallel gc, windows-amd64) -# No core dump will be written. Minidumps are not enabled by default on client versions of Windows -# - ---------------- S U M M A R Y ------------ - -Command Line: --add-modules=ALL-SYSTEM --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/sun.nio.fs=ALL-UNNAMED -Declipse.application=org.eclipse.jdt.ls.core.id1 -Dosgi.bundles.defaultStartLevel=4 -Declipse.product=org.eclipse.jdt.ls.core.product -Djava.import.generatesMetadataFilesAtProjectRoot=false -DDetectVMInstallationsJob.disabled=true -Dfile.encoding=utf8 -XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx2G -Xms100m -Xlog:disable -javaagent:c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\lombok\lombok-1.18.39-4050.jar -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=c:\Users\Evan\AppData\Roaming\Code\User\workspaceStorage\609d357b4a62589867dde8a22b91e9ee\redhat.java -Daether.dependencyCollector.impl=bf c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\server\plugins\org.eclipse.equinox.launcher_1.7.100.v20251111-0406.jar -configuration c:\Users\Evan\AppData\Roaming\Code\User\globalStorage\redhat.java\1.54.0\config_win -data c:\Users\Evan\AppData\Roaming\Code\User\workspaceStorage\609d357b4a62589867dde8a22b91e9ee\redhat.java\jdt_ws --pipe=\\.\pipe\lsp-c3923ce2cfc611e32e6dd1d393bf40eb-sock - -Host: 13th Gen Intel(R) Core(TM) i7-13620H, 16 cores, 15G, Windows 11 , 64 bit Build 26100 (10.0.26100.7623) -Time: Thu Apr 23 12:01:36 2026 SE Asia Standard Time elapsed time: 2053.483618 seconds (0d 0h 34m 13s) - ---------------- T H R E A D --------------- - -Current thread (0x000001ee45f5cd50): JavaThread "Attach Listener" daemon [_thread_in_vm, id=23756, stack(0x0000006b5d600000,0x0000006b5d700000) (1024K)] - -Stack: [0x0000006b5d600000,0x0000006b5d700000] -Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) -V [jvm.dll+0x6d7a39] -V [jvm.dll+0x8b4b26] -V [jvm.dll+0x8b70de] -V [jvm.dll+0x8b77c3] -V [jvm.dll+0x284346] -V [jvm.dll+0xc1277] -V [jvm.dll+0x6d82e9] -V [jvm.dll+0x1334a6] -V [jvm.dll+0x3f857e] -V [jvm.dll+0x85f59d] -V [jvm.dll+0x6d626d] -C [ucrtbase.dll+0x37b0] -C [KERNEL32.DLL+0x2e8d7] -C [ntdll.dll+0x8c53c] - - ---------------- P R O C E S S --------------- - -Threads class SMR info: -_java_thread_list=0x000001ee5133cff0, length=48, elements={ -0x000001ee6cf9d7b0, 0x000001ee45f583b0, 0x000001ee6cf4b440, 0x000001ee45f5bd60, -0x000001ee45f5cd50, 0x000001ee45f633d0, 0x000001ee45f619f0, 0x000001ee45f70cc0, -0x000001ee45f72a70, 0x000001ee461d7390, 0x000001ee47646aa0, 0x000001ee4c4c7880, -0x000001ee4c4c7f10, 0x000001ee4c4c57b0, 0x000001ee4c4c71f0, 0x000001ee4c4c5120, -0x000001ee4c4c4a90, 0x000001ee4c4c6b60, 0x000001ee4c4c64d0, 0x000001ee4c7b5cf0, -0x000001ee4c7b3c20, 0x000001ee4c7b4940, 0x000001ee4c7b42b0, 0x000001ee4c7b6a10, -0x000001ee4c7b3590, 0x000001ee4c7b9800, 0x000001ee4c7b70a0, 0x000001ee4c7b7dc0, -0x000001ee4c7b9e90, 0x000001ee4c7b7730, 0x000001ee4c7b9170, 0x000001ee4c7b8450, -0x000001ee4c7b8ae0, 0x000001ee4c7ba520, 0x000001ee5014c380, 0x000001ee5014bcf0, -0x000001ee5014ca10, 0x000001ee5014d730, 0x000001ee5014d0a0, 0x000001ee5014a2b0, -0x000001ee5014e450, 0x000001ee5014afd0, 0x000001ee50133120, 0x000001ee501337b0, -0x000001ee50134b60, 0x000001ee501351f0, 0x000001ee50135880, 0x000001ee509a2fa0 -} - -Java Threads: ( => current thread ) - 0x000001ee6cf9d7b0 JavaThread "main" [_thread_blocked, id=10460, stack(0x0000006b5cf00000,0x0000006b5d000000) (1024K)] - 0x000001ee45f583b0 JavaThread "Reference Handler" daemon [_thread_blocked, id=19328, stack(0x0000006b5d300000,0x0000006b5d400000) (1024K)] - 0x000001ee6cf4b440 JavaThread "Finalizer" daemon [_thread_blocked, id=3632, stack(0x0000006b5d400000,0x0000006b5d500000) (1024K)] - 0x000001ee45f5bd60 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=20860, stack(0x0000006b5d500000,0x0000006b5d600000) (1024K)] -=>0x000001ee45f5cd50 JavaThread "Attach Listener" daemon [_thread_in_vm, id=23756, stack(0x0000006b5d600000,0x0000006b5d700000) (1024K)] - 0x000001ee45f633d0 JavaThread "Service Thread" daemon [_thread_blocked, id=13388, stack(0x0000006b5d700000,0x0000006b5d800000) (1024K)] - 0x000001ee45f619f0 JavaThread "Monitor Deflation Thread" daemon [_thread_blocked, id=11932, stack(0x0000006b5d800000,0x0000006b5d900000) (1024K)] - 0x000001ee45f70cc0 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=22760, stack(0x0000006b5d900000,0x0000006b5da00000) (1024K)] - 0x000001ee45f72a70 JavaThread "C1 CompilerThread0" daemon [_thread_blocked, id=24984, stack(0x0000006b5da00000,0x0000006b5db00000) (1024K)] - 0x000001ee461d7390 JavaThread "Common-Cleaner" daemon [_thread_blocked, id=28416, stack(0x0000006b5dd00000,0x0000006b5de00000) (1024K)] - 0x000001ee47646aa0 JavaThread "Notification Thread" daemon [_thread_blocked, id=12116, stack(0x0000006b5e000000,0x0000006b5e100000) (1024K)] - 0x000001ee4c4c7880 JavaThread "Active Thread: Equinox Container: 0b653230-1c2a-4e76-8451-6cdb532e7b34" [_thread_blocked, id=23064, stack(0x0000006b5ea00000,0x0000006b5eb00000) (1024K)] - 0x000001ee4c4c7f10 JavaThread "Refresh Thread: Equinox Container: 0b653230-1c2a-4e76-8451-6cdb532e7b34" daemon [_thread_blocked, id=27188, stack(0x0000006b5ec00000,0x0000006b5ed00000) (1024K)] - 0x000001ee4c4c57b0 JavaThread "Framework Event Dispatcher: Equinox Container: 0b653230-1c2a-4e76-8451-6cdb532e7b34" daemon [_thread_blocked, id=10220, stack(0x0000006b5ed00000,0x0000006b5ee00000) (1024K)] - 0x000001ee4c4c71f0 JavaThread "Start Level: Equinox Container: 0b653230-1c2a-4e76-8451-6cdb532e7b34" daemon [_thread_blocked, id=6764, stack(0x0000006b5ee00000,0x0000006b5ef00000) (1024K)] - 0x000001ee4c4c5120 JavaThread "Bundle File Closer" daemon [_thread_blocked, id=25612, stack(0x0000006b5e100000,0x0000006b5e200000) (1024K)] - 0x000001ee4c4c4a90 JavaThread "SCR Component Actor" daemon [_thread_blocked, id=5628, stack(0x0000006b5df00000,0x0000006b5e000000) (1024K)] - 0x000001ee4c4c6b60 JavaThread "Worker-JM" [_thread_blocked, id=24024, stack(0x0000006b5f300000,0x0000006b5f400000) (1024K)] - 0x000001ee4c4c64d0 JavaThread "JNA Cleaner" daemon [_thread_blocked, id=11764, stack(0x0000006b5f000000,0x0000006b5f100000) (1024K)] - 0x000001ee4c7b5cf0 JavaThread "Worker-0" [_thread_blocked, id=3884, stack(0x0000006b5f400000,0x0000006b5f500000) (1024K)] - 0x000001ee4c7b3c20 JavaThread "Java indexing" daemon [_thread_blocked, id=12220, stack(0x0000006b5f800000,0x0000006b5f900000) (1024K)] - 0x000001ee4c7b4940 JavaThread "Worker-3" [_thread_blocked, id=20148, stack(0x0000006b5fe00000,0x0000006b5ff00000) (1024K)] - 0x000001ee4c7b42b0 JavaThread "Thread-1" daemon [_thread_in_native, id=21516, stack(0x0000006b60000000,0x0000006b60100000) (1024K)] - 0x000001ee4c7b6a10 JavaThread "Thread-2" daemon [_thread_in_native, id=18184, stack(0x0000006b60100000,0x0000006b60200000) (1024K)] - 0x000001ee4c7b3590 JavaThread "Thread-3" daemon [_thread_in_native, id=26548, stack(0x0000006b60200000,0x0000006b60300000) (1024K)] - 0x000001ee4c7b9800 JavaThread "Thread-4" daemon [_thread_in_native, id=26220, stack(0x0000006b60300000,0x0000006b60400000) (1024K)] - 0x000001ee4c7b70a0 JavaThread "Thread-5" daemon [_thread_in_native, id=4216, stack(0x0000006b60400000,0x0000006b60500000) (1024K)] - 0x000001ee4c7b7dc0 JavaThread "Thread-6" daemon [_thread_in_native, id=24700, stack(0x0000006b60500000,0x0000006b60600000) (1024K)] - 0x000001ee4c7b9e90 JavaThread "Thread-7" daemon [_thread_in_native, id=13212, stack(0x0000006b60600000,0x0000006b60700000) (1024K)] - 0x000001ee4c7b7730 JavaThread "Thread-8" daemon [_thread_in_native, id=18740, stack(0x0000006b60700000,0x0000006b60800000) (1024K)] - 0x000001ee4c7b9170 JavaThread "Thread-9" daemon [_thread_in_native, id=21404, stack(0x0000006b60800000,0x0000006b60900000) (1024K)] - 0x000001ee4c7b8450 JavaThread "Thread-10" daemon [_thread_in_native, id=10108, stack(0x0000006b60900000,0x0000006b60a00000) (1024K)] - 0x000001ee4c7b8ae0 JavaThread "Thread-11" daemon [_thread_in_native, id=25376, stack(0x0000006b60a00000,0x0000006b60b00000) (1024K)] - 0x000001ee4c7ba520 JavaThread "Thread-12" daemon [_thread_in_native, id=19180, stack(0x0000006b60b00000,0x0000006b60c00000) (1024K)] - 0x000001ee5014c380 JavaThread "Thread-13" daemon [_thread_in_native, id=21956, stack(0x0000006b60c00000,0x0000006b60d00000) (1024K)] - 0x000001ee5014bcf0 JavaThread "Thread-14" daemon [_thread_in_native, id=20232, stack(0x0000006b60d00000,0x0000006b60e00000) (1024K)] - 0x000001ee5014ca10 JavaThread "Thread-15" daemon [_thread_in_native, id=18652, stack(0x0000006b60e00000,0x0000006b60f00000) (1024K)] - 0x000001ee5014d730 JavaThread "Thread-16" daemon [_thread_in_native, id=29564, stack(0x0000006b60f00000,0x0000006b61000000) (1024K)] - 0x000001ee5014d0a0 JavaThread "Thread-17" daemon [_thread_in_native, id=14624, stack(0x0000006b61000000,0x0000006b61100000) (1024K)] - 0x000001ee5014a2b0 JavaThread "pool-2-thread-1" [_thread_blocked, id=3220, stack(0x0000006b61300000,0x0000006b61400000) (1024K)] - 0x000001ee5014e450 JavaThread "WorkspaceEventsHandler" [_thread_blocked, id=9832, stack(0x0000006b61500000,0x0000006b61600000) (1024K)] - 0x000001ee5014afd0 JavaThread "pool-1-thread-1" [_thread_blocked, id=26412, stack(0x0000006b61600000,0x0000006b61700000) (1024K)] - 0x000001ee50133120 JavaThread "Java Debug Server" daemon [_thread_in_native, id=13492, stack(0x0000006b62600000,0x0000006b62700000) (1024K)] - 0x000001ee501337b0 JavaThread "pool-4-thread-1" [_thread_in_native, id=7392, stack(0x0000006b62700000,0x0000006b62800000) (1024K)] - 0x000001ee50134b60 JavaThread "RxSchedulerPurge-1" daemon [_thread_blocked, id=18484, stack(0x0000006b62800000,0x0000006b62900000) (1024K)] - 0x000001ee501351f0 JavaThread "RxCachedWorkerPoolEvictor-1" daemon [_thread_blocked, id=7748, stack(0x0000006b62900000,0x0000006b62a00000) (1024K)] - 0x000001ee50135880 JavaThread "RxNewThreadScheduler-1" daemon [_thread_blocked, id=30100, stack(0x0000006b62a00000,0x0000006b62b00000) (1024K)] - 0x000001ee509a2fa0 JavaThread "process reaper (pid 29504)" daemon [_thread_in_native, id=22192, stack(0x0000006b5c920000,0x0000006b5c940000) (128K)] -Total: 48 - -Other Threads: - 0x000001ee6d05eb10 VMThread "VM Thread" [id=25256, stack(0x0000006b5d200000,0x0000006b5d300000) (1024K)] - 0x000001ee6ce2ca00 WatcherThread "VM Periodic Task Thread" [id=12400, stack(0x0000006b5d100000,0x0000006b5d200000) (1024K)] - 0x000001ee6cfbbc00 WorkerThread "GC Thread#0" [id=1336, stack(0x0000006b5d000000,0x0000006b5d100000) (1024K)] - 0x000001ee4c25b400 WorkerThread "GC Thread#1" [id=14740, stack(0x0000006b5e200000,0x0000006b5e300000) (1024K)] - 0x000001ee47b0cfe0 WorkerThread "GC Thread#2" [id=26604, stack(0x0000006b5e300000,0x0000006b5e400000) (1024K)] - 0x000001ee47b0c340 WorkerThread "GC Thread#3" [id=24000, stack(0x0000006b5e400000,0x0000006b5e500000) (1024K)] - 0x000001ee47b0d390 WorkerThread "GC Thread#4" [id=15728, stack(0x0000006b5e500000,0x0000006b5e600000) (1024K)] - 0x000001ee47b0d740 WorkerThread "GC Thread#5" [id=15956, stack(0x0000006b5e600000,0x0000006b5e700000) (1024K)] - 0x000001ee4c2a70b0 WorkerThread "GC Thread#6" [id=3744, stack(0x0000006b5e700000,0x0000006b5e800000) (1024K)] - 0x000001ee4c3bd2c0 WorkerThread "GC Thread#7" [id=15056, stack(0x0000006b5eb00000,0x0000006b5ec00000) (1024K)] - 0x000001ee46032dc0 WorkerThread "GC Thread#8" [id=29540, stack(0x0000006b5db00000,0x0000006b5dc00000) (1024K)] - 0x000001ee462ee630 WorkerThread "GC Thread#9" [id=27328, stack(0x0000006b5dc00000,0x0000006b5dd00000) (1024K)] - 0x000001ee461f77e0 WorkerThread "GC Thread#10" [id=6200, stack(0x0000006b5de00000,0x0000006b5df00000) (1024K)] - 0x000001ee4c2db4f0 WorkerThread "GC Thread#11" [id=27152, stack(0x0000006b5e900000,0x0000006b5ea00000) (1024K)] - 0x000001ee4c700b70 WorkerThread "GC Thread#12" [id=29084, stack(0x0000006b5ef00000,0x0000006b5f000000) (1024K)] -Total: 15 - -Threads with active compile tasks: -Total: 0 - -VM state: not at safepoint (normal execution) - -VM Mutex/Monitor currently owned by a thread: None - -Heap address: 0x0000000080000000, size: 2048 MB, Compressed Oops mode: 32-bit - -CDS archive(s) mapped at: [0x000001ee04000000-0x000001ee04ba0000-0x000001ee04ba0000), size 12189696, SharedBaseAddress: 0x000001ee04000000, ArchiveRelocationMode: 1. -Compressed class space mapped at: 0x000001ee05000000-0x000001ee45000000, reserved size: 1073741824 -Narrow klass base: 0x000001ee04000000, Narrow klass shift: 0, Narrow klass range: 0x100000000 - -GC Precious Log: - CardTable entry size: 512 - CPUs: 16 total, 16 available - Memory: 16088M - Large Page Support: Disabled - NUMA Support: Disabled - Compressed Oops: Enabled (32-bit) - Alignments: Space 512K, Generation 512K, Heap 2M - Heap Min Capacity: 100M - Heap Initial Capacity: 100M - Heap Max Capacity: 2G - Pre-touch: Disabled - Parallel Workers: 13 - -Heap: - PSYoungGen total 6656K, used 4893K [0x00000000d5580000, 0x00000000d5e00000, 0x0000000100000000) - eden space 5632K, 69% used [0x00000000d5580000,0x00000000d5952510,0x00000000d5b00000) - from space 1024K, 95% used [0x00000000d5b00000,0x00000000d5bf5220,0x00000000d5c00000) - to space 1536K, 0% used [0x00000000d5c80000,0x00000000d5c80000,0x00000000d5e00000) - ParOldGen total 165888K, used 124740K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 75% used [0x0000000080000000,0x00000000879d1148,0x000000008a200000) - Metaspace used 67718K, committed 69248K, reserved 1114112K - class space used 7272K, committed 7936K, reserved 1048576K - -Card table byte_map: [0x000001ee6c940000,0x000001ee6cd50000] _byte_map_base: 0x000001ee6c540000 - -Marking Bits: (ParMarkBitMap*) 0x00007ffe90983450 - Begin Bits: [0x000001ee00000000, 0x000001ee02000000) - End Bits: [0x000001ee02000000, 0x000001ee04000000) - -Polling page: 0x000001ee6af10000 - -Metaspace: - -Usage: - Non-class: 59.03 MB used. - Class: 7.10 MB used. - Both: 66.13 MB used. - -Virtual space: - Non-class space: 64.00 MB reserved, 59.88 MB ( 94%) committed, 1 nodes. - Class space: 1.00 GB reserved, 7.75 MB ( <1%) committed, 1 nodes. - Both: 1.06 GB reserved, 67.62 MB ( 6%) committed. - -Chunk freelists: - Non-Class: 4.13 MB - Class: 8.16 MB - Both: 12.29 MB - -MaxMetaspaceSize: unlimited -CompressedClassSpaceSize: 1.00 GB -Initial GC threshold: 21.00 MB -Current GC threshold: 97.31 MB -CDS: on - - commit_granule_bytes: 65536. - - commit_granule_words: 8192. - - virtual_space_node_default_size: 8388608. - - enlarge_chunks_in_place: 1. - - use_allocation_guard: 0. - - -Internal statistics: - -num_allocs_failed_limit: 9. -num_arena_births: 1244. -num_arena_deaths: 22. -num_vsnodes_births: 2. -num_vsnodes_deaths: 0. -num_space_committed: 1082. -num_space_uncommitted: 0. -num_chunks_returned_to_freelist: 35. -num_chunks_taken_from_freelist: 4485. -num_chunk_merges: 16. -num_chunk_splits: 2721. -num_chunks_enlarged: 1457. -num_inconsistent_stats: 0. - -CodeHeap 'non-profiled nmethods': size=119168Kb used=8085Kb max_used=8085Kb free=111083Kb - bounds [0x000001ee77d40000, 0x000001ee78530000, 0x000001ee7f1a0000] -CodeHeap 'profiled nmethods': size=119104Kb used=24483Kb max_used=24483Kb free=94620Kb - bounds [0x000001ee701a0000, 0x000001ee71990000, 0x000001ee775f0000] -CodeHeap 'non-nmethods': size=7488Kb used=1445Kb max_used=3189Kb free=6042Kb - bounds [0x000001ee775f0000, 0x000001ee77970000, 0x000001ee77d40000] -CodeCache: size=245760Kb, used=34013Kb, max_used=35757Kb, free=211745Kb - total_blobs=11537, nmethods=10772, adapters=671, full_count=0 -Compilation: enabled, stopped_count=0, restarted_count=0 - -Compilation events (20 events): -Event: 1044.605 Thread 0x000001ee45f70cc0 11595 4 java.util.concurrent.ConcurrentHashMap$CollectionView::toArray (145 bytes) -Event: 1044.736 Thread 0x000001ee45f70cc0 nmethod 11595 0x000001ee7851de90 code [0x000001ee7851e080, 0x000001ee7851ea10] -Event: 1044.737 Thread 0x000001ee45f70cc0 11596 4 io.reactivex.internal.schedulers.SchedulerPoolFactory$ScheduledTask::run (66 bytes) -Event: 1044.991 Thread 0x000001ee45f70cc0 nmethod 11596 0x000001ee7851f190 code [0x000001ee7851f460, 0x000001ee78520a08] -Event: 1141.590 Thread 0x000001ee45f70cc0 11597 4 java.util.concurrent.locks.LockSupport::setBlocker (12 bytes) -Event: 1141.592 Thread 0x000001ee45f70cc0 nmethod 11597 0x000001ee78522710 code [0x000001ee78522880, 0x000001ee78522908] -Event: 1219.854 Thread 0x000001ee45f72a70 11598 3 java.util.concurrent.ScheduledThreadPoolExecutor::triggerTime (22 bytes) -Event: 1219.878 Thread 0x000001ee45f72a70 nmethod 11598 0x000001ee71989190 code [0x000001ee71989340, 0x000001ee71989520] -Event: 1280.595 Thread 0x000001ee45f70cc0 11599 4 java.util.concurrent.locks.AbstractQueuedSynchronizer::acquire (20 bytes) -Event: 1280.603 Thread 0x000001ee45f70cc0 nmethod 11599 0x000001ee78522a10 code [0x000001ee78522ba0, 0x000001ee78522c98] -Event: 1293.524 Thread 0x000001ee45f72a70 11600 1 org.eclipse.jdt.ls.core.internal.LanguageServerApplication::getParentProcessId (5 bytes) -Event: 1293.526 Thread 0x000001ee45f72a70 nmethod 11600 0x000001ee78522d90 code [0x000001ee78522f20, 0x000001ee78522fe8] -Event: 1449.603 Thread 0x000001ee45f70cc0 11601 ! 4 java.util.concurrent.locks.AbstractQueuedSynchronizer::acquire (424 bytes) -Event: 1449.675 Thread 0x000001ee45f70cc0 nmethod 11601 0x000001ee78523090 code [0x000001ee78523300, 0x000001ee785240a8] -Event: 1513.770 Thread 0x000001ee45f70cc0 11602 4 java.util.concurrent.ScheduledThreadPoolExecutor::canRunInCurrentRunState (61 bytes) -Event: 1513.778 Thread 0x000001ee45f70cc0 nmethod 11602 0x000001ee78524910 code [0x000001ee78524aa0, 0x000001ee78524b68] -Event: 1549.592 Thread 0x000001ee45f70cc0 11603 4 java.util.concurrent.TimeUnit::convert (73 bytes) -Event: 1549.598 Thread 0x000001ee45f70cc0 nmethod 11603 0x000001ee78524c90 code [0x000001ee78524e40, 0x000001ee78524fd0] -Event: 1692.948 Thread 0x000001ee45f72a70 11604 1 com.sun.jna.internal.Cleaner::access$100 (5 bytes) -Event: 1692.954 Thread 0x000001ee45f72a70 nmethod 11604 0x000001ee78525110 code [0x000001ee785252a0, 0x000001ee78525350] - -GC Heap History (20 events): -Event: 19.287 GC heap before -{Heap before GC invocations=249 (full 3): - PSYoungGen total 8192K, used 7734K [0x00000000d5580000, 0x00000000d5f00000, 0x0000000100000000) - eden space 6656K, 100% used [0x00000000d5580000,0x00000000d5c00000,0x00000000d5c00000) - from space 1536K, 70% used [0x00000000d5c00000,0x00000000d5d0d9c0,0x00000000d5d80000) - to space 1536K, 0% used [0x00000000d5d80000,0x00000000d5d80000,0x00000000d5f00000) - ParOldGen total 165888K, used 122117K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 73% used [0x0000000080000000,0x00000000877414f8,0x000000008a200000) - Metaspace used 61701K, committed 63168K, reserved 1114112K - class space used 6571K, committed 7168K, reserved 1048576K -} -Event: 19.287 GC heap after -{Heap after GC invocations=249 (full 3): - PSYoungGen total 8192K, used 1118K [0x00000000d5580000, 0x00000000d5f00000, 0x0000000100000000) - eden space 6656K, 0% used [0x00000000d5580000,0x00000000d5580000,0x00000000d5c00000) - from space 1536K, 72% used [0x00000000d5d80000,0x00000000d5e97a78,0x00000000d5f00000) - to space 1536K, 0% used [0x00000000d5c00000,0x00000000d5c00000,0x00000000d5d80000) - ParOldGen total 165888K, used 122165K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 73% used [0x0000000080000000,0x000000008774d4f8,0x000000008a200000) - Metaspace used 61701K, committed 63168K, reserved 1114112K - class space used 6571K, committed 7168K, reserved 1048576K -} -Event: 19.303 GC heap before -{Heap before GC invocations=250 (full 3): - PSYoungGen total 8192K, used 7774K [0x00000000d5580000, 0x00000000d5f00000, 0x0000000100000000) - eden space 6656K, 100% used [0x00000000d5580000,0x00000000d5c00000,0x00000000d5c00000) - from space 1536K, 72% used [0x00000000d5d80000,0x00000000d5e97a78,0x00000000d5f00000) - to space 1536K, 0% used [0x00000000d5c00000,0x00000000d5c00000,0x00000000d5d80000) - ParOldGen total 165888K, used 122165K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 73% used [0x0000000080000000,0x000000008774d4f8,0x000000008a200000) - Metaspace used 61903K, committed 63424K, reserved 1114112K - class space used 6577K, committed 7232K, reserved 1048576K -} -Event: 19.303 GC heap after -{Heap after GC invocations=250 (full 3): - PSYoungGen total 7168K, used 384K [0x00000000d5580000, 0x00000000d5e00000, 0x0000000100000000) - eden space 6656K, 0% used [0x00000000d5580000,0x00000000d5580000,0x00000000d5c00000) - from space 512K, 75% used [0x00000000d5c00000,0x00000000d5c60000,0x00000000d5c80000) - to space 1024K, 0% used [0x00000000d5d00000,0x00000000d5d00000,0x00000000d5e00000) - ParOldGen total 165888K, used 122213K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 73% used [0x0000000080000000,0x00000000877594f8,0x000000008a200000) - Metaspace used 61903K, committed 63424K, reserved 1114112K - class space used 6577K, committed 7232K, reserved 1048576K -} -Event: 19.362 GC heap before -{Heap before GC invocations=251 (full 3): - PSYoungGen total 7168K, used 7035K [0x00000000d5580000, 0x00000000d5e00000, 0x0000000100000000) - eden space 6656K, 99% used [0x00000000d5580000,0x00000000d5bfed00,0x00000000d5c00000) - from space 512K, 75% used [0x00000000d5c00000,0x00000000d5c60000,0x00000000d5c80000) - to space 1024K, 0% used [0x00000000d5d00000,0x00000000d5d00000,0x00000000d5e00000) - ParOldGen total 165888K, used 122213K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 73% used [0x0000000080000000,0x00000000877594f8,0x000000008a200000) - Metaspace used 62695K, committed 64192K, reserved 1114112K - class space used 6664K, committed 7296K, reserved 1048576K -} -Event: 19.363 GC heap after -{Heap after GC invocations=251 (full 3): - PSYoungGen total 7680K, used 500K [0x00000000d5580000, 0x00000000d5e00000, 0x0000000100000000) - eden space 6656K, 0% used [0x00000000d5580000,0x00000000d5580000,0x00000000d5c00000) - from space 1024K, 48% used [0x00000000d5d00000,0x00000000d5d7d200,0x00000000d5e00000) - to space 1024K, 0% used [0x00000000d5c00000,0x00000000d5c00000,0x00000000d5d00000) - ParOldGen total 165888K, used 122277K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 73% used [0x0000000080000000,0x00000000877694f8,0x000000008a200000) - Metaspace used 62695K, committed 64192K, reserved 1114112K - class space used 6664K, committed 7296K, reserved 1048576K -} -Event: 19.406 GC heap before -{Heap before GC invocations=252 (full 3): - PSYoungGen total 7680K, used 7156K [0x00000000d5580000, 0x00000000d5e00000, 0x0000000100000000) - eden space 6656K, 100% used [0x00000000d5580000,0x00000000d5c00000,0x00000000d5c00000) - from space 1024K, 48% used [0x00000000d5d00000,0x00000000d5d7d200,0x00000000d5e00000) - to space 1024K, 0% used [0x00000000d5c00000,0x00000000d5c00000,0x00000000d5d00000) - ParOldGen total 165888K, used 122277K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 73% used [0x0000000080000000,0x00000000877694f8,0x000000008a200000) - Metaspace used 63154K, committed 64640K, reserved 1114112K - class space used 6703K, committed 7296K, reserved 1048576K -} -Event: 19.407 GC heap after -{Heap after GC invocations=252 (full 3): - PSYoungGen total 7680K, used 434K [0x00000000d5580000, 0x00000000d5d80000, 0x0000000100000000) - eden space 6656K, 0% used [0x00000000d5580000,0x00000000d5580000,0x00000000d5c00000) - from space 1024K, 42% used [0x00000000d5c00000,0x00000000d5c6c9f0,0x00000000d5d00000) - to space 512K, 0% used [0x00000000d5d00000,0x00000000d5d00000,0x00000000d5d80000) - ParOldGen total 165888K, used 122405K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 73% used [0x0000000080000000,0x00000000877894f8,0x000000008a200000) - Metaspace used 63154K, committed 64640K, reserved 1114112K - class space used 6703K, committed 7296K, reserved 1048576K -} -Event: 19.511 GC heap before -{Heap before GC invocations=253 (full 3): - PSYoungGen total 7680K, used 7062K [0x00000000d5580000, 0x00000000d5d80000, 0x0000000100000000) - eden space 6656K, 99% used [0x00000000d5580000,0x00000000d5bf9080,0x00000000d5c00000) - from space 1024K, 42% used [0x00000000d5c00000,0x00000000d5c6c9f0,0x00000000d5d00000) - to space 512K, 0% used [0x00000000d5d00000,0x00000000d5d00000,0x00000000d5d80000) - ParOldGen total 165888K, used 122405K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 73% used [0x0000000080000000,0x00000000877894f8,0x000000008a200000) - Metaspace used 64404K, committed 65920K, reserved 1114112K - class space used 6816K, committed 7488K, reserved 1048576K -} -Event: 19.512 GC heap after -{Heap after GC invocations=253 (full 3): - PSYoungGen total 7168K, used 499K [0x00000000d5580000, 0x00000000d5e00000, 0x0000000100000000) - eden space 6656K, 0% used [0x00000000d5580000,0x00000000d5580000,0x00000000d5c00000) - from space 512K, 97% used [0x00000000d5d00000,0x00000000d5d7ce20,0x00000000d5d80000) - to space 1024K, 0% used [0x00000000d5c00000,0x00000000d5c00000,0x00000000d5d00000) - ParOldGen total 165888K, used 122533K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 73% used [0x0000000080000000,0x00000000877a94f8,0x000000008a200000) - Metaspace used 64404K, committed 65920K, reserved 1114112K - class space used 6816K, committed 7488K, reserved 1048576K -} -Event: 19.569 GC heap before -{Heap before GC invocations=254 (full 3): - PSYoungGen total 7168K, used 7155K [0x00000000d5580000, 0x00000000d5e00000, 0x0000000100000000) - eden space 6656K, 100% used [0x00000000d5580000,0x00000000d5c00000,0x00000000d5c00000) - from space 512K, 97% used [0x00000000d5d00000,0x00000000d5d7ce20,0x00000000d5d80000) - to space 1024K, 0% used [0x00000000d5c00000,0x00000000d5c00000,0x00000000d5d00000) - ParOldGen total 165888K, used 122533K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 73% used [0x0000000080000000,0x00000000877a94f8,0x000000008a200000) - Metaspace used 65220K, committed 66752K, reserved 1114112K - class space used 6907K, committed 7552K, reserved 1048576K -} -Event: 19.570 GC heap after -{Heap after GC invocations=254 (full 3): - PSYoungGen total 7680K, used 480K [0x00000000d5580000, 0x00000000d5e00000, 0x0000000100000000) - eden space 6656K, 0% used [0x00000000d5580000,0x00000000d5580000,0x00000000d5c00000) - from space 1024K, 46% used [0x00000000d5c00000,0x00000000d5c78020,0x00000000d5d00000) - to space 1024K, 0% used [0x00000000d5d00000,0x00000000d5d00000,0x00000000d5e00000) - ParOldGen total 165888K, used 122868K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 74% used [0x0000000080000000,0x00000000877fd0b8,0x000000008a200000) - Metaspace used 65220K, committed 66752K, reserved 1114112K - class space used 6907K, committed 7552K, reserved 1048576K -} -Event: 19.631 GC heap before -{Heap before GC invocations=255 (full 3): - PSYoungGen total 7680K, used 7136K [0x00000000d5580000, 0x00000000d5e00000, 0x0000000100000000) - eden space 6656K, 100% used [0x00000000d5580000,0x00000000d5c00000,0x00000000d5c00000) - from space 1024K, 46% used [0x00000000d5c00000,0x00000000d5c78020,0x00000000d5d00000) - to space 1024K, 0% used [0x00000000d5d00000,0x00000000d5d00000,0x00000000d5e00000) - ParOldGen total 165888K, used 122868K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 74% used [0x0000000080000000,0x00000000877fd0b8,0x000000008a200000) - Metaspace used 65876K, committed 67392K, reserved 1114112K - class space used 7032K, committed 7680K, reserved 1048576K -} -Event: 19.631 GC heap after -{Heap after GC invocations=255 (full 3): - PSYoungGen total 7168K, used 416K [0x00000000d5580000, 0x00000000d5d80000, 0x0000000100000000) - eden space 6656K, 0% used [0x00000000d5580000,0x00000000d5580000,0x00000000d5c00000) - from space 512K, 81% used [0x00000000d5d00000,0x00000000d5d68000,0x00000000d5d80000) - to space 512K, 0% used [0x00000000d5c80000,0x00000000d5c80000,0x00000000d5d00000) - ParOldGen total 165888K, used 123052K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 74% used [0x0000000080000000,0x000000008782b0d8,0x000000008a200000) - Metaspace used 65876K, committed 67392K, reserved 1114112K - class space used 7032K, committed 7680K, reserved 1048576K -} -Event: 19.688 GC heap before -{Heap before GC invocations=256 (full 3): - PSYoungGen total 7168K, used 7072K [0x00000000d5580000, 0x00000000d5d80000, 0x0000000100000000) - eden space 6656K, 100% used [0x00000000d5580000,0x00000000d5c00000,0x00000000d5c00000) - from space 512K, 81% used [0x00000000d5d00000,0x00000000d5d68000,0x00000000d5d80000) - to space 512K, 0% used [0x00000000d5c80000,0x00000000d5c80000,0x00000000d5d00000) - ParOldGen total 165888K, used 123052K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 74% used [0x0000000080000000,0x000000008782b0d8,0x000000008a200000) - Metaspace used 66605K, committed 68160K, reserved 1114112K - class space used 7141K, committed 7808K, reserved 1048576K -} -Event: 19.688 GC heap after -{Heap after GC invocations=256 (full 3): - PSYoungGen total 7168K, used 384K [0x00000000d5580000, 0x00000000d5d80000, 0x0000000100000000) - eden space 6656K, 0% used [0x00000000d5580000,0x00000000d5580000,0x00000000d5c00000) - from space 512K, 75% used [0x00000000d5c80000,0x00000000d5ce0000,0x00000000d5d00000) - to space 512K, 0% used [0x00000000d5d00000,0x00000000d5d00000,0x00000000d5d80000) - ParOldGen total 165888K, used 123212K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 74% used [0x0000000080000000,0x0000000087853108,0x000000008a200000) - Metaspace used 66605K, committed 68160K, reserved 1114112K - class space used 7141K, committed 7808K, reserved 1048576K -} -Event: 30.835 GC heap before -{Heap before GC invocations=257 (full 3): - PSYoungGen total 7168K, used 7040K [0x00000000d5580000, 0x00000000d5d80000, 0x0000000100000000) - eden space 6656K, 100% used [0x00000000d5580000,0x00000000d5c00000,0x00000000d5c00000) - from space 512K, 75% used [0x00000000d5c80000,0x00000000d5ce0000,0x00000000d5d00000) - to space 512K, 0% used [0x00000000d5d00000,0x00000000d5d00000,0x00000000d5d80000) - ParOldGen total 165888K, used 123212K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 74% used [0x0000000080000000,0x0000000087853108,0x000000008a200000) - Metaspace used 67075K, committed 68672K, reserved 1114112K - class space used 7195K, committed 7872K, reserved 1048576K -} -Event: 30.836 GC heap after -{Heap after GC invocations=257 (full 3): - PSYoungGen total 6144K, used 512K [0x00000000d5580000, 0x00000000d6000000, 0x0000000100000000) - eden space 5632K, 0% used [0x00000000d5580000,0x00000000d5580000,0x00000000d5b00000) - from space 512K, 100% used [0x00000000d5d00000,0x00000000d5d80000,0x00000000d5d80000) - to space 2048K, 0% used [0x00000000d5b00000,0x00000000d5b00000,0x00000000d5d00000) - ParOldGen total 165888K, used 124244K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 74% used [0x0000000080000000,0x0000000087955148,0x000000008a200000) - Metaspace used 67075K, committed 68672K, reserved 1114112K - class space used 7195K, committed 7872K, reserved 1048576K -} -Event: 169.382 GC heap before -{Heap before GC invocations=258 (full 3): - PSYoungGen total 6144K, used 6144K [0x00000000d5580000, 0x00000000d6000000, 0x0000000100000000) - eden space 5632K, 100% used [0x00000000d5580000,0x00000000d5b00000,0x00000000d5b00000) - from space 512K, 100% used [0x00000000d5d00000,0x00000000d5d80000,0x00000000d5d80000) - to space 2048K, 0% used [0x00000000d5b00000,0x00000000d5b00000,0x00000000d5d00000) - ParOldGen total 165888K, used 124244K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 74% used [0x0000000080000000,0x0000000087955148,0x000000008a200000) - Metaspace used 67527K, committed 69120K, reserved 1114112K - class space used 7255K, committed 7936K, reserved 1048576K -} -Event: 169.386 GC heap after -{Heap after GC invocations=258 (full 3): - PSYoungGen total 6656K, used 980K [0x00000000d5580000, 0x00000000d5e00000, 0x0000000100000000) - eden space 5632K, 0% used [0x00000000d5580000,0x00000000d5580000,0x00000000d5b00000) - from space 1024K, 95% used [0x00000000d5b00000,0x00000000d5bf5220,0x00000000d5c00000) - to space 1536K, 0% used [0x00000000d5c80000,0x00000000d5c80000,0x00000000d5e00000) - ParOldGen total 165888K, used 124740K [0x0000000080000000, 0x000000008a200000, 0x00000000d5580000) - object space 165888K, 75% used [0x0000000080000000,0x00000000879d1148,0x000000008a200000) - Metaspace used 67527K, committed 69120K, reserved 1114112K - class space used 7255K, committed 7936K, reserved 1048576K -} - -Dll operation events (12 events): -Event: 0.007 Loaded shared library c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\java.dll -Event: 0.043 Loaded shared library c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\zip.dll -Event: 0.055 Loaded shared library C:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\instrument.dll -Event: 0.058 Loaded shared library C:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\net.dll -Event: 0.059 Loaded shared library C:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\nio.dll -Event: 0.061 Loaded shared library C:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\zip.dll -Event: 0.071 Loaded shared library C:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\jimage.dll -Event: 0.114 Loaded shared library c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\verify.dll -Event: 1.018 Loaded shared library C:\Users\Evan\AppData\Roaming\Code\User\globalStorage\redhat.java\1.54.0\config_win\org.eclipse.equinox.launcher\org.eclipse.equinox.launcher.win32.win32.x86_64_1.3.0.v20260203-2149\eclipse_11919.dll -Event: 8.641 Loaded shared library C:\Users\Evan\AppData\Local\Temp\jna-2172094\jna6651005057382125844.dll -Event: 16.256 Loaded shared library C:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\sunmscapi.dll -Event: 19.486 Loaded shared library C:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\extnet.dll - -Deoptimization events (20 events): -Event: 30.812 Thread 0x000001ee4c4c7880 DEOPT PACKING pc=0x000001ee70a3b850 sp=0x0000006b5eafeac0 -Event: 30.813 Thread 0x000001ee4c4c7880 DEOPT UNPACKING pc=0x000001ee77644242 sp=0x0000006b5eafe018 mode 0 -Event: 30.813 Thread 0x000001ee4c4c7880 DEOPT PACKING pc=0x000001ee70a3b850 sp=0x0000006b5eafeac0 -Event: 30.813 Thread 0x000001ee4c4c7880 DEOPT UNPACKING pc=0x000001ee77644242 sp=0x0000006b5eafe018 mode 0 -Event: 30.813 Thread 0x000001ee4c4c7880 DEOPT PACKING pc=0x000001ee70a3b850 sp=0x0000006b5eafeac0 -Event: 30.813 Thread 0x000001ee4c4c7880 DEOPT UNPACKING pc=0x000001ee77644242 sp=0x0000006b5eafe018 mode 0 -Event: 30.814 Thread 0x000001ee4c4c7880 DEOPT PACKING pc=0x000001ee70a3b850 sp=0x0000006b5eafeac0 -Event: 30.814 Thread 0x000001ee4c4c7880 DEOPT UNPACKING pc=0x000001ee77644242 sp=0x0000006b5eafe018 mode 0 -Event: 30.845 Thread 0x000001ee4c4c7880 Uncommon trap: trap_request=0xffffff45 fr.pc=0x000001ee783807a8 relative=0x0000000000000948 -Event: 30.845 Thread 0x000001ee4c4c7880 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000001ee783807a8 method=java.util.ImmutableCollections$AbstractImmutableList.equals(Ljava/lang/Object;)Z @ 2 c2 -Event: 30.846 Thread 0x000001ee4c4c7880 DEOPT PACKING pc=0x000001ee783807a8 sp=0x0000006b5eafe480 -Event: 30.846 Thread 0x000001ee4c4c7880 DEOPT UNPACKING pc=0x000001ee77643aa2 sp=0x0000006b5eafe420 mode 2 -Event: 167.002 Thread 0x000001ee5014b660 Uncommon trap: trap_request=0xffffffcc fr.pc=0x000001ee78480b40 relative=0x0000000000002780 -Event: 167.002 Thread 0x000001ee5014b660 Uncommon trap: reason=intrinsic_or_type_checked_inlining action=make_not_entrant pc=0x000001ee78480b40 method=java.util.ArrayList$SubList.toArray([Ljava/lang/Object;)[Ljava/lang/Object; @ 58 c2 -Event: 167.002 Thread 0x000001ee5014b660 DEOPT PACKING pc=0x000001ee78480b40 sp=0x0000006b618fbac0 -Event: 167.003 Thread 0x000001ee5014b660 DEOPT UNPACKING pc=0x000001ee77643aa2 sp=0x0000006b618fb880 mode 2 -Event: 167.003 Thread 0x000001ee5014b660 Uncommon trap: trap_request=0xffffffcc fr.pc=0x000001ee7846c8d8 relative=0x0000000000001838 -Event: 167.003 Thread 0x000001ee5014b660 Uncommon trap: reason=intrinsic_or_type_checked_inlining action=make_not_entrant pc=0x000001ee7846c8d8 method=java.util.ArrayList$SubList.toArray([Ljava/lang/Object;)[Ljava/lang/Object; @ 58 c2 -Event: 167.003 Thread 0x000001ee5014b660 DEOPT PACKING pc=0x000001ee7846c8d8 sp=0x0000006b618fb800 -Event: 167.003 Thread 0x000001ee5014b660 DEOPT UNPACKING pc=0x000001ee77643aa2 sp=0x0000006b618fb728 mode 2 - -Classes loaded (20 events): -Event: 30.847 Loading class sun/util/cldr/CLDRTimeZoneNameProviderImpl -Event: 30.847 Loading class sun/util/locale/provider/TimeZoneNameProviderImpl -Event: 30.847 Loading class sun/util/locale/provider/TimeZoneNameProviderImpl done -Event: 30.847 Loading class sun/util/cldr/CLDRTimeZoneNameProviderImpl done -Event: 30.849 Loading class sun/util/resources/cldr/TimeZoneNames -Event: 30.849 Loading class sun/util/resources/TimeZoneNamesBundle -Event: 30.849 Loading class sun/util/resources/OpenListResourceBundle -Event: 30.849 Loading class sun/util/resources/OpenListResourceBundle done -Event: 30.849 Loading class sun/util/resources/TimeZoneNamesBundle done -Event: 30.849 Loading class sun/util/resources/cldr/TimeZoneNames done -Event: 30.849 Loading class sun/util/resources/cldr/TimeZoneNames_en -Event: 30.850 Loading class sun/util/resources/cldr/TimeZoneNames_en done -Event: 30.851 Loading class sun/util/resources/cldr/TimeZoneNames_en_US -Event: 30.851 Loading class sun/util/resources/cldr/TimeZoneNames_en_US done -Event: 30.852 Loading class sun/util/cldr/CLDRBaseLocaleDataMetaInfo$TZCanonicalIDMapHolder -Event: 30.853 Loading class sun/util/cldr/CLDRBaseLocaleDataMetaInfo$TZCanonicalIDMapHolder done -Event: 30.855 Loading class sun/util/resources/TimeZoneNames -Event: 30.856 Loading class sun/util/resources/TimeZoneNames done -Event: 30.856 Loading class sun/util/resources/TimeZoneNames_en -Event: 30.856 Loading class sun/util/resources/TimeZoneNames_en done - -Classes unloaded (11 events): -Event: 9.654 Thread 0x000001ee6d05eb10 Unloading class 0x000001ee051af400 'java/lang/invoke/LambdaForm$MH+0x000001ee051af400' -Event: 9.654 Thread 0x000001ee6d05eb10 Unloading class 0x000001ee051af000 'java/lang/invoke/LambdaForm$MH+0x000001ee051af000' -Event: 9.654 Thread 0x000001ee6d05eb10 Unloading class 0x000001ee051aec00 'java/lang/invoke/LambdaForm$MH+0x000001ee051aec00' -Event: 9.654 Thread 0x000001ee6d05eb10 Unloading class 0x000001ee051ae800 'java/lang/invoke/LambdaForm$MH+0x000001ee051ae800' -Event: 9.654 Thread 0x000001ee6d05eb10 Unloading class 0x000001ee051ae400 'java/lang/invoke/LambdaForm$BMH+0x000001ee051ae400' -Event: 9.654 Thread 0x000001ee6d05eb10 Unloading class 0x000001ee051ae000 'java/lang/invoke/LambdaForm$DMH+0x000001ee051ae000' -Event: 9.654 Thread 0x000001ee6d05eb10 Unloading class 0x000001ee051acc00 'java/lang/invoke/LambdaForm$DMH+0x000001ee051acc00' -Event: 17.616 Thread 0x000001ee6d05eb10 Unloading class 0x000001ee056dd000 'java/lang/invoke/LambdaForm$DMH+0x000001ee056dd000' -Event: 17.616 Thread 0x000001ee6d05eb10 Unloading class 0x000001ee056dc800 'java/lang/invoke/LambdaForm$DMH+0x000001ee056dc800' -Event: 17.616 Thread 0x000001ee6d05eb10 Unloading class 0x000001ee056dcc00 'java/lang/invoke/LambdaForm$DMH+0x000001ee056dcc00' -Event: 17.616 Thread 0x000001ee6d05eb10 Unloading class 0x000001ee056dc000 'java/lang/invoke/LambdaForm$DMH+0x000001ee056dc000' - -Classes redefined (0 events): -No events - -Internal exceptions (20 events): -Event: 19.056 Thread 0x000001ee5012e260 Exception (0x00000000d5b11540) -thrown [s\src\hotspot\share\prims\jni.cpp, line 520] -Event: 19.086 Thread 0x000001ee50151240 Implicit null exception at 0x000001ee783c2b5c to 0x000001ee783c3164 -Event: 19.087 Thread 0x000001ee4c7b2f00 Exception (0x00000000d55bece8) -thrown [s\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 19.091 Thread 0x000001ee50151240 Exception (0x00000000d55dc138) -thrown [s\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 19.091 Thread 0x000001ee4c7b2f00 Exception (0x00000000d55c5078) -thrown [s\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 19.234 Thread 0x000001ee4c7b2f00 Exception (0x00000000d5a25358) -thrown [s\src\hotspot\share\prims\jni.cpp, line 520] -Event: 19.234 Thread 0x000001ee4c7b2f00 Exception (0x00000000d5a26430) -thrown [s\src\hotspot\share\prims\jni.cpp, line 520] -Event: 19.235 Thread 0x000001ee4c7b2f00 Exception (0x00000000d5a27190) -thrown [s\src\hotspot\share\prims\jni.cpp, line 520] -Event: 19.517 Thread 0x000001ee501337b0 Exception (0x00000000d55e4100) -thrown [s\src\hotspot\share\prims\jni.cpp, line 520] -Event: 19.648 Thread 0x000001ee501337b0 Exception (0x00000000d57911d8) -thrown [s\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 19.681 Thread 0x000001ee50135880 Exception (0x00000000d5ba6dc8) -thrown [s\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 19.697 Thread 0x000001ee50135880 Exception (0x00000000d55d6df8) -thrown [s\src\hotspot\share\prims\jni.cpp, line 520] -Event: 19.697 Thread 0x000001ee50135880 Exception (0x00000000d55d7df8) -thrown [s\src\hotspot\share\prims\jni.cpp, line 520] -Event: 20.430 Thread 0x000001ee509a5d90 Exception (0x00000000d56f1168) -thrown [s\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 20.431 Thread 0x000001ee509a5d90 Exception (0x00000000d56fb0e0) -thrown [s\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 24.990 Thread 0x000001ee509a5d90 Exception (0x00000000d58f8a30) -thrown [s\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 31.624 Thread 0x000001ee5014afd0 Exception (0x00000000d5658cb0) -thrown [s\src\hotspot\share\interpreter\linkResolver.cpp, line 840] -Event: 166.552 Thread 0x000001ee5014afd0 Exception (0x00000000d56c4fd0) -thrown [s\src\hotspot\share\interpreter\linkResolver.cpp, line 840] -Event: 179.109 Thread 0x000001ee5014afd0 Exception (0x00000000d56c35c0) -thrown [s\src\hotspot\share\interpreter\linkResolver.cpp, line 840] -Event: 179.111 Thread 0x000001ee5014b660 Exception (0x00000000d56f7b30) -thrown [s\src\hotspot\share\interpreter\linkResolver.cpp, line 773] - -ZGC Phase Switch (0 events): -No events - -VM Operations (20 events): -Event: 1262.668 Executing non-safepoint VM operation: HandshakeAllThreads (HandshakeForDeflation) -Event: 1262.669 Executing non-safepoint VM operation: HandshakeAllThreads (HandshakeForDeflation) done -Event: 1262.669 Executing non-safepoint VM operation: RendezvousGCThreads -Event: 1262.669 Executing non-safepoint VM operation: RendezvousGCThreads done -Event: 1322.809 Executing non-safepoint VM operation: HandshakeAllThreads (HandshakeForDeflation) -Event: 1322.809 Executing non-safepoint VM operation: HandshakeAllThreads (HandshakeForDeflation) done -Event: 1322.809 Executing non-safepoint VM operation: RendezvousGCThreads -Event: 1322.809 Executing non-safepoint VM operation: RendezvousGCThreads done -Event: 1563.007 Executing non-safepoint VM operation: HandshakeAllThreads (HandshakeForDeflation) -Event: 1563.007 Executing non-safepoint VM operation: HandshakeAllThreads (HandshakeForDeflation) done -Event: 1563.007 Executing non-safepoint VM operation: RendezvousGCThreads -Event: 1563.007 Executing non-safepoint VM operation: RendezvousGCThreads done -Event: 1923.783 Executing non-safepoint VM operation: HandshakeAllThreads (HandshakeForDeflation) -Event: 1923.783 Executing non-safepoint VM operation: HandshakeAllThreads (HandshakeForDeflation) done -Event: 1923.783 Executing non-safepoint VM operation: RendezvousGCThreads -Event: 1923.783 Executing non-safepoint VM operation: RendezvousGCThreads done -Event: 1983.919 Executing non-safepoint VM operation: HandshakeAllThreads (HandshakeForDeflation) -Event: 1983.919 Executing non-safepoint VM operation: HandshakeAllThreads (HandshakeForDeflation) done -Event: 1983.919 Executing non-safepoint VM operation: RendezvousGCThreads -Event: 1983.919 Executing non-safepoint VM operation: RendezvousGCThreads done - -Memory protections (0 events): -No events - -Nmethod flushes (20 events): -Event: 17.648 Thread 0x000001ee6d05eb10 flushing osr nmethod 0x000001ee70afc610 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b18890 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b1eb10 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b29b90 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b3ae90 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b46910 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b47290 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b47a90 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b48a90 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b4e310 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b6db10 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b6e110 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b6e990 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b6ed10 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b70790 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b7bf10 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70b82390 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70bb7910 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing nmethod 0x000001ee70bbb310 -Event: 17.648 Thread 0x000001ee6d05eb10 flushing osr nmethod 0x000001ee70bfd090 - -Events (20 events): -Event: 169.390 Thread 0x000001ee45f72a70 Thread added: 0x000001ee4e200af0 -Event: 169.391 Thread 0x000001ee45f72a70 Thread added: 0x000001ee4e2011c0 -Event: 173.598 Thread 0x000001ee4e2011c0 Thread exited: 0x000001ee4e2011c0 -Event: 173.598 Thread 0x000001ee4e200af0 Thread exited: 0x000001ee4e200af0 -Event: 178.612 Thread 0x000001ee4e201890 Thread exited: 0x000001ee4e201890 -Event: 178.612 Thread 0x000001ee4e203aa0 Thread exited: 0x000001ee4e203aa0 -Event: 178.612 Thread 0x000001ee4e200420 Thread exited: 0x000001ee4e200420 -Event: 243.150 Thread 0x000001ee5014b660 Thread exited: 0x000001ee5014b660 -Event: 303.164 Thread 0x000001ee50150bb0 Thread exited: 0x000001ee50150bb0 -Event: 363.330 Thread 0x000001ee50150520 Thread exited: 0x000001ee50150520 -Event: 423.343 Thread 0x000001ee501316e0 Thread exited: 0x000001ee501316e0 -Event: 483.410 Thread 0x000001ee5014fe90 Thread exited: 0x000001ee5014fe90 -Event: 543.414 Thread 0x000001ee5014f170 Thread exited: 0x000001ee5014f170 -Event: 603.433 Thread 0x000001ee50130330 Thread exited: 0x000001ee50130330 -Event: 663.442 Thread 0x000001ee5014f800 Thread exited: 0x000001ee5014f800 -Event: 723.450 Thread 0x000001ee50131d70 Thread exited: 0x000001ee50131d70 -Event: 783.459 Thread 0x000001ee501518d0 Thread exited: 0x000001ee501518d0 -Event: 843.465 Thread 0x000001ee5012ef80 Thread exited: 0x000001ee5012ef80 -Event: 903.467 Thread 0x000001ee5012fca0 Thread exited: 0x000001ee5012fca0 -Event: 963.483 Thread 0x000001ee5014eae0 Thread exited: 0x000001ee5014eae0 - - -Dynamic libraries: -0x00007ff617d60000 - 0x00007ff617d6e000 c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\java.exe -0x00007fff5cb20000 - 0x00007fff5cd87000 C:\WINDOWS\SYSTEM32\ntdll.dll -0x00007fff5b530000 - 0x00007fff5b5f9000 C:\WINDOWS\System32\KERNEL32.DLL -0x00007fff59fb0000 - 0x00007fff5a39f000 C:\WINDOWS\System32\KERNELBASE.dll -0x00007fff59c70000 - 0x00007fff59dbb000 C:\WINDOWS\System32\ucrtbase.dll -0x00007fff33740000 - 0x00007fff33758000 c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\jli.dll -0x00007fff33640000 - 0x00007fff3365e000 c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\VCRUNTIME140.dll -0x00007fff5a940000 - 0x00007fff5ab05000 C:\WINDOWS\System32\USER32.dll -0x00007fff5a530000 - 0x00007fff5a557000 C:\WINDOWS\System32\win32u.dll -0x00007fff2d190000 - 0x00007fff2d423000 C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.26100.7309_none_3e05feeae336a044\COMCTL32.dll -0x00007fff5b9d0000 - 0x00007fff5b9fb000 C:\WINDOWS\System32\GDI32.dll -0x00007fff5c890000 - 0x00007fff5c939000 C:\WINDOWS\System32\msvcrt.dll -0x00007fff5a620000 - 0x00007fff5a74c000 C:\WINDOWS\System32\gdi32full.dll -0x00007fff59f00000 - 0x00007fff59fa3000 C:\WINDOWS\System32\msvcp_win.dll -0x00007fff5b680000 - 0x00007fff5b6b1000 C:\WINDOWS\System32\IMM32.DLL -0x00007fff39030000 - 0x00007fff3903c000 c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\vcruntime140_1.dll -0x00007ffee72d0000 - 0x00007ffee735d000 c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\msvcp140.dll -0x00007ffe8fcc0000 - 0x00007ffe90a61000 c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\server\jvm.dll -0x00007fff5b8b0000 - 0x00007fff5b964000 C:\WINDOWS\System32\ADVAPI32.dll -0x00007fff5c750000 - 0x00007fff5c7f6000 C:\WINDOWS\System32\sechost.dll -0x00007fff5b400000 - 0x00007fff5b518000 C:\WINDOWS\System32\RPCRT4.dll -0x00007fff5b600000 - 0x00007fff5b674000 C:\WINDOWS\System32\WS2_32.dll -0x00007fff59160000 - 0x00007fff591be000 C:\WINDOWS\SYSTEM32\POWRPROF.dll -0x00007fff4e900000 - 0x00007fff4e935000 C:\WINDOWS\SYSTEM32\WINMM.dll -0x00007fff48e70000 - 0x00007fff48e7b000 C:\WINDOWS\SYSTEM32\VERSION.dll -0x00007fff59140000 - 0x00007fff59154000 C:\WINDOWS\SYSTEM32\UMPDC.dll -0x00007fff58a20000 - 0x00007fff58a3b000 C:\WINDOWS\SYSTEM32\kernel.appcore.dll -0x00007fff35640000 - 0x00007fff3564a000 c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\jimage.dll -0x00007fff57330000 - 0x00007fff57572000 C:\WINDOWS\SYSTEM32\DBGHELP.DLL -0x00007fff5bd20000 - 0x00007fff5c0a6000 C:\WINDOWS\System32\combase.dll -0x00007fff5bb00000 - 0x00007fff5bbd6000 C:\WINDOWS\System32\OLEAUT32.dll -0x00007fff47240000 - 0x00007fff4727c000 C:\WINDOWS\SYSTEM32\dbgcore.DLL -0x00007fff59e50000 - 0x00007fff59ef5000 C:\WINDOWS\System32\bcryptPrimitives.dll -0x00007fff33280000 - 0x00007fff3328f000 c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\instrument.dll -0x00007fff33260000 - 0x00007fff33280000 c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\java.dll -0x00007fff5ac80000 - 0x00007fff5b3d3000 C:\WINDOWS\System32\SHELL32.dll -0x00007fff5a750000 - 0x00007fff5a8ba000 C:\WINDOWS\System32\wintypes.dll -0x00007fff57850000 - 0x00007fff580ae000 C:\WINDOWS\SYSTEM32\windows.storage.dll -0x00007fff5c650000 - 0x00007fff5c745000 C:\WINDOWS\System32\SHCORE.dll -0x00007fff5c540000 - 0x00007fff5c5a6000 C:\WINDOWS\System32\shlwapi.dll -0x00007fff59b90000 - 0x00007fff59bb9000 C:\WINDOWS\SYSTEM32\profapi.dll -0x00007fff32410000 - 0x00007fff32428000 c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\zip.dll -0x00007fff32220000 - 0x00007fff32230000 C:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\net.dll -0x00007fff51ca0000 - 0x00007fff51dc8000 C:\WINDOWS\SYSTEM32\WINHTTP.dll -0x00007fff59000000 - 0x00007fff5906b000 C:\WINDOWS\system32\mswsock.dll -0x00007fff2fc90000 - 0x00007fff2fca6000 C:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\nio.dll -0x00007fff32210000 - 0x00007fff32220000 c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\verify.dll -0x00007ffee4950000 - 0x00007ffee4995000 C:\Users\Evan\AppData\Roaming\Code\User\globalStorage\redhat.java\1.54.0\config_win\org.eclipse.equinox.launcher\org.eclipse.equinox.launcher.win32.win32.x86_64_1.3.0.v20260203-2149\eclipse_11919.dll -0x00007fff5c940000 - 0x00007fff5cad7000 C:\WINDOWS\System32\ole32.dll -0x00007fff59370000 - 0x00007fff5938b000 C:\WINDOWS\SYSTEM32\CRYPTSP.dll -0x00007fff58980000 - 0x00007fff589ba000 C:\WINDOWS\system32\rsaenh.dll -0x00007fff590d0000 - 0x00007fff590fb000 C:\WINDOWS\SYSTEM32\USERENV.dll -0x00007fff59b60000 - 0x00007fff59b8a000 C:\WINDOWS\SYSTEM32\bcrypt.dll -0x00007fff59390000 - 0x00007fff5939c000 C:\WINDOWS\SYSTEM32\CRYPTBASE.dll -0x00007fff584a0000 - 0x00007fff584d4000 C:\WINDOWS\SYSTEM32\IPHLPAPI.DLL -0x00007fff5b8a0000 - 0x00007fff5b8aa000 C:\WINDOWS\System32\NSI.dll -0x00007ffed9210000 - 0x00007ffed9259000 C:\Users\Evan\AppData\Local\Temp\jna-2172094\jna6651005057382125844.dll -0x00007fff5c600000 - 0x00007fff5c608000 C:\WINDOWS\System32\PSAPI.DLL -0x00007fff51e80000 - 0x00007fff51e9e000 C:\WINDOWS\SYSTEM32\dhcpcsvc6.DLL -0x00007fff51e50000 - 0x00007fff51e73000 C:\WINDOWS\SYSTEM32\dhcpcsvc.DLL -0x00007fff2fc20000 - 0x00007fff2fc2e000 C:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\sunmscapi.dll -0x00007fff5a3b0000 - 0x00007fff5a527000 C:\WINDOWS\System32\CRYPT32.dll -0x00007fff59590000 - 0x00007fff595c0000 C:\WINDOWS\SYSTEM32\ncrypt.dll -0x00007fff59540000 - 0x00007fff5957f000 C:\WINDOWS\SYSTEM32\NTASN1.dll -0x00007fff2e1a0000 - 0x00007fff2e1a9000 C:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\extnet.dll - -JVMTI agents: -c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\lombok\lombok-1.18.39-4050.jar path:c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\instrument.dll, loaded, initialized, instrumentlib options:none - -dbghelp: loaded successfully - version: 4.0.5 - missing functions: none -symbol engine: initialized successfully - sym options: 0x614 - pdb path: .;c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin;C:\WINDOWS\SYSTEM32;C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.26100.7309_none_3e05feeae336a044;c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\jre\21.0.10-win32-x86_64\bin\server;C:\Users\Evan\AppData\Roaming\Code\User\globalStorage\redhat.java\1.54.0\config_win\org.eclipse.equinox.launcher\org.eclipse.equinox.launcher.win32.win32.x86_64_1.3.0.v20260203-2149;C:\Users\Evan\AppData\Local\Temp\jna-2172094 - -VM Arguments: -jvm_args: --add-modules=ALL-SYSTEM --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/sun.nio.fs=ALL-UNNAMED -Declipse.application=org.eclipse.jdt.ls.core.id1 -Dosgi.bundles.defaultStartLevel=4 -Declipse.product=org.eclipse.jdt.ls.core.product -Djava.import.generatesMetadataFilesAtProjectRoot=false -DDetectVMInstallationsJob.disabled=true -Dfile.encoding=utf8 -XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx2G -Xms100m -Xlog:disable -javaagent:c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\lombok\lombok-1.18.39-4050.jar -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=c:\Users\Evan\AppData\Roaming\Code\User\workspaceStorage\609d357b4a62589867dde8a22b91e9ee\redhat.java -Daether.dependencyCollector.impl=bf -java_command: c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\server\plugins\org.eclipse.equinox.launcher_1.7.100.v20251111-0406.jar -configuration c:\Users\Evan\AppData\Roaming\Code\User\globalStorage\redhat.java\1.54.0\config_win -data c:\Users\Evan\AppData\Roaming\Code\User\workspaceStorage\609d357b4a62589867dde8a22b91e9ee\redhat.java\jdt_ws --pipe=\\.\pipe\lsp-c3923ce2cfc611e32e6dd1d393bf40eb-sock -java_class_path (initial): c:\Users\Evan\.vscode\extensions\redhat.java-1.54.0-win32-x64\server\plugins\org.eclipse.equinox.launcher_1.7.100.v20251111-0406.jar -Launcher Type: SUN_STANDARD - -[Global flags] - uintx AdaptiveSizePolicyWeight = 90 {product} {command line} - intx CICompilerCount = 12 {product} {ergonomic} - uintx GCTimeRatio = 4 {product} {command line} - bool HeapDumpOnOutOfMemoryError = true {manageable} {command line} - ccstr HeapDumpPath = c:\Users\Evan\AppData\Roaming\Code\User\workspaceStorage\609d357b4a62589867dde8a22b91e9ee\redhat.java {manageable} {command line} - size_t InitialHeapSize = 104857600 {product} {command line} - size_t MaxHeapSize = 2147483648 {product} {command line} - size_t MaxNewSize = 715653120 {product} {ergonomic} - size_t MinHeapDeltaBytes = 524288 {product} {ergonomic} - size_t MinHeapSize = 104857600 {product} {command line} - size_t NewSize = 34603008 {product} {ergonomic} - uintx NonNMethodCodeHeapSize = 7602480 {pd product} {ergonomic} - uintx NonProfiledCodeHeapSize = 122027880 {pd product} {ergonomic} - size_t OldSize = 70254592 {product} {ergonomic} - uintx ProfiledCodeHeapSize = 122027880 {pd product} {ergonomic} - uintx ReservedCodeCacheSize = 251658240 {pd product} {ergonomic} - bool SegmentedCodeCache = true {product} {ergonomic} - size_t SoftMaxHeapSize = 2147483648 {manageable} {ergonomic} - bool UseCompressedOops = true {product lp64_product} {ergonomic} - bool UseLargePagesIndividualAllocation = false {pd product} {ergonomic} - bool UseParallelGC = true {product} {command line} - -Logging: -Log output configuration: - #0: stdout all=off uptime,level,tags foldmultilines=false - #1: stderr all=off uptime,level,tags foldmultilines=false - -Release file: -JAVA_VERSION="21.0.10" -MODULES="java.base java.compiler java.datatransfer java.xml java.prefs java.desktop java.instrument java.logging java.management java.security.sasl java.naming java.rmi java.management.rmi java.net.http java.scripting java.security.jgss java.transaction.xa java.sql java.sql.rowset java.xml.crypto java.se java.smartcardio jdk.accessibility jdk.internal.jvmstat jdk.attach jdk.charsets jdk.internal.opt jdk.zipfs jdk.compiler jdk.crypto.ec jdk.crypto.cryptoki jdk.crypto.mscapi jdk.dynalink jdk.internal.ed jdk.editpad jdk.hotspot.agent jdk.httpserver jdk.internal.le jdk.internal.vm.ci jdk.internal.vm.compiler jdk.internal.vm.compiler.management jdk.jartool jdk.javadoc jdk.jcmd jdk.management jdk.management.agent jdk.jconsole jdk.jdeps jdk.jdwp.agent jdk.jdi jdk.jfr jdk.jshell jdk.jsobject jdk.jstatd jdk.localedata jdk.management.jfr jdk.naming.dns jdk.naming.rmi jdk.net jdk.nio.mapmode jdk.random jdk.sctp jdk.security.auth jdk.security.jgss jdk.unsupported jdk.unsupported.desktop jdk.xml.dom" - -Environment Variables: -JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-21.0.8.9-hotspot -PATH=C:\Program Files\Eclipse Adoptium\jdk-21.0.8.9-hotspot\bin;C:\Program Files\Eclipse Adoptium\jdk-8.0.462.8-hotspot\bin;C:\Program Files\Eclipse Adoptium\jdk-17.0.15.6-hotspot\bin;C:\Program Files\Common Files\Oracle\Java\javapath;C:\Program Files (x86)\Common Files\Oracle\Java\java8path;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;D:\Tools\Bitvise;D:\Tools\Git\Git\cmd;D:\Tools\Node\;D:\Tools\Sqlite3\;C:\Program Files\NVIDIA Corporation\NVIDIA App\NvDLISR;C:\mingw64\bin;;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;D:\Tools & IDE\AWS CLI\;C:\Program Files\Go\bin;C:\Program Files\dotnet\;C:\Users\Evan\AppData\Local\Programs\Python\Python313\Scripts\;C:\Users\Evan\AppData\Local\Programs\Python\Python313\;C:\Users\Evan\AppData\Local\Programs\Python\Launcher\;C:\Users\Evan\AppData\Local\Microsoft\WindowsApps;D:\Tools\VSCode\Microsoft VS Code\bin;C:\Users\Evan\AppData\Local\GitHubDesktop\bin;C:\Users\Evan\AppData\Roaming\npm;C:\Users\Evan\go\bin -USERNAME=Evan -OS=Windows_NT -PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 186 Stepping 2, GenuineIntel -TMP=C:\Users\Evan\AppData\Local\Temp -TEMP=C:\Users\Evan\AppData\Local\Temp - - - - -Periodic native trim disabled - ---------------- S Y S T E M --------------- - -OS: - Windows 11 , 64 bit Build 26100 (10.0.26100.7623) -OS uptime: 0 days 23:11 hours -Hyper-V role detected - -CPU: total 16 (initial active 16) (8 cores per cpu, 2 threads per core) family 6 model 186 stepping 2 microcode 0x410e, cx8, cmov, fxsr, ht, mmx, 3dnowpref, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, lzcnt, tsc, tscinvbit, avx, avx2, aes, erms, clmul, bmi1, bmi2, adx, sha, fma, vzeroupper, clflush, clflushopt, clwb, hv, serialize, rdtscp, rdpid, fsrm, f16c, cet_ibt, cet_ss -Processor Information for the first 16 processors : - Max Mhz: 2400, Current Mhz: 2400, Mhz Limit: 2400 - -Memory: 4k page, system-wide physical 16088M (896M free) -TotalPageFile size 32838M (AvailPageFile size 228M) -current process WorkingSet (physical memory assigned to process): 12M, peak: 426M -current process commit charge ("private bytes"): 464M, peak: 512M - -vm_info: OpenJDK 64-Bit Server VM (21.0.10+7-LTS) for windows-amd64 JRE (21.0.10+7-LTS), built on 2026-01-20T00:00:00Z by "admin" with MS VC++ 17.12 (VS2022) - -END. From c72b951b52dcae500127573d6d29f60307d88a00 Mon Sep 17 00:00:00 2001 From: 5803024019 Date: Tue, 19 May 2026 17:43:39 +0700 Subject: [PATCH 3/4] chore: update root gitignore to cover android properties --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3d03636..3fa0349 100644 --- a/.gitignore +++ b/.gitignore @@ -44,5 +44,5 @@ build/ walkguide-backend/demo/hs_err_pid*.log # Android SDK path (generated by Android Studio) -android/local.properties +walkguide-mobile/walkguide_app/android/local.properties From c862d4eaebd278e74ce83160d26da7b825cdee6d Mon Sep 17 00:00:00 2001 From: 5803024019 Date: Wed, 20 May 2026 09:02:21 +0700 Subject: [PATCH 4/4] docs: add design patterns documentation for WalkGuide --- ooad-docs/DESIGN_PATTERNS.puml | 499 +++++++++++++++ ooad-docs/DESIGN_PATTERNS_NOTES.md | 994 +++++++++++++++++++++++++++++ 2 files changed, 1493 insertions(+) create mode 100644 ooad-docs/DESIGN_PATTERNS.puml create mode 100644 ooad-docs/DESIGN_PATTERNS_NOTES.md diff --git a/ooad-docs/DESIGN_PATTERNS.puml b/ooad-docs/DESIGN_PATTERNS.puml new file mode 100644 index 0000000..d409c9c --- /dev/null +++ b/ooad-docs/DESIGN_PATTERNS.puml @@ -0,0 +1,499 @@ +' ============================================================ +' WALKGUIDE — DESIGN PATTERNS (GoF) +' Flutter × Spring Boot × In-Device AI +' 7 Patterns: 2 Creational · 2 Structural · 3 Behavioral +' ============================================================ + +@startuml WalkGuide_Design_Patterns + +skinparam monochrome false +skinparam shadowing false +skinparam defaultFontName Arial +skinparam defaultFontSize 12 +skinparam roundCorner 10 +skinparam ArrowColor #555555 +skinparam ArrowThickness 1.2 + +skinparam class { + BackgroundColor #FAFAFA + BorderColor #AAAAAA + HeaderBackgroundColor #E8E8E8 + FontColor #222222 + StereotypeFontColor #666666 + AttributeFontColor #333333 +} + +skinparam package { + BackgroundColor #F5F5F5 + BorderColor #888888 + FontColor #333333 + FontStyle bold +} + +skinparam note { + BackgroundColor #FFFDE7 + BorderColor #F9A825 + FontColor #444444 + FontSize 11 +} + +' ============================================================ +' PATTERN 1 — BUILDER (Creational) +' ============================================================ + +package "① Builder Pattern [Creational]" #EEF6EE { + + interface "UserBuilder\n<>" as UserBuilder { + + email(String) : UserBuilder + + password(String) : UserBuilder + + displayName(String) : UserBuilder + + uniqueUserId(String) : UserBuilder + + fcmToken(String) : UserBuilder + + role(Role) : UserBuilder + + build() : User + } + + class "User\n<>" as User { + - id : Long + - email : String + - password : String + - displayName : String + - uniqueUserId : String + - fcmToken : String + - role : Role + - createdAt : Timestamp + + {static} builder() : UserBuilder + } + + class "FcmService\n<>" as FcmService { + + sendPushNotification(userId, payload) + + sendSosAlert(guardianId, lat, lng) + - buildMessage(token, title, body) : Message + } + + class "AuthService\n<>" as AuthService { + + register(RegisterRequest) : AuthDataResponse + + login(LoginRequest) : AuthDataResponse + - buildAuthResponse(user, tokens) : AuthDataResponse + } + + UserBuilder ..> User : <> + User ..> UserBuilder : <> + FcmService ..> "Firebase\nMessage.builder()" : uses + AuthService ..> "AuthDataResponse\n.builder()" : uses +} + +note bottom of UserBuilder + Lombok @Builder pada User.java + Memisahkan konstruksi objek kompleks + dari representasinya. Optional fields + (displayName, uniqueUserId, fcmToken) + tidak perlu constructor overloading. +end note + +' ============================================================ +' PATTERN 2 — SINGLETON (Creational) +' ============================================================ + +package "② Singleton Pattern [Creational]" #EEF0FF { + + class "GetIt\n<>" as GetIt { + - {static} _instance : GetIt + + {static} instance : GetIt + + registerSingleton(T) + + get() : T + } + + class "TtsService\n<>" as TtsService { + - {static} _instance : TtsService + - _flutterTts : FlutterTts + + speak(String text) + + speakImmediate(String text) + + stop() + + setLanguage(String lang) + } + + class "SttService\n<>" as SttService { + - {static} _instance : SttService + - _speechToText : SpeechToText + + startListening() + + stopListening() + + onResult : Stream + } + + class "YoloDetector\n<>" as YoloDetector { + - {static} _instance : YoloDetector + - _interpreter : Interpreter + - _labels : List + + loadModel() + + detect(CameraImage) : List + + isRunning : bool + } + + class "WebSocketService\n<>" as WebSocketService { + - {static} _instance : WebSocketService + - _stompClient : StompClient + + connect(String token) + + subscribe(String destination) + + disconnect() + } + + class "AgoraService\n<>" as AgoraService { + - {static} _instance : AgoraService + - _engine : RtcEngine + + joinChannel(token, channel, uid) + + leaveChannel() + + muteLocalAudio(bool) + } + + GetIt --> TtsService : registers &\nmanages + GetIt --> SttService : registers &\nmanages + GetIt --> YoloDetector : registers &\nmanages + GetIt --> WebSocketService : registers &\nmanages + GetIt --> AgoraService : registers &\nmanages +} + +note right of GetIt + injection_container.dart: + sl.registerSingleton(TtsService()) + sl.registerSingleton(YoloDetector()) + sl.registerSingleton(WebSocketService()) + Satu instance untuk seluruh lifecycle app. +end note + +' ============================================================ +' PATTERN 3 — FACADE (Structural) — Flutter +' ============================================================ + +package "③ Facade Pattern [Structural]" #FFF8E1 { + + class "VoiceCommandHandler\n<>" as VoiceCommandHandler { + - _ttsService : TtsService + - _sttService : SttService + - _router : GoRouter + - _walkGuideBloc : WalkGuideBloc + - _sosBloc : SosBloc + - _notifBloc : NotificationBloc + + processText(String command) : void + - _matchCommand(String) : VoiceCommandKey? + - _executeCommand(VoiceCommandKey) : void + } + + class "WalkGuideBloc\n<>" as WalkGuideBlocFacade { + + onVoiceCommand(String text) + } + + class "GuardianDashboardService\n<>" as GuardianDashboardService { + - _locationService : LocationService + - _activityService : ActivityLogService + - _sosService : SosService + - _notifService : NotificationService + + getDashboard(guardianId) : DashboardResponse + } + + class "SttService " as SttServiceFacade <> + class "TtsService " as TtsServiceFacade <> + class "GoRouter\n<>" as GoRouterFacade <> + class "SosBloc " as SosBlocFacade <> + + class "LocationService\n<>" as LocationService <> + class "ActivityLogService\n<>" as ActivityService <> + class "SosService\n<>" as SosServiceFacade <> + + WalkGuideBlocFacade --> VoiceCommandHandler : processText() + VoiceCommandHandler --> SttServiceFacade : delegates + VoiceCommandHandler --> TtsServiceFacade : delegates + VoiceCommandHandler --> GoRouterFacade : delegates + VoiceCommandHandler --> SosBlocFacade : delegates + + GuardianDashboardService --> LocationService : aggregates + GuardianDashboardService --> ActivityService : aggregates + GuardianDashboardService --> SosServiceFacade : aggregates +} + +note right of VoiceCommandHandler + Client hanya panggil processText("start walkguide") + tanpa perlu tahu kompleksitas di baliknya: + matching phrase → execute command → TTS feedback + → route navigation → BLoC event dispatch +end note + +' ============================================================ +' PATTERN 4 — REPOSITORY / PROXY (Structural) +' ============================================================ + +package "④ Repository Pattern [Structural — Proxy]" #FFF3E0 { + + interface "WalkGuideRepository\n<>" as WalkGuideRepo { + + startSession() : Either + + stopSession() : Either + + logObstacle(ObstacleLogRequest) : Either + + getObstacleLogs() : Either> + } + + interface "ActivityLogRepository\n<>" as ActivityRepo { + + getLogs(page) : Either> + + savePending(ActivityLog) : Either + + syncPending() : Either + } + + class "WalkGuideRepositoryImpl\n<>" as WalkGuideRepoImpl { + - _remoteDataSource : WalkGuideRemoteDataSource + - _localDataSource : WalkGuideLocalDataSource + - _connectivity : ConnectivityPlus + + startSession() : Either + + logObstacle(req) : Either + - _isOnline() : bool + } + + class "ActivityLogRepositoryImpl\n<>" as ActivityRepoImpl { + - _remoteDataSource : ActivityRemoteDataSource + - _localDataSource : ActivityLocalDataSource + + getLogs(page) : Either + + syncPending() : Either + } + + class "WalkGuideRemoteDataSource\n<>" as RemoteDSWalk { + + startSession() : void + + logObstacle(req) : void + ' POST /api/v1/user/obstacle + } + + class "WalkGuideLocalDataSource\n<>" as LocalDSWalk { + + cacheObstacle(ObstacleLog) : void + + getPendingLogs() : List + ' Drift ORM — offline first + } + + WalkGuideRepo <|.. WalkGuideRepoImpl : implements + ActivityRepo <|.. ActivityRepoImpl : implements + WalkGuideRepoImpl --> RemoteDSWalk : online path + WalkGuideRepoImpl --> LocalDSWalk : offline path +} + +note bottom of WalkGuideRepoImpl + Proxy memutuskan sumber data: + if (isOnline) → fetch remote API + else → baca/tulis SQLite (Drift) + Domain layer tidak tahu perbedaannya. + dartz Either untuk typed error. +end note + +' ============================================================ +' PATTERN 5 — OBSERVER (Behavioral) +' ============================================================ + +package "⑤ Observer Pattern [Behavioral]" #F3E5F5 { + + abstract class "Bloc\n<>" as BlocSubject { + # stateController : StreamController + + {abstract} on(EventHandler) + + add(Event event) + + emit(State state) + + stream : Stream + } + + class "WalkGuideBloc\n<>" as WalkGuideBlocObs { + + on(_onStart) + + on(_onStop) + + on(_onFrame) + + on(_onObstacle) + - _yoloDetector : YoloDetector + - _ttsService : TtsService + - _hapticService : HapticService + } + + class "BlocBuilder\n<>" as BlocBuilderWidget { + + builder(ctx, state) : Widget + ' Rebuilds UI on every state emission + } + + class "BlocListener\n<>" as BlocListenerWidget { + + listener(ctx, state) : void + ' Side effects: TTS, haptic, navigation + } + + class "WebSocketService\n<>" as WebSocketObs { + - _stompClient : StompClient + + subscribe(destination) : Stream + + onLocationUpdate : StreamController + + onSosAlert : StreamController + + onNotification : StreamController + } + + class "GuardianMapScreen\n<>" as GuardianMapObs { + + onLocationUpdate(LocationData) + ' Updates flutter_map markers in real-time + } + + BlocSubject <|-- WalkGuideBlocObs : extends + WalkGuideBlocObs --> BlocBuilderWidget : emits state\n(rebuilds UI) + WalkGuideBlocObs --> BlocListenerWidget : emits state\n(side effects) + WebSocketObs --> GuardianMapObs : notifies\nlive location +} + +note left of WebSocketObs + Guardian subscribe topic: + /topic/location/{userId} — live map + /queue/sos/{guardianId} — SOS alert + /queue/notif/{userId} — notifications + STOMP over SockJS (stomp_dart_client) +end note + +' ============================================================ +' PATTERN 6 — STRATEGY (Behavioral) +' ============================================================ + +package "⑥ Strategy Pattern [Behavioral]" #E8F5E9 { + + interface "ObstacleAlertStrategy\n<>" as AlertStrategy { + + alert(DetectionResult result) : void + } + + class "TtsOnlyStrategy\n<>" as TtsOnly { + - _ttsService : TtsService + + alert(result) : void + ' TTS: "Caution! {label} {direction}. {distance}." + } + + class "TtsWithHapticStrategy\n<>" as TtsHaptic { + - _ttsService : TtsService + - _hapticService : HapticService + + alert(result) : void + ' TTS + vibration pattern + } + + class "HapticOnlyStrategy\n<>" as HapticOnly { + - _hapticService : HapticService + + alert(result) : void + ' Vibration only (silent environment) + } + + class "ObstacleAnalyzer\n<>" as ObstacleAnalyzerCtx { + - _strategy : ObstacleAlertStrategy + - _aiConfig : AiConfig + + setStrategy(ObstacleAlertStrategy) + + analyze(List) : void + + prioritize(results) : DetectionResult + + calculateDirection(bbox) : Direction + } + + class "AiConfig\n<>" as AiConfigStrategy { + + alertMode : AlertMode + + confidenceThreshold : double + + maxInferenceFps : int + + enabledLabels : List + } + + AlertStrategy <|.. TtsOnly : implements + AlertStrategy <|.. TtsHaptic : implements + AlertStrategy <|.. HapticOnly : implements + ObstacleAnalyzerCtx --> AlertStrategy : uses + ObstacleAnalyzerCtx ..> AiConfigStrategy : reads alertMode\nto select strategy +} + +note right of ObstacleAnalyzerCtx + Guardian dapat ganti strategy dari dashboard: + alertMode = TTS_ONLY | TTS_HAPTIC | HAPTIC_ONLY + PUT /api/v1/guardian/ai-config + Strategy dipilih runtime tanpa ubah kode utama. +end note + +' ============================================================ +' PATTERN 7 — CHAIN OF RESPONSIBILITY (Behavioral) +' ============================================================ + +package "⑦ Chain of Responsibility [Behavioral]" #FCE4EC { + + ' --- Flutter: Dio Interceptor Chain --- + abstract class "Interceptor\n<>" as DioInterceptor { + + onRequest(options, handler) + + onResponse(response, handler) + + onError(error, handler) + } + + class "AuthInterceptor\n<>" as AuthInterceptor { + - _secureStorage : FlutterSecureStorage + + onRequest(options, handler) + ' Attach Bearer token ke setiap request + + onError(error, handler) + ' Jika 401: refresh token → retry request + } + + class "ErrorInterceptor\n<>" as ErrorInterceptor { + + onError(error, handler) + ' Map HTTP error codes → Failure domain objects + ' 401 → UnauthorizedFailure + ' 404 → NotFoundFailure + ' 500 → ServerFailure + } + + class "LogInterceptor\n<>" as LogInterceptorFlutter { + + onRequest(options, handler) + + onResponse(response, handler) + + onError(error, handler) + ' Print request/response untuk debugging + } + + class "ApiClient\n<>" as ApiClient { + - _dio : Dio + + get(url) : Response + + post(url, data) : Response + + put(url, data) : Response + ' Interceptors dieksekusi berurutan + } + + ' --- Backend: Spring Security Filter Chain --- + abstract class "OncePerRequestFilter\n<>" as SpringFilter { + + {abstract} doFilterInternal(req, res, chain) + + doFilter(req, res, chain) + } + + class "JwtAuthFilter\n<>" as JwtAuthFilter { + - _jwtUtil : JwtUtil + - _userDetailsService : UserDetailsService + + doFilterInternal(req, res, chain) + ' Extract JWT → validate → set SecurityContext + ' Jika invalid: 401 Unauthorized langsung + } + + class "SecurityConfig\n<>" as SecurityConfigChain { + + securityFilterChain(http) : SecurityFilterChain + ' /auth/** → permitAll + ' /api/v1/** → authenticated + ' ROLE_GUARDIAN vs ROLE_USER routing + } + + class "Controller\n<>" as ControllerChain { + + handleRequest(request) : ResponseEntity + ' Request tiba hanya jika lolos semua filter + } + + DioInterceptor <|-- AuthInterceptor : extends + DioInterceptor <|-- ErrorInterceptor : extends + DioInterceptor <|-- LogInterceptorFlutter : extends + + ApiClient --> AuthInterceptor : chain[0] + AuthInterceptor --> ErrorInterceptor : passes to\nchain[1] + ErrorInterceptor --> LogInterceptorFlutter : passes to\nchain[2] + + SpringFilter <|-- JwtAuthFilter : extends + JwtAuthFilter --> SecurityConfigChain : passes to + SecurityConfigChain --> ControllerChain : passes to\n(if authorized) +} + +note bottom of ApiClient + Flutter — Dio interceptor chain: + HTTP Request → AuthInterceptor → ErrorInterceptor → LogInterceptor → Response + Setiap handler bisa: proses, modifikasi, atau blok request. + AuthInterceptor otomatis refresh JWT jika expired (401). +end note + +note bottom of JwtAuthFilter + Backend — Spring Security filter chain: + HTTP Request → JwtAuthFilter → SecurityConfig → Controller + JwtAuthFilter extract & validasi Bearer token setiap request. + Jika invalid → langsung 401 tanpa lanjut ke controller. +end note + +@enduml diff --git a/ooad-docs/DESIGN_PATTERNS_NOTES.md b/ooad-docs/DESIGN_PATTERNS_NOTES.md new file mode 100644 index 0000000..196476d --- /dev/null +++ b/ooad-docs/DESIGN_PATTERNS_NOTES.md @@ -0,0 +1,994 @@ +# Design Patterns — WalkGuide + +> **Flutter × Spring Boot × In-Device AI** +> Dokumentasi 7 Design Patterns (GoF) · Wajib ≥4, min. 1 per kategori + +--- + +## Daftar Isi + +1. [Gambaran Umum](#gambaran-umum) +2. [Creational Patterns](#creational-patterns) + - [Builder Pattern](#1-builder-pattern) + - [Singleton Pattern](#2-singleton-pattern) +3. [Structural Patterns](#structural-patterns) + - [Facade Pattern](#3-facade-pattern) + - [Repository Pattern (Proxy)](#4-repository-pattern-proxy) +4. [Behavioral Patterns](#behavioral-patterns) + - [Observer Pattern](#5-observer-pattern) + - [Strategy Pattern](#6-strategy-pattern) + - [Chain of Responsibility Pattern](#7-chain-of-responsibility-pattern) +5. [Ringkasan Matriks](#ringkasan-matriks) + +--- + +## Gambaran Umum + +WalkGuide mengimplementasikan **7 design patterns GoF** yang tersebar di seluruh lapisan sistem — Flutter (mobile), Spring Boot (backend), dan lapisan AI on-device. Setiap pattern dipilih berdasarkan kebutuhan nyata arsitektur, bukan sekadar pemenuhan syarat akademis. + +| # | Pattern | Kategori | Layer | +|---|---------|----------|-------| +| 1 | Builder | Creational | Backend (Spring Boot) | +| 2 | Singleton | Creational | Flutter | +| 3 | Facade | Structural | Flutter + Backend | +| 4 | Repository (Proxy) | Structural | Flutter | +| 5 | Observer | Behavioral | Flutter + Backend | +| 6 | Strategy | Behavioral | Flutter + Backend | +| 7 | Chain of Responsibility | Behavioral | Flutter + Backend | + +--- + +## Creational Patterns + +Creational patterns mengatur **cara objek diciptakan**, memisahkan logika konstruksi dari penggunaan objek tersebut. + +--- + +### 1. Builder Pattern + +**Lokasi:** `entity/User.java`, `service/FcmService.java`, `service/AuthService.java` + +#### Masalah yang Diselesaikan + +Entitas `User` memiliki banyak field opsional — `displayName`, `uniqueUserId`, `fcmToken` — yang tidak selalu diisi. Tanpa Builder, constructor akan memiliki terlalu banyak parameter sehingga kode sulit dibaca dan rawan salah urutan argumen. + +#### Solusi + +Lombok `@Builder` pada `User.java` membangkitkan builder class secara otomatis. `FcmService` menggunakan `Message.builder()` dari Firebase Admin SDK untuk menyusun payload notifikasi secara berantai. `AuthService` membangun `AuthDataResponse` step-by-step. + +#### Implementasi + +```java +// entity/User.java +@Entity +@Table(name = "users") +@Data +@Builder // ← Builder Pattern +@NoArgsConstructor +@AllArgsConstructor +public class User { + @Id @GeneratedValue + private Long id; + + private String email; + private String password; + private String displayName; // opsional + private String uniqueUserId; // hanya ROLE_USER + private String fcmToken; // update tiap login + + @Enumerated(EnumType.STRING) + private Role role; +} +``` + +```java +// service/AuthService.java — bangun response step-by-step +private AuthDataResponse buildAuthResponse(User user, String accessToken, String refreshToken) { + return AuthDataResponse.builder() + .accessToken(accessToken) + .refreshToken(refreshToken) + .role(user.getRole().name()) + .userId(user.getId()) + .displayName(user.getDisplayName()) + .uniqueUserId(user.getUniqueUserId()) // null jika GUARDIAN + .build(); +} +``` + +```java +// service/FcmService.java — Firebase Message builder +private Message buildSosMessage(String fcmToken, double lat, double lng) { + return Message.builder() + .setToken(fcmToken) + .setNotification(Notification.builder() + .setTitle("🚨 SOS ALERT!") + .setBody("User butuh bantuan! Lokasi: " + lat + ", " + lng) + .build()) + .putData("type", "SOS_ALERT") + .putData("lat", String.valueOf(lat)) + .putData("lng", String.valueOf(lng)) + .setAndroidConfig(AndroidConfig.builder() + .setPriority(AndroidConfig.Priority.HIGH) + .build()) + .build(); +} +``` + +#### Diagram + +``` + «Builder» + UserBuilder + ┌─────────────────────┐ + │ + email(String) │ + │ + password(String) │ + │ + displayName(...) │ + │ + uniqueUserId(...) │ + │ + fcmToken(...) │ + │ + build() : User │ + └──────────┬──────────┘ + │ creates + ▼ + «Entity» + User + ┌─────────────────────┐ + │ - id : Long │ + │ - email : String │ + │ - displayName │ + │ - uniqueUserId │ + │ - fcmToken │ + │ + builder() │ + └─────────────────────┘ +``` + +#### Keuntungan dalam WalkGuide + +- Kode registrasi user bersih meski ada field yang `null` (Guardian tidak punya `uniqueUserId`). +- Firebase `Message` payload bisa disusun kondisional tanpa if-else bertumpuk. +- Mudah di-test karena konstruksi objek eksplisit dan readable. + +--- + +### 2. Singleton Pattern + +**Lokasi:** `app/injection_container.dart`, semua `core/services/*.dart` + +#### Masalah yang Diselesaikan + +`YoloDetector` memuat model `.tflite` ~6 MB ke memori. `TtsService` mengelola engine TTS. `WebSocketService` mempertahankan satu koneksi STOMP. Membuat multiple instance dari service-service ini akan membuang memori dan menyebabkan konflik resource. + +#### Solusi + +Semua heavy service di-register sebagai singleton melalui `GetIt` service locator. `GetIt` menjamin hanya ada satu instance untuk seluruh lifecycle aplikasi. + +#### Implementasi + +```dart +// app/injection_container.dart +final sl = GetIt.instance; + +Future initDependencies() async { + // ── Singletons (dibuat sekali, hidup selamanya) ────────────── + sl.registerSingleton(TtsService()); + sl.registerSingleton(SttService()); + sl.registerSingleton(YoloDetector()); + sl.registerSingleton(WebSocketService()); + sl.registerSingleton(AgoraService()); + sl.registerSingleton(HapticService()); + + // ── Factories (baru tiap pakai) ────────────────────────────── + sl.registerFactory( + () => WalkGuideBloc( + yoloDetector: sl(), + ttsService: sl(), // inject singleton yang sama + hapticService: sl(), + ), + ); +} +``` + +```dart +// core/ai/yolo_detector.dart — resource-heavy singleton +class YoloDetector { + Interpreter? _interpreter; + List _labels = []; + bool get isRunning => _isRunning; + bool _isRunning = false; + + Future loadModel() async { + final modelPath = await _getModelPath('assets/models/yolov8n.tflite'); + _interpreter = await Interpreter.fromAsset(modelPath, + options: InterpreterOptions()..useNnApiForAndroid = true); + _labels = await _loadLabels('assets/models/labels.txt'); + } + + Future> detect(CameraImage frame) async { + if (_isRunning) return []; // skip frame, model sedang dipakai + _isRunning = true; + try { + // YUV420 → RGB → resize 640×640 → normalize → inference → NMS + return await compute(_runInference, frame); + } finally { + _isRunning = false; + } + } +} +``` + +#### Diagram + +``` + GetIt (Service Locator) + ┌────────────────────────────────┐ + │ registerSingleton(T) │ + │ get() : T │ + └──┬──────┬──────┬──────┬───────┘ + │ │ │ │ + ▼ ▼ ▼ ▼ + Yolo TTS STT WebSocket + Detector Service Service Service + (6MB AI) (TTS (Always (STOMP + model) engine) listen) connect) +``` + +#### Keuntungan dalam WalkGuide + +- Model YOLO hanya di-load satu kali saat startup, bukan setiap buka layar. +- Semua BLoC berbagi instance TTS yang sama — tidak ada suara bertumpuk. +- Koneksi WebSocket tidak dibuat ulang setiap navigasi. + +--- + +## Structural Patterns + +Structural patterns mengatur **cara objek dan kelas disusun** menjadi struktur yang lebih besar. + +--- + +### 3. Facade Pattern + +**Lokasi (Flutter):** `core/services/voice_command_handler.dart` +**Lokasi (Backend):** `service/GuardianDashboardService.java` + +#### Masalah yang Diselesaikan + +Memproses satu perintah suara seperti `"Send SOS"` membutuhkan koordinasi antara: STT service, command matcher, SOS BLoC, GPS service, TTS feedback, dan router navigasi. Tanpa Facade, setiap widget harus tahu dan memanggil semua subsystem tersebut sendiri. + +#### Solusi + +`VoiceCommandHandler` bertindak sebagai Facade — satu antarmuka tunggal yang menyembunyikan seluruh kompleksitas di baliknya. Client hanya perlu memanggil `processText(string)`. + +Di backend, `GuardianDashboardService` adalah Facade yang mengagregasi data dari `LocationService`, `ActivityLogService`, `SosService`, dan `NotificationService` menjadi satu response `DashboardResponse`. + +#### Implementasi + +```dart +// core/services/voice_command_handler.dart +class VoiceCommandHandler { + final TtsService _ttsService; + final GoRouter _router; + final WalkGuideBloc _walkGuideBloc; + final SosBloc _sosBloc; + final NotificationBloc _notifBloc; + List _commandConfigs = []; + + // ─── Satu-satunya method yang perlu dipanggil client ───────── + Future processText(String rawText) async { + final normalized = rawText.toLowerCase().trim(); + final key = _matchCommand(normalized); + if (key == null) return; + await _executeCommand(key); + } + + VoiceCommandKey? _matchCommand(String text) { + for (final config in _commandConfigs) { + if (!config.enabled) continue; + if (text.contains(config.triggerPhrase.toLowerCase())) { + return config.commandKey; + } + } + return null; + } + + Future _executeCommand(VoiceCommandKey key) async { + switch (key) { + case VoiceCommandKey.START_WALKGUIDE: + _walkGuideBloc.add(StartWalkGuide()); + case VoiceCommandKey.SEND_SOS: + _sosBloc.add(TriggerSos()); + await _ttsService.speakImmediate('SOS sent. Guardian has been alerted.'); + case VoiceCommandKey.WHERE_AM_I: + final pos = await Geolocator.getCurrentPosition(); + await _ttsService.speak('You are at ${pos.latitude}, ${pos.longitude}'); + case VoiceCommandKey.CALL_GUARDIAN: + _router.push('/user/call'); + // ... 10 command lainnya + } + } +} +``` + +```java +// service/GuardianDashboardService.java +@Service +@RequiredArgsConstructor +public class GuardianDashboardService { + + private final LocationService locationService; + private final ActivityLogService activityLogService; + private final SosService sosService; + private final NotificationService notificationService; + private final PairingService pairingService; + + // ─── Facade: satu method agregasi semua data dashboard ─────── + public DashboardResponse getDashboard(Long guardianId) { + Long userId = pairingService.getPairedUserId(guardianId); + + return DashboardResponse.builder() + .lastLocation(locationService.getLastLocation(userId)) + .recentActivities(activityLogService.getRecent(userId, 10)) + .activeSosCount(sosService.countActive(userId)) + .unreadNotifCount(notificationService.countUnread(userId)) + .userStatus(locationService.getUserStatus(userId)) + .build(); + } +} +``` + +#### Diagram + +``` +Client (WalkGuideBloc) + │ + │ processText("start walkguide") + ▼ + VoiceCommandHandler ← FACADE + ┌─────────────────────────────────────┐ + │ _matchCommand(text) │ + │ _executeCommand(key) │ + └──┬──────┬──────┬──────┬────────────┘ + │ │ │ │ + ▼ ▼ ▼ ▼ + TTS WalkGuide Sos GoRouter + Service Bloc Bloc (navigate) + ↑ ↑ ↑ ↑ + └──────┴──────┴──────┘ + Subsystems + (client tidak tahu ini) +``` + +#### Keuntungan dalam WalkGuide + +- Widget cukup panggil satu method — tidak perlu inject 6 dependency berbeda. +- Mudah menambah command baru tanpa mengubah semua widget yang memanggil handler. +- Backend: satu endpoint `GET /guardian/dashboard` mengembalikan semua data yang dibutuhkan, mengurangi jumlah request dari Flutter. + +--- + +### 4. Repository Pattern (Proxy) + +**Lokasi:** `features/*/data/repositories/*_repository_impl.dart` + +#### Masalah yang Diselesaikan + +WalkGuide harus berjalan saat offline (area tanpa sinyal). Obstacle log dan activity log harus tetap tersimpan meski tidak ada koneksi, lalu di-sync ke backend saat online kembali. Domain layer tidak boleh tahu apakah data berasal dari API atau cache lokal. + +#### Solusi + +Setiap `*_repository_impl.dart` bertindak sebagai **Proxy** yang mengimplementasikan abstract interface dari domain layer. Proxy memutuskan: ambil dari SQLite (Drift) saat offline, atau dari REST API saat online. Domain layer — termasuk BLoC dan use case — hanya kenal interface, tidak tahu implementasinya. + +#### Implementasi + +```dart +// features/walk_guide/domain/repositories/walk_guide_repository.dart +abstract class WalkGuideRepository { + Future> startSession(); + Future> stopSession(); + Future> logObstacle(ObstacleLogRequest request); + Future>> getObstacleLogs({int page = 0}); +} +``` + +```dart +// features/walk_guide/data/repositories/walk_guide_repository_impl.dart +class WalkGuideRepositoryImpl implements WalkGuideRepository { + final WalkGuideRemoteDataSource _remote; + final WalkGuideLocalDataSource _local; // SQLite/Drift + final ConnectivityPlus _connectivity; + + @override + Future> logObstacle(ObstacleLogRequest request) async { + try { + if (await _isOnline()) { + // ── Online: kirim langsung ke backend ────────────────── + await _remote.logObstacle(request); + return const Right(null); + } else { + // ── Offline: simpan di SQLite dulu ───────────────────── + await _local.cacheObstacle(request); + return const Right(null); // domain layer tidak tahu bedanya + } + } catch (e) { + return Left(ServerFailure(e.toString())); + } + } + + @override + Future>> getObstacleLogs({int page = 0}) async { + if (await _isOnline()) { + try { + final logs = await _remote.fetchObstacleLogs(page: page); + await _local.cacheLogs(logs); // update cache + return Right(logs); + } catch (_) { + // fallback ke cache jika request gagal + final cached = await _local.getCachedLogs(page: page); + return Right(cached); + } + } + final cached = await _local.getCachedLogs(page: page); + return Right(cached); + } + + Future _isOnline() async { + final result = await _connectivity.checkConnectivity(); + return result != ConnectivityResult.none; + } +} +``` + +```dart +// Sync pending saat koneksi kembali +class SyncPendingLogsUseCase { + final WalkGuideRepository _repository; + + Future> call() async { + final pending = await _repository.getPendingLogs(); + for (final log in pending) { + await _repository.syncToRemote(log); + } + return const Right(null); + } +} +``` + +#### Diagram + +``` + Domain Layer (BLoC/UseCase) + │ + │ logObstacle(request) + ▼ + «interface» WalkGuideRepository + │ implements + ▼ + WalkGuideRepositoryImpl ← PROXY + ┌──────────────────────────────┐ + │ if (isOnline) │ + │ → RemoteDataSource (API) │ + │ else │ + │ → LocalDataSource (SQLite)│ + └──────────────────────────────┘ + │ │ + ▼ ▼ + REST API SQLite/Drift + (online) (offline cache) +``` + +#### Keuntungan dalam WalkGuide + +- Tunanetra tetap bisa menggunakan WalkGuide detection meski sinyal hilang. +- Perubahan strategi caching tidak mempengaruhi BLoC atau use case sama sekali. +- `dartz Either` memastikan error handling eksplisit di setiap layer. + +--- + +## Behavioral Patterns + +Behavioral patterns mengatur **cara objek berkomunikasi dan berinteraksi** satu sama lain. + +--- + +### 5. Observer Pattern + +**Lokasi:** `features/*/presentation/bloc/*.dart`, `core/services/websocket_service.dart` + +#### Masalah yang Diselesaikan + +Ketika YOLO mendeteksi obstacle, puluhan komponen perlu bereaksi: kamera overlay perlu menampilkan bounding box, TTS perlu berbicara, haptic perlu bergetar, dan backend perlu dicatat. Menghubungkan semua komponen ini secara langsung akan menciptakan coupling yang sangat ketat. + +#### Solusi + +BLoC pattern adalah implementasi Observer. `WalkGuideBloc` berperan sebagai **Subject** yang menyimpan state dan memancarkan (emit) state baru setiap ada perubahan. Widget (`BlocBuilder`, `BlocConsumer`, `BlocListener`) berperan sebagai **Observer** yang otomatis bereaksi terhadap perubahan state. `WebSocketService` juga menggunakan Observer untuk meneruskan update lokasi real-time dari User ke Guardian. + +#### Implementasi + +```dart +// features/walk_guide/presentation/bloc/walk_guide_bloc.dart +class WalkGuideBloc extends Bloc { + final YoloDetector _yoloDetector; + final TtsService _ttsService; + final HapticService _hapticService; + final WalkGuideRepository _repository; + + WalkGuideBloc({...}) : super(WalkGuideIdle()) { + on(_onStart); + on(_onStop); + on(_onFrame); + } + + Future _onFrame( + CameraFrameReceived event, + Emitter emit, + ) async { + if (_yoloDetector.isRunning) return; // throttle + + final results = await _yoloDetector.detect(event.frame); + if (results.isEmpty) return; + + final top = _prioritize(results); + + // ─── Emit state baru → semua Observer bereaksi ──────────── + emit(WalkGuideObstacleDetected( + label: top.label, + direction: top.direction, + distance: top.estimatedDistance, + confidence: top.confidence, + boundingBox: top.boundingBox, + )); + + // Side effects + await _ttsService.speakImmediate(_buildTtsMessage(top)); + _hapticService.obstacleVeryClose(); + await _repository.logObstacle(ObstacleLogRequest.from(top)); + } +} +``` + +```dart +// features/walk_guide/presentation/screens/walk_guide_screen.dart +class WalkGuideScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Stack( + children: [ + // ── Observer 1: rebuild kamera overlay ──────────────── + BlocBuilder( + builder: (context, state) { + if (state is WalkGuideObstacleDetected) { + return DetectionOverlay( + boundingBox: state.boundingBox, + label: state.label, + direction: state.direction, + ); + } + return const SizedBox.shrink(); + }, + ), + // ── Observer 2: side effects (navigasi, snackbar) ───── + BlocListener( + listener: (context, state) { + if (state is WalkGuideError) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(state.message)), + ); + } + }, + child: const CameraPreview(), + ), + ], + ); + } +} +``` + +```dart +// core/services/websocket_service.dart — Observer untuk Guardian +class WebSocketService { + StompClient? _stompClient; + final StreamController _locationController = + StreamController.broadcast(); + + Stream get onLocationUpdate => _locationController.stream; + + void subscribeToUserLocation(String userId) { + _stompClient?.subscribe( + destination: '/topic/location/$userId', + callback: (frame) { + final data = LocationData.fromJson(jsonDecode(frame.body!)); + _locationController.add(data); // notify semua Observer + }, + ); + } +} + +// guardian_map_screen.dart — Observer menerima update +class GuardianMapScreen extends StatefulWidget { + @override + void initState() { + super.initState(); + sl().onLocationUpdate.listen((location) { + setState(() => _userMarker = LatLng(location.lat, location.lng)); + }); + } +} +``` + +#### Diagram + +``` + WalkGuideBloc ← SUBJECT + ┌─────────────────┐ + │ emit(state) │──────────────────────────────┐ + └─────────────────┘ │ + │ │ + ┌────────┴────────┐ ┌──────────┴──────────┐ + ▼ ▼ ▼ ▼ +BlocBuilder BlocListener WebSocketService GuardianMap +(UI rebuild) (side effects) (STOMP Subject) (Observer) + ↑ ↑ │ + OBSERVER OBSERVER │ notify + ▼ + Guardian's map + updates live +``` + +#### Keuntungan dalam WalkGuide + +- Menambah Observer baru (misal: logging screen) tidak memerlukan perubahan pada BLoC. +- Guardian melihat posisi User real-time di peta tanpa polling setiap detik. +- BLoC stream bisa di-test dengan `bloc_test` package secara terisolasi. + +--- + +### 6. Strategy Pattern + +**Lokasi (Flutter):** `core/ai/obstacle_analyzer.dart` +**Lokasi (Backend):** `service/ObstacleAlertStrategyService.java` + +#### Masalah yang Diselesaikan + +Cara WalkGuide memperingatkan user tentang obstacle berbeda-beda: ada yang butuh TTS saja, ada yang perlu TTS + getaran, ada yang hanya getaran (lingkungan bising). Guardian harus bisa mengganti mode ini dari dashboard tanpa update APK. + +#### Solusi + +`ObstacleAlertStrategy` interface mendefinisikan kontrak peringatan. Tiga implementasi konkret (`TtsOnlyStrategy`, `TtsWithHapticStrategy`, `HapticOnlyStrategy`) dapat dipertukarkan runtime. `ObstacleAnalyzer` sebagai Context menyimpan referensi ke strategy aktif dan mendelegasikan eksekusi tanpa tahu implementasinya. + +#### Implementasi + +```dart +// core/ai/strategy/obstacle_alert_strategy.dart +abstract class ObstacleAlertStrategy { + Future alert(DetectionResult result); +} + +// ── Concrete Strategy 1 ─────────────────────────────────────── +class TtsOnlyStrategy implements ObstacleAlertStrategy { + final TtsService _ttsService; + + @override + Future alert(DetectionResult result) async { + final msg = 'Caution! ${result.label} ${result.direction}. ' + '${result.estimatedDistance}. Please stop.'; + await _ttsService.speakImmediate(msg); + } +} + +// ── Concrete Strategy 2 ─────────────────────────────────────── +class TtsWithHapticStrategy implements ObstacleAlertStrategy { + final TtsService _ttsService; + final HapticService _hapticService; + + @override + Future alert(DetectionResult result) async { + await Future.wait([ + _ttsService.speakImmediate('Caution! ${result.label} ahead.'), + _hapticService.obstaclePattern(result.estimatedDistance), + ]); + } +} + +// ── Concrete Strategy 3 ─────────────────────────────────────── +class HapticOnlyStrategy implements ObstacleAlertStrategy { + final HapticService _hapticService; + + @override + Future alert(DetectionResult result) async { + await _hapticService.obstaclePattern(result.estimatedDistance); + } +} +``` + +```dart +// core/ai/obstacle_analyzer.dart — Context +class ObstacleAnalyzer { + ObstacleAlertStrategy _strategy; + final AiConfig _config; + + // ─── Ganti strategy runtime tanpa ubah kode lain ───────────── + void setStrategy(ObstacleAlertStrategy strategy) { + _strategy = strategy; + } + + Future analyze(List results) async { + if (results.isEmpty) return; + final top = prioritize(results); + if (top.confidence < _config.confidenceThreshold) return; + await _strategy.alert(top); // delegasi ke strategy aktif + } + + DetectionResult prioritize(List results) { + return results.reduce((a, b) => + _dangerScore(a) > _dangerScore(b) ? a : b); + } + + double _dangerScore(DetectionResult r) { + const distanceScore = { + 'Very Close': 4.0, 'Close': 3.0, 'Medium': 2.0, 'Far': 1.0 + }; + return r.confidence * (distanceScore[r.estimatedDistance] ?? 1.0); + } +} +``` + +```dart +// Saat AiConfig diupdate dari Guardian +void _onAiConfigUpdated(AiConfig config) { + final strategy = switch (config.alertMode) { + AlertMode.ttsOnly => TtsOnlyStrategy(_ttsService), + AlertMode.ttsAndHaptic => TtsWithHapticStrategy(_ttsService, _hapticService), + AlertMode.hapticOnly => HapticOnlyStrategy(_hapticService), + }; + sl().setStrategy(strategy); +} +``` + +#### Diagram + +``` + «interface» + ObstacleAlertStrategy + ┌─────────────────┐ + │ + alert(result) │ + └────────┬────────┘ + │ implements + ┌──────┼──────┐ + ▼ ▼ ▼ + TtsOnly TTS+ Haptic +Strategy Haptic Only + Strat. Strategy + + ObstacleAnalyzer (Context) + ┌────────────────────────────┐ + │ - _strategy: Strategy │◄── setStrategy() + │ + analyze(results) │ ▲ + │ → _strategy.alert(top) │ │ + └────────────────────────────┘ AiConfig.alertMode + (dari Guardian) +``` + +#### Keuntungan dalam WalkGuide + +- Guardian bisa mengganti mode alert dari `PUT /guardian/ai-config` tanpa restart app. +- Menambah strategy baru (misal: `FlashLightStrategy`) tidak mengubah `ObstacleAnalyzer`. +- Setiap strategy mudah di-unit-test secara terisolasi. + +--- + +### 7. Chain of Responsibility Pattern + +**Lokasi (Flutter):** `core/network/api_client.dart` (Dio interceptors) +**Lokasi (Backend):** `security/JwtAuthFilter.java` + Spring Security + +#### Masalah yang Diselesaikan + +Setiap HTTP request perlu melewati beberapa proses: menambahkan JWT token, menangani error secara terpusat, dan mencatat log untuk debugging. Di backend, setiap request harus divalidasi JWT sebelum mencapai controller. Tanpa pola ini, logika ini akan tersebar dan terduplikasi di mana-mana. + +#### Solusi + +**Flutter:** Dio interceptor chain memproses setiap request secara berurutan — `AuthInterceptor → ErrorInterceptor → LogInterceptor`. Setiap interceptor bisa memproses, memodifikasi, atau memblokir request, lalu meneruskan ke handler berikutnya. + +**Backend:** Spring Security filter chain — `JwtAuthFilter → SecurityConfig → Controller` — memvalidasi setiap request sebelum mencapai endpoint bisnis. + +#### Implementasi + +```dart +// core/network/api_client.dart +class ApiClient { + late final Dio _dio; + + ApiClient() { + _dio = Dio(BaseOptions( + connectTimeout: const Duration(seconds: 10), + receiveTimeout: const Duration(seconds: 30), + )); + + // ─── Chain: urutan eksekusi diatur oleh urutan penambahan ──── + _dio.interceptors.addAll([ + AuthInterceptor(_dio), // [0] attach token, refresh jika expired + ErrorInterceptor(), // [1] map HTTP error → domain Failure + LogInterceptor( // [2] print request/response + requestBody: true, + responseBody: kDebugMode, + ), + ]); + } +} +``` + +```dart +// core/network/interceptors/auth_interceptor.dart +class AuthInterceptor extends QueuedInterceptorsWrapper { + final Dio _dio; + final FlutterSecureStorage _storage = const FlutterSecureStorage(); + + @override + Future onRequest( + RequestOptions options, + RequestInterceptorHandler handler, + ) async { + // ─── Attach Bearer token ke setiap request ─────────────── + final token = await _storage.read(key: 'access_token'); + if (token != null) { + options.headers['Authorization'] = 'Bearer $token'; + } + handler.next(options); // teruskan ke interceptor berikutnya + } + + @override + Future onError( + DioException err, + ErrorInterceptorHandler handler, + ) async { + if (err.response?.statusCode == 401) { + // ─── Token expired: refresh otomatis lalu retry ────────── + try { + final refreshToken = await _storage.read(key: 'refresh_token'); + final response = await _dio.post('/auth/refresh', + data: {'refreshToken': refreshToken}); + final newToken = response.data['data']['accessToken']; + await _storage.write(key: 'access_token', value: newToken); + + // Retry request asli dengan token baru + err.requestOptions.headers['Authorization'] = 'Bearer $newToken'; + final retried = await _dio.fetch(err.requestOptions); + handler.resolve(retried); + return; + } catch (_) { + // Refresh juga gagal → paksa logout + GetIt.I().add(LogoutRequested()); + } + } + handler.next(err); // teruskan ke ErrorInterceptor + } +} +``` + +```dart +// core/network/interceptors/error_interceptor.dart +class ErrorInterceptor extends Interceptor { + @override + void onError(DioException err, ErrorInterceptorHandler handler) { + // ─── Map HTTP error code → domain Failure object ────────── + final failure = switch (err.response?.statusCode) { + 400 => ValidationFailure(err.response?.data['message']), + 401 => UnauthorizedFailure(), + 403 => ForbiddenFailure(), + 404 => NotFoundFailure(), + 500 => ServerFailure('Server error, please try again'), + _ => NetworkFailure('No internet connection'), + }; + handler.next(err.copyWith(error: failure)); + } +} +``` + +```java +// security/JwtAuthFilter.java — Backend chain handler +@Component +@RequiredArgsConstructor +public class JwtAuthFilter extends OncePerRequestFilter { + + private final JwtUtil jwtUtil; + private final UserDetailsService userDetailsService; + + @Override + protected void doFilterInternal( + HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain // ← chain berikutnya + ) throws ServletException, IOException { + + final String authHeader = request.getHeader("Authorization"); + + if (authHeader == null || !authHeader.startsWith("Bearer ")) { + filterChain.doFilter(request, response); // lewati jika tidak ada token + return; + } + + final String jwt = authHeader.substring(7); + + try { + final String email = jwtUtil.extractEmail(jwt); + final UserDetails userDetails = userDetailsService.loadUserByUsername(email); + + if (jwtUtil.isTokenValid(jwt, userDetails)) { + // ─── Set authentication context ────────────────────── + UsernamePasswordAuthenticationToken auth = + new UsernamePasswordAuthenticationToken( + userDetails, null, userDetails.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(auth); + } + } catch (JwtException e) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return; // blokir — tidak diteruskan ke controller + } + + filterChain.doFilter(request, response); // teruskan ke SecurityConfig + } +} +``` + +#### Diagram + +``` +HTTP Request dari Flutter + │ + ▼ +┌───────────────────┐ +│ AuthInterceptor │ → attach Bearer token +│ [Flutter Dio] │ → auto-refresh jika 401 +└────────┬──────────┘ + │ handler.next() + ▼ +┌───────────────────┐ +│ ErrorInterceptor │ → map error → domain Failure +└────────┬──────────┘ + │ handler.next() + ▼ +┌───────────────────┐ +│ LogInterceptor │ → print untuk debugging +└────────┬──────────┘ + │ + ▼ + Backend REST API + │ + ▼ +┌───────────────────┐ +│ JwtAuthFilter │ → extract & validasi JWT +│ [Spring Security] │ → set SecurityContext +└────────┬──────────┘ + │ filterChain.doFilter() + ▼ +┌───────────────────┐ +│ SecurityConfig │ → cek role: GUARDIAN vs USER +└────────┬──────────┘ + │ (jika authorized) + ▼ +┌───────────────────┐ +│ Controller │ → proses bisnis logic +└───────────────────┘ +``` + +#### Keuntungan dalam WalkGuide + +- Token refresh otomatis — user tidak perlu login ulang saat token expired. +- Error handling terpusat — tidak ada `try-catch` duplikat di setiap repository. +- Menambah interceptor baru (misal: rate limiting, analytics) cukup ditambah ke chain. +- Backend: satu filter untuk semua 26 endpoint, tidak perlu validasi JWT di setiap controller. + +--- + +## Ringkasan Matriks + +| # | Pattern | Kategori | Problem Solved | File Utama | +|---|---------|----------|---------------|------------| +| 1 | **Builder** | Creational | Konstruksi objek kompleks dengan banyak optional field | `User.java`, `FcmService.java` | +| 2 | **Singleton** | Creational | Satu instance untuk heavy resource (model AI, TTS, WebSocket) | `injection_container.dart` | +| 3 | **Facade** | Structural | Sembunyikan kompleksitas koordinasi multi-service | `voice_command_handler.dart`, `GuardianDashboardService.java` | +| 4 | **Repository (Proxy)** | Structural | Offline-first — domain layer tidak tahu sumber data | `*_repository_impl.dart` | +| 5 | **Observer** | Behavioral | Reaktif terhadap state change tanpa coupling ketat | `walk_guide_bloc.dart`, `websocket_service.dart` | +| 6 | **Strategy** | Behavioral | Alert mode bisa diganti runtime tanpa ubah core logic | `obstacle_analyzer.dart`, `ObstacleAlertStrategyService.java` | +| 7 | **Chain of Responsibility** | Behavioral | Pipeline request: auth → error → log (Flutter & Backend) | `api_client.dart`, `JwtAuthFilter.java` | + +> **Catatan exam:** 7 patterns (≥4 ✅), mencakup 3 kategori GoF (≥1 per kategori ✅): Creational, Structural, Behavioral.