diff --git a/.github/workflows/nightly-artifacts.yml b/.github/workflows/nightly-artifacts.yml index bfbeecf7..8c3c4c47 100644 --- a/.github/workflows/nightly-artifacts.yml +++ b/.github/workflows/nightly-artifacts.yml @@ -25,9 +25,104 @@ permissions: packages: write jobs: + # Same job as in pr-compile-check.yml, copied rather than shared: a reusable workflow + # would be one more indirection to read, and the comments belong next to the steps they + # explain. Every packaging job below needs this one, so a commit whose tests fail builds + # no artifact (#62). Edit all three copies together. + test: + name: Test (Java 21, headless) + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Set up Java 21 + uses: actions/setup-java@v6.0.1 + with: + distribution: temurin + java-version: "21" + + - name: Ensure gradlew is executable + run: chmod +x gradlew + + # Skiko's native library links against libGL, so it has to be loadable even though + # nothing here renders through it: the drawing tests use Skia's software backend and + # runComposeUiTest never opens a window. Without this the whole Compose half of the + # suite dies with "libskiko-linux-x64.so: libGL.so.1: cannot open shared object + # file" -- which reads like a missing display and is not one. Found by running this + # job under act, where the container has no libGL; GitHub's own runner image happens + # to ship it, so the step is what makes the job reproducible off GitHub. + - name: Install the OpenGL client library skiko links against + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends libgl1 + + # No Xvfb, deliberately. Everything that pins behaviour runs without a display: + # runComposeUiTest reaches the semantics tree headless (measured before this job was + # written), and the ImageComposeScene drawing tests render in software. The handful + # of tests that open a real window guard themselves with assumeFalse(isHeadless) and + # skip here; the summary below prints the skip count, so that is visible rather than + # assumed. + # + # Software GL under Xvfb was considered and rejected: a missing Skia GL context is + # the hardest failure in this codebase to read, and importing that class of flake + # into CI would cost more than the few window tests are worth here. + + # All three modules. The translation generator is a Gradle module and not buildSrc + # precisely so that its 42 tests run here: buildSrc tests do not run on `./gradlew + # build` -- measured, not assumed. The summary below globs */build/test-results, so + # the module was counted the moment it existed. + - name: Test + run: ./gradlew -S test + + - name: Summarise the test results + if: always() + run: | + set -euo pipefail + shopt -s nullglob + files=(*/build/test-results/test/TEST-*.xml) + if [ ${#files[@]} -eq 0 ]; then + echo "No test result XML was produced -- the test task did not run." >&2 + exit 1 + fi + # Counted from the XML and not from Gradle's console output: this project's own + # rule is never to infer "all tests passed" from an exit code. + summary=$(grep -h "> "$GITHUB_STEP_SUMMARY" + if [ "$failures" != "0" ] || [ "$errors" != "0" ]; then + echo "The result XML reports failures or errors." >&2 + exit 1 + fi + + - name: Keep the test reports on a failure + if: failure() + uses: actions/upload-artifact@v6 + with: + name: test-results + path: | + */build/test-results/test/ + */build/reports/tests/test/ + if-no-files-found: ignore + retention-days: 7 + build-windows-zip: name: Build Windows ZIP runs-on: windows-latest + needs: test steps: - name: Checkout @@ -80,6 +175,7 @@ jobs: build-linux-appimage: name: Build Linux AppImage runs-on: ubuntu-latest + needs: test steps: - name: Checkout @@ -153,6 +249,7 @@ jobs: build-linux-deb: name: Build Debian package runs-on: ubuntu-latest + needs: test steps: - name: Checkout @@ -198,6 +295,7 @@ jobs: build-linux-rpm: name: Build Fedora package runs-on: ubuntu-latest + needs: test steps: - name: Checkout @@ -243,6 +341,7 @@ jobs: build-linux-arch: name: Build Arch Linux package runs-on: ubuntu-latest + needs: test steps: - name: Checkout @@ -354,6 +453,7 @@ jobs: build-flatpak: name: Build Flatpak runs-on: ubuntu-latest + needs: test steps: - name: Checkout @@ -538,6 +638,7 @@ jobs: build-macos-dmg: name: Build macOS DMG (${{ matrix.os }}) runs-on: ${{ matrix.os }} + needs: test strategy: fail-fast: false matrix: diff --git a/.github/workflows/pr-compile-check.yml b/.github/workflows/pr-compile-check.yml index f54f78b4..654c0b99 100644 --- a/.github/workflows/pr-compile-check.yml +++ b/.github/workflows/pr-compile-check.yml @@ -141,6 +141,14 @@ jobs: - name: Test run: ./gradlew -S test + # Coverage is a report, not a gate: no threshold, nothing in it can fail on a + # percentage. Deliberately not `if: always()` -- without a completed test run the + # report would be partial, and after a failed test the result XML below is what matters. + # jacocoTestReport writes the per-module XML the summary reads; the aggregate merges + # core and app-desktop (i18n-generator is build tooling and stays out). + - name: Coverage report + run: ./gradlew -S jacocoTestReport jacocoAggregatedReport + - name: Summarise the test results if: always() run: | @@ -173,6 +181,50 @@ jobs: exit 1 fi + - name: Summarise the coverage + if: always() + run: | + set -euo pipefail + # The last LINE/BRANCH counter in a JaCoCo XML is the report-level total; the + # per-package and per-class counters come before it. + percent() { + local file="$1" type="$2" + { grep -o "]*/>" "$file" || true; } | tail -1 \ + | sed 's/.*missed="\([0-9]*\)".*covered="\([0-9]*\)".*/\1 \2/' \ + | awk 'NF == 2 { t=$1+$2; if (t==0) print "n/a"; else printf "%.1f%% (%d/%d)", 100*$2/t, $2, t }' + } + row() { + local label="$1" file="$2" + if [ -f "$file" ]; then + echo "| $label | $(percent "$file" LINE) | $(percent "$file" BRANCH) |" + else + echo "| $label | no report | no report |" + fi + } + { + echo "" + echo "### Coverage" + echo "" + echo "| module | lines | branches |" + echo "|---|---|---|" + row "core" core/build/reports/jacoco/test/jacocoTestReport.xml + row "app-desktop" app-desktop/build/reports/jacoco/test/jacocoTestReport.xml + row "core + app-desktop" build/reports/jacoco/aggregated/jacoco.xml + echo "" + echo "Report only: nothing fails on a percentage. The aggregated HTML report is the" + echo "coverage-report artifact of this run. i18n-generator is build tooling and is" + echo "not counted." + } >> "$GITHUB_STEP_SUMMARY" + + - name: Keep the coverage report + if: always() + uses: actions/upload-artifact@v6 + with: + name: coverage-report + path: build/reports/jacoco/aggregated/html/ + if-no-files-found: ignore + retention-days: 14 + - name: Keep the test reports on a failure if: failure() uses: actions/upload-artifact@v6 diff --git a/.github/workflows/tagged-release.yml b/.github/workflows/tagged-release.yml index ed260fba..44f32b49 100644 --- a/.github/workflows/tagged-release.yml +++ b/.github/workflows/tagged-release.yml @@ -16,9 +16,104 @@ env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true jobs: + # Same job as in pr-compile-check.yml, copied rather than shared: a reusable workflow + # would be one more indirection to read, and the comments belong next to the steps they + # explain. Every packaging job below needs this one, so a commit whose tests fail builds + # no artifact (#62). Edit all three copies together. + test: + name: Test (Java 21, headless) + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Set up Java 21 + uses: actions/setup-java@v6.0.1 + with: + distribution: temurin + java-version: "21" + + - name: Ensure gradlew is executable + run: chmod +x gradlew + + # Skiko's native library links against libGL, so it has to be loadable even though + # nothing here renders through it: the drawing tests use Skia's software backend and + # runComposeUiTest never opens a window. Without this the whole Compose half of the + # suite dies with "libskiko-linux-x64.so: libGL.so.1: cannot open shared object + # file" -- which reads like a missing display and is not one. Found by running this + # job under act, where the container has no libGL; GitHub's own runner image happens + # to ship it, so the step is what makes the job reproducible off GitHub. + - name: Install the OpenGL client library skiko links against + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends libgl1 + + # No Xvfb, deliberately. Everything that pins behaviour runs without a display: + # runComposeUiTest reaches the semantics tree headless (measured before this job was + # written), and the ImageComposeScene drawing tests render in software. The handful + # of tests that open a real window guard themselves with assumeFalse(isHeadless) and + # skip here; the summary below prints the skip count, so that is visible rather than + # assumed. + # + # Software GL under Xvfb was considered and rejected: a missing Skia GL context is + # the hardest failure in this codebase to read, and importing that class of flake + # into CI would cost more than the few window tests are worth here. + + # All three modules. The translation generator is a Gradle module and not buildSrc + # precisely so that its 42 tests run here: buildSrc tests do not run on `./gradlew + # build` -- measured, not assumed. The summary below globs */build/test-results, so + # the module was counted the moment it existed. + - name: Test + run: ./gradlew -S test + + - name: Summarise the test results + if: always() + run: | + set -euo pipefail + shopt -s nullglob + files=(*/build/test-results/test/TEST-*.xml) + if [ ${#files[@]} -eq 0 ]; then + echo "No test result XML was produced -- the test task did not run." >&2 + exit 1 + fi + # Counted from the XML and not from Gradle's console output: this project's own + # rule is never to infer "all tests passed" from an exit code. + summary=$(grep -h "> "$GITHUB_STEP_SUMMARY" + if [ "$failures" != "0" ] || [ "$errors" != "0" ]; then + echo "The result XML reports failures or errors." >&2 + exit 1 + fi + + - name: Keep the test reports on a failure + if: failure() + uses: actions/upload-artifact@v6 + with: + name: test-results + path: | + */build/test-results/test/ + */build/reports/tests/test/ + if-no-files-found: ignore + retention-days: 7 + build-windows-zip: name: Build Windows ZIP runs-on: windows-latest + needs: test steps: - name: Checkout @@ -61,6 +156,7 @@ jobs: build-linux-appimage: name: Build Linux AppImage runs-on: ubuntu-latest + needs: test steps: - name: Checkout @@ -127,6 +223,7 @@ jobs: build-linux-deb: name: Build Debian package runs-on: ubuntu-latest + needs: test steps: - name: Checkout @@ -165,6 +262,7 @@ jobs: build-linux-rpm: name: Build Fedora package runs-on: ubuntu-latest + needs: test steps: - name: Checkout @@ -203,6 +301,7 @@ jobs: build-linux-arch: name: Build Arch Linux package runs-on: ubuntu-latest + needs: test steps: - name: Checkout @@ -305,6 +404,7 @@ jobs: build-flatpak: name: Build Flatpak runs-on: ubuntu-latest + needs: test steps: - name: Checkout @@ -430,6 +530,7 @@ jobs: build-macos-dmg: name: Build macOS DMG (${{ matrix.os }}) runs-on: ${{ matrix.os }} + needs: test strategy: fail-fast: false matrix: diff --git a/.gitignore b/.gitignore index 6e89ba3a..949ef5d6 100644 --- a/.gitignore +++ b/.gitignore @@ -65,3 +65,6 @@ scratch/ # Kotlin incremental build data .kotlin/ + +# JVM crash reports +hs_err_pid*.log diff --git a/AGENTS.md b/AGENTS.md index 098ff61b..9da07732 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -124,11 +124,11 @@ Read the current `gradle.properties` and `gradle/libs.versions.toml` before rely At this context snapshot the project uses Java 21, Kotlin 2.2 and Compose Multiplatform 1.8.x, with JUnit 5/Mockito, PMD and SpotBugs integrated. JavaFX is gone; there is no `org.openjfx` dependency left. -Important: the build configuration has historically allowed test failures to be ignored, and static-analysis findings do not fail the build. Therefore: +Important: a test failure fails the build, but PMD and SpotBugs run with `ignoreFailures`, so static-analysis findings do not. Test classes live under `src/test` only (since #62; before that a few sat under `src/main` and were never run), and JUnit/Mockito are test-only dependencies. Therefore: - inspect the Gradle test summary; - inspect the test-results XML under `*/build/test-results/` when needed; -- do not infer "all tests passed" from exit code 0; +- do not infer "all tests passed" from exit code 0 -- read the XML; - report PMD/SpotBugs findings that are visible in the relevant build. Run focused tests first, then normally the relevant broader test/build command for the scope. diff --git a/app-desktop/build.gradle.kts b/app-desktop/build.gradle.kts index 348ca0cf..c0e2d3f3 100644 --- a/app-desktop/build.gradle.kts +++ b/app-desktop/build.gradle.kts @@ -10,10 +10,8 @@ kotlin { } dependencies { - // Mirrors the compile-scope entries in pom.xml: a few test classes still live under - // src/main/java and need JUnit and Mockito on the main compile classpath. - implementation(libs.junit.jupiter.api) - implementation(libs.mockito.core.compile) + // JUnit and Mockito are test-only. Until #62 a few test classes sat under src/main/java + // and dragged both -- plus byte-buddy and objenesis -- into lib/app of every app image. implementation(libs.jetbrains.annotations) implementation(project(":core")) implementation(compose.desktop.currentOs) diff --git a/app-desktop/src/main/java/kst4contest/test/PatternMatcherTest.java b/app-desktop/src/main/java/kst4contest/test/PatternMatcherTest.java deleted file mode 100644 index 3511295b..00000000 --- a/app-desktop/src/main/java/kst4contest/test/PatternMatcherTest.java +++ /dev/null @@ -1,131 +0,0 @@ -package kst4contest.test; - -import kst4contest.observe.SimpleValue; -import kst4contest.controller.Utils4KST; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class PatternMatcherTest { - - /** - * Tests if pattern matches with the given String. - * - * @param testString - * @param regExPattern - * @return true if match, else false - */ - - private static boolean testPattern(String testString, String regExPattern) { - - Pattern pattern = Pattern.compile(regExPattern); - Matcher matcher = pattern.matcher(testString); - - return matcher.find(); - } - - /** - * Normalizes a chatmembers frequency-string for cluster usage
- * returns a frequency String in KHz like = "144300" or "144300.0" to match DXC protocol needs - * - * @param optionalPrefix: if there is a value like ".300", it have to be decided, wich ".300": 144.300, 432.300, 1296.300 .... prefix means for example "144." - */ - private static String normalizeFrequencyString(String qrgString, String optionalPrefix) { - -// final String PTRN_QRG_CAT2 = "(([0-9]{3,4}[\\.|,| ]?[0-9]{3})([\\.|,][\\d]{1,2})?)|(([a-zA-Z][0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)|((\\b[0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)"; - - final String PTRN_QRG_CAT2_wholeQRGMHz4Digits = "(([0-9]{4}[\\.|,| ]?[0-9]{3})([\\.|,][\\d]{1,2})?)"; //1296.300.3 etc - final String PTRN_QRG_CAT2_wholeQRGMHz3Digits = "(([0-9]{3}[\\.|,| ]?[0-9]{3})([\\.][\\d]{1,2})?)"; //144.300.3 etc - final String PTRN_QRG_CAT2_QRGwithoutPrefix = "((\\b[0-4]{1}[\\d]{2}\\b)([\\.|,][\\d]{1,2}\\b)?)"; //144.300.3 etc - String predefinedPrefixInMHz = optionalPrefix; - - String stringAggregation = ""; - - if (testPattern(qrgString, PTRN_QRG_CAT2_wholeQRGMHz4Digits)) { - System.out.print("yep: "); - stringAggregation = qrgString; - - stringAggregation = stringAggregation.replace(".",""); - stringAggregation = stringAggregation.replace(",",""); - if (stringAggregation.length() == 8) { - String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length()-1) + "." + stringAggregation.substring(stringAggregation.length()-1, stringAggregation.length()); - stringAggregation = stringAggregationNew; - } else if (stringAggregation.length() == 9) { - String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length()-2) + "." + stringAggregation.substring(stringAggregation.length()-2, stringAggregation.length()); - stringAggregation = stringAggregationNew; - } - - } else - - if (testPattern(qrgString, PTRN_QRG_CAT2_wholeQRGMHz3Digits)) { - System.out.print("yep: "); - stringAggregation = qrgString; - - stringAggregation = stringAggregation.replace(".",""); - stringAggregation = stringAggregation.replace(",",""); - if (stringAggregation.length() == 7) { - String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length()-1) + "." + stringAggregation.substring(stringAggregation.length()-1, stringAggregation.length()); - stringAggregation = stringAggregationNew; - } else if (stringAggregation.length() == 8) { - String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length()-2) + "." + stringAggregation.substring(stringAggregation.length()-2, stringAggregation.length()); - stringAggregation = stringAggregationNew; - } - } - else - - if (testPattern(qrgString, PTRN_QRG_CAT2_QRGwithoutPrefix)) { //case ".050 or .300 or something like that" - System.out.print("yep: "); - stringAggregation = qrgString; - - stringAggregation = stringAggregation.replace(".", ""); - stringAggregation = stringAggregation.replace(",", ""); - if (stringAggregation.length() == 3) { // like 050 or 300 - String stringAggregationNew = optionalPrefix + stringAggregation; - stringAggregation = stringAggregationNew; - return stringAggregation; - - } else if (stringAggregation.length() == 4) { //like 050.2 --> 0502 - - stringAggregation = optionalPrefix + stringAggregation; - String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length() - 1) + "." + stringAggregation.substring(stringAggregation.length() - 1, stringAggregation.length()); - stringAggregation = stringAggregationNew; - return stringAggregation; - - } else if (stringAggregation.length() == 5) { //like 050.20 --> 05020 - - stringAggregation = optionalPrefix + stringAggregation; - String stringAggregationNew = stringAggregation.substring(0, stringAggregation.length() - 2) + "." + stringAggregation.substring(stringAggregation.length() - 2, stringAggregation.length()); - stringAggregation = stringAggregationNew; - return stringAggregation; - } - } - - return qrgString; - } - - public static void main(String[] args) { - - int i = 0; - - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.775", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.300.2", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144,300.2", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144300.2", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144300,2", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.300", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.300.20", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("300", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString(".300", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString(".300.2", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString(".300.20", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300.2", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300.20", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300,2", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300,20", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300,2", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300.2", new SimpleValue<>("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("q305", new SimpleValue<>("144"))); - } -} diff --git a/build.gradle.kts b/build.gradle.kts index d4e76fa5..a7c74c7e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,8 @@ plugins { java + // Applied here as well as in the subprojects: the root needs the JacocoReport task + // type and the tool classpath for the aggregated report below. + jacoco alias(libs.plugins.spotbugs) apply false } @@ -17,11 +20,13 @@ allprojects { val pmdVersion = libs.versions.pmd.get() val spotbugsVersion = libs.versions.spotbugs.get() +val jacocoVersion = libs.versions.jacoco.get() subprojects { apply(plugin = "java") apply(plugin = "com.github.spotbugs") apply(plugin = "pmd") + apply(plugin = "jacoco") // Both tools report only; the Maven build had the failing goals commented out. extensions.configure { @@ -36,6 +41,17 @@ subprojects { ignoreFailures.set(true) } + /* + * Coverage is a report, not a gate: there is no jacocoTestCoverageVerification and no + * minimum percentage. A threshold set at today's number would trip on the next unrelated + * change; one set at a target would fail every build until tests are written for the + * number's sake. The figure is published so it can be read when deciding what to test + * next (docs/superpowers/specs/2026-10-11-test-coverage-design.md, #62). + */ + extensions.configure { + toolVersion = jacocoVersion + } + extensions.configure { toolchain { languageVersion.set(JavaLanguageVersion.of(21)) @@ -45,4 +61,45 @@ subprojects { tasks.withType().configureEach { useJUnitPlatform() } + + // XML for CI to read, HTML for people. Gradle does not wire the report after the test + // task on its own; without this dependsOn the report task would read stale or missing + // execution data. Kotlin classes count too: the Kotlin plugin adds its output to the + // main source set, which is what the default report reads. + tasks.withType().configureEach { + dependsOn(tasks.withType()) + reports { + xml.required.set(true) + html.required.set(true) + } + } +} + +/* + * One report over the two shipped modules. i18n-generator stays out: it is a build tool, + * and its coverage says nothing about the application. Sources and classes are resolved + * lazily because the root script is evaluated before the subprojects have their source sets. + */ +val coveredProjects = listOf(project(":core"), project(":app-desktop")) + +val jacocoAggregatedReport by tasks.registering(JacocoReport::class) { + description = "Merges the JaCoCo coverage of core and app-desktop into one report" + group = "verification" + + dependsOn(coveredProjects.map { it.tasks.named("test") }) + + executionData.setFrom(coveredProjects.map { it.layout.buildDirectory.file("jacoco/test.exec") }) + sourceDirectories.setFrom(provider { + coveredProjects.flatMap { it.extensions.getByType()["main"].allSource.srcDirs } + }) + classDirectories.setFrom(provider { + coveredProjects.map { it.extensions.getByType()["main"].output } + }) + + reports { + xml.required.set(true) + xml.outputLocation.set(layout.buildDirectory.file("reports/jacoco/aggregated/jacoco.xml")) + html.required.set(true) + html.outputLocation.set(layout.buildDirectory.dir("reports/jacoco/aggregated/html")) + } } diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 180bd184..73d4495e 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -6,10 +6,8 @@ plugins { // kst4contest.observe and hands UI work over via UiDispatcher. dependencies { - // Test classes live under src/main/java in this project, so JUnit and Mockito - // are needed on the main compile classpath. This mirrored pom.xml before Gradle. - implementation(libs.junit.jupiter.api) - implementation(libs.mockito.core.compile) + // JUnit and Mockito are test-only. Until #62 a handful of test classes sat under + // src/main/java and dragged both onto the runtime classpath of the shipped app. implementation(libs.jetbrains.annotations) implementation(libs.sqlite.jdbc) implementation(libs.jlayer) diff --git a/core/src/main/java/kst4contest/controller/ChatController.java b/core/src/main/java/kst4contest/controller/ChatController.java index 2c04e4a9..bc8d4ab1 100644 --- a/core/src/main/java/kst4contest/controller/ChatController.java +++ b/core/src/main/java/kst4contest/controller/ChatController.java @@ -22,7 +22,6 @@ import kst4contest.locatorUtils.DirectionUtils; import kst4contest.logic.BandOpportunityResolver; import kst4contest.logic.PriorityCalculator; import kst4contest.model.*; -import kst4contest.test.MockKstServer; import kst4contest.utils.ApplicationFileUtils; import kst4contest.utils.PlayAudioUtils; import kst4contest.locatorUtils.Location; diff --git a/core/src/main/java/kst4contest/controller/MessageBusManagementThreadFrequencyContextTest.java b/core/src/main/java/kst4contest/controller/MessageBusManagementThreadFrequencyContextTest.java deleted file mode 100644 index dbafb49f..00000000 --- a/core/src/main/java/kst4contest/controller/MessageBusManagementThreadFrequencyContextTest.java +++ /dev/null @@ -1,81 +0,0 @@ -//package kst4contest.controller; -// -//import kst4contest.model.Band; -//import org.junit.jupiter.api.Test; -//import org.junit.jupiter.params.ParameterizedTest; -//import org.junit.jupiter.params.provider.ValueSource; -// -//import java.util.regex.Matcher; -//import java.util.regex.Pattern; -// -//import static org.junit.jupiter.api.Assertions.assertEquals; -//import static org.junit.jupiter.api.Assertions.assertFalse; -//import static org.junit.jupiter.api.Assertions.assertNotNull; -//import static org.junit.jupiter.api.Assertions.assertNull; -//import static org.junit.jupiter.api.Assertions.assertTrue; -// -//class MessageBusManagementThreadFrequencyContextTest { -// -// private static final Pattern THREE_DIGIT_VALUE = -// Pattern.compile("\\b\\d{3}\\b"); -// -// @ParameterizedTest -// @ValueSource(strings = { -// "qrg 210", -// "QRG: 210", -// "freq is 210", -// "frequency = 210", -// "on 210", -// "210 MHz", -// "210 qrg" -// }) -// void acceptsBareThreeDigitValueWithFrequencyContext(String messageText) { -// Matcher matcher = findThreeDigitValue(messageText); -// -// assertTrue( -// MessageBusManagementThread -// .hasExplicitBareFrequencyContext( -// messageText, -// matcher.start(), -// matcher.end() -// ) -// ); -// } -// -// @ParameterizedTest -// @ValueSource(strings = { -// "599", -// "144", -// "serial 210", -// "score 210", -// "worked 210 stations" -// }) -// void rejectsBareThreeDigitValueWithoutFrequencyContext(String messageText) { -// Matcher matcher = findThreeDigitValue(messageText); -// -// assertFalse( -// MessageBusManagementThread -// .hasExplicitBareFrequencyContext( -// messageText, -// matcher.start(), -// matcher.end() -// ) -// ); -// } -// -// @Test -// void resolvesOnlySupportedFallbackPrefixes() { -// assertEquals(Band.B_144, Band.fromPrefix("144")); -// assertEquals(Band.B_432, Band.fromPrefix(" 432 ")); -// assertEquals(Band.B_10G, Band.fromPrefix("10368")); -// assertNull(Band.fromPrefix("999")); -// assertNull(Band.fromPrefix(null)); -// } -// -// private Matcher findThreeDigitValue(String messageText) { -// Matcher matcher = THREE_DIGIT_VALUE.matcher(messageText); -// assertTrue(matcher.find(), "Test message must contain a three-digit value"); -// assertNotNull(matcher.group()); -// return matcher; -// } -//} \ No newline at end of file diff --git a/core/src/main/java/kst4contest/controller/On4KstConnectionManager.java b/core/src/main/java/kst4contest/controller/On4KstConnectionManager.java index 902d9411..95841a81 100644 --- a/core/src/main/java/kst4contest/controller/On4KstConnectionManager.java +++ b/core/src/main/java/kst4contest/controller/On4KstConnectionManager.java @@ -509,16 +509,6 @@ final class On4KstConnectionManager { category, preferences.getStn_loginNameMainCat())); } sendControl(session, On4KstProtocol.back(category)); - - String secondLocator = preferences.getStn_loginLocatorSecondCat(); - String mainLocator = preferences.getStn_loginLocatorMainCat(); - if (preferences.isLoginToSecondChatEnabled() - && secondLocator != null && !secondLocator.isBlank() - && !secondLocator.equalsIgnoreCase(mainLocator)) { - controller.onOn4KstConnectionWarning( - "ON4KST uses one locator per TCP session. The second-chat locator '" - + secondLocator + "' is ignored; using '" + mainLocator + "'."); - } } private void configureSecondChat(Session session) { diff --git a/core/src/main/java/kst4contest/controller/ReadUDPByWintestThreadTest.java b/core/src/main/java/kst4contest/controller/ReadUDPByWintestThreadTest.java deleted file mode 100644 index 860d7bdc..00000000 --- a/core/src/main/java/kst4contest/controller/ReadUDPByWintestThreadTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package kst4contest.controller; - -import kst4contest.model.ChatPreferences; - -public class ReadUDPByWintestThreadTest { - - public static void main(String[] args) { - ChatController ctrl1 = new ChatController(); - - ChatPreferences prefs = new ChatPreferences(); - ctrl1.setChatPreferences(prefs); - -// ReadUDPByWintestThread test = new ReadUDPByWintestThread(ctrl1); - - -// test.run(); - } -} diff --git a/core/src/main/java/kst4contest/controller/RegexTester.java b/core/src/main/java/kst4contest/controller/RegexTester.java deleted file mode 100644 index 7cd6c559..00000000 --- a/core/src/main/java/kst4contest/controller/RegexTester.java +++ /dev/null @@ -1,86 +0,0 @@ -package kst4contest.controller; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import kst4contest.model.ChatMember; - -public class RegexTester { - - public static void main(String[] args) { - - - String temp; - - temp = "DL1KDA JO30EP Alex\r\n" - + "DL3LST JO61FI Ray(Rainer)\r\n" - + "DL4ZAQ JN49MP Peter 2m&70cm&6m\r\n" - + "DL9LBH JN59ID Hans 2/70/23\r\n" - + "DO5AMF JN49FK Marc\r\n" - + "F5ICN JN03BF Alex QRV 2/70/23\r\n" - + "F6GRA JN04DB Carol 2m\r\n" - + "F6HTJ JN12KQ Michel\r\n" - + "G0BIX JO01GI Terry\r\n" - + "G0HOF IO92UL Ken 11el + 400 W\r\n" - + "G0LBK JO03BD David\r\n" - + "G0MBL JO01QH Andrew 2m\r\n" - + "G1SDX IO80FL Grant\r\n" - + "G3MXH JO02LF Terry\r\n" - + "G3OVH IO92JP Tony\r\n" - + "G3VCA IO93MG bob\r\n" - + "G4AEP IO91MB bill\r\n" - + "G4DHF IO92UU David\r\n" - + "G4FUF JO01GN Keith\r\n" - + "G4TRA IO81WN Steve\r\n" - + "G6HKS IO92OB Richard\r\n" - + "G8SEI IO92FO Jeff 6/4/2/70\r\n" - + "GM0EWX IO67UL Calum\r\n" - + "GW8IZR IO73TI Paul\r\n" - + "IV3GTH JN65RU Gigi\r\n" - + "IZ2XZM JN45KH Nick\r\n" - + "LY1BWB KO24PR VU Club 2/70\r\n" - + "LY2EN KO24PQ QRT\r\n" - + "OK1FPR JO80CE Milos\r\n" - + "OV3T JO46CM Thomas\r\n" - + "OY4TN IP62NB Trygvi 11EL/350W\r\n" - + "OZ2M JO65FR Bo PNGonVHF\r\n" - + "OZ3Z JO45UN Anders @432.228\r\n" - + "OZ7UV JO65DH Svend\r\n" - + "PA3DOL JO22MT Sjoerd\r\n" - + "PA3PCV JO20VV Marcel 2m\r\n" - + "PA9R JO22JK Rob\r\n" - + "S52FO JN76EF Janez\r\n" - + "S53RM JN76HD Sine\r\n" - + "SM2CEW KP15CR Peter\r\n" - + "SP6VGJ JO81HU Jacek"; - - - Pattern pattern = Pattern.compile("([a-zA-Z0-9]{2}/{1})?([a-zA-Z0-9]{1,3}[0-9][a-zA-Z0-9]{0,3}[a-zA-Z]{0,3})(/p)? [a-zA-Z]{2}[0-9]{2}[a-zA-Z]{2} [ -~]{1,20}"); - Matcher matcher = pattern.matcher(temp); - /** - * "([a-zA-Z0-9]{1,2}\/)?[a-zA-Z0-9]{1,3}[0-9][a-zA-Z0-9]{0,3}[a-zA-Z](\/(p|m))?( )[a-zA-Z]{2}[0-9]{2}[a-zA-Z]{2}[ -~]{0,30}"gm - * Thats a line of the show users list - */ - while (matcher.find()) { -// System.out.println("Chatmember detected: "+ matcher.group() + " " + matcher.start()); - - ChatMember member = new ChatMember(); - String matchedString = matcher.group(); - - String[] splittedUserString; - splittedUserString = matchedString.split(" "); - - member.setCallSign(splittedUserString[0]); - member.setQra(splittedUserString[1]); - - String stringAggregation = ""; - for (int i = 2; i < splittedUserString.length; i++) { - stringAggregation += splittedUserString[i] + " "; - } - member.setName(stringAggregation); - - System.out.println("Call: " + member.getCallSign() + ", QRA: " + member.getQra() + ", Name: " + member.getName()); - } - } - -} diff --git a/core/src/main/java/kst4contest/locatorUtils/TestLocatorUtils.java b/core/src/main/java/kst4contest/locatorUtils/TestLocatorUtils.java deleted file mode 100644 index 7ad76f11..00000000 --- a/core/src/main/java/kst4contest/locatorUtils/TestLocatorUtils.java +++ /dev/null @@ -1,43 +0,0 @@ -package kst4contest.locatorUtils; - -public class TestLocatorUtils { - - public static void main(String[] args) { - - -// isInAngle(myLocation, location1, location2); - System.out.println(isInAngleAndRange("JN49FL", "jo43xm", "jo30sa", 900, 50)); - System.out.println(isInAngleAndRange("JN49FL", "jo51ij", "jn39oc", 900, 50)); - System.out.println(isInAngleAndRange("JN49FL", "jn39oc", "jo51ij", 1100, 50)); - } - - public static boolean isInAngleAndRange(String myLocator, String locatorOfSkedSender, String locatorOfSekdReceiver, double maxRangeKm, double hisAntennaBeamWidth) { - - Location myLocation = new Location(myLocator); - Location skedSenderLocation = new Location(locatorOfSkedSender); - Location skedReceiverLocation = new Location(locatorOfSekdReceiver); - - double distanceFromMeToLocSender = new Location(myLocator).getDistanceKm(new Location(locatorOfSkedSender)); - - // Check if distance exceeds my setted maximum range - if (distanceFromMeToLocSender > maxRangeKm) { - System.out.println("too far, " + distanceFromMeToLocSender + " km"); - return false; - } - - //check bearing of sender to receiver - - double bearingOfSekdSenderToSkedReceiver = skedSenderLocation.getBearing(skedReceiverLocation); - System.out.println("skedTX -> skedRX deg: " + bearingOfSekdSenderToSkedReceiver); - - double bearingOfSekdSenderToMe = skedSenderLocation.getBearing(myLocation); - System.out.println("skedTX -> me deg: " + bearingOfSekdSenderToMe); - - if (DirectionUtils.isAngleInRange(bearingOfSekdSenderToSkedReceiver, bearingOfSekdSenderToMe, hisAntennaBeamWidth)) { - //may I should get "/2" because of 50% of the 3dB opening angle if txer is directed to sender exactly - return true; - } else return false; - } - - -} diff --git a/core/src/main/java/kst4contest/model/ChatPreferences.java b/core/src/main/java/kst4contest/model/ChatPreferences.java index 45230b3c..77355f94 100644 --- a/core/src/main/java/kst4contest/model/ChatPreferences.java +++ b/core/src/main/java/kst4contest/model/ChatPreferences.java @@ -218,7 +218,6 @@ public class ChatPreferences { String stn_loginNameMainCat = "KST4Contest"; String stn_loginNameSecondCat = "KST4ContestSHF"; String stn_loginLocatorMainCat = "jn49fk"; - String stn_loginLocatorSecondCat = "jn49fk"; double stn_antennaBeamWidthDeg = 50; double stn_maxQRBDefault = 900; @@ -323,7 +322,6 @@ public class ChatPreferences { lstNotify_QSOSniffer_sniffedCallSignList = new SimpleRoster<>(); // SimpleRoster lstNotify_QSOSniffer_sniffedCallSignList = new SimpleRoster<>(); - SimpleRoster lstNotify_QSOSniffer_sniffedWordsList = new SimpleRoster<>(); SimpleRoster lstNotify_QSOSniffer_sniffedPrefixLocList = new SimpleRoster<>(); // Scoring / interaction metrics @@ -554,15 +552,6 @@ public class ChatPreferences { return lstNotify_QSOSniffer_sniffedCallSignList; } - public SimpleRoster getLstNotify_QSOSniffer_sniffedWordsList() { - return lstNotify_QSOSniffer_sniffedWordsList; - } - - public void setLstNotify_QSOSniffer_sniffedWordsList(java.util.Collection lstNotify_QSOSniffer_sniffedWordsList) { - // Fill the existing roster: replacing the field would orphan its listeners. - this.lstNotify_QSOSniffer_sniffedWordsList.setAll(lstNotify_QSOSniffer_sniffedWordsList); - } - public SimpleRoster getLstNotify_QSOSniffer_sniffedPrefixLocList() { return lstNotify_QSOSniffer_sniffedPrefixLocList; } @@ -660,14 +649,6 @@ public class ChatPreferences { this.logsynch_wintestUsePassQrg = logsynch_wintestUsePassQrg; } - public String getStn_loginLocatorSecondCat() { - return stn_loginLocatorSecondCat; - } - - public void setStn_loginLocatorSecondCat(String stn_loginLocatorSecondCat) { - this.stn_loginLocatorSecondCat = stn_loginLocatorSecondCat; - } - public boolean isBcn_beaconsEnabledSecondCat() { return bcn_beaconsEnabledSecondCat; } @@ -1962,15 +1943,6 @@ public class ChatPreferences { /** * QSO Sniffer Lists */ - Element snifferWords = doc.createElement("snifferWords"); - rootElement.appendChild(snifferWords); - - for (String word : lstNotify_QSOSniffer_sniffedWordsList.snapshot()) { - Element temp = doc.createElement("w"); - temp.setTextContent(word); - snifferWords.appendChild(temp); - } - Element snifferCallSigns = doc.createElement("snifferCallSigns"); rootElement.appendChild(snifferCallSigns); @@ -2935,47 +2907,6 @@ public class ChatPreferences { } } - list = doc.getElementsByTagName("snifferWords"); - if (list != null && list.getLength() != 0) { - // reset to avoid duplicates when reloading - lstNotify_QSOSniffer_sniffedWordsList.clear(); - for (int temp = 0; temp < list.getLength(); temp++) { - Node node = list.item(temp); - if (node.getNodeType() == Node.ELEMENT_NODE) { - Element element = (Element) node; - NodeList children = element.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - Node child = children.item(i); - if (child.getNodeType() == Node.ELEMENT_NODE) { - String callSign = child.getTextContent(); - - if (callSign != null - && !callSign.isBlank()) { - - /* - * Older preference files may contain complete KST callsigns - * such as DN9APW-2. QSO monitoring is stored by base callsign, - * so one entry covers every suffix of the same station. - */ - String normalizedCallSign = - ChatMember.normalizeCallSignToBaseCallSign( - callSign - ); - - if (normalizedCallSign != null - && !normalizedCallSign.isBlank() - && !lstNotify_QSOSniffer_sniffedCallSignList.snapshot() - .contains(normalizedCallSign)) { - lstNotify_QSOSniffer_sniffedCallSignList - .add(normalizedCallSign); - } - } - } - } - } - } - } - list = doc.getElementsByTagName("snifferPrefixes"); if (list != null && list.getLength() != 0) { lstNotify_QSOSniffer_sniffedPrefixLocList.clear(); diff --git a/core/src/main/java/kst4contest/test/MockKstServer.java b/core/src/main/java/kst4contest/test/MockKstServer.java deleted file mode 100644 index da8e627b..00000000 --- a/core/src/main/java/kst4contest/test/MockKstServer.java +++ /dev/null @@ -1,256 +0,0 @@ -package kst4contest.test; - -import java.io.*; -import java.net.*; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.concurrent.CopyOnWriteArrayList; - -public class MockKstServer { - - private static final int PORT = 23001; - private static final String CHAT_ID = "2"; // 2 = 144/432 MHz - - // Thread-sichere Liste aller verbundenen Clients (OutputStreams) - private final List clients = new CopyOnWriteArrayList<>(); - - // Permanente User (Ihre Test-Callsigns) - private final Map onlineUsers = new HashMap<>(); - // Historien müssen synchronisiert werden - private final List historyChat = Collections.synchronizedList(new ArrayList<>()); - private final List historyDx = Collections.synchronizedList(new ArrayList<>()); - - private boolean running = false; - private ServerSocket serverSocket; - - public MockKstServer() { - // Initiale Permanente User - addUser("DK5EW", "Erwin", "JN47NX"); - addUser("DL1TEST", "TestOp", "JO50XX"); - addUser("ON4KST", "Alain", "JO20HI"); - addUser("PA9R-2", "2", "JO20HI"); - addUser("PA9R-70", "70", "JO20HI"); - addUser("PA9R", "general", "JO20HI"); - } - - // Startet den Server im Hintergrund (Non-Blocking) - public void start() { - if (running) return; - running = true; - - new Thread(() -> { - try { - serverSocket = new ServerSocket(PORT); - System.out.println("[Server] ON4KST Simulation gestartet auf Port " + PORT); - - // Startet den Simulator für Zufallstraffic - new Thread(this::simulationLoop).start(); - - while (running) { - Socket clientSocket = serverSocket.accept(); - System.out.println("[Server] Neuer Client verbunden: " + clientSocket.getInetAddress()); - new Thread(new ClientHandler(clientSocket)).start(); - } - } catch (IOException e) { - if (running) e.printStackTrace(); - } - }).start(); - } - - public void stop() { - running = false; - try { - if (serverSocket != null) serverSocket.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void addUser(String call, String name, String loc) { - onlineUsers.put(call, new User(call, name, loc)); - } - - private void removeUser(String call) { - onlineUsers.remove(call); - } - - // Sendet Nachricht an ALLE verbundenen Clients (inkl. Sender) - private void broadcast(String message) { - if (!message.endsWith("\r\n")) message += "\r\n"; - String finalMsg = message; - - for (PrintWriter writer : clients) { - try { - writer.print(finalMsg); - writer.flush(); // WICHTIG: Sofort senden! - } catch (Exception e) { - // Client wohl weg, wird beim nächsten Schreibversuch oder im Handler entfernt - } - } - } - - // --- Innere Logik: Client Handler --- - private class ClientHandler implements Runnable { - private Socket socket; - private PrintWriter out; - private BufferedReader in; - private String myCall = "MYCLIENT"; // Default, wird bei LOGIN überschrieben - - public ClientHandler(Socket socket) { - this.socket = socket; - } - - @Override - public void run() { - try { - // ISO-8859-1 ist Standard für KST/Telnet Cluster - in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "ISO-8859-1")); - out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "ISO-8859-1"), true); - - clients.add(out); - - String line; - boolean loginComplete = false; - - while ((line = in.readLine()) != null) { - // System.out.println("[RECV] " + line); // Debugging aktivieren falls nötig - String[] parts = line.split("\\|"); - String cmd = parts[0]; - - if (cmd.equals("LOGIN") || cmd.equals("LOGINC")) { - // Protokoll: LOGIN|callsign|password|... [cite: 21] - if (parts.length > 1) myCall = parts[1]; - - // 1. Login Bestätigung - // Format: LOGSTAT|100|chat id|client software version|session key|config|dx option| - send("LOGSTAT|100|" + CHAT_ID + "|JavaSim|KEY123|Config|3|"); - - // Bei LOGIN senden wir die Daten sofort - // Bei LOGINC warten wir eigentlich auf SDONE, senden hier aber vereinfacht direkt - if (cmd.equals("LOGIN")) { - sendInitialData(); - loginComplete = true; - } - } - else if (cmd.equals("SDONE")) { - // Abschluss der Settings (bei LOGINC) [cite: 34] - sendInitialData(); - loginComplete = true; - } - else if (cmd.equals("MSG")) { - // MSG|chat id|destination|command|0| [cite: 42] - if (parts.length >= 4) { - String text = parts[3]; - // Nachricht sofort als CH Frame an alle verteilen (Echo) - handleChatMessage(myCall, "Me", text); - } - } - else if (cmd.equals("CK")) { - // Keepalive [cite: 20] - // Server muss nicht zwingend antworten, aber Connection bleibt offen - } - } - } catch (IOException e) { - // System.out.println("Client getrennt"); - } finally { - clients.remove(out); - try { socket.close(); } catch (IOException e) {} - } - } - - private void send(String msg) { - if (!msg.endsWith("\r\n")) msg += "\r\n"; - out.print(msg); - out.flush(); - } - - private void sendInitialData() { - // 1. User Liste UA0 [cite: 14] - for (User u : onlineUsers.values()) { - send("UA0|" + CHAT_ID + "|" + u.call + "|" + u.name + "|" + u.loc + "|0|"); - } - // 2. Chat History CR [cite: 7] - synchronized(historyChat) { - for (String h : historyChat) send(h); - } - // 3. DX History DL [cite: 10] - synchronized(historyDx) { - for (String d : historyDx) send(d); - } - // 4. Ende User Liste UE [cite: 15] - send("UE|" + CHAT_ID + "|" + onlineUsers.size() + "|"); - } - } - - // --- Hilfsmethoden für Traffic --- - - private void handleChatMessage(String call, String name, String text) { - // CH|chat id|date|callsign|firstname|destination|msg|highlight| - String date = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); - String frame = String.format("CH|%s|%s|%s|%s|0|%s|0|", CHAT_ID, date, call, name, text); - - synchronized(historyChat) { - historyChat.add(frame); - if (historyChat.size() > 50) historyChat.remove(0); - } - broadcast(frame); - } - - private void handleDxSpot(String spotter, String dx, String freq) { - // DL|Unix time|dx utc|spotter|qrg|dx|info|spotter locator|dx locator| [cite: 10] - long unixTime = System.currentTimeMillis() / 1000; - String utc = new SimpleDateFormat("HHmm").format(new Date()); - // Simple Dummy Locators - String frame = String.format("DL|%d|%s|%s|%s|%s|Simulated|JO00|JO99|", - unixTime, utc, spotter, freq, dx); - - synchronized(historyDx) { - historyDx.add(frame); - if (historyDx.size() > 20) historyDx.remove(0); - } - broadcast(frame); - } - - private void simulationLoop() { - String[] randomCalls = {"PA0GUS", "F6APE", "OH8K", "OZ2M", "G4CBW"}; - String[] msgs = {"CQ 144.300", "Tnx for QSO", "Any sked?", "QRV 432.200"}; - Random rand = new Random(); - - while (running) { - try { - Thread.sleep(3000 + rand.nextInt(5000)); // 3-8 Sek Pause - - int action = rand.nextInt(10); - String call = randomCalls[rand.nextInt(randomCalls.length)]; - - if (action < 4) { // 40% Chat - handleChatMessage(call, "SimOp", msgs[rand.nextInt(msgs.length)]); - } else if (action < 7) { // 30% DX Spot - handleDxSpot(call, randomCalls[rand.nextInt(randomCalls.length)], "144." + rand.nextInt(400)); - } else if (action == 8) { // Login Simulation UA5 - if (!onlineUsers.containsKey(call)) { - addUser(call, "SimOp", "JO11"); - broadcast("UA5|" + CHAT_ID + "|" + call + "|SimOp|JO11|2|"); - } - } else if (action == 9) { // Logout Simulation UR6 - if (onlineUsers.containsKey(call) && !call.equals("DK5EW")) { // DK5EW nicht kicken - removeUser(call); - broadcast("UR6|" + CHAT_ID + "|" + call + "|"); - } - } - - // Ping ab und zu - if (rand.nextInt(5) == 0) broadcast("CK|"); - - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - } - - // Kleine Datenklasse - private static class User { - String call, name, loc; - User(String c, String n, String l) { this.call=c; this.name=n; this.loc=l; } - } -} \ No newline at end of file diff --git a/core/src/main/java/kst4contest/view/map/mapTest.java b/core/src/main/java/kst4contest/view/map/mapTest.java deleted file mode 100644 index d00978fc..00000000 --- a/core/src/main/java/kst4contest/view/map/mapTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package kst4contest.view.map; - -public class mapTest { - - public static void main(String[] args) { - - TerrainPackageService terrainPackageService = new TerrainPackageService(); - - TerrainPackageService.TerrainPreparationResult result = - terrainPackageService.prepareTerrainForLocators( - "JO51IJ", - "JO22JK", - "TEST", - 144.300, - 10.0, - 10.0, - "" - ); - - System.out.println(result.success()); - System.out.println(result.message()); - - } -} diff --git a/core/src/test/java/kst4contest/controller/DBControllerSchemaMigrationTest.java b/core/src/test/java/kst4contest/controller/DBControllerSchemaMigrationTest.java new file mode 100644 index 00000000..a436c62b --- /dev/null +++ b/core/src/test/java/kst4contest/controller/DBControllerSchemaMigrationTest.java @@ -0,0 +1,332 @@ +package kst4contest.controller; + +import kst4contest.ApplicationConstants; +import kst4contest.model.ChatMember; +import kst4contest.utils.ApplicationFileUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.lang.reflect.Field; +import java.nio.file.Files; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Opens databases of older schema generations with a {@link DBController} and verifies that + * the controller migrates them to the current schema: all columns present, PRAGMA + * user_version at the current level, legacy callsign keys merged to base callsigns and the + * existing rows preserved. The fixtures are built with plain sqlite-jdbc so the test does not + * depend on the controller to create "old" files. + */ +class DBControllerSchemaMigrationTest { + + private static final String USER_HOME_PROPERTY = "user.home"; + + /** Columns the current ChatMember CREATE TABLE statement in DBController declares. */ + private static final List CHAT_MEMBER_COLUMNS = List.of( + "callsign", "qra", "name", "lastActivityDateTime", + "worked", "worked144", "worked432", "worked1240", "worked2300", "worked3400", + "worked5600", "worked10G", "worked50", "worked70", + "notQRV144", "notQRV432", "notQRV1240", "notQRV2300", "notQRV3400", "notQRV5600", + "notQRV10G", "notQRV50", "notQRV70", + "lastFlagsChangeEpochMs"); + + /** Columns the current WorkedGrossField CREATE TABLE statement in DBController declares. */ + private static final List WORKED_GROSS_FIELD_COLUMNS = List.of( + "band", "grossField", "locator", "callsign", "source", "lastWorkedEpochMs"); + + /** + * ChatMember as created by release 1.1: no not-QRV columns, no timestamp, no 50/70 MHz. + */ + private static final String CREATE_CHAT_MEMBER_V11 = + "CREATE TABLE ChatMember (" + + "callsign TEXT NOT NULL PRIMARY KEY, qra TEXT, name TEXT, " + + "lastActivityDateTime TEXT, " + + "worked BOOLEAN DEFAULT 0, worked144 BOOLEAN DEFAULT 0, " + + "worked432 BOOLEAN DEFAULT 0, worked1240 BOOLEAN DEFAULT 0, " + + "worked2300 BOOLEAN DEFAULT 0, worked3400 BOOLEAN DEFAULT 0, " + + "worked5600 BOOLEAN DEFAULT 0, worked10G BOOLEAN DEFAULT 0);"; + + /** + * ChatMember as created by release 1.3: not-QRV columns and the expiry timestamp exist, + * the 50/70 MHz columns of release 1.4 do not. + */ + private static final String CREATE_CHAT_MEMBER_V13 = + "CREATE TABLE ChatMember (" + + "callsign TEXT NOT NULL PRIMARY KEY, qra TEXT, name TEXT, " + + "lastActivityDateTime TEXT, " + + "worked BOOLEAN DEFAULT 0, worked144 BOOLEAN DEFAULT 0, " + + "worked432 BOOLEAN DEFAULT 0, worked1240 BOOLEAN DEFAULT 0, " + + "worked2300 BOOLEAN DEFAULT 0, worked3400 BOOLEAN DEFAULT 0, " + + "worked5600 BOOLEAN DEFAULT 0, worked10G BOOLEAN DEFAULT 0, " + + "notQRV144 BOOLEAN DEFAULT 0, notQRV432 BOOLEAN DEFAULT 0, " + + "notQRV1240 BOOLEAN DEFAULT 0, notQRV2300 BOOLEAN DEFAULT 0, " + + "notQRV3400 BOOLEAN DEFAULT 0, notQRV5600 BOOLEAN DEFAULT 0, " + + "notQRV10G BOOLEAN DEFAULT 0, " + + "lastFlagsChangeEpochMs INTEGER DEFAULT 0);"; + + @TempDir + Path temporaryHomeDirectory; + + private String originalUserHome; + private DBController controller; + + @BeforeEach + void redirectUserHomeToTemporaryDirectory() { + originalUserHome = System.getProperty(USER_HOME_PROPERTY); + System.setProperty(USER_HOME_PROPERTY, temporaryHomeDirectory.toString()); + } + + @AfterEach + void closeControllerAndRestoreUserHome() { + if (controller != null) { + controller.closeDBConnection(); + controller = null; + } + if (originalUserHome == null) { + System.clearProperty(USER_HOME_PROPERTY); + } else { + System.setProperty(USER_HOME_PROPERTY, originalUserHome); + } + } + + @Test + void seededTemplateDatabaseIsMigratedToTheCurrentSchema() throws Exception { + controller = new DBController("praktiKST.db", true); + String databasePath = controller.getDatabaseFilePath(); + + assertEquals(currentSchemaVersion(), userVersion(databasePath)); + assertColumns(databasePath, "ChatMember", CHAT_MEMBER_COLUMNS); + assertColumns(databasePath, "WorkedGrossField", WORKED_GROSS_FIELD_COLUMNS); + assertEquals(0, legacyCallsignRowCount(databasePath), + "the normalisation rebuild must leave no slash or dash keys behind"); + + Map stations = controller.fetchChatMemberWkdDataFromDB(); + // The bundled template carries 3452 foreign callsigns, 199 of them with a suffix or + // prefix; merging those to their base callsign shrinks the table but keeps the stations. + assertTrue(stations.size() > 3000 && stations.size() < 3452, + "unexpected station count after the rebuild: " + stations.size()); + + // "OE/HA5DDX" is the only row of this station in the template. + ChatMember ha5ddx = stations.get("HA5DDX"); + assertNotNull(ha5ddx, "OE/HA5DDX must be stored under its base callsign"); + assertEquals("JN77WM", ha5ddx.getQra()); + assertEquals("Shani", ha5ddx.getName()); + assertFalse(stations.containsKey("OE/HA5DDX")); + + // "F6KFH" and "F6KFH-2" both exist in the template and collapse into one row. + assertTrue(stations.containsKey("F6KFH")); + assertFalse(stations.containsKey("F6KFH-2")); + } + + @Test + void release11SchemaGainsAllColumnsAndMergesLegacyCallsignKeys() throws Exception { + String relativeName = "profiles/legacy11/praktiKST.db"; + String databasePath = fixturePath(relativeName); + try (Connection raw = openRaw(databasePath); Statement statement = raw.createStatement()) { + statement.executeUpdate(CREATE_CHAT_MEMBER_V11); + statement.executeUpdate("INSERT INTO ChatMember (callsign, qra, name, worked144) " + + "VALUES ('OK2M-70', 'JN69UN', 'Team', 1);"); + statement.executeUpdate("INSERT INTO ChatMember (callsign, worked432) " + + "VALUES ('OK2M', 1);"); + statement.executeUpdate("INSERT INTO ChatMember (callsign, qra, name, worked) " + + "VALUES ('EA5/G8MBI/P', 'IM98PA', 'Bob', 1);"); + statement.executeUpdate("INSERT INTO ChatMember (callsign, qra, name) " + + "VALUES ('DL1XYZ', 'JO31AA', 'Plain');"); + } + assertEquals(0, userVersion(databasePath)); + + controller = new DBController(relativeName, false); + + assertEquals(currentSchemaVersion(), userVersion(databasePath)); + assertColumns(databasePath, "ChatMember", CHAT_MEMBER_COLUMNS); + assertColumns(databasePath, "WorkedGrossField", WORKED_GROSS_FIELD_COLUMNS); + assertEquals(0, legacyCallsignRowCount(databasePath)); + + Map stations = controller.fetchChatMemberWkdDataFromDB(); + assertEquals(Set.of("DL1XYZ", "G8MBI", "OK2M"), new TreeSet<>(stations.keySet())); + + ChatMember ok2m = stations.get("OK2M"); + assertTrue(ok2m.isWorked144(), "worked144 of OK2M-70 must survive the merge"); + assertTrue(ok2m.isWorked432(), "worked432 of OK2M must survive the merge"); + assertEquals("JN69UN", ok2m.getQra(), "the merge fills an empty locator from the other row"); + assertEquals("Team", ok2m.getName()); + assertTrue(ok2m.isQrv144() && ok2m.isQrv50() && ok2m.isQrv70(), + "columns added by the migration default to QRV"); + + ChatMember g8mbi = stations.get("G8MBI"); + assertTrue(g8mbi.isWorked()); + assertEquals("IM98PA", g8mbi.getQra()); + + ChatMember dl1xyz = stations.get("DL1XYZ"); + assertFalse(dl1xyz.isWorked()); + assertFalse(dl1xyz.isWorked144()); + assertEquals("Plain", dl1xyz.getName()); + } + + @Test + void release13SchemaGainsBandColumnsAndKeepsRowsUntouched() throws Exception { + String relativeName = "profiles/legacy13/praktiKST.db"; + String databasePath = fixturePath(relativeName); + long recentFlagsChange = System.currentTimeMillis() - 60_000L; + try (Connection raw = openRaw(databasePath); Statement statement = raw.createStatement()) { + statement.executeUpdate(CREATE_CHAT_MEMBER_V13); + statement.executeUpdate("INSERT INTO ChatMember (callsign, qra, name, " + + "lastActivityDateTime, worked144, notQRV432, lastFlagsChangeEpochMs) " + + "VALUES ('DL2ABC', 'JO62QL', 'Anna', 'Sun Aug 06 10:21:23 CEST 2023', 1, 1, " + + recentFlagsChange + ");"); + statement.executeUpdate("INSERT INTO ChatMember (callsign) VALUES ('DL3DEF');"); + } + + controller = new DBController(relativeName, false); + + assertEquals(currentSchemaVersion(), userVersion(databasePath)); + assertColumns(databasePath, "ChatMember", CHAT_MEMBER_COLUMNS); + + Map stations = controller.fetchChatMemberWkdDataFromDB(); + assertEquals(Set.of("DL2ABC", "DL3DEF"), new TreeSet<>(stations.keySet())); + + ChatMember dl2abc = stations.get("DL2ABC"); + assertTrue(dl2abc.isWorked144()); + assertFalse(dl2abc.isQrv432()); + assertTrue(dl2abc.isQrv144()); + assertFalse(dl2abc.isWorked50()); + assertFalse(dl2abc.isWorked70()); + assertTrue(dl2abc.isQrv50()); + assertTrue(dl2abc.isQrv70()); + assertEquals(recentFlagsChange, dl2abc.getLastFlagsChangeEpochMs(), + "a recent flags timestamp must not be reset by the expiry cleanup"); + + // Without legacy keys no rebuild happens, so even the column the controller never + // reads back stays as it was. + assertEquals("Sun Aug 06 10:21:23 CEST 2023", + scalar(databasePath, "SELECT lastActivityDateTime FROM ChatMember WHERE callsign = 'DL2ABC';")); + } + + @Test + void reopeningAnUpToDateDatabaseChangesNothing() throws Exception { + String relativeName = "profiles/current/praktiKST.db"; + controller = new DBController(relativeName, false); + String databasePath = controller.getDatabaseFilePath(); + + ChatMember worked = new ChatMember(); + worked.setCallSign("DL0XYZ"); + worked.setQra("JO51IJ"); + worked.setWorked(true); + worked.setWorked144(true); + controller.storeChatMember(worked); + controller.closeDBConnection(); + controller = null; + + assertEquals(currentSchemaVersion(), userVersion(databasePath)); + List before = dump(databasePath); + + controller = new DBController(relativeName, false); + assertTrue(controller.fetchChatMemberWkdDataFromDB().get("DL0XYZ").isWorked144()); + controller.closeDBConnection(); + controller = null; + + assertEquals(before, dump(databasePath), + "schema, user_version and rows must be identical after reopening"); + } + + // --------------------------------------------------------------------------------------- + // helpers + // --------------------------------------------------------------------------------------- + + private static int currentSchemaVersion() throws ReflectiveOperationException { + Field field = DBController.class.getDeclaredField("CURRENT_DATABASE_SCHEMA_VERSION"); + field.setAccessible(true); + return field.getInt(null); + } + + private static String fixturePath(String relativeName) throws Exception { + String path = ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, relativeName); + Files.createDirectories(Path.of(path).getParent()); + return path; + } + + private static Connection openRaw(String databasePath) throws SQLException { + return DriverManager.getConnection("jdbc:sqlite:" + databasePath); + } + + private static int userVersion(String databasePath) throws SQLException { + return Integer.parseInt(scalar(databasePath, "PRAGMA user_version;")); + } + + private static String scalar(String databasePath, String sql) throws SQLException { + try (Connection raw = openRaw(databasePath); + Statement statement = raw.createStatement(); + ResultSet resultSet = statement.executeQuery(sql)) { + assertTrue(resultSet.next(), "no row for " + sql); + return resultSet.getString(1); + } + } + + private static int legacyCallsignRowCount(String databasePath) throws SQLException { + return Integer.parseInt(scalar(databasePath, + "SELECT count(*) FROM ChatMember WHERE callsign LIKE '%/%' OR callsign LIKE '%-%';")); + } + + private static void assertColumns(String databasePath, String table, List expected) + throws SQLException { + Set actual = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + try (Connection raw = openRaw(databasePath); + Statement statement = raw.createStatement(); + ResultSet resultSet = statement.executeQuery("PRAGMA table_info(" + table + ");")) { + while (resultSet.next()) { + actual.add(resultSet.getString("name")); + } + } + List missing = new ArrayList<>(); + for (String column : expected) { + if (!actual.contains(column)) { + missing.add(column); + } + } + assertEquals(List.of(), missing, "columns missing in " + table + "; present: " + actual); + } + + /** Captures schema, user_version and every row, so two states can be compared. */ + private static List dump(String databasePath) throws SQLException { + List lines = new ArrayList<>(); + lines.add("user_version=" + userVersion(databasePath)); + try (Connection raw = openRaw(databasePath); Statement statement = raw.createStatement()) { + try (ResultSet resultSet = statement.executeQuery( + "SELECT type, name, sql FROM sqlite_master ORDER BY type, name;")) { + while (resultSet.next()) { + lines.add(resultSet.getString(1) + " " + resultSet.getString(2) + " " + resultSet.getString(3)); + } + } + for (String table : List.of("ChatMember", "WorkedGrossField")) { + try (ResultSet resultSet = statement.executeQuery("SELECT * FROM " + table + " ORDER BY 1;")) { + int columns = resultSet.getMetaData().getColumnCount(); + while (resultSet.next()) { + StringBuilder row = new StringBuilder(table); + for (int i = 1; i <= columns; i++) { + row.append('|').append(resultSet.getString(i)); + } + lines.add(row.toString()); + } + } + } + } + return lines; + } +} diff --git a/core/src/main/java/kst4contest/controller/On4KstProtocolTest.java b/core/src/test/java/kst4contest/controller/On4KstProtocolTest.java similarity index 97% rename from core/src/main/java/kst4contest/controller/On4KstProtocolTest.java rename to core/src/test/java/kst4contest/controller/On4KstProtocolTest.java index bdf27a8c..5b91a72b 100644 --- a/core/src/main/java/kst4contest/controller/On4KstProtocolTest.java +++ b/core/src/test/java/kst4contest/controller/On4KstProtocolTest.java @@ -1,7 +1,5 @@ package kst4contest.controller; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/core/src/main/java/kst4contest/controller/On4KstSocketThreadTest.java b/core/src/test/java/kst4contest/controller/On4KstSocketThreadTest.java similarity index 100% rename from core/src/main/java/kst4contest/controller/On4KstSocketThreadTest.java rename to core/src/test/java/kst4contest/controller/On4KstSocketThreadTest.java diff --git a/core/src/main/java/kst4contest/model/ChatMemberDirectionOpportunityTest.java b/core/src/test/java/kst4contest/model/ChatMemberDirectionOpportunityTest.java similarity index 100% rename from core/src/main/java/kst4contest/model/ChatMemberDirectionOpportunityTest.java rename to core/src/test/java/kst4contest/model/ChatMemberDirectionOpportunityTest.java diff --git a/core/src/test/java/kst4contest/model/ChatPreferencesObservableTest.java b/core/src/test/java/kst4contest/model/ChatPreferencesObservableTest.java index 35d448ed..b7ad4b9b 100644 --- a/core/src/test/java/kst4contest/model/ChatPreferencesObservableTest.java +++ b/core/src/test/java/kst4contest/model/ChatPreferencesObservableTest.java @@ -31,7 +31,7 @@ class ChatPreferencesObservableTest { void theListSettingsStartEmpty() { ChatPreferences prefs = new ChatPreferences(); - assertTrue(prefs.getLstNotify_QSOSniffer_sniffedWordsList().snapshot().isEmpty()); + assertTrue(prefs.getLstNotify_QSOSniffer_sniffedCallSignList().snapshot().isEmpty()); assertTrue(prefs.getLstNotify_QSOSniffer_sniffedPrefixLocList().snapshot().isEmpty()); assertTrue(prefs.getLst_txtSnipList().snapshot().isEmpty()); assertTrue(prefs.getLst_txtShortCutBtnList().snapshot().isEmpty()); diff --git a/core/src/test/java/kst4contest/model/ChatPreferencesRoundTripTest.java b/core/src/test/java/kst4contest/model/ChatPreferencesRoundTripTest.java new file mode 100644 index 00000000..2d7fb40b --- /dev/null +++ b/core/src/test/java/kst4contest/model/ChatPreferencesRoundTripTest.java @@ -0,0 +1,335 @@ +package kst4contest.model; + +import kst4contest.observe.MutableValue; +import kst4contest.observe.ObservableRoster; +import kst4contest.observe.SimpleValue; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Drives every public single-argument setter of {@link ChatPreferences} to a value that + * differs from the compiled-in default, writes the preferences to XML, reads them into a + * fresh instance and compares every getter. The setters are discovered by reflection so a + * newly added preference is covered automatically; a field that is not persisted on purpose + * must be listed in {@link #NOT_PERSISTED_SETTERS} with a reason. + */ +class ChatPreferencesRoundTripTest { + + /** + * Setters whose value is intentionally not written to the XML file. Each entry names the + * evidence in {@code ChatPreferences}. A field that is lost by accident must not be added + * here silently; a known persistence bug is listed with a "BUG:" prefix so the test stays + * green while the report stays loud. + */ + private static final Map NOT_PERSISTED_SETTERS = Map.ofEntries( + Map.entry("setStoreAndRestorePreferencesFileName", + "Path of the XML file itself; set by the constructors, never a child " + + "element of "), + Map.entry("setChatState", + "Declared as 'working variable only for use by primarystage (title bar)'; " + + "writePreferencesToXmlFile never emits it"), + Map.entry("setProgramVersion", + "Compiled-in about text; writePreferencesToXmlFile never emits it"), + Map.entry("setActualQTF", + "Runtime antenna direction ('will be updated by user at runtime!'); " + + "writePreferencesToXmlFile never emits it"), + Map.entry("setMessageHandling_autoAnswerTextSecondCat", + "Written as , but readPreferencesFromXmlFile " + + "deliberately mirrors the main-category text over it because the UI " + + "exposes one shared auto-answer setting (see the comment above " + + "'messageHandling_autoAnswerTextSecondCat = " + + "messageHandling_autoAnswerTextMainCat')"), + Map.entry("setMessageHandling_autoAnswerEnabledSecondCat", + "Same deliberate mirroring as the second-category auto-answer text; the " + + "main-category flag wins after every read"), + Map.entry("setBcn_contestScoreSum", + "DEAD FIELD: declared with accessors only, no caller in core or app-desktop, " + + "never written nor read") + ); + + /** + * Setters that are an alias for another setter and therefore have no getter of their own. + * The canonical setter is covered by the reflective loop. + */ + private static final Map ALIAS_SETTERS = Map.ofEntries( + Map.entry("setLogSynch_storeWorkedCallSignsFileNameUDPMessageBackup", + "Capital-S alias of setLogsynch_storeWorkedCallSignsFileNameUDPMessageBackup") + ); + + /** + * Setters whose argument is validated or parsed, so the generic "distinctive value per + * type" would be rejected. The value here is a valid, non-default one. + */ + private static final Map SPECIAL_VALUES = Map.ofEntries( + Map.entry("setGuiOptions_language", "de"), + Map.entry("setMYQRGFirstCat", "144.321.00"), + Map.entry("setMYQRGSecondCat", "432.321.00"), + Map.entry("setAirScout_asBandString", "4320000") + ); + + @TempDir + Path temporaryDirectory; + + @Test + void everySetterSurvivesTheXmlRoundTrip() throws Exception { + Path preferencesFile = temporaryDirectory.resolve("roundtrip.xml"); + ChatPreferences defaults = new ChatPreferences(preferencesFile); + ChatPreferences written = new ChatPreferences(preferencesFile); + + List setters = settersUnderTest(); + assertTrue(setters.size() > 100, + "Expected the reflective scan to find the ~130 setters, found " + setters.size()); + + List unbuildable = new ArrayList<>(); + List withoutGetter = new ArrayList<>(); + List unchangedByValue = new ArrayList<>(); + Map getterBySetter = new LinkedHashMap<>(); + + for (Method setter : setters) { + Method getter = findGetter(setter); + if (getter == null) { + withoutGetter.add(setter.getName()); + continue; + } + Object valueToSet = distinctiveValue(setter, getter.invoke(defaults)); + if (valueToSet == null) { + unbuildable.add(setter.getName() + "(" + setter.getParameterTypes()[0].getSimpleName() + ")"); + continue; + } + setter.invoke(written, valueToSet); + getterBySetter.put(setter, getter); + + if (sameValue(getter.invoke(defaults), getter.invoke(written))) { + unchangedByValue.add(setter.getName() + " still reads " + describe(getter.invoke(written))); + } + } + + assertEquals(List.of(), withoutGetter, + "Setters without a matching getter (add them to ALIAS_SETTERS with a reason)"); + assertEquals(List.of(), unbuildable, + "Setters whose parameter type this test cannot construct"); + assertEquals(List.of(), unchangedByValue, + "Setters whose distinctive value equals the default (the round trip could not " + + "detect a loss for them)"); + + assertTrue(written.writePreferencesToXmlFile(), "writing " + preferencesFile + " failed"); + + ChatPreferences restored = new ChatPreferences(preferencesFile); + assertTrue(restored.readPreferencesFromXmlFile(), "reading " + preferencesFile + " failed"); + + List lost = new ArrayList<>(); + for (Map.Entry entry : getterBySetter.entrySet()) { + Method getter = entry.getValue(); + Object expected = getter.invoke(written); + Object actual = getter.invoke(restored); + if (!sameValue(expected, actual)) { + lost.add(entry.getKey().getName() + ": written=" + describe(expected) + + " restored=" + describe(actual)); + } + } + + assertEquals(List.of(), lost, + "Fields that did not survive writePreferencesToXmlFile -> readPreferencesFromXmlFile"); + } + + @Test + void bundledTemplatePreferencesLoadWithKnownValues() throws IOException { + Path templateCopy = temporaryDirectory.resolve("template.xml"); + try (InputStream template = ChatPreferences.class + .getResourceAsStream(ChatPreferences.PREFERENCE_RESOURCE)) { + assertNotNull(template, "bundled resource " + ChatPreferences.PREFERENCE_RESOURCE); + Files.copy(template, templateCopy, StandardCopyOption.REPLACE_EXISTING); + } + + ChatPreferences fromTemplate = new ChatPreferences(templateCopy); + assertTrue(fromTemplate.readPreferencesFromXmlFile()); + + // Values the seeded template carries today; the station block uses the legacy tag names. + assertEquals("DO5AMF", fromTemplate.getStn_loginCallSign()); + assertEquals("JO54ME", fromTemplate.getStn_loginLocatorMainCat()); + assertEquals(2, fromTemplate.getLoginChatCategoryMain().getCategoryNumber()); + assertEquals(3, fromTemplate.getLoginChatCategorySecond().getCategoryNumber()); + assertTrue(fromTemplate.isLoginToSecondChatEnabled()); + assertEquals(1333.0, fromTemplate.getStn_maxQRBDefault()); + assertEquals(12060, fromTemplate.getLogsynch_ucxUDPWkdCallListenerPort()); + assertEquals(8000, fromTemplate.getNotify_dxclusterServerPort()); + assertEquals(9872, fromTemplate.getAirScout_asCommunicationPort()); + assertTrue(fromTemplate.getLst_txtShortCutBtnList().snapshot().contains("sked")); + assertTrue(fromTemplate.isStn_bandActive144()); + assertFalse(fromTemplate.isStn_bandActive10G()); + } + + @Test + void legacyFileWithoutConfigVersionMapsOldTagNamesOntoCurrentFields() throws IOException { + Path legacyFile = temporaryDirectory.resolve("legacy.xml"); + Files.writeString(legacyFile, """ + + + + DL1ABC-2 + secret + Old Name + JO31AA + 3 + + + 8123 + + + """); + + ChatPreferences legacy = new ChatPreferences(legacyFile); + assertTrue(legacy.readPreferencesFromXmlFile()); + + assertEquals("DL1ABC-2", legacy.getStn_loginCallSign()); + assertEquals("secret", legacy.getStn_loginPassword()); + assertEquals("Old Name", legacy.getStn_loginNameMainCat()); + assertEquals("JO31AA", legacy.getStn_loginLocatorMainCat()); + assertEquals(3, legacy.getLoginChatCategoryMain().getCategoryNumber()); + assertEquals(8123, legacy.getNotify_dxclusterServerPort()); + // A tag that is missing keeps the compiled-in default. + assertEquals(new ChatPreferences(legacyFile).getStn_on4kstServersPort(), + legacy.getStn_on4kstServersPort()); + } + + // --------------------------------------------------------------------------------------- + // reflection helpers + // --------------------------------------------------------------------------------------- + + private static List settersUnderTest() { + List setters = new ArrayList<>(); + for (Method method : ChatPreferences.class.getMethods()) { + if (method.getDeclaringClass() != ChatPreferences.class + || Modifier.isStatic(method.getModifiers()) + || !method.getName().startsWith("set") + || method.getParameterCount() != 1 + || NOT_PERSISTED_SETTERS.containsKey(method.getName()) + || ALIAS_SETTERS.containsKey(method.getName())) { + continue; + } + setters.add(method); + } + setters.sort(Comparator.comparing(Method::getName)); + return setters; + } + + private static Method findGetter(Method setter) { + String property = setter.getName().substring(3); + for (String prefix : new String[] {"get", "is"}) { + try { + return ChatPreferences.class.getMethod(prefix + property); + } catch (NoSuchMethodException ignored) { + // try the next prefix + } + } + return null; + } + + /** + * Builds a value that differs from the current one. Returns null when the parameter type + * cannot be constructed here. + */ + private static Object distinctiveValue(Method setter, Object currentValue) { + Object special = SPECIAL_VALUES.get(setter.getName()); + if (special != null) { + return special; + } + + Class type = setter.getParameterTypes()[0]; + String name = setter.getName().substring(3); + Object current = unwrap(currentValue); + + if (type == boolean.class) { + return !(current instanceof Boolean b && b); + } + if (type == int.class) { + return (current instanceof Integer i ? i : 0) + 7; + } + if (type == long.class) { + return (current instanceof Long l ? l : 0L) + 7L; + } + if (type == double.class) { + return (current instanceof Double d ? d : 0.0) + 7.5; + } + if (type == String.class) { + return "rt-" + name; + } + if (type == double[].class) { + double[] base = current instanceof double[] array && array.length > 0 + ? array : new double[] {0.0, 0.0}; + double[] changed = new double[base.length]; + for (int i = 0; i < base.length; i++) { + // Window positions default to NaN ("not yet placed"); NaN + 7 is still NaN. + changed[i] = Double.isNaN(base[i]) ? 100.0 + i : base[i] + 7.0 + i; + } + return changed; + } + if (Collection.class.isAssignableFrom(type)) { + return List.of("rt-" + name + "-a", "rt-" + name + "-b"); + } + if (type == ChatCategory.class) { + int currentNumber = current instanceof Integer i ? i : 2; + return new ChatCategory(currentNumber == 5 ? 6 : 5); + } + if (type == MutableValue.class) { + return new SimpleValue<>(current instanceof Double d ? d + 7.5 : 7.5); + } + return null; + } + + /** Reduces observable wrappers and domain objects to plain comparable values. */ + private static Object unwrap(Object value) { + if (value instanceof MutableValue mutable) { + return mutable.get(); + } + if (value instanceof ObservableRoster roster) { + return roster.snapshot(); + } + if (value instanceof ChatCategory category) { + return category.getCategoryNumber(); + } + return value; + } + + private static boolean sameValue(Object left, Object right) { + Object a = unwrap(left); + Object b = unwrap(right); + if (a instanceof double[] x && b instanceof double[] y) { + return Arrays.equals(x, y); + } + if (a instanceof Double x && b instanceof Double y) { + return Math.abs(x - y) < 1e-9; + } + return Objects.equals(a, b); + } + + private static String describe(Object value) { + Object plain = unwrap(value); + if (plain instanceof double[] array) { + return Arrays.toString(array); + } + return String.valueOf(plain); + } +} diff --git a/core/src/test/java/kst4contest/model/ChatPreferencesSnifferListTest.java b/core/src/test/java/kst4contest/model/ChatPreferencesSnifferListTest.java new file mode 100644 index 00000000..64dd66a1 --- /dev/null +++ b/core/src/test/java/kst4contest/model/ChatPreferencesSnifferListTest.java @@ -0,0 +1,47 @@ +package kst4contest.model; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Guards the QSO sniffer callsign list against the historical {@code } block. + * Older preference files still carry that element; its entries must not end up in the + * monitored-callsign list (issue #103). + */ +class ChatPreferencesSnifferListTest { + + @TempDir + Path temporaryDirectory; + + @Test + void legacySnifferWordsDoNotLeakIntoTheCallsignList() throws IOException { + Path preferencesFile = temporaryDirectory.resolve("sniffer.xml"); + Files.writeString(preferencesFile, """ + + + + DL1ABC + + + DN9APW-2 + + + """); + + ChatPreferences preferences = new ChatPreferences(preferencesFile); + assertTrue(preferences.readPreferencesFromXmlFile()); + + assertEquals(List.of("DN9APW"), + preferences.getLstNotify_QSOSniffer_sniffedCallSignList().snapshot(), + "only the entry, normalised to its base callsign, " + + "may be monitored; is an ignored legacy element"); + } +} diff --git a/app-desktop/src/main/java/kst4contest/test/ChatPreferencesStationMapVisibilityTest.java b/core/src/test/java/kst4contest/test/ChatPreferencesStationMapVisibilityTest.java similarity index 100% rename from app-desktop/src/main/java/kst4contest/test/ChatPreferencesStationMapVisibilityTest.java rename to core/src/test/java/kst4contest/test/ChatPreferencesStationMapVisibilityTest.java diff --git a/app-desktop/src/main/java/kst4contest/test/FrequencyTextParserTest.java b/core/src/test/java/kst4contest/test/FrequencyTextParserTest.java similarity index 100% rename from app-desktop/src/main/java/kst4contest/test/FrequencyTextParserTest.java rename to core/src/test/java/kst4contest/test/FrequencyTextParserTest.java diff --git a/core/src/test/java/kst4contest/test/TestApplicationFileUtils.java b/core/src/test/java/kst4contest/test/TestApplicationFileUtils.java deleted file mode 100644 index c3e8359e..00000000 --- a/core/src/test/java/kst4contest/test/TestApplicationFileUtils.java +++ /dev/null @@ -1,15 +0,0 @@ -package kst4contest.test; - -import kst4contest.ApplicationConstants; -import kst4contest.utils.ApplicationFileUtils; - -public class TestApplicationFileUtils { - public static final String DATABASE_FILE = "praktiKST.db"; - private static final String DB_PATH = ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, DATABASE_FILE); - - public static void main(String[] args) { - - System.out.println("DB Path = " + DB_PATH); - } - -} diff --git a/core/src/test/java/kst4contest/test/TestChatPreferences.java b/core/src/test/java/kst4contest/test/TestChatPreferences.java deleted file mode 100644 index fe0ae343..00000000 --- a/core/src/test/java/kst4contest/test/TestChatPreferences.java +++ /dev/null @@ -1,18 +0,0 @@ -package kst4contest.test; - -import kst4contest.model.ChatPreferences; -import org.junit.jupiter.api.Test; - -public class TestChatPreferences { - - @Test - public static void main(String[] args) { - - ChatPreferences prefs = new ChatPreferences(); - prefs.readPreferencesFromXmlFile(); //works - - prefs.writePreferencesToXmlFile(); //works - - } - -} diff --git a/core/src/test/java/kst4contest/test/TestDBController.java b/core/src/test/java/kst4contest/test/TestDBController.java deleted file mode 100644 index 91fe4151..00000000 --- a/core/src/test/java/kst4contest/test/TestDBController.java +++ /dev/null @@ -1,33 +0,0 @@ -package kst4contest.test; - -import kst4contest.ApplicationConstants; -import kst4contest.controller.DBController; -import kst4contest.controller.Utils4KST; -import kst4contest.model.ChatMember; -import kst4contest.utils.ApplicationFileUtils; - -public class TestDBController { - - public static final String DATABASE_FILE = "praktiKST.db"; - private static final String DB_PATH = ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, DATABASE_FILE); - - - public static void main(String[] args) { - - - DBController dbc = DBController.getInstance(); -// dbc.initDBConnection(); - - ChatMember dummy = new ChatMember(); - dummy.setCallSign("DM5M"); - dummy.setQra("jo51ij"); - dummy.setName("Team Test"); - dummy.setLastActivity(new Utils4KST().time_generateActualTimeInDateFormat()); - dummy.setWorked5600(true); -// dummy.setWorked432(true); - - dbc.fetchChatMemberWkdDataForOnlyOneCallsignFromDB(dummy); - - - } -} diff --git a/core/src/test/java/kst4contest/test/TestLocatorUtils.java b/core/src/test/java/kst4contest/test/TestLocatorUtils.java deleted file mode 100644 index f78dbec5..00000000 --- a/core/src/test/java/kst4contest/test/TestLocatorUtils.java +++ /dev/null @@ -1,41 +0,0 @@ -package kst4contest.test; - -import kst4contest.locatorUtils.Angle; -import kst4contest.locatorUtils.Latitude; -import kst4contest.locatorUtils.Location; -import kst4contest.locatorUtils.Longitude; - -import java.text.DecimalFormat; - -public class TestLocatorUtils { - - public static void main(String[] args) { - Location location = new Location("JN49FL"); - Location location2 = new Location("JO51IJ"); - -// System.out.println(location.getDistanceKm(location2)); -// System.out.println(Location.getBearing(location, location2)); - - - System.out.println((new Location().getDistanceKmByTwoLocatorStrings("JN49FL", "kn02fx") + "")); -// System.out.println((new Location().getBearing()); -// int test = 888.08; -// System.out.println(test); - -// String test = new Location().getDistanceKmByTwoLocatorStrings("JN49FL", "Jo51ij") + ""; -// -// DecimalFormat df = new DecimalFormat("#.##"); -// -// System.out.println(df.format(Double.parseDouble(test))); - -// Angle angle = new Angle(); -// Latitude lat = new Latitude(); -// Longitude lon = new Longitude(); -// -// location.setLatitude(lat); -// location.setLongitude(lon); - - - - } -} diff --git a/core/src/test/java/kst4contest/test/TestReadUDPASListenerThread.java b/core/src/test/java/kst4contest/test/TestReadUDPASListenerThread.java deleted file mode 100644 index d4833966..00000000 --- a/core/src/test/java/kst4contest/test/TestReadUDPASListenerThread.java +++ /dev/null @@ -1,27 +0,0 @@ -package kst4contest.test; - -import kst4contest.controller.ReadUDPbyAirScoutMessageThread; -import org.junit.jupiter.api.Test; - -public class TestReadUDPASListenerThread { - - @Test - public static void main(String[] args) { - -// ReadUDPbyAirScoutMessageThread asUDPReader = new ReadUDPbyAirScoutMessageThread(9872, null, "AS", "KST"); -// asUDPReader.start(); - - String testThis; - -// testThis = "ASNEAREST: \"AS\" \"KST\" \"2023-04-01 21:33:42Z,DO5AMF,JN49GL,G4CLA,IO92JL,9,VLG2PT,M,190,75,14,BAW809,M,250,50,18,BEL6CM,M,143,50,12,WZZ6719,M,148,50,11,KLM1678,M,313,75,22,TRA1B,M,271,75,20,SAS4728,M,125,75,9,RYR6TL,M,90,75,6,UAE10,S,96,50,6\""; -// asUDPReader.processASUDPMessage(testThis); - - -// ucxUDPReader.processUCXUDPMessage(testThis); - - -// ucxUDPReader =new ReadUDPbyUCXMessageThread(12060); -// ucxUDPReader.processUCXUDPMessage(testThis); - } - -} diff --git a/core/src/test/java/kst4contest/test/TestReadUDPUCXListenerThread.java b/core/src/test/java/kst4contest/test/TestReadUDPUCXListenerThread.java deleted file mode 100644 index 11d270c1..00000000 --- a/core/src/test/java/kst4contest/test/TestReadUDPUCXListenerThread.java +++ /dev/null @@ -1,82 +0,0 @@ -package kst4contest.test; - -import kst4contest.controller.ReadUDPbyUCXMessageThread; -import org.junit.jupiter.api.Test; - -public class TestReadUDPUCXListenerThread { - - @Test - public static void main(String[] args) { - -// ReadUDPbyUCXMessageThread ucxUDPReader = new ReadUDPbyUCXMessageThread(12060); -// ucxUDPReader.start(); - - - String testThis; - - testThis = "\r\n" - + "\r\n" - + " UcxLog\r\n" - + " \r\n" - + " \r\n" - + " 2022-10-30 11:51:00\r\n" - + " DO5AMF\r\n" - + " 144\r\n" - + " 14400000\r\n" - + " 14400000\r\n" - + " \r\n" - + " USB\r\n" - + " DM1AO\r\n" - + " \r\n" - + " \r\n" - + " \r\n" - + " EU\r\n" - + " 59\r\n" - + " 021 JN49FK\r\n" - + " 59\r\n" - + " 001 JO50LT\r\n" - + " \r\n" - + " \r\n" - + "
\r\n" - + " \r\n" - + " \r\n" - + " \r\n" - + " \r\n" - + " \r\n" - + " 0\r\n" - + " \r\n" - + " 0\r\n" - + " \r\n" - + " \r\n" - + " \r\n" - + " \r\n" - + " 1\r\n" - + " 1\r\n" - + " \r\n" - + " 0\r\n" - + " 0\r\n" - + " True\r\n" - + " \r\n" - + " 0\r\n" - + " LAPTOP-05GRNFHI\r\n" - + " 0C73B5B3B82C4836\r\n" - + " True\r\n" - + "
"; -// ucxUDPReader.processUCXUDPMessage(testThis); - - - testThis ="\r\n" - + "\r\n" - + " UcxLog\r\n" - + " 1\r\n" - + " 2101100\r\n" - + " 2101100\r\n" - + " CW\r\n" - + " False\r\n" - + ""; - -// ucxUDPReader =new ReadUDPbyUCXMessageThread(12060); -// ucxUDPReader.processUCXUDPMessage(testThis); - } - -} diff --git a/core/src/test/java/kst4contest/test/UDPAirScoutSendMessages.java b/core/src/test/java/kst4contest/test/UDPAirScoutSendMessages.java deleted file mode 100644 index fbf4875b..00000000 --- a/core/src/test/java/kst4contest/test/UDPAirScoutSendMessages.java +++ /dev/null @@ -1,44 +0,0 @@ -package kst4contest.test; - -import org.junit.jupiter.api.Test; - -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; - -public class UDPAirScoutSendMessages { - - @Test - public static void main(String args[]) { - try { -// String host = "www.java2s.com"; -// byte[] message = "ASWATCHLIST: \"KST\" \"AS\" 1440000,DO5AMF,JN49GL,OK1MZM,JN89IW ".getBytes(); - - - - // Get the internet address of the specified host -// InetAddress address = InetAddress.getByName(host);^ -// byte[] byteAddress = "127.0.0.1".getBytes(); -// System.out.println(byteAddress.length); - String host = "255.255.255.255"; - int port = 9872; - - byte[] message = "ASSETPATH: \"KST\" \"AS\" 1440000,DO5AMF,JN49GL,OK1MZM,JN89IW ".getBytes(); - InetAddress address = InetAddress.getByName("255.255.255.255"); - - // Initialize a datagram packet with data and address - DatagramPacket packet = new DatagramPacket(message, message.length, - address, port); - - - // Create a datagram socket, send the packet through it, close it. - DatagramSocket dsocket = new DatagramSocket(); - dsocket.setBroadcast(true); - dsocket.send(packet); - dsocket.close(); - - } catch (Exception e) { - System.err.println(e); - } - } - } \ No newline at end of file diff --git a/app-desktop/src/main/java/kst4contest/test/Utils4KSTFrequencyTest.java b/core/src/test/java/kst4contest/test/Utils4KSTFrequencyTest.java similarity index 100% rename from app-desktop/src/main/java/kst4contest/test/Utils4KSTFrequencyTest.java rename to core/src/test/java/kst4contest/test/Utils4KSTFrequencyTest.java diff --git a/core/src/test/java/kst4contest/test/testTimeGeneration.java b/core/src/test/java/kst4contest/test/testTimeGeneration.java deleted file mode 100644 index cee6eb59..00000000 --- a/core/src/test/java/kst4contest/test/testTimeGeneration.java +++ /dev/null @@ -1,15 +0,0 @@ -package kst4contest.test; - -import kst4contest.controller.Utils4KST; -import org.junit.jupiter.api.Test; - -public class testTimeGeneration { - - @Test - public static void main(String[] args) { - - System.out.println(new Utils4KST().time_convertEpochToReadable("1664669836")); - - } - -} diff --git a/docs/PROJECT_CONTEXT.md b/docs/PROJECT_CONTEXT.md index 6797c5b3..badcb086 100644 --- a/docs/PROJECT_CONTEXT.md +++ b/docs/PROJECT_CONTEXT.md @@ -199,8 +199,10 @@ CR/LF framing, XML framing, ports/transports, callsign normalization and frequen - Use the repository Gradle wrapper (`.\gradlew.bat` on Windows). - The project uses Java 21, Kotlin 2.2 and Compose Multiplatform 1.8.x at this context snapshot. JavaFX has been removed; no `org.openjfx` dependency remains. -- JUnit 5/Mockito, PMD and SpotBugs are part of the verification environment. -- Build/test configuration has historically allowed some test/static-analysis failures not to fail the process exit code. Always read actual summaries/reports. +- JUnit 5/Mockito, PMD and SpotBugs are part of the verification environment. JUnit and Mockito are test-only dependencies; nothing of them reaches the shipped app image. +- Test classes live under `src/test` only. Until #62 a few JUnit classes sat under `src/main`, compiled on every build and were never executed; that is the historical reason the two modules once declared JUnit and Mockito as `implementation` dependencies. +- A test failure fails the build. Only PMD and SpotBugs run with `ignoreFailures`, so their findings do not. Still read the test-result XML under `*/build/test-results/test/` rather than inferring a pass from the exit code. +- Coverage is measured with JaCoCo as a report only: no `jacocoTestCoverageVerification`, no threshold (rationale in `docs/superpowers/specs/2026-10-11-test-coverage-design.md`). `./gradlew jacocoTestReport` writes a per-module report under `*/build/reports/jacoco/test/` (XML and HTML); `./gradlew jacocoAggregatedReport` merges `core` and `app-desktop` into `build/reports/jacoco/aggregated/jacoco.xml` and `.../aggregated/html/`. Both run the tests first when needed. `i18n-generator` still gets its per-module report but is left out of the aggregated one: it is build tooling and says nothing about the shipped application. The PR workflow prints line and branch coverage per module and aggregated into the job summary and uploads the aggregated HTML as the `coverage-report` artifact for 14 days. The nightly and tagged-release workflows run the test job first; no packaging job starts before it has passed. ## Documentation Surfaces diff --git a/docs/superpowers/specs/2026-10-11-test-coverage-design.md b/docs/superpowers/specs/2026-10-11-test-coverage-design.md new file mode 100644 index 00000000..c91b23fc --- /dev/null +++ b/docs/superpowers/specs/2026-10-11-test-coverage-design.md @@ -0,0 +1,161 @@ +# Konzept: Testabdeckung (#62) + +> Status: Konzept, freigegeben am 2026-10-11, umgesetzt im Zweig `feature/62-test-coverage`. +> Alle Zeilenanker beziehen sich auf `main` bei `4a90ae7d`. + +Issue #62 verlangt einen Blick auf die Testsuite als Ganzes: Was läuft, was sieht nur so aus, +als liefe es, und wie viel des Codes erreicht die Suite tatsächlich. Dieses Dokument hält den +vorgefundenen Stand fest, die getroffenen Entscheidungen und das, was bewusst eigenen Issues +überlassen wird. + +## Das Problem + +Vier Befunde, gemessen am Stand `4a90ae7d`. + +**Sieben JUnit-Klassen liegen unter `src/main` und werden nie ausgeführt.** Gradles +`test`-Task durchsucht nur `src/test`. Deshalb werden +`core/src/main/java/kst4contest/controller/On4KstProtocolTest.java`, +`On4KstSocketThreadTest.java`, `MessageBusManagementThreadFrequencyContextTest.java` +(vollständig auskommentiert), `core/src/main/java/kst4contest/model/ChatMemberDirectionOpportunityTest.java` +und die drei Klassen unter `app-desktop/src/main/java/kst4contest/test/` +(`Utils4KSTFrequencyTest`, `FrequencyTextParserTest`, `ChatPreferencesStationMapVisibilityTest`) +bei jedem Build kompiliert und zählen für nichts. Der Protokolltest darunter nagelt die +exakten `LOGINC|`-, `SDONE|`- und `ACHAT|`-Frames fest, der Socket-Test genau ein CR/LF je +Frame. Beides sind Invarianten, die `AGENTS.md` ausdrücklich nennt, und keine davon hat seit +der Maven-Zeit ein Build geprüft. + +**Wegen dieser Klassen wird JUnit und Mockito mit der Anwendung ausgeliefert.** `core` und +`app-desktop` deklarieren `implementation(libs.junit.jupiter.api)` und +`implementation(libs.mockito.core.compile)`. Damit liegen `junit-jupiter-api`, +`junit-platform-commons`, `opentest4j`, `mockito-core`, `byte-buddy`, `byte-buddy-agent` und +`objenesis` auf dem Laufzeit-Klassenpfad und in `lib/app` jedes App-Image, Flatpak und +Installers. `docs/CONCEPT_IN_APP_UPDATE.md` nennt das bereits als Vorbedingung für einen +signierten Update-Pfad: Ein Bytecode-Manipulations-Agent in einem signierten Produktionsbinary +ist das Falsche, was man erklären müsste. + +**Acht Dateien unter `core/src/test/java/kst4contest/test/` sind toter Scratch-Code von +2023/2024.** `TestChatPreferences`, `TestReadUDPASListenerThread`, +`TestReadUDPUCXListenerThread`, `UDPAirScoutSendMessages`, `testTimeGeneration`, +`TestApplicationFileUtils`, `TestDBController` und `TestLocatorUtils` enthalten keine einzige +Assertion. Fünf davon tragen `@Test` an einer `public static void main`, die Jupiter nie +ausführt; die anderen drei haben gar keine Annotation. Manche schreiben beim manuellen Start die +echte Preferences-Datei, senden echten UDP-Broadcast oder öffnen die echte Nutzerdatenbank. +Fünf weitere `main()`-Programme derselben Art liegen unter `src/main` +(`ReadUDPByWintestThreadTest`, `PatternMatcherTest`, `mapTest`, `RegexTester`, +`locatorUtils/TestLocatorUtils`), dazu `MockKstServer`, auf den nur noch ein ungenutzter Import +in `ChatController` verweist. + +**Es gibt keine Abdeckungszahl.** Die Suite ist durch die Compose-Migration auf mehrere hundert +Tests gewachsen, aber niemand kann sagen, welchen Teil von `core` sie erreicht. Drei Bereiche +sind bekannt dünn: der XML-Roundtrip von `ChatPreferences` jenseits der Handvoll Felder, die +Einzeltests festnageln, die Schema-Migration in `DBController`, und die Netzwerk-Threads +(`ReadThread`/`WriteThread`, die UDP-Listener), die bestenfalls je einen Loopback-Test haben. + +## Entscheidungen + +**Tote Tests löschen, nicht retten.** Ein Test ohne Assertion dokumentiert nichts, und die mit +Seiteneffekten sind eine Gefahr, sobald jemand „alle Tests“ aus der IDE startet. Ihre +Gegenstände sind entweder anderswo abgedeckt (`ChatPreferences*Test`, +`DBControllerProfileDatabaseTest`, `DirectionUtilsConsoleOutputTest`) oder werden zu den zwei +neuen Testbereichen unten. Der auskommentierte `MessageBusManagementThreadFrequencyContextTest` +wird ebenfalls gelöscht; was er abgedeckt hätte +(`MessageBusManagementThread.hasExplicitBareFrequencyContext` und `Band.fromPrefix`), ist im +Umsetzungsbericht vermerkt, damit es mit der Frequenz-Parsing-Arbeit aufgegriffen und nicht +stillschweigend verloren wird. + +**Tests liegen ausschließlich unter `src/test`.** Die sechs lebenden JUnit-Klassen wandern nach +`src/test` des Moduls, dem die getestete Klasse gehört, mit unveränderten Paketnamen, neben die +Geschwistertests, die dort schon liegen (`FrequencyTextParserRegressionTest`, +`ChatPreferencesStationMapClusteringTest`). Die drei Klassen aus `app-desktop` testen +ausschließlich `core`-Klassen und ziehen deshalb nach `core`. Ohne Testklasse unter `src/main` +entfallen die beiden `implementation`-Deklarationen und die doppelten Katalogeinträge +(`junit-jupiter-api`, `mockito-core-compile`, Version `mockitoCompile`). JUnit und Mockito sind +nur noch `testImplementation`, was die vorhandenen `testImplementation`-Zeilen ohnehin schon +sagten. Nachgewiesen über `:app-desktop:dependencies --configuration runtimeClasspath` ohne die +sieben Artefakte und über die Jar-Liste von `createDistributable`. + +**JaCoCo nur als Bericht, ohne Schwellwert.** Das `jacoco`-Plugin wird aus dem Root-Build auf +jedes Modul angewandt, `jacocoTestReport` läuft nach `test` und schreibt XML und HTML je Modul, +und ein Root-Task `jacocoAggregatedReport` führt `core` und `app-desktop` zu einem Bericht unter +`build/reports/jacoco/aggregated/` zusammen. `i18n-generator` bleibt außen vor: Es ist ein +Bauwerkzeug, seine Abdeckung sagt nichts über die ausgelieferte Anwendung. Es gibt bewusst keine +`jacocoTestCoverageVerification` und keinen Mindestprozentsatz. Ein heute gesetzter Schwellwert +stünde bei der Zahl, die zufällig gerade herauskommt, und wäre damit ein Stolperdraht für die +nächste unabhängige Änderung statt einer Aussage über Qualität; ein Schwellwert auf Zielniveau +ließe jeden Build scheitern, bis jemand Tests um der Zahl willen schreibt. Der Bericht existiert, +damit die Zahl in jedem Pull Request sichtbar ist und bei der Entscheidung hilft, was als +Nächstes zu testen ist. Sie zu heben ist Sache der unten gelisteten Issues, nicht der +Build-Konfiguration. + +**Tests laufen vor dem Packaging.** Der Nightly- und der Release-Workflow bauen sieben +Paketformate aus einem Commit, den unterwegs niemand getestet hat: `pr-compile-check.yml` führt +die Suite nur für Pull Requests aus, und `main` kann direkte Pushes erhalten. Beide Workflows +bekommen eine Kopie des `test`-Jobs aus `pr-compile-check.yml`, einschließlich des +`libgl1`-Schritts und der XML-basierten Zusammenfassung, und jeder Packaging-Job deklariert +`needs: test`. Der Job wird dupliziert statt in einen wiederverwendbaren Workflow ausgelagert: +Drei Kopien von vierzig Zeilen lesen sich leichter als eine Indirektion, und die Kommentare im +Job erklären Entscheidungen, die die Packaging-Workflows bei sich tragen sollen. Der +PR-Workflow führt zusätzlich `jacocoAggregatedReport` aus, schreibt aus dem JaCoCo-XML eine +Abdeckungstabelle in die Job-Zusammenfassung und lädt den aggregierten HTML-Bericht für +vierzehn Tage als Artefakt `coverage-report` hoch. + +**Zwei neue Testbereiche entstehen im selben Zweig, aber in eigenen Commits.** Issue #62 nennt +den `ChatPreferences`-Roundtrip und die `DBController`-Schema-Migration als die zwei +ungetesteten Risikobereiche, die sich jetzt schließen lassen. Es sind gewöhnliche +Testergänzungen, die vom Aufräumen nicht abhängen; sie landen nach dem Aufräumen, damit ihre +Wirkung im aggregierten Bericht sichtbar wird. + +## Bewusst außerhalb des Umfangs + +Jeder dieser Punkte ist eine echte Lücke, die unterwegs gefunden wurde, und jeder wird ein +eigenes Issue, weil jeder eine Entscheidung braucht, die dieses Aufräumen nicht nebenbei +treffen sollte: + +- **Refactoring von `MessageBusManagementThread` für Testbarkeit.** Frequenzextraktion, + Worked-Prüfung und der DX-Cluster-Spot-Pfad sind heute nur über einen konstruierten Thread + mit gemockten Mitspielern erreichbar. Sie in testbare Einheiten zu teilen berührt die + Nachrichten-Pipeline und braucht ein eigenes Konzept. +- **Loopback-Tests für die Netzwerk-Threads.** `On4KstSocketThreadTest` deckt `ReadThread` + und `WriteThread` ab; die UDP-Listener für Win-Test, UCXLog und AirScout und der + PSTRotator-Client haben kein Gegenstück. Ein Loopback-Harness mit Port-0-Socket je Protokoll + ist die richtige Form, aber das Framing jedes Protokolls verdient eine Prüfung, bevor ein Test + es festnagelt. +- **Compose-Screen-Tests.** Die State-Tests und die zwei Settings-Abdeckungsnetze prüfen, dass + Setter aufgerufen werden; nur `runComposeUiTest` kann prüfen, dass ein Wert den Bildschirm + erreicht hat. Welche Screens diesen Aufwand wert sind, ist eine Oberflächenentscheidung. +- **Pfadanalyse-Mathematik.** `PathPropagationAssessment` und die Terrainprofil-Berechnung + haben Layout-Tests, aber keine numerischen Referenzfälle. Referenzwerte brauchen eine Quelle, + die sich zitieren lässt. +- **Entfernen von `Thread.sleep`.** Mehrere Tests und einige Produktionspfade warten noch auf + die Wanduhr. Sie durch injizierbare Uhren oder Latches zu ersetzen ist mechanisch, aber breit. + +## Definition von „fertig“ für #62 + +- Unter keinem `src/main` bleibt eine mit `@Test` annotierte Klasse oder ein Import von + `org.junit` oder `org.mockito`. +- `./gradlew clean build` führt die verschobenen Tests aus; die Ergebnis-XML unter + `*/build/test-results/test/` meldet null Fehlschläge und null Fehler. +- `./gradlew :app-desktop:dependencies --configuration runtimeClasspath` listet keines von + `junit`, `mockito`, `byte-buddy`, `objenesis`, `opentest4j`, und + `app-desktop/build/compose/binaries/main/app/KST4Contest/lib/app` enthält kein Jar dieser + Namen. +- `./gradlew jacocoAggregatedReport` schreibt `build/reports/jacoco/aggregated/jacoco.xml` und + einen HTML-Bericht; die PR-Job-Zusammenfassung zeigt eine Abdeckungstabelle und bietet das + Artefakt `coverage-report` an. +- `nightly-artifacts.yml` und `tagged-release.yml` führen den Test-Job aus, und kein + Packaging-Job startet, bevor er bestanden ist. +- `AGENTS.md` und `docs/PROJECT_CONTEXT.md` behaupten nicht mehr, Testfehler könnten den Build + passieren; sie sagen, dass nur PMD und SpotBugs mit `ignoreFailures` laufen. +- Die zwei neuen Testbereiche (`ChatPreferences`-Roundtrip, `DBController`-Schema-Migration) + liegen im Zweig, und die Punkte außerhalb des Umfangs existieren als Issues. + +## Was unverändert bleibt + +- Testverhalten: Keine Assertion wird abgeschwächt und kein Test deaktiviert, damit der Umzug + kompiliert. +- Der Produktionscode, bis auf den entfernten `MockKstServer`-Import in `ChatController`. +- PMD und SpotBugs behalten `ignoreFailures`; ihre Befunde werden wie bisher aus den Berichten + gelesen. +- Die Packaging-Jobs selbst: Es kommt nur `needs: test` hinzu. +- Keine neue Laufzeitabhängigkeit. JaCoCo ist ein Gradle-Plugin, das die Test-JVM + instrumentiert; nichts davon erreicht das Jar. diff --git a/github_docs/de-Changelog.md b/github_docs/de-Changelog.md index 7da6d190..e81bab65 100644 --- a/github_docs/de-Changelog.md +++ b/github_docs/de-Changelog.md @@ -42,6 +42,8 @@ Mehrere Operateure an einem Rechner können jetzt eigene Rufzeichen, Locators un - **AP-Spalte sortiert numerisch:** Die Spalte **AP [minutes / pot%]** in der Benutzerliste und bei den gerichteten Nachrichten wurde nach ihrem Text sortiert, sodass `13 (75%)` vor `3 (50%)` stand. Jetzt sortiert sie nach den Minuten des ersten Flugzeugs und bei gleichen Minuten nach dem besseren Potenzial; leere und `nil`-Zellen stehen aufsteigend am Ende. Damit ist [Issue #87](https://github.com/praktimarc/kst4contest/issues/87) behoben. - **Keine automatischen Cluster-Spots für gearbeitete Stationen:** Der lokale DX-Cluster-Server erzeugte Spots aus Richtungsgelegenheiten, ohne den Worked-Status zu prüfen. Jetzt wird kein Spot mehr erzeugt, wenn die Station auf dem Band der erkannten Frequenz bereits gearbeitet ist; ohne bandbezogene Information zählt der allgemeine Worked-Status. Manuelle Spots aus der Karte und der Test-Spot in den Einstellungen bleiben unverändert. Damit ist [Issue #91](https://github.com/praktimarc/kst4contest/issues/91) behoben. +- **QSO-Monitoring übernimmt keine Fremdeinträge mehr:** Die `preferences.xml` enthielt neben der Liste der überwachten Rufzeichen eine zweite Liste `snifferWords`, die nirgends in der Oberfläche erschien. Beim Laden wurden ihre Einträge trotzdem als Rufzeichen in das QSO-Monitoring übernommen. Die tote Liste ist entfernt; ein vorhandenes `snifferWords`-Element in alten Dateien wird ignoriert. Damit ist [Issue #103](https://github.com/praktimarc/kst4contest/issues/103) behoben. +- **Kein Locator für die zweite Kategorie mehr:** Intern gab es eine Einstellung für einen eigenen Locator der zweiten Chat-Kategorie, die weder in der Oberfläche noch in der `preferences.xml` erschien und deshalb immer auf ihrem eingebauten Standardwert stand. Beim Verbindungsaufbau wurde dieser Standardwert mit dem eigenen Locator verglichen und eine Warnung ausgegeben, dass der zweite Locator ignoriert werde. ON4KST verwendet ohnehin einen Locator pro TCP-Sitzung; die Einstellung und die Warnung sind entfernt. Damit ist [Issue #104](https://github.com/praktimarc/kst4contest/issues/104) behoben. ### Hinweise zur Aktualisierung diff --git a/github_docs/en-Changelog.md b/github_docs/en-Changelog.md index c0a25368..c736bbbc 100644 --- a/github_docs/en-Changelog.md +++ b/github_docs/en-Changelog.md @@ -42,6 +42,8 @@ Several operators sharing one computer can now use their own callsigns, locators - **AP column sorts numerically:** the **AP [minutes / pot%]** column in the user list and in the directed messages was sorted by its text, which put `13 (75%)` above `3 (50%)`. It now sorts by the minutes of the first aeroplane and, for equal minutes, by the better potential first; empty and `nil` cells go to the bottom in ascending order. This fixes [Issue #87](https://github.com/praktimarc/kst4contest/issues/87). - **No automatic cluster spots for worked stations:** the local DX Cluster server generated spots from directional opportunities without checking the worked state. A spot is no longer created when the station has already been worked on the band of the detected frequency; without per-band information the global worked state counts. Manual spots from the map and the test spot in the settings are unchanged. This fixes [Issue #91](https://github.com/praktimarc/kst4contest/issues/91). +- **QSO monitoring no longer picks up foreign entries:** besides the list of monitored callsigns, `preferences.xml` carried a second list `snifferWords` that never appeared in the user interface. On loading, its entries were nevertheless added to QSO monitoring as callsigns. The dead list is removed; a `snifferWords` element in older files is ignored. This fixes [Issue #103](https://github.com/praktimarc/kst4contest/issues/103). +- **No second-category locator any more:** internally there was a setting for a separate locator of the second chat category that appeared neither in the user interface nor in `preferences.xml`, so it always kept its compiled-in default. During login that default was compared with the station's locator and a warning was emitted that the second locator is ignored. ON4KST uses one locator per TCP session anyway; the setting and the warning are removed. This fixes [Issue #104](https://github.com/praktimarc/kst4contest/issues/104). ### Upgrade notes diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index af3533c4..c5316312 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,20 +3,18 @@ sqliteJdbc = "3.53.4.0" jlayer = "1.0.1" junit = "6.1.3" mockito = "5.24.0" -mockitoCompile = "5.24.0" jetbrainsAnnotations = "26.1.0" kotlin = "2.2.0" composeMultiplatform = "1.8.2" spotbugsPlugin = "6.5.12" spotbugs = "4.9.8" pmd = "7.17.0" +jacoco = "0.8.13" [libraries] sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqliteJdbc" } jlayer = { module = "javazoom:jlayer", version.ref = "jlayer" } junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" } -junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } -mockito-core-compile = { module = "org.mockito:mockito-core", version.ref = "mockitoCompile" } jetbrains-annotations = { module = "org.jetbrains:annotations", version.ref = "jetbrainsAnnotations" } mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" } mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version.ref = "mockito" } diff --git a/hs_err_pid26344.log b/hs_err_pid26344.log deleted file mode 100644 index 10c81b29..00000000 --- a/hs_err_pid26344.log +++ /dev/null @@ -1,1013 +0,0 @@ -# -# A fatal error has been detected by the Java Runtime Environment: -# -# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007fff972d146c, pid=26344, tid=27012 -# -# JRE version: OpenJDK Runtime Environment (21.0.1+12) (build 21.0.1+12-29) -# Java VM: OpenJDK 64-Bit Server VM (21.0.1+12-29, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64) -# Problematic frame: -# C [VCRUNTIME140.dll+0x146c] -# -# No core dump will be written. Minidumps are not enabled by default on client versions of Windows -# -# If you would like to submit a bug report, please visit: -# https://bugreport.java.com/bugreport/crash.jsp -# - ---------------- S U M M A R Y ------------ - -Command Line: -javaagent:C:\Users\prakt\AppData\Local\Programs\IntelliJ IDEA Community Edition\lib\idea_rt.jar=50765 -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 --module-path=C:\Users\prakt\.m2\repository\org\openjfx\javafx-controls\21.0.5\javafx-controls-21.0.5-win.jar;C:\Users\prakt\.m2\repository\org\junit\jupiter\junit-jupiter-api\5.10.1\junit-jupiter-api-5.10.1.jar;C:\Users\prakt\.m2\repository\javazoom\jlayer\1.0.1\jlayer-1.0.1.jar;C:\Users\prakt\.m2\repository\org\apiguardian\apiguardian-api\1.1.2\apiguardian-api-1.1.2.jar;C:\Users\prakt\.m2\repository\org\openjfx\javafx-web\21.0.5\javafx-web-21.0.5-win.jar;C:\Users\prakt\IdeaProjects\kst4contest\target\classes;C:\Users\prakt\.m2\repository\org\openjfx\javafx-fxml\21.0.5\javafx-fxml-21.0.5-win.jar;C:\Users\prakt\.m2\repository\org\xerial\sqlite-jdbc\3.43.2.2\sqlite-jdbc-3.43.2.2.jar;C:\Users\prakt\.m2\repository\org\mockito\mockito-core\5.17.0\mockito-core-5.17.0.jar;C:\Users\prakt\.m2\repository\org\openjfx\javafx-media\21.0.5\javafx-media-21.0.5-win.jar;C:\Users\prakt\.m2\repository\net\bytebuddy\byte-buddy\1.15.11\byte-buddy-1.15.11.jar;C:\Users\prakt\.m2\repository\org\openjfx\javafx-base\21.0.5\javafx-base-21.0.5-win.jar;C:\Users\prakt\.m2\repository\net\bytebuddy\byte-buddy-agent\1.15.11\byte-buddy-agent-1.15.11.jar;C:\Users\prakt\.m2\repository\org\openjfx\javafx-graphics\21.0.5\javafx-graphics-21.0.5-win.jar;C:\Users\prakt\.m2\repository\org\opentest4j\opentest4j\1.3.0\opentest4j-1.3.0.jar;C:\Users\prakt\.m2\repository\org\slf4j\slf4j-api\1.7.36\slf4j-api-1.7.36.jar;C:\Users\prakt\.m2\repository\org\objenesis\objenesis\3.3\objenesis-3.3.jar;C:\Users\prakt\.m2\repository\org\junit\platform\junit-platform-commons\1.10.1\junit-platform-commons-1.10.1.jar -Djdk.module.main=praktiKST praktiKST/kst4contest.view.Kst4ContestApplication - -Host: 12th Gen Intel(R) Core(TM) i7-12700H, 20 cores, 15G, Windows 11 , 64 bit Build 26100 (10.0.26100.8875) -Time: Tue Aug 11 22:44:01 2026 Mitteleuropäische Sommerzeit elapsed time: 10119.199488 seconds (0d 2h 48m 39s) - ---------------- T H R E A D --------------- - -Current thread (0x000001a27c770090): JavaThread "pool-4-thread-1" [_thread_in_vm, id=27012, stack(0x0000004d90c00000,0x0000004d90d00000) (1024K)] - -Stack: [0x0000004d90c00000,0x0000004d90d00000], sp=0x0000004d90cffc38, free space=1023k -Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) -C [VCRUNTIME140.dll+0x146c] -V [jvm.dll+0x801d7b] -V [jvm.dll+0x8080a6] -V [jvm.dll+0x3ecd9e] -V [jvm.dll+0x3edfd3] -V [jvm.dll+0x6c777d] -C [ucrtbase.dll+0x2cd30] -C [KERNEL32.DLL+0x2e957] -C [ntdll.dll+0xaad6c] - - -siginfo: EXCEPTION_ACCESS_VIOLATION (0xc0000005), reading address 0xffffffffffffffff - - -Registers: -RAX=0x000001a208c60480, RBX=0x000001a27c770090, RCX=0x000001a208c60480, RDX=0x8d34440affff0000 -RSP=0x0000004d90cffc38, RBP=0x0000000000000000, RSI=0x000001a27bf36a50, RDI=0x000001a209d25830 -R8 =0x00000007fffffff8, R9 =0x000001a208c60480, R10=0x00007fff972d0000, R11=0x0000004d90cffc00 -R12=0x0000000000000000, R13=0x0000000000000000, R14=0x00000000ffffffff, R15=0x0000000000000000 -RIP=0x00007fff972d146c, EFLAGS=0x0000000000010202 - - -Register to memory mapping: - -RAX=0x000001a208c60480 points into unknown readable memory: 0x16629080eb1c164b | 4b 16 1c eb 80 90 62 16 -RBX=0x000001a27c770090 points into unknown readable memory: 0x00007fff304e3b78 | 78 3b 4e 30 ff 7f 00 00 -RCX=0x000001a208c60480 points into unknown readable memory: 0x16629080eb1c164b | 4b 16 1c eb 80 90 62 16 -RDX=0x8d34440affff0000 is an unknown value -RSP=0x0000004d90cffc38 points into unknown readable memory: 0x00007fff30301d7b | 7b 1d 30 30 ff 7f 00 00 -RBP=0x0 is null -RSI=0x000001a27bf36a50 points into unknown readable memory: 0x8d34440affff0000 | 00 00 ff ff 0a 44 34 8d -RDI=0x000001a209d25830 points into unknown readable memory: 0xffffffff544c5354 | 54 53 4c 54 ff ff ff ff -R8 = -[error occurred during error reporting (printing register info), id 0xc0000005, EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007fff2fc3e1f1] -R9 =0x000001a208c60480 points into unknown readable memory: 0x16629080eb1c164b | 4b 16 1c eb 80 90 62 16 -R10=0x00007fff972d0000 VCRUNTIME140.dll -R11=0x0000004d90cffc00 points into unknown readable memory: 0xffffffffffffffff | ff ff ff ff ff ff ff ff -R12=0x0 is null -R13=0x0 is null -R14=0x00000000ffffffff is an unknown value -R15=0x0 is null - -Top of Stack: (sp=0x0000004d90cffc38) -0x0000004d90cffc38: 00007fff30301d7b 00000000ffffffff -0x0000004d90cffc48: 000001a27bf36a50 00007fff3073a5f8 -0x0000004d90cffc58: 0000000000000000 00007fff3073a5f8 -0x0000004d90cffc68: 00007fff303080a6 000001a27c770090 -0x0000004d90cffc78: 0000004d90cffda0 0000000000000000 -0x0000004d90cffc88: 000001a27c770090 00007fff304e3e20 -0x0000004d90cffc98: 00007fff2feecd9e 00007fff304e3e18 -0x0000004d90cffca8: 00000007ffa55b98 00000007ffa55b98 -0x0000004d90cffcb8: 00000007ffa55b98 000001a236486678 -0x0000004d90cffcc8: 000001a27c770090 000001a27bf38450 -0x0000004d90cffcd8: 000001a27bf38450 000001a236486678 -0x0000004d90cffce8: 000001a27c770090 000001a20000000e -0x0000004d90cffcf8: 000001a23603d3f8 000001a27c770090 -0x0000004d90cffd08: 0000000000000000 000001a20516d4a0 -0x0000004d90cffd18: 000001a20516d400 0000000000000000 -0x0000004d90cffd28: 00000000000000d8 0000004d90cffd00 -0x0000004d90cffd38: 0000000000000000 000001a27c770090 -0x0000004d90cffd48: 00007fff2feef100 0000000000000000 -0x0000004d90cffd58: 000001a27c770090 000001a27c49de00 -0x0000004d90cffd68: 0000000000000000 000001a27c770090 -0x0000004d90cffd78: 00007fff0000000e 000001a200000000 -0x0000004d90cffd88: 000001a27c770090 000001a20516d4b8 -0x0000004d90cffd98: 0000000000000009 000001a27c770090 -0x0000004d90cffda8: 000001a20434e030 000001a20516d4a0 -0x0000004d90cffdb8: 000001a20516d4b0 000001a20516d588 -0x0000004d90cffdc8: 00000000000000d8 000001a20434de30 -0x0000004d90cffdd8: 00007fff302fd728 0000000000000000 -0x0000004d90cffde8: 0000000000000000 0000000000000000 -0x0000004d90cffdf8: 0000000000000000 0000000000000000 -0x0000004d90cffe08: 0000000000000000 0000000000004e93 -0x0000004d90cffe18: 000001a27c770090 0000000000000000 -0x0000004d90cffe28: 00007fff2feedfd3 000001a27c770090 - -Instructions: (pc=0x00007fff972d146c) -0x00007fff972d136c: 89 08 66 44 89 40 04 44 88 48 06 c3 4c 8b 02 8b -0x00007fff972d137c: 4a 08 44 0f b7 4a 0c 4c 89 00 89 48 08 66 44 89 -0x00007fff972d138c: 48 0c c3 0f b7 0a 44 0f b6 42 02 66 89 08 44 88 -0x00007fff972d139c: 40 02 c3 90 4c 8b 02 8b 4a 08 44 0f b6 4a 0c 4c -0x00007fff972d13ac: 89 00 89 48 08 44 88 48 0c c3 4c 8b 02 0f b7 4a -0x00007fff972d13bc: 08 4c 89 00 66 89 48 08 c3 4c 8b 02 0f b6 4a 08 -0x00007fff972d13cc: 4c 89 00 88 48 08 c3 4c 8b 02 8b 4a 08 4c 89 00 -0x00007fff972d13dc: 89 48 08 c3 8b 0a 44 0f b7 42 04 89 08 66 44 89 -0x00007fff972d13ec: 40 04 c3 8b 0a 44 0f b6 42 04 89 08 44 88 40 04 -0x00007fff972d13fc: c3 48 8b 0a 48 89 08 c3 0f b6 0a 88 08 c3 8b 0a -0x00007fff972d140c: 89 08 c3 90 49 83 f8 20 77 17 f3 0f 6f 0a f3 42 -0x00007fff972d141c: 0f 6f 54 02 f0 f3 0f 7f 09 f3 42 0f 7f 54 01 f0 -0x00007fff972d142c: c3 48 3b d1 73 0e 4e 8d 0c 02 49 3b c9 0f 82 41 -0x00007fff972d143c: 04 00 00 90 83 3d d1 4b 01 00 03 0f 82 e3 02 00 -0x00007fff972d144c: 00 49 81 f8 00 20 00 00 76 16 49 81 f8 00 00 18 -0x00007fff972d145c: 00 77 0d f6 05 56 4f 01 00 02 0f 85 64 fe ff ff -0x00007fff972d146c: c5 fe 6f 02 c4 a1 7e 6f 6c 02 e0 49 81 f8 00 01 -0x00007fff972d147c: 00 00 0f 86 c4 00 00 00 4c 8b c9 49 83 e1 1f 49 -0x00007fff972d148c: 83 e9 20 49 2b c9 49 2b d1 4d 03 c1 49 81 f8 00 -0x00007fff972d149c: 01 00 00 0f 86 a3 00 00 00 49 81 f8 00 00 18 00 -0x00007fff972d14ac: 0f 87 3e 01 00 00 66 66 66 66 66 66 0f 1f 84 00 -0x00007fff972d14bc: 00 00 00 00 c5 fe 6f 0a c5 fe 6f 52 20 c5 fe 6f -0x00007fff972d14cc: 5a 40 c5 fe 6f 62 60 c5 fd 7f 09 c5 fd 7f 51 20 -0x00007fff972d14dc: c5 fd 7f 59 40 c5 fd 7f 61 60 c5 fe 6f 8a 80 00 -0x00007fff972d14ec: 00 00 c5 fe 6f 92 a0 00 00 00 c5 fe 6f 9a c0 00 -0x00007fff972d14fc: 00 00 c5 fe 6f a2 e0 00 00 00 c5 fd 7f 89 80 00 -0x00007fff972d150c: 00 00 c5 fd 7f 91 a0 00 00 00 c5 fd 7f 99 c0 00 -0x00007fff972d151c: 00 00 c5 fd 7f a1 e0 00 00 00 48 81 c1 00 01 00 -0x00007fff972d152c: 00 48 81 c2 00 01 00 00 49 81 e8 00 01 00 00 49 -0x00007fff972d153c: 81 f8 00 01 00 00 0f 83 78 ff ff ff 4d 8d 48 1f -0x00007fff972d154c: 49 83 e1 e0 4d 8b d9 49 c1 eb 05 47 8b 9c 9a 40 -0x00007fff972d155c: 80 01 00 4d 03 da 41 ff e3 c4 a1 7e 6f 8c 0a 00 - - -Stack slot to memory mapping: - -stack at sp + 0 slots: 0x00007fff30301d7b jvm.dll -stack at sp + 1 slots: 0x00000000ffffffff is an unknown value -stack at sp + 2 slots: 0x000001a27bf36a50 points into unknown readable memory: 0x8d34440affff0000 | 00 00 ff ff 0a 44 34 8d -stack at sp + 3 slots: 0x00007fff3073a5f8 jvm.dll -stack at sp + 4 slots: 0x0 is null -stack at sp + 5 slots: 0x00007fff3073a5f8 jvm.dll -stack at sp + 6 slots: 0x00007fff303080a6 jvm.dll -stack at sp + 7 slots: 0x000001a27c770090 points into unknown readable memory: 0x00007fff304e3b78 | 78 3b 4e 30 ff 7f 00 00 - - ---------------- P R O C E S S --------------- - -Threads class SMR info: -_java_thread_list=0x000001a27bf36a40, length=0, elements={ - -[error occurred during error reporting (printing all threads), id 0xc0000005, EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007fff30301512] -VM state: not at safepoint (normal execution) - -VM Mutex/Monitor currently owned by a thread: ([mutex/lock_event]) -[0x00007fff3073a5f8] Threads_lock - owner thread: 0x000001a27c770090 - -Heap address: 0x0000000704400000, size: 4028 MB, Compressed Oops mode: Zero based, Oop shift amount: 3 - -CDS archive(s) mapped at: [0x000001a236000000-0x000001a236c90000-0x000001a236c90000), size 13172736, SharedBaseAddress: 0x000001a236000000, ArchiveRelocationMode: 1. -Compressed class space mapped at: 0x000001a237000000-0x000001a277000000, reserved size: 1073741824 -Narrow klass base: 0x000001a236000000, Narrow klass shift: 0, Narrow klass range: 0x100000000 - -GC Precious Log: - CardTable entry size: 512 - Card Set container configuration: InlinePtr #cards 4 size 8 Array Of Cards #cards 16 size 48 Howl #buckets 8 coarsen threshold 3686 Howl Bitmap #cards 512 size 80 coarsen threshold 460 Card regions per heap region 1 cards per card region 4096 - CPUs: 20 total, 20 available - Memory: 16108M - Large Page Support: Disabled - NUMA Support: Disabled - Compressed Oops: Enabled (Zero based) - Heap Region Size: 2M - Heap Min Capacity: 8M - Heap Initial Capacity: 252M - Heap Max Capacity: 4028M - Pre-touch: Disabled - Parallel Workers: 15 - Concurrent Workers: 4 - Concurrent Refinement Workers: 15 - Periodic GC: Disabled - -Heap: - garbage-first heap total 372736K, used 239863K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 41 young (83968K), 7 survivors (14336K) - Metaspace used 51555K, committed 52416K, reserved 1114112K - class space used 6426K, committed 6848K, reserved 1048576K - -Heap Regions: E=young(eden), S=young(survivor), O=old, HS=humongous(starts), HC=humongous(continues), CS=collection set, F=free, TAMS=top-at-mark-start, PB=parsable bottom -| 0|0x0000000704400000, 0x0000000704600000, 0x0000000704600000|100%| O| |TAMS 0x0000000704400000| PB 0x0000000704400000| Untracked -| 1|0x0000000704600000, 0x0000000704800000, 0x0000000704800000|100%| O| |TAMS 0x0000000704600000| PB 0x0000000704600000| Untracked -| 2|0x0000000704800000, 0x0000000704a00000, 0x0000000704a00000|100%| O| |TAMS 0x0000000704800000| PB 0x0000000704800000| Untracked -| 3|0x0000000704a00000, 0x0000000704c00000, 0x0000000704c00000|100%| O| |TAMS 0x0000000704a00000| PB 0x0000000704a00000| Untracked -| 4|0x0000000704c00000, 0x0000000704e00000, 0x0000000704e00000|100%| O| |TAMS 0x0000000704c00000| PB 0x0000000704c00000| Untracked -| 5|0x0000000704e00000, 0x0000000705000000, 0x0000000705000000|100%| O| |TAMS 0x0000000704e00000| PB 0x0000000704e00000| Untracked -| 6|0x0000000705000000, 0x0000000705200000, 0x0000000705200000|100%| O| |TAMS 0x0000000705000000| PB 0x0000000705000000| Untracked -| 7|0x0000000705200000, 0x0000000705400000, 0x0000000705400000|100%| O| |TAMS 0x0000000705200000| PB 0x0000000705200000| Untracked -| 8|0x0000000705400000, 0x0000000705600000, 0x0000000705600000|100%| O| |TAMS 0x0000000705400000| PB 0x0000000705400000| Untracked -| 9|0x0000000705600000, 0x0000000705800000, 0x0000000705800000|100%| O| |TAMS 0x0000000705600000| PB 0x0000000705600000| Untracked -| 10|0x0000000705800000, 0x0000000705a00000, 0x0000000705a00000|100%| O| |TAMS 0x0000000705800000| PB 0x0000000705800000| Untracked -| 11|0x0000000705a00000, 0x0000000705c00000, 0x0000000705c00000|100%| O| |TAMS 0x0000000705a00000| PB 0x0000000705a00000| Untracked -| 12|0x0000000705c00000, 0x0000000705e00000, 0x0000000705e00000|100%| O| |TAMS 0x0000000705c00000| PB 0x0000000705c00000| Untracked -| 13|0x0000000705e00000, 0x0000000706000000, 0x0000000706000000|100%| O| |TAMS 0x0000000705e00000| PB 0x0000000705e00000| Untracked -| 14|0x0000000706000000, 0x0000000706200000, 0x0000000706200000|100%| O| |TAMS 0x0000000706000000| PB 0x0000000706000000| Untracked -| 15|0x0000000706200000, 0x0000000706400000, 0x0000000706400000|100%| O| |TAMS 0x0000000706200000| PB 0x0000000706200000| Untracked -| 16|0x0000000706400000, 0x0000000706600000, 0x0000000706600000|100%| O| |TAMS 0x0000000706400000| PB 0x0000000706400000| Untracked -| 17|0x0000000706600000, 0x0000000706800000, 0x0000000706800000|100%| O| |TAMS 0x0000000706600000| PB 0x0000000706600000| Untracked -| 18|0x0000000706800000, 0x0000000706a00000, 0x0000000706a00000|100%| O| |TAMS 0x0000000706800000| PB 0x0000000706800000| Untracked -| 19|0x0000000706a00000, 0x0000000706c00000, 0x0000000706c00000|100%| O| |TAMS 0x0000000706a00000| PB 0x0000000706a00000| Untracked -| 20|0x0000000706c00000, 0x0000000706e00000, 0x0000000706e00000|100%| O| |TAMS 0x0000000706c00000| PB 0x0000000706c00000| Untracked -| 21|0x0000000706e00000, 0x0000000707000000, 0x0000000707000000|100%| O| |TAMS 0x0000000706e00000| PB 0x0000000706e00000| Untracked -| 22|0x0000000707000000, 0x0000000707200000, 0x0000000707200000|100%| O| |TAMS 0x0000000707000000| PB 0x0000000707000000| Untracked -| 23|0x0000000707200000, 0x0000000707400000, 0x0000000707400000|100%| O| |TAMS 0x0000000707200000| PB 0x0000000707200000| Untracked -| 24|0x0000000707400000, 0x0000000707600000, 0x0000000707600000|100%| O| |TAMS 0x0000000707400000| PB 0x0000000707400000| Untracked -| 25|0x0000000707600000, 0x0000000707800000, 0x0000000707800000|100%| O| |TAMS 0x0000000707600000| PB 0x0000000707600000| Untracked -| 26|0x0000000707800000, 0x0000000707a00000, 0x0000000707a00000|100%| O| |TAMS 0x0000000707800000| PB 0x0000000707800000| Untracked -| 27|0x0000000707a00000, 0x0000000707c00000, 0x0000000707c00000|100%|HS| |TAMS 0x0000000707a00000| PB 0x0000000707a00000| Complete -| 28|0x0000000707c00000, 0x0000000707e00000, 0x0000000707e00000|100%| O| |TAMS 0x0000000707c00000| PB 0x0000000707c00000| Untracked -| 29|0x0000000707e00000, 0x0000000708000000, 0x0000000708000000|100%| O| |TAMS 0x0000000707e00000| PB 0x0000000707e00000| Untracked -| 30|0x0000000708000000, 0x0000000708200000, 0x0000000708200000|100%|HS| |TAMS 0x0000000708000000| PB 0x0000000708000000| Complete -| 31|0x0000000708200000, 0x0000000708400000, 0x0000000708400000|100%|HC| |TAMS 0x0000000708200000| PB 0x0000000708200000| Complete -| 32|0x0000000708400000, 0x0000000708600000, 0x0000000708600000|100%| O| |TAMS 0x0000000708400000| PB 0x0000000708400000| Untracked -| 33|0x0000000708600000, 0x0000000708800000, 0x0000000708800000|100%| O| |TAMS 0x0000000708600000| PB 0x0000000708600000| Untracked -| 34|0x0000000708800000, 0x0000000708a00000, 0x0000000708a00000|100%| O| |TAMS 0x0000000708800000| PB 0x0000000708800000| Untracked -| 35|0x0000000708a00000, 0x0000000708c00000, 0x0000000708c00000|100%| O| |TAMS 0x0000000708a00000| PB 0x0000000708a00000| Untracked -| 36|0x0000000708c00000, 0x0000000708e00000, 0x0000000708e00000|100%| O| |TAMS 0x0000000708c00000| PB 0x0000000708c00000| Untracked -| 37|0x0000000708e00000, 0x0000000709000000, 0x0000000709000000|100%| O| |TAMS 0x0000000708e00000| PB 0x0000000708e00000| Untracked -| 38|0x0000000709000000, 0x0000000709200000, 0x0000000709200000|100%| O| |TAMS 0x0000000709000000| PB 0x0000000709000000| Untracked -| 39|0x0000000709200000, 0x0000000709400000, 0x0000000709400000|100%| O| |TAMS 0x0000000709200000| PB 0x0000000709200000| Untracked -| 40|0x0000000709400000, 0x0000000709600000, 0x0000000709600000|100%| O| |TAMS 0x0000000709400000| PB 0x0000000709400000| Untracked -| 41|0x0000000709600000, 0x0000000709800000, 0x0000000709800000|100%| O| |TAMS 0x0000000709600000| PB 0x0000000709600000| Untracked -| 42|0x0000000709800000, 0x0000000709a00000, 0x0000000709a00000|100%| O| |TAMS 0x0000000709800000| PB 0x0000000709800000| Untracked -| 43|0x0000000709a00000, 0x0000000709c00000, 0x0000000709c00000|100%| O| |TAMS 0x0000000709a00000| PB 0x0000000709a00000| Untracked -| 44|0x0000000709c00000, 0x0000000709e00000, 0x0000000709e00000|100%| O| |TAMS 0x0000000709c00000| PB 0x0000000709c00000| Untracked -| 45|0x0000000709e00000, 0x000000070a000000, 0x000000070a000000|100%| O| |TAMS 0x0000000709e00000| PB 0x0000000709e00000| Untracked -| 46|0x000000070a000000, 0x000000070a200000, 0x000000070a200000|100%| O| |TAMS 0x000000070a000000| PB 0x000000070a000000| Untracked -| 47|0x000000070a200000, 0x000000070a400000, 0x000000070a400000|100%| O| |TAMS 0x000000070a200000| PB 0x000000070a200000| Untracked -| 48|0x000000070a400000, 0x000000070a600000, 0x000000070a600000|100%| O| |TAMS 0x000000070a400000| PB 0x000000070a400000| Untracked -| 49|0x000000070a600000, 0x000000070a800000, 0x000000070a800000|100%| O| |TAMS 0x000000070a600000| PB 0x000000070a600000| Untracked -| 50|0x000000070a800000, 0x000000070aa00000, 0x000000070aa00000|100%| O| |TAMS 0x000000070a800000| PB 0x000000070a800000| Untracked -| 51|0x000000070aa00000, 0x000000070ac00000, 0x000000070ac00000|100%| O| |TAMS 0x000000070aa00000| PB 0x000000070aa00000| Untracked -| 52|0x000000070ac00000, 0x000000070ae00000, 0x000000070ae00000|100%| O| |TAMS 0x000000070ac00000| PB 0x000000070ac00000| Untracked -| 53|0x000000070ae00000, 0x000000070b000000, 0x000000070b000000|100%| O| |TAMS 0x000000070ae00000| PB 0x000000070ae00000| Untracked -| 54|0x000000070b000000, 0x000000070b200000, 0x000000070b200000|100%| O| |TAMS 0x000000070b000000| PB 0x000000070b000000| Untracked -| 55|0x000000070b200000, 0x000000070b400000, 0x000000070b400000|100%| O| |TAMS 0x000000070b200000| PB 0x000000070b200000| Untracked -| 56|0x000000070b400000, 0x000000070b600000, 0x000000070b600000|100%| O| |TAMS 0x000000070b400000| PB 0x000000070b400000| Untracked -| 57|0x000000070b600000, 0x000000070b800000, 0x000000070b800000|100%| O| |TAMS 0x000000070b600000| PB 0x000000070b600000| Untracked -| 58|0x000000070b800000, 0x000000070ba00000, 0x000000070ba00000|100%| O| |TAMS 0x000000070b800000| PB 0x000000070b800000| Untracked -| 59|0x000000070ba00000, 0x000000070bc00000, 0x000000070bc00000|100%| O| |TAMS 0x000000070ba00000| PB 0x000000070ba00000| Untracked -| 60|0x000000070bc00000, 0x000000070be00000, 0x000000070be00000|100%| O| |TAMS 0x000000070bc00000| PB 0x000000070bc00000| Untracked -| 61|0x000000070be00000, 0x000000070c000000, 0x000000070c000000|100%| O| |TAMS 0x000000070be00000| PB 0x000000070be00000| Untracked -| 62|0x000000070c000000, 0x000000070c200000, 0x000000070c200000|100%| O| |TAMS 0x000000070c000000| PB 0x000000070c000000| Untracked -| 63|0x000000070c200000, 0x000000070c400000, 0x000000070c400000|100%| O| |TAMS 0x000000070c200000| PB 0x000000070c200000| Untracked -| 64|0x000000070c400000, 0x000000070c600000, 0x000000070c600000|100%| O| |TAMS 0x000000070c400000| PB 0x000000070c400000| Untracked -| 65|0x000000070c600000, 0x000000070c800000, 0x000000070c800000|100%| O| |TAMS 0x000000070c600000| PB 0x000000070c600000| Untracked -| 66|0x000000070c800000, 0x000000070ca00000, 0x000000070ca00000|100%| O| |TAMS 0x000000070c800000| PB 0x000000070c800000| Untracked -| 67|0x000000070ca00000, 0x000000070cc00000, 0x000000070cc00000|100%| O| |TAMS 0x000000070ca00000| PB 0x000000070ca00000| Untracked -| 68|0x000000070cc00000, 0x000000070ce00000, 0x000000070ce00000|100%| O| |TAMS 0x000000070cc00000| PB 0x000000070cc00000| Untracked -| 69|0x000000070ce00000, 0x000000070d000000, 0x000000070d000000|100%| O| |TAMS 0x000000070ce00000| PB 0x000000070ce00000| Untracked -| 70|0x000000070d000000, 0x000000070d200000, 0x000000070d200000|100%| O| |TAMS 0x000000070d000000| PB 0x000000070d000000| Untracked -| 71|0x000000070d200000, 0x000000070d400000, 0x000000070d400000|100%| O| |TAMS 0x000000070d200000| PB 0x000000070d200000| Untracked -| 72|0x000000070d400000, 0x000000070d600000, 0x000000070d600000|100%| O| |TAMS 0x000000070d400000| PB 0x000000070d400000| Untracked -| 73|0x000000070d600000, 0x000000070d800000, 0x000000070d800000|100%| O| |TAMS 0x000000070d600000| PB 0x000000070d600000| Untracked -| 74|0x000000070d800000, 0x000000070da00000, 0x000000070da00000|100%| O| |TAMS 0x000000070d800000| PB 0x000000070d800000| Untracked -| 75|0x000000070da00000, 0x000000070dc00000, 0x000000070dc00000|100%| O| |TAMS 0x000000070da00000| PB 0x000000070da00000| Untracked -| 76|0x000000070dc00000, 0x000000070dcae550, 0x000000070de00000| 34%| O| |TAMS 0x000000070dc00000| PB 0x000000070dc00000| Untracked -| 77|0x000000070de00000, 0x000000070de00000, 0x000000070e000000| 0%| F| |TAMS 0x000000070de00000| PB 0x000000070de00000| Untracked -| 78|0x000000070e000000, 0x000000070e000000, 0x000000070e200000| 0%| F| |TAMS 0x000000070e000000| PB 0x000000070e000000| Untracked -| 79|0x000000070e200000, 0x000000070e200000, 0x000000070e400000| 0%| F| |TAMS 0x000000070e200000| PB 0x000000070e200000| Untracked -| 80|0x000000070e400000, 0x000000070e400000, 0x000000070e600000| 0%| F| |TAMS 0x000000070e400000| PB 0x000000070e400000| Untracked -| 81|0x000000070e600000, 0x000000070e600000, 0x000000070e800000| 0%| F| |TAMS 0x000000070e600000| PB 0x000000070e600000| Untracked -| 82|0x000000070e800000, 0x000000070e800000, 0x000000070ea00000| 0%| F| |TAMS 0x000000070e800000| PB 0x000000070e800000| Untracked -| 83|0x000000070ea00000, 0x000000070ea00000, 0x000000070ec00000| 0%| F| |TAMS 0x000000070ea00000| PB 0x000000070ea00000| Untracked -| 84|0x000000070ec00000, 0x000000070ee00000, 0x000000070ee00000|100%| O| |TAMS 0x000000070ec00000| PB 0x000000070ec00000| Untracked -| 85|0x000000070ee00000, 0x000000070ee00000, 0x000000070f000000| 0%| F| |TAMS 0x000000070ee00000| PB 0x000000070ee00000| Untracked -| 86|0x000000070f000000, 0x000000070f000000, 0x000000070f200000| 0%| F| |TAMS 0x000000070f000000| PB 0x000000070f000000| Untracked -| 87|0x000000070f200000, 0x000000070f200000, 0x000000070f400000| 0%| F| |TAMS 0x000000070f200000| PB 0x000000070f200000| Untracked -| 88|0x000000070f400000, 0x000000070f400000, 0x000000070f600000| 0%| F| |TAMS 0x000000070f400000| PB 0x000000070f400000| Untracked -| 89|0x000000070f600000, 0x000000070f78fa70, 0x000000070f800000| 78%| S|CS|TAMS 0x000000070f600000| PB 0x000000070f600000| Complete -| 90|0x000000070f800000, 0x000000070f800000, 0x000000070fa00000| 0%| F| |TAMS 0x000000070f800000| PB 0x000000070f800000| Untracked -| 91|0x000000070fa00000, 0x000000070fc00000, 0x000000070fc00000|100%| S|CS|TAMS 0x000000070fa00000| PB 0x000000070fa00000| Complete -| 92|0x000000070fc00000, 0x000000070fe00000, 0x000000070fe00000|100%| S|CS|TAMS 0x000000070fc00000| PB 0x000000070fc00000| Complete -| 93|0x000000070fe00000, 0x000000070fe00000, 0x0000000710000000| 0%| F| |TAMS 0x000000070fe00000| PB 0x000000070fe00000| Untracked -| 94|0x0000000710000000, 0x0000000710000000, 0x0000000710200000| 0%| F| |TAMS 0x0000000710000000| PB 0x0000000710000000| Untracked -| 95|0x0000000710200000, 0x0000000710200000, 0x0000000710400000| 0%| F| |TAMS 0x0000000710200000| PB 0x0000000710200000| Untracked -| 96|0x0000000710400000, 0x0000000710600000, 0x0000000710600000|100%| S|CS|TAMS 0x0000000710400000| PB 0x0000000710400000| Complete -| 97|0x0000000710600000, 0x0000000710800000, 0x0000000710800000|100%| S|CS|TAMS 0x0000000710600000| PB 0x0000000710600000| Complete -| 98|0x0000000710800000, 0x0000000710800000, 0x0000000710a00000| 0%| F| |TAMS 0x0000000710800000| PB 0x0000000710800000| Untracked -| 99|0x0000000710a00000, 0x0000000710a00000, 0x0000000710c00000| 0%| F| |TAMS 0x0000000710a00000| PB 0x0000000710a00000| Untracked -| 100|0x0000000710c00000, 0x0000000710e00000, 0x0000000710e00000|100%| S|CS|TAMS 0x0000000710c00000| PB 0x0000000710c00000| Complete -| 101|0x0000000710e00000, 0x0000000711000000, 0x0000000711000000|100%| S|CS|TAMS 0x0000000710e00000| PB 0x0000000710e00000| Complete -| 102|0x0000000711000000, 0x0000000711000000, 0x0000000711200000| 0%| F| |TAMS 0x0000000711000000| PB 0x0000000711000000| Untracked -| 103|0x0000000711200000, 0x0000000711200000, 0x0000000711400000| 0%| F| |TAMS 0x0000000711200000| PB 0x0000000711200000| Untracked -| 104|0x0000000711400000, 0x0000000711400000, 0x0000000711600000| 0%| F| |TAMS 0x0000000711400000| PB 0x0000000711400000| Untracked -| 105|0x0000000711600000, 0x0000000711600000, 0x0000000711800000| 0%| F| |TAMS 0x0000000711600000| PB 0x0000000711600000| Untracked -| 106|0x0000000711800000, 0x0000000711800000, 0x0000000711a00000| 0%| F| |TAMS 0x0000000711800000| PB 0x0000000711800000| Untracked -| 107|0x0000000711a00000, 0x0000000711a00000, 0x0000000711c00000| 0%| F| |TAMS 0x0000000711a00000| PB 0x0000000711a00000| Untracked -| 108|0x0000000711c00000, 0x0000000711c00000, 0x0000000711e00000| 0%| F| |TAMS 0x0000000711c00000| PB 0x0000000711c00000| Untracked -| 109|0x0000000711e00000, 0x0000000711e00000, 0x0000000712000000| 0%| F| |TAMS 0x0000000711e00000| PB 0x0000000711e00000| Untracked -| 110|0x0000000712000000, 0x0000000712000000, 0x0000000712200000| 0%| F| |TAMS 0x0000000712000000| PB 0x0000000712000000| Untracked -| 111|0x0000000712200000, 0x0000000712200000, 0x0000000712400000| 0%| F| |TAMS 0x0000000712200000| PB 0x0000000712200000| Untracked -| 112|0x0000000712400000, 0x0000000712400000, 0x0000000712600000| 0%| F| |TAMS 0x0000000712400000| PB 0x0000000712400000| Untracked -| 113|0x0000000712600000, 0x0000000712600000, 0x0000000712800000| 0%| F| |TAMS 0x0000000712600000| PB 0x0000000712600000| Untracked -| 114|0x0000000712800000, 0x0000000712800000, 0x0000000712a00000| 0%| F| |TAMS 0x0000000712800000| PB 0x0000000712800000| Untracked -| 115|0x0000000712a00000, 0x0000000712a00000, 0x0000000712c00000| 0%| F| |TAMS 0x0000000712a00000| PB 0x0000000712a00000| Untracked -| 116|0x0000000712c00000, 0x0000000712c00000, 0x0000000712e00000| 0%| F| |TAMS 0x0000000712c00000| PB 0x0000000712c00000| Untracked -| 117|0x0000000712e00000, 0x0000000712e00000, 0x0000000713000000| 0%| F| |TAMS 0x0000000712e00000| PB 0x0000000712e00000| Untracked -| 118|0x0000000713000000, 0x0000000713000000, 0x0000000713200000| 0%| F| |TAMS 0x0000000713000000| PB 0x0000000713000000| Untracked -| 119|0x0000000713200000, 0x0000000713200000, 0x0000000713400000| 0%| F| |TAMS 0x0000000713200000| PB 0x0000000713200000| Untracked -| 120|0x0000000713400000, 0x0000000713400000, 0x0000000713600000| 0%| F| |TAMS 0x0000000713400000| PB 0x0000000713400000| Untracked -| 121|0x0000000713600000, 0x0000000713600000, 0x0000000713800000| 0%| F| |TAMS 0x0000000713600000| PB 0x0000000713600000| Untracked -| 122|0x0000000713800000, 0x0000000713800000, 0x0000000713a00000| 0%| F| |TAMS 0x0000000713800000| PB 0x0000000713800000| Untracked -| 123|0x0000000713a00000, 0x0000000713a00000, 0x0000000713c00000| 0%| F| |TAMS 0x0000000713a00000| PB 0x0000000713a00000| Untracked -| 124|0x0000000713c00000, 0x0000000713c00000, 0x0000000713e00000| 0%| F| |TAMS 0x0000000713c00000| PB 0x0000000713c00000| Untracked -| 125|0x0000000713e00000, 0x0000000713e00000, 0x0000000714000000| 0%| F| |TAMS 0x0000000713e00000| PB 0x0000000713e00000| Untracked -| 126|0x0000000714000000, 0x0000000714000000, 0x0000000714200000| 0%| F| |TAMS 0x0000000714000000| PB 0x0000000714000000| Untracked -| 127|0x0000000714200000, 0x0000000714200000, 0x0000000714400000| 0%| F| |TAMS 0x0000000714200000| PB 0x0000000714200000| Untracked -| 128|0x0000000714400000, 0x0000000714400000, 0x0000000714600000| 0%| F| |TAMS 0x0000000714400000| PB 0x0000000714400000| Untracked -| 129|0x0000000714600000, 0x0000000714600000, 0x0000000714800000| 0%| F| |TAMS 0x0000000714600000| PB 0x0000000714600000| Untracked -| 130|0x0000000714800000, 0x0000000714800000, 0x0000000714a00000| 0%| F| |TAMS 0x0000000714800000| PB 0x0000000714800000| Untracked -| 131|0x0000000714a00000, 0x0000000714a00000, 0x0000000714c00000| 0%| F| |TAMS 0x0000000714a00000| PB 0x0000000714a00000| Untracked -| 132|0x0000000714c00000, 0x0000000714c00000, 0x0000000714e00000| 0%| F| |TAMS 0x0000000714c00000| PB 0x0000000714c00000| Untracked -| 133|0x0000000714e00000, 0x0000000714e00000, 0x0000000715000000| 0%| F| |TAMS 0x0000000714e00000| PB 0x0000000714e00000| Untracked -| 134|0x0000000715000000, 0x0000000715000000, 0x0000000715200000| 0%| F| |TAMS 0x0000000715000000| PB 0x0000000715000000| Untracked -| 135|0x0000000715200000, 0x0000000715200000, 0x0000000715400000| 0%| F| |TAMS 0x0000000715200000| PB 0x0000000715200000| Untracked -| 136|0x0000000715400000, 0x0000000715400000, 0x0000000715600000| 0%| F| |TAMS 0x0000000715400000| PB 0x0000000715400000| Untracked -| 137|0x0000000715600000, 0x0000000715600000, 0x0000000715800000| 0%| F| |TAMS 0x0000000715600000| PB 0x0000000715600000| Untracked -| 138|0x0000000715800000, 0x0000000715800000, 0x0000000715a00000| 0%| F| |TAMS 0x0000000715800000| PB 0x0000000715800000| Untracked -| 139|0x0000000715a00000, 0x0000000715a00000, 0x0000000715c00000| 0%| F| |TAMS 0x0000000715a00000| PB 0x0000000715a00000| Untracked -| 140|0x0000000715c00000, 0x0000000715c00000, 0x0000000715e00000| 0%| F| |TAMS 0x0000000715c00000| PB 0x0000000715c00000| Untracked -| 141|0x0000000715e00000, 0x0000000715e00000, 0x0000000716000000| 0%| F| |TAMS 0x0000000715e00000| PB 0x0000000715e00000| Untracked -| 142|0x0000000716000000, 0x0000000716000000, 0x0000000716200000| 0%| F| |TAMS 0x0000000716000000| PB 0x0000000716000000| Untracked -| 143|0x0000000716200000, 0x0000000716200000, 0x0000000716400000| 0%| F| |TAMS 0x0000000716200000| PB 0x0000000716200000| Untracked -| 144|0x0000000716400000, 0x0000000716400000, 0x0000000716600000| 0%| F| |TAMS 0x0000000716400000| PB 0x0000000716400000| Untracked -| 145|0x0000000716600000, 0x0000000716600000, 0x0000000716800000| 0%| F| |TAMS 0x0000000716600000| PB 0x0000000716600000| Untracked -| 146|0x0000000716800000, 0x0000000716800000, 0x0000000716a00000| 0%| F| |TAMS 0x0000000716800000| PB 0x0000000716800000| Untracked -| 147|0x0000000716a00000, 0x0000000716bb4068, 0x0000000716c00000| 85%| E| |TAMS 0x0000000716a00000| PB 0x0000000716a00000| Complete -| 148|0x0000000716c00000, 0x0000000716e00000, 0x0000000716e00000|100%| E|CS|TAMS 0x0000000716c00000| PB 0x0000000716c00000| Complete -| 149|0x0000000716e00000, 0x0000000717000000, 0x0000000717000000|100%| E|CS|TAMS 0x0000000716e00000| PB 0x0000000716e00000| Complete -| 150|0x0000000717000000, 0x0000000717200000, 0x0000000717200000|100%| E|CS|TAMS 0x0000000717000000| PB 0x0000000717000000| Complete -| 151|0x0000000717200000, 0x0000000717400000, 0x0000000717400000|100%| E|CS|TAMS 0x0000000717200000| PB 0x0000000717200000| Complete -| 152|0x0000000717400000, 0x0000000717600000, 0x0000000717600000|100%| E|CS|TAMS 0x0000000717400000| PB 0x0000000717400000| Complete -| 153|0x0000000717600000, 0x0000000717800000, 0x0000000717800000|100%| E|CS|TAMS 0x0000000717600000| PB 0x0000000717600000| Complete -| 154|0x0000000717800000, 0x0000000717a00000, 0x0000000717a00000|100%| E|CS|TAMS 0x0000000717800000| PB 0x0000000717800000| Complete -| 155|0x0000000717a00000, 0x0000000717c00000, 0x0000000717c00000|100%| E|CS|TAMS 0x0000000717a00000| PB 0x0000000717a00000| Complete -| 156|0x0000000717c00000, 0x0000000717e00000, 0x0000000717e00000|100%| E|CS|TAMS 0x0000000717c00000| PB 0x0000000717c00000| Complete -| 157|0x0000000717e00000, 0x0000000718000000, 0x0000000718000000|100%| E|CS|TAMS 0x0000000717e00000| PB 0x0000000717e00000| Complete -| 158|0x0000000718000000, 0x0000000718200000, 0x0000000718200000|100%| E|CS|TAMS 0x0000000718000000| PB 0x0000000718000000| Complete -| 159|0x0000000718200000, 0x0000000718400000, 0x0000000718400000|100%| E|CS|TAMS 0x0000000718200000| PB 0x0000000718200000| Complete -| 160|0x0000000718400000, 0x0000000718600000, 0x0000000718600000|100%| E|CS|TAMS 0x0000000718400000| PB 0x0000000718400000| Complete -| 161|0x0000000718600000, 0x0000000718800000, 0x0000000718800000|100%| E|CS|TAMS 0x0000000718600000| PB 0x0000000718600000| Complete -| 162|0x0000000718800000, 0x0000000718a00000, 0x0000000718a00000|100%| E| |TAMS 0x0000000718800000| PB 0x0000000718800000| Complete -| 163|0x0000000718a00000, 0x0000000718c00000, 0x0000000718c00000|100%| E|CS|TAMS 0x0000000718a00000| PB 0x0000000718a00000| Complete -| 164|0x0000000718c00000, 0x0000000718e00000, 0x0000000718e00000|100%| E|CS|TAMS 0x0000000718c00000| PB 0x0000000718c00000| Complete -| 165|0x0000000718e00000, 0x0000000719000000, 0x0000000719000000|100%| E|CS|TAMS 0x0000000718e00000| PB 0x0000000718e00000| Complete -| 166|0x0000000719000000, 0x0000000719200000, 0x0000000719200000|100%| E|CS|TAMS 0x0000000719000000| PB 0x0000000719000000| Complete -| 167|0x0000000719200000, 0x0000000719400000, 0x0000000719400000|100%| E|CS|TAMS 0x0000000719200000| PB 0x0000000719200000| Complete -| 168|0x0000000719400000, 0x0000000719600000, 0x0000000719600000|100%| E|CS|TAMS 0x0000000719400000| PB 0x0000000719400000| Complete -| 169|0x0000000719600000, 0x0000000719800000, 0x0000000719800000|100%| E|CS|TAMS 0x0000000719600000| PB 0x0000000719600000| Complete -| 170|0x0000000719800000, 0x0000000719a00000, 0x0000000719a00000|100%| E|CS|TAMS 0x0000000719800000| PB 0x0000000719800000| Complete -| 171|0x0000000719a00000, 0x0000000719c00000, 0x0000000719c00000|100%| E|CS|TAMS 0x0000000719a00000| PB 0x0000000719a00000| Complete -| 172|0x0000000719c00000, 0x0000000719e00000, 0x0000000719e00000|100%| E|CS|TAMS 0x0000000719c00000| PB 0x0000000719c00000| Complete -| 173|0x0000000719e00000, 0x000000071a000000, 0x000000071a000000|100%| E|CS|TAMS 0x0000000719e00000| PB 0x0000000719e00000| Complete -| 174|0x000000071a000000, 0x000000071a200000, 0x000000071a200000|100%| E|CS|TAMS 0x000000071a000000| PB 0x000000071a000000| Complete -| 175|0x000000071a200000, 0x000000071a400000, 0x000000071a400000|100%| E|CS|TAMS 0x000000071a200000| PB 0x000000071a200000| Complete -| 176|0x000000071a400000, 0x000000071a600000, 0x000000071a600000|100%| E|CS|TAMS 0x000000071a400000| PB 0x000000071a400000| Complete -| 177|0x000000071a600000, 0x000000071a800000, 0x000000071a800000|100%| E|CS|TAMS 0x000000071a600000| PB 0x000000071a600000| Complete -| 178|0x000000071a800000, 0x000000071aa00000, 0x000000071aa00000|100%| E|CS|TAMS 0x000000071a800000| PB 0x000000071a800000| Complete -|2011|0x00000007ffa00000, 0x00000007ffc00000, 0x00000007ffc00000|100%| O| |TAMS 0x00000007ffa00000| PB 0x00000007ffa00000| Untracked -|2012|0x00000007ffc00000, 0x00000007ffe00000, 0x00000007ffe00000|100%| E|CS|TAMS 0x00000007ffc00000| PB 0x00000007ffc00000| Complete -|2013|0x00000007ffe00000, 0x0000000800000000, 0x0000000800000000|100%| E|CS|TAMS 0x00000007ffe00000| PB 0x00000007ffe00000| Complete - -Card table byte_map: [0x000001a22dab0000,0x000001a22e290000] _byte_map_base: 0x000001a22a28e000 - -Marking Bits: (CMBitMap*) 0x000001a215453c00 - Bits: [0x000001a22e290000, 0x000001a232180000) - -Polling page: 0x000001a2132d0000 - -Metaspace: - -Usage: - Non-class: 44.07 MB used. - Class: 6.28 MB used. - Both: 50.35 MB used. - -Virtual space: - Non-class space: 64.00 MB reserved, 44.50 MB ( 70%) committed, 1 nodes. - Class space: 1.00 GB reserved, 6.69 MB ( <1%) committed, 1 nodes. - Both: 1.06 GB reserved, 51.19 MB ( 5%) committed. - -Chunk freelists: - Non-Class: 2.97 MB - Class: 9.29 MB - Both: 12.26 MB - -MaxMetaspaceSize: unlimited -CompressedClassSpaceSize: 1.00 GB -Initial GC threshold: 21.00 MB -Current GC threshold: 85.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: 6. -num_arena_births: 2078. -num_arena_deaths: 748. -num_vsnodes_births: 2. -num_vsnodes_deaths: 0. -num_space_committed: 819. -num_space_uncommitted: 0. -num_chunks_returned_to_freelist: 938. -num_chunks_taken_from_freelist: 4237. -num_chunk_merges: 294. -num_chunk_splits: 2343. -num_chunks_enlarged: 1217. -num_inconsistent_stats: 0. - -CodeHeap 'non-profiled nmethods': size=119168Kb used=20127Kb max_used=20465Kb free=99040Kb - bounds [0x000001a2253d0000, 0x000001a2267f0000, 0x000001a22c830000] -CodeHeap 'profiled nmethods': size=119104Kb used=18694Kb max_used=24458Kb free=100409Kb - bounds [0x000001a21d830000, 0x000001a21f020000, 0x000001a224c80000] -CodeHeap 'non-nmethods': size=7488Kb used=2345Kb max_used=4092Kb free=5143Kb - bounds [0x000001a224c80000, 0x000001a225090000, 0x000001a2253d0000] - total_blobs=12505 nmethods=11266 adapters=1142 - compilation: enabled - stopped_count=0, restarted_count=0 - full_count=0 - -Compilation events (20 events): -Event: 9891.815 Thread 0x000001a23536e810 nmethod 26316 0x000001a2267cc590 code [0x000001a2267cd3a0, 0x000001a2267da110] -Event: 9896.248 Thread 0x000001a23536e810 26317 4 com.sun.javafx.scene.control.SelectedCellsMap$$Lambda/0x000001a237229ad8::compare (12 bytes) -Event: 9896.250 Thread 0x000001a23536e810 nmethod 26317 0x000001a226108710 code [0x000001a2261088a0, 0x000001a2261089c8] -Event: 9902.050 Thread 0x000001a23537dba0 26318 3 sun.rmi.transport.DGCImpl::checkInput (149 bytes) -Event: 9902.051 Thread 0x000001a23537dba0 nmethod 26318 0x000001a21dfae210 code [0x000001a21dfae460, 0x000001a21dfaec78] -Event: 9912.769 Thread 0x000001a23536e810 26319 4 com.sun.org.apache.xerces.internal.impl.XMLScanner::init (91 bytes) -Event: 9912.794 Thread 0x000001a23536e810 nmethod 26319 0x000001a225deb490 code [0x000001a225deb6e0, 0x000001a225dec900] -Event: 9916.302 Thread 0x000001a23536e810 26320 ! 4 javafx.collections.ModifiableObservableListBase::addAll (63 bytes) -Event: 9916.311 Thread 0x000001a23536e810 nmethod 26320 0x000001a225856110 code [0x000001a225856340, 0x000001a225856bb8] -Event: 9932.828 Thread 0x000001a23536e810 26321 4 kst4contest.view.Kst4ContestApplication::updateTopCandidateButton (131 bytes) -Event: 9932.874 Thread 0x000001a23536e810 nmethod 26321 0x000001a225910690 code [0x000001a225910a00, 0x000001a225912bc8] -Event: 9961.165 Thread 0x000001a23536e810 26322 4 kst4contest.view.map.PathObstructionSummary::hasDominantLosObstruction (42 bytes) -Event: 9961.166 Thread 0x000001a23536e810 nmethod 26322 0x000001a225deb090 code [0x000001a225deb260, 0x000001a225deb390] -Event: 10000.148 Thread 0x000001a23536e810 26323 4 kst4contest.view.map.PathHorizonSummary::hasTargetTerrainHorizon (43 bytes) -Event: 10000.149 Thread 0x000001a23536e810 nmethod 26323 0x000001a225deac90 code [0x000001a225deae60, 0x000001a225deaf78] -Event: 10052.797 Thread 0x000001a23536e810 26324 4 com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl::scanDocument (346 bytes) -Event: 10052.810 Thread 0x000001a23536e810 nmethod 26324 0x000001a2260a7690 code [0x000001a2260a7900, 0x000001a2260a8288] -Event: 10118.529 Thread 0x000001a23537dba0 26325 3 javafx.scene.layout.GridPane::getColumnPrefWidth (36 bytes) -Event: 10118.530 Thread 0x000001a23537dba0 nmethod 26325 0x000001a21ec7c890 code [0x000001a21ec7cae0, 0x000001a21ec7d240] -Event: 10119.189 Thread 0x000001a23536e810 26326 4 javafx.scene.Node::disabledPropertyImpl (24 bytes) - -GC Heap History (20 events): -Event: 10005.159 GC heap before -{Heap before GC invocations=1169 (full 0): - garbage-first heap total 372736K, used 337764K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 87 young (178176K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10005.167 GC heap after -{Heap after GC invocations=1170 (full 0): - garbage-first heap total 372736K, used 171663K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 6 young (12288K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10017.156 GC heap before -{Heap before GC invocations=1170 (full 0): - garbage-first heap total 372736K, used 337551K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 87 young (178176K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10017.162 GC heap after -{Heap after GC invocations=1171 (full 0): - garbage-first heap total 372736K, used 173290K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 7 young (14336K), 7 survivors (14336K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10034.868 GC heap before -{Heap before GC invocations=1171 (full 0): - garbage-first heap total 372736K, used 335082K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 86 young (176128K), 7 survivors (14336K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10034.875 GC heap after -{Heap after GC invocations=1172 (full 0): - garbage-first heap total 372736K, used 171598K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 6 young (12288K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10044.146 GC heap before -{Heap before GC invocations=1172 (full 0): - garbage-first heap total 372736K, used 337486K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 87 young (178176K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10044.151 GC heap after -{Heap after GC invocations=1173 (full 0): - garbage-first heap total 372736K, used 171897K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 6 young (12288K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10059.342 GC heap before -{Heap before GC invocations=1173 (full 0): - garbage-first heap total 372736K, used 335737K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 87 young (178176K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10059.351 GC heap after -{Heap after GC invocations=1174 (full 0): - garbage-first heap total 372736K, used 171902K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 6 young (12288K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10068.160 GC heap before -{Heap before GC invocations=1174 (full 0): - garbage-first heap total 372736K, used 335742K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 87 young (178176K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10068.170 GC heap after -{Heap after GC invocations=1175 (full 0): - garbage-first heap total 372736K, used 172017K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 6 young (12288K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10077.140 GC heap before -{Heap before GC invocations=1175 (full 0): - garbage-first heap total 372736K, used 335857K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 87 young (178176K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10077.152 GC heap after -{Heap after GC invocations=1176 (full 0): - garbage-first heap total 372736K, used 170954K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 6 young (12288K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10087.378 GC heap before -{Heap before GC invocations=1176 (full 0): - garbage-first heap total 372736K, used 336842K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 87 young (178176K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10087.397 GC heap after -{Heap after GC invocations=1177 (full 0): - garbage-first heap total 372736K, used 171205K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 6 young (12288K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10096.614 GC heap before -{Heap before GC invocations=1177 (full 0): - garbage-first heap total 372736K, used 335045K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 87 young (178176K), 6 survivors (12288K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10096.628 GC heap after -{Heap after GC invocations=1178 (full 0): - garbage-first heap total 372736K, used 173257K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 7 young (14336K), 7 survivors (14336K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10113.155 GC heap before -{Heap before GC invocations=1178 (full 0): - garbage-first heap total 372736K, used 333001K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 86 young (176128K), 7 survivors (14336K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} -Event: 10113.166 GC heap after -{Heap after GC invocations=1179 (full 0): - garbage-first heap total 372736K, used 174327K [0x0000000704400000, 0x0000000800000000) - region size 2048K, 7 young (14336K), 7 survivors (14336K) - Metaspace used 51542K, committed 52416K, reserved 1114112K - class space used 6424K, committed 6848K, reserved 1048576K -} - -Dll operation events (20 events): -Event: 1.514 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-process-l1-1-0.dll -Event: 1.520 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-runtime-l1-1-0.dll -Event: 1.526 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-stdio-l1-1-0.dll -Event: 1.535 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-string-l1-1-0.dll -Event: 1.542 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-time-l1-1-0.dll -Event: 1.548 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-utility-l1-1-0.dll -Event: 1.577 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\ucrtbase.dll -Event: 1.584 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\vcruntime140.dll -Event: 1.591 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\vcruntime140_1.dll -Event: 1.611 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\msvcp140.dll -Event: 1.619 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\msvcp140_1.dll -Event: 1.629 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\msvcp140_2.dll -Event: 1.817 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\prism_d3d.dll -Event: 2.279 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\glass.dll -Event: 2.697 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\javafx_font.dll -Event: 3.858 Loaded shared library C:\Users\prakt\.jdks\openjdk-21.0.1\bin\sunmscapi.dll -Event: 4.683 Loaded shared library C:\Users\prakt\.jdks\openjdk-21.0.1\bin\verify.dll -Event: 5.058 Loaded shared library C:\Users\prakt\AppData\Local\Temp\sqlite-3.43.2.2-fc42fa49-3dcf-45c4-8b9b-c5967d4cb394-sqlitejdbc.dll -Event: 50.881 Loaded shared library C:\Users\prakt\.jdks\openjdk-21.0.1\bin\jsound.dll -Event: 5961.271 Loaded shared library C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\jfxwebkit.dll - -Deoptimization events (20 events): -Event: 10119.188 Thread 0x000001a2065a1970 Uncommon trap: trap_request=0xffffff45 fr.pc=0x000001a225d092f8 relative=0x0000000000000058 -Event: 10119.188 Thread 0x000001a2065a1970 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000001a225d092f8 method=java.lang.Thread.getAndClearInterrupt()Z @ 6 c2 -Event: 10119.188 Thread 0x000001a2065a1970 DEOPT PACKING pc=0x000001a225d092f8 sp=0x0000004d914fee20 -Event: 10119.188 Thread 0x000001a2065a1970 DEOPT UNPACKING pc=0x000001a224cd46a2 sp=0x0000004d914fed58 mode 2 -Event: 10119.188 Thread 0x000001a27c76a4b0 Uncommon trap: trap_request=0xffffff45 fr.pc=0x000001a225f2e3f0 relative=0x0000000000003b30 -Event: 10119.188 Thread 0x000001a2065a1970 Uncommon trap: trap_request=0xffffff45 fr.pc=0x000001a225a2c9c0 relative=0x0000000000000980 -Event: 10119.188 Thread 0x000001a2065a1970 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000001a225a2c9c0 method=java.util.concurrent.ThreadPoolExecutor.runStateAtLeast(II)Z @ 2 c2 -Event: 10119.188 Thread 0x000001a2065a1970 DEOPT PACKING pc=0x000001a225a2c9c0 sp=0x0000004d914feef0 -Event: 10119.188 Thread 0x000001a27c76a4b0 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000001a225f2e3f0 method=sun.nio.ch.DatagramChannelImpl.sourceSocketAddress()Ljava/net/InetSocketAddress; @ 28 c2 -Event: 10119.188 Thread 0x000001a2065a1970 DEOPT UNPACKING pc=0x000001a224cd46a2 sp=0x0000004d914fee40 mode 2 -Event: 10119.188 Thread 0x000001a27c76a4b0 DEOPT PACKING pc=0x000001a225f2e3f0 sp=0x0000004d8f8ff160 -Event: 10119.188 Thread 0x000001a27c76a4b0 DEOPT UNPACKING pc=0x000001a224cd46a2 sp=0x0000004d8f8fef50 mode 2 -Event: 10119.188 Thread 0x000001a27c76a4b0 Uncommon trap: trap_request=0xffffff45 fr.pc=0x000001a225af9484 relative=0x0000000000000244 -Event: 10119.188 Thread 0x000001a27c76a4b0 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000001a225af9484 method=java.nio.channels.spi.AbstractInterruptibleChannel.isOpen()Z @ 4 c2 -Event: 10119.188 Thread 0x000001a27c76a4b0 DEOPT PACKING pc=0x000001a225af9484 sp=0x0000004d8f8fef70 -Event: 10119.189 Thread 0x000001a27c76a4b0 DEOPT UNPACKING pc=0x000001a224cd46a2 sp=0x0000004d8f8feed0 mode 2 -Event: 10119.189 Thread 0x000001a27c76c580 Uncommon trap: trap_request=0xffffff45 fr.pc=0x000001a22604ba88 relative=0x0000000000000068 -Event: 10119.189 Thread 0x000001a27c76c580 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000001a22604ba88 method=java.util.TaskQueue.isEmpty()Z @ 4 c2 -Event: 10119.189 Thread 0x000001a27c76c580 DEOPT PACKING pc=0x000001a22604ba88 sp=0x0000004d905ff670 -Event: 10119.189 Thread 0x000001a27c76c580 DEOPT UNPACKING pc=0x000001a224cd46a2 sp=0x0000004d905ff600 mode 2 - -Classes loaded (20 events): -Event: 5961.976 Loading class java/util/AbstractMap$2$1 done -Event: 5962.115 Loading class java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntrySetSpliterator -Event: 5962.116 Loading class java/util/Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntrySetSpliterator done -Event: 5962.116 Loading class java/util/TreeMap$EntrySpliterator -Event: 5962.116 Loading class java/util/TreeMap$TreeMapSpliterator -Event: 5962.117 Loading class java/util/TreeMap$TreeMapSpliterator done -Event: 5962.117 Loading class java/util/TreeMap$EntrySpliterator done -Event: 5962.121 Loading class java/util/zip/DataFormatException -Event: 5962.122 Loading class java/util/zip/DataFormatException done -Event: 6024.927 Loading class sun/security/ssl/PreSharedKeyExtension$PskIdentity -Event: 6024.927 Loading class sun/security/ssl/PreSharedKeyExtension$PskIdentity done -Event: 6024.928 Loading class sun/security/ssl/PreSharedKeyExtension$CHPreSharedKeySpec -Event: 6024.929 Loading class sun/security/ssl/PreSharedKeyExtension$CHPreSharedKeySpec done -Event: 6024.929 Loading class sun/security/ssl/PreSharedKeyExtension$PartialClientHelloMessage -Event: 6024.930 Loading class sun/security/ssl/PreSharedKeyExtension$PartialClientHelloMessage done -Event: 6024.959 Loading class sun/security/ssl/PreSharedKeyExtension$SHPreSharedKeySpec -Event: 6024.960 Loading class sun/security/ssl/PreSharedKeyExtension$SHPreSharedKeySpec done -Event: 6635.186 Loading class sun/security/ssl/Alert$AlertMessage -Event: 6635.187 Loading class sun/security/ssl/Alert$AlertMessage done -Event: 10119.189 Loading class sun/net/ConnectionResetException - -Classes unloaded (20 events): -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a23758e000 'java/lang/invoke/LambdaForm$MH+0x000001a23758e000' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a23758e800 'java/lang/invoke/LambdaForm$MH+0x000001a23758e800' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a237593000 'java/lang/invoke/LambdaForm$MH+0x000001a237593000' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a23759f000 'java/lang/invoke/LambdaForm$MH+0x000001a23759f000' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a23759fc00 'java/lang/invoke/LambdaForm$MH+0x000001a23759fc00' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a2375a0800 'java/lang/invoke/LambdaForm$MH+0x000001a2375a0800' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a2375a4800 'java/lang/invoke/LambdaForm$MH+0x000001a2375a4800' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a2375a6400 'java/lang/invoke/LambdaForm$MH+0x000001a2375a6400' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a2375a9800 'java/lang/invoke/LambdaForm$MH+0x000001a2375a9800' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a23709ac00 'java/lang/invoke/LambdaForm$MH+0x000001a23709ac00' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a237254000 'java/lang/invoke/LambdaForm$MH+0x000001a237254000' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a237256c00 'java/lang/invoke/LambdaForm$MH+0x000001a237256c00' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a237257000 'java/lang/invoke/LambdaForm$MH+0x000001a237257000' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a237574c00 'java/lang/invoke/LambdaForm$MH+0x000001a237574c00' -Event: 8520.210 Thread 0x000001a235339090 Unloading class 0x000001a237606000 'java/lang/invoke/LambdaForm$MH+0x000001a237606000' -Event: 8829.200 Thread 0x000001a235339090 Unloading class 0x000001a237252000 'java/lang/invoke/LambdaForm$MH+0x000001a237252000' -Event: 8829.200 Thread 0x000001a235339090 Unloading class 0x000001a237252c00 'java/lang/invoke/LambdaForm$MH+0x000001a237252c00' -Event: 8829.200 Thread 0x000001a235339090 Unloading class 0x000001a237253c00 'java/lang/invoke/LambdaForm$MH+0x000001a237253c00' -Event: 8829.200 Thread 0x000001a235339090 Unloading class 0x000001a237255c00 'java/lang/invoke/LambdaForm$MH+0x000001a237255c00' -Event: 8829.200 Thread 0x000001a235339090 Unloading class 0x000001a237259000 'java/lang/invoke/LambdaForm$MH+0x000001a237259000' - -Classes redefined (0 events): -No events - -Internal exceptions (20 events): -Event: 6732.749 Thread 0x000001a27ba75380 Implicit null exception at 0x000001a22621ba29 to 0x000001a22621d748 -Event: 6732.749 Thread 0x000001a27ba75380 Implicit null exception at 0x000001a22621ba29 to 0x000001a22621d748 -Event: 6732.749 Thread 0x000001a27ba75380 Implicit null exception at 0x000001a22621ba29 to 0x000001a22621d748 -Event: 6732.750 Thread 0x000001a27ba75380 Implicit null exception at 0x000001a22621ba29 to 0x000001a22621d748 -Event: 7032.696 Thread 0x000001a27c769e20 Implicit null exception at 0x000001a2258c3b44 to 0x000001a2258c4338 -Event: 7035.078 Thread 0x000001a27ba75380 Exception (0x0000000713c1b388) -thrown [s\open\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 7035.085 Thread 0x000001a27ba75380 Implicit null exception at 0x000001a22554f6c0 to 0x000001a22554fea8 -Event: 7069.480 Thread 0x000001a27ba75380 Exception (0x00000007113f8760) -thrown [s\open\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 7096.201 Thread 0x000001a27ba75380 Exception (0x000000071182b810) -thrown [s\open\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 7271.303 Thread 0x000001a27c770090 Exception (0x0000000718f67d08) -thrown [s\open\src\hotspot\share\prims\jni.cpp, line 520] -Event: 7292.246 Thread 0x000001a27ba75380 Exception (0x00000007ffd94180) -thrown [s\open\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 7682.402 Thread 0x000001a27ba75380 Exception (0x00000007154321c0) -thrown [s\open\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 7844.544 Thread 0x000001a27ba75380 Exception (0x0000000714a98580) -thrown [s\open\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 7886.186 Thread 0x000001a27ba75380 Exception (0x0000000717914940) -thrown [s\open\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 9142.053 Thread 0x000001a27ba75380 Exception (0x0000000715990138) -thrown [s\open\src\hotspot\share\interpreter\linkResolver.cpp, line 773] -Event: 9430.822 Thread 0x000001a27ba75380 Implicit null exception at 0x000001a225b2f4ea to 0x000001a225b332f0 -Event: 9430.822 Thread 0x000001a27ba75380 Implicit null exception at 0x000001a22568bdd5 to 0x000001a22568bfd8 -Event: 10117.109 Thread 0x000001a235752510 Implicit null exception at 0x000001a2261b94e1 to 0x000001a2261baaf4 -Event: 10119.187 Thread 0x000001a27c76ece0 Exception (0x0000000716ff9ec0) -thrown [s\open\src\hotspot\share\prims\jni.cpp, line 520] -Event: 10119.189 Thread 0x000001a27c76b1d0 Exception (0x000000071a177ad8) -thrown [s\open\src\hotspot\share\prims\jni.cpp, line 520] - -ZGC Phase Switch (0 events): -No events - -VM Operations (20 events): -Event: 10044.146 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) -Event: 10044.151 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) done -Event: 10059.342 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) -Event: 10059.351 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) done -Event: 10063.353 Executing VM operation: Cleanup -Event: 10063.353 Executing VM operation: Cleanup done -Event: 10068.160 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) -Event: 10068.170 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) done -Event: 10077.140 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) -Event: 10077.153 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) done -Event: 10087.378 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) -Event: 10087.397 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) done -Event: 10096.614 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) -Event: 10096.628 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) done -Event: 10102.040 Executing VM operation: HandshakeAllThreads (HandshakeForDeflation) -Event: 10102.040 Executing VM operation: HandshakeAllThreads (HandshakeForDeflation) done -Event: 10102.040 Executing VM operation: RendezvousGCThreads -Event: 10102.040 Executing VM operation: RendezvousGCThreads done -Event: 10113.155 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) -Event: 10113.167 Executing VM operation: G1CollectForAllocation (G1 Evacuation Pause) done - -Events (20 events): -Event: 9362.394 Thread 0x000001a27c3fb910 Thread exited: 0x000001a27c3fb910 -Event: 9374.163 Thread 0x000001a27c3fa560 Thread added: 0x000001a27c3fa560 -Event: 9374.163 Thread 0x000001a27c3fa560 Thread exited: 0x000001a27c3fa560 -Event: 9379.903 Thread 0x000001a208ccf1b0 Thread exited: 0x000001a208ccf1b0 -Event: 9381.319 Thread 0x000001a27c3fabf0 Thread added: 0x000001a27c3fabf0 -Event: 9381.321 Thread 0x000001a209279b80 Thread added: 0x000001a209279b80 -Event: 9391.269 Thread 0x000001a27c3fb280 Thread added: 0x000001a27c3fb280 -Event: 9391.269 Thread 0x000001a27c3fb280 Thread exited: 0x000001a27c3fb280 -Event: 9440.188 Thread 0x000001a20a12fbe0 Thread added: 0x000001a20a12fbe0 -Event: 9440.188 Thread 0x000001a20a12fbe0 Thread exited: 0x000001a20a12fbe0 -Event: 9441.322 Thread 0x000001a209279b80 Thread exited: 0x000001a209279b80 -Event: 9441.440 Thread 0x000001a27c3fabf0 Thread exited: 0x000001a27c3fabf0 -Event: 9445.806 Thread 0x000001a208cd1910 Thread added: 0x000001a208cd1910 -Event: 9445.807 Thread 0x000001a208cd1fa0 Thread added: 0x000001a208cd1fa0 -Event: 9450.868 Thread 0x000001a2356c2420 Thread added: 0x000001a2356c2420 -Event: 9450.868 Thread 0x000001a2356c2420 Thread exited: 0x000001a2356c2420 -Event: 9505.823 Thread 0x000001a208cd1fa0 Thread exited: 0x000001a208cd1fa0 -Event: 9505.948 Thread 0x000001a208cd1910 Thread exited: 0x000001a208cd1910 -Event: 10119.187 Thread 0x000001a27c769e20 Thread exited: 0x000001a27c769e20 -Event: 10119.187 Thread 0x000001a27c76ece0 Thread exited: 0x000001a27c76ece0 - - -Dynamic libraries: -0x00007ff78eda0000 - 0x00007ff78edae000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\java.exe -0x00007fffa2220000 - 0x00007fffa2486000 C:\WINDOWS\SYSTEM32\ntdll.dll -0x00007fffa03b0000 - 0x00007fffa0479000 C:\WINDOWS\System32\KERNEL32.DLL -0x00007fff9fa10000 - 0x00007fff9fe0e000 C:\WINDOWS\System32\KERNELBASE.dll -0x00007fff9f8b0000 - 0x00007fff9f9fc000 C:\WINDOWS\System32\ucrtbase.dll -0x00007fff972d0000 - 0x00007fff972eb000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\VCRUNTIME140.dll -0x00007fff972b0000 - 0x00007fff972c8000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\jli.dll -0x00007fff9ff50000 - 0x00007fffa0117000 C:\WINDOWS\System32\USER32.dll -0x00007fff86de0000 - 0x00007fff87072000 C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.26100.8894_none_3e0f749ee32e02ea\COMCTL32.dll -0x00007fff9f880000 - 0x00007fff9f8a7000 C:\WINDOWS\System32\win32u.dll -0x00007fffa0930000 - 0x00007fffa09d9000 C:\WINDOWS\System32\msvcrt.dll -0x00007fffa1a70000 - 0x00007fffa1a9b000 C:\WINDOWS\System32\GDI32.dll -0x00007fff9fe20000 - 0x00007fff9ff4a000 C:\WINDOWS\System32\gdi32full.dll -0x00007fff9f5c0000 - 0x00007fff9f663000 C:\WINDOWS\System32\msvcp_win.dll -0x00007fffa0710000 - 0x00007fffa0742000 C:\WINDOWS\System32\IMM32.DLL -0x00007fff9a9f0000 - 0x00007fff9a9fc000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\vcruntime140_1.dll -0x00007fff95b10000 - 0x00007fff95b9e000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\msvcp140.dll -0x00007fff2fb00000 - 0x00007fff30815000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\server\jvm.dll -0x00007fffa1e30000 - 0x00007fffa1ee7000 C:\WINDOWS\System32\ADVAPI32.dll -0x00007fffa0170000 - 0x00007fffa021a000 C:\WINDOWS\System32\sechost.dll -0x00007fffa1f20000 - 0x00007fffa2038000 C:\WINDOWS\System32\RPCRT4.dll -0x00007fffa0320000 - 0x00007fffa03a0000 C:\WINDOWS\System32\WS2_32.dll -0x00007fff9df40000 - 0x00007fff9df9e000 C:\WINDOWS\SYSTEM32\POWRPROF.dll -0x00007fff96e70000 - 0x00007fff96ea6000 C:\WINDOWS\SYSTEM32\WINMM.dll -0x00007fff97750000 - 0x00007fff9775b000 C:\WINDOWS\SYSTEM32\VERSION.dll -0x00007fff9df20000 - 0x00007fff9df34000 C:\WINDOWS\SYSTEM32\UMPDC.dll -0x00007fff9e200000 - 0x00007fff9e21b000 C:\WINDOWS\SYSTEM32\kernel.appcore.dll -0x00007fff992f0000 - 0x00007fff992fa000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\jimage.dll -0x00007fff9c970000 - 0x00007fff9cbb2000 C:\WINDOWS\SYSTEM32\DBGHELP.DLL -0x00007fffa1aa0000 - 0x00007fffa1e23000 C:\WINDOWS\System32\combase.dll -0x00007fffa1050000 - 0x00007fffa1129000 C:\WINDOWS\System32\OLEAUT32.dll -0x00007fff79350000 - 0x00007fff7938b000 C:\WINDOWS\SYSTEM32\dbgcore.DLL -0x00007fff9f500000 - 0x00007fff9f5ac000 C:\WINDOWS\System32\bcryptPrimitives.dll -0x00007fff959b0000 - 0x00007fff959bf000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\instrument.dll -0x00007fff95a00000 - 0x00007fff95a1f000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\java.dll -0x00007fffa12b0000 - 0x00007fffa1a42000 C:\WINDOWS\System32\SHELL32.dll -0x00007fff9cee0000 - 0x00007fff9d772000 C:\WINDOWS\SYSTEM32\windows.storage.dll -0x00007fffa0220000 - 0x00007fffa0317000 C:\WINDOWS\System32\SHCORE.dll -0x00007fffa0760000 - 0x00007fffa07c7000 C:\WINDOWS\System32\shlwapi.dll -0x00007fff9f360000 - 0x00007fff9f389000 C:\WINDOWS\SYSTEM32\profapi.dll -0x00007ffef05e0000 - 0x00007ffef06b7000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\jsvml.dll -0x00007fff959c0000 - 0x00007fff959d0000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\net.dll -0x00007fff96930000 - 0x00007fff96a57000 C:\WINDOWS\SYSTEM32\WINHTTP.dll -0x00007fff9e790000 - 0x00007fff9e7fc000 C:\WINDOWS\system32\mswsock.dll -0x00007fff88de0000 - 0x00007fff88df6000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\nio.dll -0x00007fff88da0000 - 0x00007fff88db8000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\zip.dll -0x00007fff9dbb0000 - 0x00007fff9dd06000 C:\WINDOWS\SYSTEM32\DNSAPI.dll -0x00007fff9e5b0000 - 0x00007fff9e5bd000 C:\WINDOWS\SYSTEM32\DSPARSE.dll -0x00007fff9db20000 - 0x00007fff9db53000 C:\WINDOWS\SYSTEM32\IPHLPAPI.DLL -0x00007fffa0750000 - 0x00007fffa075a000 C:\WINDOWS\System32\NSI.dll -0x00007fff97640000 - 0x00007fff9764b000 C:\Windows\System32\rasadhlp.dll -0x00007fff95fc0000 - 0x00007fff96046000 C:\WINDOWS\System32\fwpuclnt.dll -0x00007fff95970000 - 0x00007fff9597a000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\management.dll -0x00007fff88ce0000 - 0x00007fff88ceb000 C:\Users\prakt\.jdks\openjdk-21.0.1\bin\management_ext.dll -0x00007fffa06e0000 - 0x00007fffa06e8000 C:\WINDOWS\System32\PSAPI.DLL -0x000001a213310000 - 0x000001a213313000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-console-l1-1-0.dll -0x000001a213320000 - 0x000001a213323000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-console-l1-2-0.dll -0x000001a2152e0000 - 0x000001a2152e3000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-datetime-l1-1-0.dll -0x000001a2152f0000 - 0x000001a2152f3000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-debug-l1-1-0.dll -0x000001a215300000 - 0x000001a215303000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-errorhandling-l1-1-0.dll -0x000001a215310000 - 0x000001a215314000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-file-l1-1-0.dll -0x000001a215320000 - 0x000001a215323000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-file-l1-2-0.dll -0x000001a215330000 - 0x000001a215333000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-file-l2-1-0.dll -0x000001a215340000 - 0x000001a215343000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-handle-l1-1-0.dll -0x000001a215350000 - 0x000001a215353000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-heap-l1-1-0.dll -0x000001a215360000 - 0x000001a215363000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-interlocked-l1-1-0.dll -0x000001a215370000 - 0x000001a215373000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-libraryloader-l1-1-0.dll -0x000001a215380000 - 0x000001a215383000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-localization-l1-2-0.dll -0x000001a215390000 - 0x000001a215393000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-memory-l1-1-0.dll -0x000001a2153a0000 - 0x000001a2153a3000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-namedpipe-l1-1-0.dll -0x000001a235d10000 - 0x000001a235d13000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-processenvironment-l1-1-0.dll -0x000001a235d20000 - 0x000001a235d23000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-processthreads-l1-1-0.dll -0x000001a235e30000 - 0x000001a235e33000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-processthreads-l1-1-1.dll -0x000001a235e40000 - 0x000001a235e43000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-profile-l1-1-0.dll -0x000001a235e50000 - 0x000001a235e53000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-rtlsupport-l1-1-0.dll -0x000001a235e60000 - 0x000001a235e63000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-string-l1-1-0.dll -0x000001a235e70000 - 0x000001a235e73000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-synch-l1-1-0.dll -0x000001a235e80000 - 0x000001a235e83000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-synch-l1-2-0.dll -0x000001a235e90000 - 0x000001a235e93000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-sysinfo-l1-1-0.dll -0x000001a235ea0000 - 0x000001a235ea3000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-timezone-l1-1-0.dll -0x000001a235eb0000 - 0x000001a235eb3000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-core-util-l1-1-0.dll -0x000001a235ec0000 - 0x000001a235ec3000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-conio-l1-1-0.dll -0x000001a235ed0000 - 0x000001a235ed4000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-convert-l1-1-0.dll -0x000001a235ee0000 - 0x000001a235ee3000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-environment-l1-1-0.dll -0x000001a235ef0000 - 0x000001a235ef3000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-filesystem-l1-1-0.dll -0x000001a235f00000 - 0x000001a235f03000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-heap-l1-1-0.dll -0x000001a235f10000 - 0x000001a235f13000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-locale-l1-1-0.dll -0x000001a235f20000 - 0x000001a235f25000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-math-l1-1-0.dll -0x000001a235f30000 - 0x000001a235f35000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-multibyte-l1-1-0.dll -0x000001a235f40000 - 0x000001a235f50000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-private-l1-1-0.dll -0x000001a235f50000 - 0x000001a235f53000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-process-l1-1-0.dll -0x000001a235f60000 - 0x000001a235f64000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-runtime-l1-1-0.dll -0x000001a235f70000 - 0x000001a235f74000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-stdio-l1-1-0.dll -0x000001a235f80000 - 0x000001a235f84000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-string-l1-1-0.dll -0x000001a235f90000 - 0x000001a235f93000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-time-l1-1-0.dll -0x000001a235fa0000 - 0x000001a235fa3000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\api-ms-win-crt-utility-l1-1-0.dll -0x00007ffed7920000 - 0x00007ffed7a1c000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\ucrtbase.dll -0x00007fff88cc0000 - 0x00007fff88cdb000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\vcruntime140.dll -0x00007fff88cb0000 - 0x00007fff88cbc000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\vcruntime140_1.dll -0x00007ffef6950000 - 0x00007ffef69de000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\msvcp140.dll -0x00007fff88ca0000 - 0x00007fff88ca9000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\msvcp140_1.dll -0x00007fff2b6c0000 - 0x00007fff2b701000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\msvcp140_2.dll -0x00007fff9ebc0000 - 0x00007fff9ebdb000 C:\WINDOWS\SYSTEM32\CRYPTSP.dll -0x00007fff9e160000 - 0x00007fff9e199000 C:\WINDOWS\system32\rsaenh.dll -0x00007fff9e850000 - 0x00007fff9e882000 C:\WINDOWS\SYSTEM32\USERENV.dll -0x00007fff9f330000 - 0x00007fff9f35a000 C:\WINDOWS\SYSTEM32\bcrypt.dll -0x00007fff9ea00000 - 0x00007fff9ea0c000 C:\WINDOWS\SYSTEM32\CRYPTBASE.dll -0x00007fff95bf0000 - 0x00007fff95c08000 C:\WINDOWS\system32\napinsp.dll -0x00007fff95bd0000 - 0x00007fff95be3000 C:\WINDOWS\System32\winrnr.dll -0x00007fff95ba0000 - 0x00007fff95bc2000 C:\WINDOWS\system32\nlansp_c.dll -0x00007fff982c0000 - 0x00007fff982d6000 C:\WINDOWS\system32\wshbth.dll -0x00007fff42000000 - 0x00007fff42030000 C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64\prism_d3d.dll -0x00007fff27080000 - 0x00007fff27232000 C:\WINDOWS\system32\d3d9.dll -0x00007fff9c270000 - 0x00007fff9c29f000 C:\WINDOWS\SYSTEM32\dwmapi.dll -0x00007fff9c340000 - 0x00007fff9c386000 C:\WINDOWS\SYSTEM32\dxcore.dll -0x00007fff9bca0000 - 0x00007fff9bd49000 C:\WINDOWS\system32\uxtheme.dll -0x00007fff7ad00000 - 0x00007fff7adc3000 C:\WINDOWS\SYSTEM32\d3d9on12.dll -0x00007fff9c100000 - 0x00007fff9c23e000 C:\WINDOWS\SYSTEM32\dxgi.dll -0x00007fff81650000 - 0x00007fff81673000 C:\WINDOWS\SYSTEM32\d3d12.dll -0x00007fff9f080000 - 0x00007fff9f0d1000 C:\WINDOWS\SYSTEM32\cfgmgr32.dll -0x00007fff3e4c0000 - 0x00007fff3e817000 C:\WINDOWS\SYSTEM32\D3D12Core.dll -0x00007fff80dd0000 - 0x00007fff80e28000 C:\WINDOWS\SYSTEM32\pdh.dll -0x00007fff407f0000 - 0x00007fff408f7000 C:\WINDOWS\System32\DriverStore\FileRepository\iigd_dch.inf_amd64_a582115f5de863e1\igd12umd64.dll -0x00007fff37060000 - 0x00007fff37f65000 C:\WINDOWS\System32\DriverStore\FileRepository\iigd_dch.inf_amd64_a582115f5de863e1\igd12um64xel.dll -0x00007fff9f670000 - 0x00007fff9f7e8000 C:\WINDOWS\System32\CRYPT32.dll -0x00007fffa2040000 - 0x00007fffa21d9000 C:\WINDOWS\System32\ole32.dll -0x00007fff76f50000 - 0x00007fff76f94000 C:\WINDOWS\SYSTEM32\ControlLib.dll -0x00007fffa0b30000 - 0x00007fffa0fb7000 C:\WINDOWS\System32\SETUPAPI.dll - -dbghelp: loaded successfully - version: 4.0.5 - missing functions: none -symbol engine: initialized successfully - sym options: 0x614 - pdb path: .;C:\Users\prakt\.jdks\openjdk-21.0.1\bin;C:\WINDOWS\SYSTEM32;C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.26100.8894_none_3e0f749ee32e02ea;C:\Users\prakt\.jdks\openjdk-21.0.1\bin\server;C:\Users\prakt\.openjfx\cache\21.0.5+1\amd64;C:\WINDOWS\System32\DriverStore\FileRepository\iigd_dch.inf_amd64_a582115f5de863e1;C:\Users\prakt\AppData\Local\Temp;C:\Program Files\Common Files\Microsoft Shared\Ink - -VM Arguments: -jvm_args: -javaagent:C:\Users\prakt\AppData\Local\Programs\IntelliJ IDEA Community Edition\lib\idea_rt.jar=50765 -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 --module-path=C:\Users\prakt\.m2\repository\org\openjfx\javafx-controls\21.0.5\javafx-controls-21.0.5-win.jar;C:\Users\prakt\.m2\repository\org\junit\jupiter\junit-jupiter-api\5.10.1\junit-jupiter-api-5.10.1.jar;C:\Users\prakt\.m2\repository\javazoom\jlayer\1.0.1\jlayer-1.0.1.jar;C:\Users\prakt\.m2\repository\org\apiguardian\apiguardian-api\1.1.2\apiguardian-api-1.1.2.jar;C:\Users\prakt\.m2\repository\org\openjfx\javafx-web\21.0.5\javafx-web-21.0.5-win.jar;C:\Users\prakt\IdeaProjects\kst4contest\target\classes;C:\Users\prakt\.m2\repository\org\openjfx\javafx-fxml\21.0.5\javafx-fxml-21.0.5-win.jar;C:\Users\prakt\.m2\repository\org\xerial\sqlite-jdbc\3.43.2.2\sqlite-jdbc-3.43.2.2.jar;C:\Users\prakt\.m2\repository\org\mockito\mockito-core\5.17.0\mockito-core-5.17.0.jar;C:\Users\prakt\.m2\repository\org\openjfx\javafx-media\21.0.5\javafx-media-21.0.5-win.jar;C:\Users\prakt\.m2\repository\net\bytebuddy\byte-buddy\1.15.11\byte-buddy-1.15.11.jar;C:\Users\prakt\.m2\repository\org\openjfx\javafx-base\21.0.5\javafx-base-21.0.5-win.jar;C:\Users\prakt\.m2\repository\net\bytebuddy\byte-buddy-agent\1.15.11\byte-buddy-agent-1.15.11.jar;C:\Users\prakt\.m2\repository\org\openjfx\javafx-graphics\21.0.5\javafx-graphics-21.0.5-win.jar;C:\Users\prakt\.m2\repository\org\opentest4j\opentest4j\1.3.0\opentest4j-1.3.0.jar;C:\Users\prakt\.m2\repository\org\slf4j\slf4j-api\1.7.36\slf4j-api-1.7.36.jar;C:\Users\prakt\.m2\repository\org\objenesis\objenesis\3.3\objenesis-3.3.jar;C:\Users\prakt\.m2\repository\org\junit\platform\junit-platform-commons\1.10.1\junit-platform-commons-1.10.1.jar -Djdk.module.main=praktiKST -java_command: praktiKST/kst4contest.view.Kst4ContestApplication -java_class_path (initial): C:\Users\prakt\.m2\repository\org\openjfx\javafx-controls\21.0.5\javafx-controls-21.0.5.jar;C:\Users\prakt\.m2\repository\org\openjfx\javafx-graphics\21.0.5\javafx-graphics-21.0.5.jar;C:\Users\prakt\.m2\repository\org\openjfx\javafx-base\21.0.5\javafx-base-21.0.5.jar;C:\Users\prakt\.m2\repository\org\openjfx\javafx-fxml\21.0.5\javafx-fxml-21.0.5.jar;C:\Users\prakt\.m2\repository\org\openjfx\javafx-web\21.0.5\javafx-web-21.0.5.jar;C:\Users\prakt\.m2\repository\org\openjfx\javafx-media\21.0.5\javafx-media-21.0.5.jar;C:\Users\prakt\.m2\repository\org\jetbrains\annotations\24.0.1\annotations-24.0.1.jar -Launcher Type: SUN_STANDARD - -[Global flags] - intx CICompilerCount = 12 {product} {ergonomic} - uint ConcGCThreads = 4 {product} {ergonomic} - uint G1ConcRefinementThreads = 15 {product} {ergonomic} - size_t G1HeapRegionSize = 2097152 {product} {ergonomic} - uintx GCDrainStackTargetSize = 64 {product} {ergonomic} - size_t InitialHeapSize = 264241152 {product} {ergonomic} - size_t MarkStackSize = 4194304 {product} {ergonomic} - size_t MaxHeapSize = 4223664128 {product} {ergonomic} - size_t MaxNewSize = 2533359616 {product} {ergonomic} - size_t MinHeapDeltaBytes = 2097152 {product} {ergonomic} - size_t MinHeapSize = 8388608 {product} {ergonomic} - uintx NonNMethodCodeHeapSize = 7602480 {pd product} {ergonomic} - uintx NonProfiledCodeHeapSize = 122027880 {pd product} {ergonomic} - uintx ProfiledCodeHeapSize = 122027880 {pd product} {ergonomic} - uintx ReservedCodeCacheSize = 251658240 {pd product} {ergonomic} - bool SegmentedCodeCache = true {product} {ergonomic} - size_t SoftMaxHeapSize = 4223664128 {manageable} {ergonomic} - bool UseCompressedOops = true {product lp64_product} {ergonomic} - bool UseG1GC = true {product} {ergonomic} - bool UseLargePagesIndividualAllocation = false {pd product} {ergonomic} - -Logging: -Log output configuration: - #0: stdout all=warning uptime,level,tags foldmultilines=false - #1: stderr all=off uptime,level,tags foldmultilines=false - -Environment Variables: -JAVA_HOME=C:\Program Files\Java\jdk-17\bin -PATH=C:\Program Files\Common Files\Oracle\Java\javapath;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\PuTTY\;C:\Program Files\Git\cmd;C:\WSJT\wsjtx\bin;C:\Program Files (x86)\Bitvise SSH Client;C:\Program Files\WireGuard\;C:\Program Files\dotnet\;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;C:\Program Files\Microsoft SQL Server\170\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\Program Files\nodejs\;C:\Program Files\Docker\Docker\resources\bin;C:\Users\prakt\AppData\Local\Microsoft\WindowsApps;C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2023.2.5\bin;C:\Users\prakt\AppData\Local\JetBrains\Toolbox\scripts;;C:\Users\prakt\AppData\Local\Microsoft\WindowsApps;C:\Users\prakt\AppData\Local\Python\bin;C:\Users\prakt\AppData\Roaming\npm -USERNAME=prakt -OS=Windows_NT -PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 154 Stepping 3, GenuineIntel -TMP=C:\Users\prakt\AppData\Local\Temp -TEMP=C:\Users\prakt\AppData\Local\Temp - - - - -Periodic native trim disabled - ---------------- S Y S T E M --------------- - -OS: - Windows 11 , 64 bit Build 26100 (10.0.26100.8875) -OS uptime: 11 days 9:25 hours -Hyper-V role detected - -CPU: total 20 (initial active 20) (10 cores per cpu, 2 threads per core) family 6 model 154 stepping 3 microcode 0x432, 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 processor 0 - Max Mhz: 2300, Current Mhz: 2300, Mhz Limit: 2300 -Processor Information for processor 1 - Max Mhz: 2300, Current Mhz: 2300, Mhz Limit: 2300 -Processor Information for processor 2 - Max Mhz: 2300, Current Mhz: 1506, Mhz Limit: 2300 -Processor Information for processor 3 - Max Mhz: 2300, Current Mhz: 2300, Mhz Limit: 2300 -Processor Information for processor 4 - Max Mhz: 2300, Current Mhz: 2300, Mhz Limit: 2300 -Processor Information for processor 5 - Max Mhz: 2300, Current Mhz: 2300, Mhz Limit: 2300 -Processor Information for processor 6 - Max Mhz: 2300, Current Mhz: 1506, Mhz Limit: 2300 -Processor Information for processor 7 - Max Mhz: 2300, Current Mhz: 1506, Mhz Limit: 2300 -Processor Information for processor 8 - Max Mhz: 2300, Current Mhz: 2300, Mhz Limit: 2300 -Processor Information for processor 9 - Max Mhz: 2300, Current Mhz: 2300, Mhz Limit: 2300 -Processor Information for processor 10 - Max Mhz: 2300, Current Mhz: 2300, Mhz Limit: 2300 -Processor Information for processor 11 - Max Mhz: 2300, Current Mhz: 2300, Mhz Limit: 2300 -Processor Information for processor 12 - Max Mhz: 2300, Current Mhz: 1700, Mhz Limit: 1679 -Processor Information for processor 13 - Max Mhz: 2300, Current Mhz: 1500, Mhz Limit: 1679 -Processor Information for processor 14 - Max Mhz: 2300, Current Mhz: 1500, Mhz Limit: 1679 -Processor Information for processor 15 - Max Mhz: 2300, Current Mhz: 1500, Mhz Limit: 1679 -Processor Information for processor 16 - Max Mhz: 2300, Current Mhz: 1500, Mhz Limit: 1679 -Processor Information for processor 17 - Max Mhz: 2300, Current Mhz: 1700, Mhz Limit: 1679 -Processor Information for processor 18 - Max Mhz: 2300, Current Mhz: 1500, Mhz Limit: 1679 -Processor Information for processor 19 - Max Mhz: 2300, Current Mhz: 1700, Mhz Limit: 1679 - -Memory: 4k page, system-wide physical 16108M (866M free) -TotalPageFile size 44780M (AvailPageFile size 17359M) -current process WorkingSet (physical memory assigned to process): 681M, peak: 926M -current process commit charge ("private bytes"): 1052M, peak: 1127M - -vm_info: OpenJDK 64-Bit Server VM (21.0.1+12-29) for windows-amd64 JRE (21.0.1+12-29), built on 2023-10-05T13:27:09Z by "mach5one" with MS VC++ 17.1 (VS2022) - -END.