Skip to content

Implement Dependabot findings: JUnit 6.1.3, Groovy 5.1.0, nativeimage 25.2.4, android-emulator-runner 2.38.0 - #2960

Merged
riccardobl merged 3 commits into
jMonkeyEngine:masterfrom
jaime-jmebot:jaime/issue-2958-414d1ac8
Sep 17, 2026
Merged

riccardobl merged 3 commits into
jMonkeyEngine:masterfrom
jaime-jmebot:jaime/issue-2958-414d1ac8

Conversation

@jaime-jmebot

@jaime-jmebot jaime-jmebot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Tracks #2958

Implementation plan

  • Prepare the bot fork and implementation branch
  • Align JUnit to 6.1.3 (libs.versions.toml + the two hardcoded screenshot-test pins)
  • Bump org.apache.groovy:groovy-test to 5.1.0
  • Bump org.graalvm.sdk:nativeimage to 25.2.4 (svm stays 25.0.3)
  • Bump reactivecircus/android-emulator-runner to v2.38.0
  • Migrate AppStateManagerTest.groovy from groovy.test.GroovyTestCase to JUnit 5 Jupiter
  • Compile JUnit-6 consumers with release 17 in common.gradle while keeping the engine on Java 8
  • Run the available static validation (metadata syntax, version consistency, migration and build-rule checks)
  • Run and validate tests
  • Publish the validated patch
  • Mark this pull request ready for review

Progress summary

Apply the four open Dependabot dependency updates in jMonkeyEngine/jmonkeyengine and fix the build fallout, without touching unrelated dependencies (in particular do NOT change org.graalvm.nativeimage:svm, mockito, or any engine version).

Tests

7 approved test command(s) completed successfully in the sandbox

This checklist is maintained automatically by Jaime.

Result

Implements the four open Dependabot findings for #2958, plus the minimum build fallout they cause.

Dependency updates

Finding File Change
#2955 gradle/libs.versions.toml org.junit:junit-bom 5.13.4 → 6.1.3
#2955 jme3-screenshot-tests-shared/build.gradle, jme3-screenshot-tests-desktop/build.gradle hardcoded org.junit:junit-bom / useJUnitJupiter 5.9.1 → 6.1.3 (all JUnit usages now resolve to one version)
#2956 gradle/libs.versions.toml org.apache.groovy:groovy-test 4.0.31 → 5.1.0
#2957 jme3-nativeimage-plugin/build.gradle org.graalvm.sdk:nativeimage 25.0.3 → 25.2.4 (org.graalvm.nativeimage:svm deliberately left at 25.0.3, as in the Dependabot PR)
#2933 .github/workflows/android-screenshot.yml reactivecircus/android-emulator-runner v2.37.0 → v2.38.0

Required fallout fixes

jme3-core/src/test/groovy/com/jme3/app/state/AppStateManagerTest.groovy — migrated from the JUnit-3-based groovy.test.GroovyTestCase (removed in Groovy 5) to JUnit 5 Jupiter. The old file also could never run: its test classes were nested static classes extending GroovyTestCase, which useJUnitPlatform() does not discover. All 8 original cases and assertions are preserved (group names carried into the method names); shouldFail(IllegalArgumentException) {} became assertThrows(IllegalArgumentException, { … } as Executable) and the assertion helpers are statically imported, matching the style of the Java test sources.

common.gradle — JUnit 6 is compiled for Java 17, while every JavaCompile task in this build uses options.release = 8, so javac rejects the JUnit 6 jars. options.release is now raised to 17 for test compilation (all modules) and for the main compilation of the :jme3-screenshot-tests:* framework modules, whose main sources use JUnit (e.g. ScreenshotTest.java imports org.junit.jupiter.api.Assertions.fail). The engine itself still targets Java 8.

No other dependency was touched.

Validation status (read before approving)

Performed in the sandbox on a clean checkout of the patch:

  • gradle/libs.versions.toml parses; junit-bom = …6.1.3, groovy-test = …5.1.0.
  • .github/workflows/android-screenshot.yml parses as YAML; runner pinned at @v2.38.0.
  • version audit: no junit-bom:5*, groovy-test:4*, nativeimage:25.0.3 (only svm:25.0.3 remains), emulator-runner@v2.37.0 or 5.9.1 anywhere in the touched files.
  • AppStateManagerTest.groovy: no GroovyTestCase reference left in the repo, 8 @Test methods, 4 assertThrows uses.
  • evidence for the release-17 rule: the shared screenshot-test module's main sources import org.junit.

Not performed here: compiling and running the test suite. This sandbox has no route to services.gradle.org (the Gradle wrapper distribution download fails) and no Android SDK, so ./gradlew cannot run at all — neither :jme3-core:test nor the isolated jme3-nativeimage-plugin compile against nativeimage 25.2.4 could be executed. Nothing in this description should be read as a passing build.

So CI must be the gate for this PR (BuildJMonkey, Checkstyle, ScreenshotTests, android-screenshot), and a local ./gradlew :jme3-core:test is the fastest pre-merge confirmation.

Known residual risks to watch in CI:

  1. compileTestJava/compileJava now use --release 17; if the release-17 override does not win over the shared options.release = 8 block, javac will report "class file has wrong version 61.0" for the JUnit 6 jars — that is the exact symptom to look for.
  2. mockito-junit-jupiter 5.23.0 was intentionally not bumped; if its Jupiter extension does not accept JUnit 6 at runtime, the affected tests will fail with an API/NoSuchMethodError and Mockito would need a companion bump (reported here rather than worked around).
  3. The Android app module dexes JUnit 6 (Java 17 class files) transitively through the shared module; AGP 9.1 should accept that, but it can only be confirmed by the Android build.

… 25.2.4, android-emulator-runner 2.38.0

Implements the four open Dependabot findings for jMonkeyEngine#2958, plus the minimum build fallout they cause.

## Dependency updates

| Finding | File | Change |
| --- | --- | --- |
| jMonkeyEngine#2955 | `gradle/libs.versions.toml` | `org.junit:junit-bom` 5.13.4 → 6.1.3 |
| jMonkeyEngine#2955 | `jme3-screenshot-tests-shared/build.gradle`, `jme3-screenshot-tests-desktop/build.gradle` | hardcoded `org.junit:junit-bom` / `useJUnitJupiter` 5.9.1 → 6.1.3 (all JUnit usages now resolve to one version) |
| jMonkeyEngine#2956 | `gradle/libs.versions.toml` | `org.apache.groovy:groovy-test` 4.0.31 → 5.1.0 |
| jMonkeyEngine#2957 | `jme3-nativeimage-plugin/build.gradle` | `org.graalvm.sdk:nativeimage` 25.0.3 → 25.2.4 (`org.graalvm.nativeimage:svm` deliberately left at 25.0.3, as in the Dependabot PR) |
| jMonkeyEngine#2933 | `.github/workflows/android-screenshot.yml` | `reactivecircus/android-emulator-runner` v2.37.0 → v2.38.0 |

## Required fallout fixes

**`jme3-core/src/test/groovy/com/jme3/app/state/AppStateManagerTest.groovy`** — migrated from the JUnit-3-based `groovy.test.GroovyTestCase` (removed in Groovy 5) to JUnit 5 Jupiter. The old file also could never run: its test classes were nested `static` classes extending `GroovyTestCase`, which `useJUnitPlatform()` does not discover. All 8 original cases and assertions are preserved (group names carried into the method names); `shouldFail(IllegalArgumentException) {}` became `assertThrows(IllegalArgumentException, { … } as Executable)` and the assertion helpers are statically imported, matching the style of the Java test sources.

**`common.gradle`** — JUnit 6 is compiled for Java 17, while every `JavaCompile` task in this build uses `options.release = 8`, so javac rejects the JUnit 6 jars. `options.release` is now raised to 17 for test compilation (all modules) and for the main compilation of the `:jme3-screenshot-tests:*` framework modules, whose main sources use JUnit (e.g. `ScreenshotTest.java` imports `org.junit.jupiter.api.Assertions.fail`). The engine itself still targets Java 8.

No other dependency was touched.

## Validation status (read before approving)

Performed in the sandbox on a clean checkout of the patch:

* `gradle/libs.versions.toml` parses; `junit-bom = …6.1.3`, `groovy-test = …5.1.0`.
* `.github/workflows/android-screenshot.yml` parses as YAML; runner pinned at `@v2.38.0`.
* version audit: no `junit-bom:5*`, `groovy-test:4*`, `nativeimage:25.0.3` (only `svm:25.0.3` remains), `emulator-runner@v2.37.0` or `5.9.1` anywhere in the touched files.
* `AppStateManagerTest.groovy`: no `GroovyTestCase` reference left in the repo, 8 `@Test` methods, 4 `assertThrows` uses.
* evidence for the release-17 rule: the shared screenshot-test module's **main** sources import `org.junit`.

**Not performed here:** compiling and running the test suite. This sandbox has no route to `services.gradle.org` (the Gradle wrapper distribution download fails) and no Android SDK, so `./gradlew` cannot run at all — neither `:jme3-core:test` nor the isolated `jme3-nativeimage-plugin` compile against nativeimage 25.2.4 could be executed. Nothing in this description should be read as a passing build.

So CI must be the gate for this PR (`BuildJMonkey`, `Checkstyle`, `ScreenshotTests`, `android-screenshot`), and a local `./gradlew :jme3-core:test` is the fastest pre-merge confirmation.

Known residual risks to watch in CI:

1. `compileTestJava`/`compileJava` now use `--release 17`; if the release-17 override does not win over the shared `options.release = 8` block, javac will report "class file has wrong version 61.0" for the JUnit 6 jars — that is the exact symptom to look for.
2. `mockito-junit-jupiter` 5.23.0 was intentionally **not** bumped; if its Jupiter extension does not accept JUnit 6 at runtime, the affected tests will fail with an API/`NoSuchMethodError` and Mockito would need a companion bump (reported here rather than worked around).
3. The Android app module dexes JUnit 6 (Java 17 class files) transitively through the shared module; AGP 9.1 should accept that, but it can only be confirmed by the Android build.
@jaime-jmebot jaime-jmebot changed the title Dependabot findings: JUnit 6.1.3, Groovy 5.1.0, nativeimage 25.2.4, android-emulator-runner 2.38.0 Implement Dependabot findings: JUnit 6.1.3, Groovy 5.1.0, nativeimage 25.2.4, android-emulator-runner 2.38.0 Sep 17, 2026
@jaime-jmebot
jaime-jmebot marked this pull request as ready for review September 17, 2026 08:06
@riccardobl

Copy link
Copy Markdown
Member

@jaime-jmebot the CI fails, fix this PR

@jaime-jmebot

Copy link
Copy Markdown
Contributor Author

Confirmed from CI run 35197961153 and 35197961087. Root cause is not the --release 17 rule or Groovy; it is JUnit 6 in the Android dex inputs.

Failing jobs

  • Build on linux/mac/windows jdk25 — all three fail at :jme3-screenshot-tests:jme3-screenshot-tests-android:mergeExtDexDebug:
    Execution failed for task '...:jme3-screenshot-tests-android:mergeExtDexDebug'
    > Could not resolve all files for configuration '...:debugRuntimeClasspath'.
       > Failed to transform junit-jupiter-engine-6.1.3.jar ... > Error while dexing.
    ERROR: D8: Invalid build configuration. Attempt to create a global synthetic
    for 'Record desugaring' without a global-synthetics consumer.
    
    Same for junit-jupiter-api, junit-jupiter-params, junit-platform-engine, junit-platform-commons 6.1.3. The dexing component attributes show minSdkVersion=28, enableGlobalSynthetics=false: JUnit 6 jars are Java 17 class files containing records, and the external-library dex transform of the app module cannot desugar them. With 5.9.1 the same jars were Java 8 and dexed fine, so the bump is what breaks it.
  • screenshot-test-android fails downstream of that (no APK built, then report/screenshotProtoReport.json missing).

Passing: Run Checkstyle, Run SpotBugs, Run Javadoc Doclint, Run Screenshot Tests (opengl), Run Screenshot Tests (angle), Test iOS build.

Next step: JUnit 6 must not reach :jme3-screenshot-tests:jme3-screenshot-tests-android's runtime classpath (it currently arrives transitively through :jme3-screenshot-tests:jme3-screenshot-tests-shared's implementation JUnit dependency). I'll take the write phase to make that change along with a CI re-run; no patch is proposed in this comment.

The shared framework's JUnit Jupiter dependency is now compileOnly, so JUnit 6.1.3 no longer reaches the Android app's runtime classpath (D8 record-desugaring failure at mergeExtDexDebug).
@jaime-jmebot
jaime-jmebot marked this pull request as draft September 17, 2026 10:11
@jaime-jmebot

Copy link
Copy Markdown
Contributor Author

Fixed in 952cd4b.

Change (jme3-screenshot-tests/jme3-screenshot-tests-shared/build.gradle, the only file touched):

compileOnly platform('org.junit:junit-bom:6.1.3')
compileOnly 'org.junit.jupiter:junit-jupiter'

testImplementation platform('org.junit:junit-bom:6.1.3')
testImplementation 'org.junit.jupiter:junit-jupiter'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

JUnit Jupiter is no longer an implementation dependency of the shared framework, so JUnit 6.1.3 is gone from the runtime classpath that :jme3-screenshot-tests:jme3-screenshot-tests-android inherits. That removes the Java 17 record-containing jars from the app's dex inputs, which is what produced the D8 ... 'Record desugaring' ... global-synthetics consumer failure at mergeExtDexDebug. The module's own JUnit 5 unit tests still get the full Jupiter dependency plus the platform launcher (version-managed by the BOM on the test configurations), and useJUnitJupiter('6.1.3') is unchanged.

Why compileOnly is sufficient rather than merely convenient: the framework's main sources reference JUnit only in imports (ScreenshotTest, TestDriver, ScreenshotTestBase) and never call into it, so nothing on the device resolves those classes at runtime. The Android app and its instrumentation tests use JUnit 4 only (org.junit.Assert, @Rule via androidx.test.ext:junit), and the JUnit BOM no longer constrains any runtime configuration. Note that other Java 17 jars (Jackson 3.x) already dexed fine before this bump, so class file version 61 was not the problem — records were.

Validation run in the sandbox (4 commands): the compile-only/test wiring in shared/build.gradle, no JUnit 5 dependency on any runtime classpath of shared/android/proto-report, and no non-import JUnit reference in the framework's main sources. The Gradle build itself cannot run in this sandbox (no wrapper distribution and no Android SDK), so this still needs CI confirmation — mergeExtDexDebug and screenshot-test-android are the two jobs to watch.

@riccardobl

Copy link
Copy Markdown
Member

@jaime-jmebot android CI is still failing

@jaime-jmebot

Copy link
Copy Markdown
Contributor Author

Checked the run for the current head (952cd4b, run 35209217479). The Android build breakage is gone; the remaining red is a flaky screenshot comparison that also fails on master.

What is fixed on this head

  • Build on linux/mac/windows jdk25 all pass, as do Checkstyle, SpotBugs, Javadoc Doclint, both desktop screenshot suites and the iOS build.
  • In screenshot-test-android, mergeExtDexDebug, mergeLibDexDebug, dexBuilderDebug and both APK packaging steps now complete; the previous D8: ... 'Record desugaring' ... global-synthetics consumer error is gone. The compileOnly change in jme3-screenshot-tests-shared/build.gradle did what it was meant to do.

What still fails

  • :jme3-screenshot-tests:jme3-screenshot-tests-android:connectedDebugAndroidTest — the emulator runs all 12 instrumentation tests, 11 pass, 1 fails: org.jmonkeyengine.screenshottests.android.effects.TestExplosionEffect.testExplosionEffectAssertionError: Generated images is different from committed image at ScreenshotTest.bootAppForTest (the frame-15 explosion image, changed file 442,598 bytes).
  • This is not a regression of this PR. The diff touches no rendering, scenario, app or reference-image file (only libs.versions.toml, common.gradle, the two screenshot build.gradle files, the shared build.gradle, jme3-nativeimage-plugin/build.gradle, android-screenshot.yml and AppStateManagerTest.groovy), and the same test fails on master: run 35126140847 (commit 0af47ac) fails identically, with the same 442,598-byte changed image, while master's next commit 1a3e7ef — this PR's base — passes the job. That is failure/success toggling without any dependency change, i.e. a flaky, environment-sensitive image comparison.

What I need

  • A re-run of the failed screenshot-test-android job (or a fresh CI run) — I have no tool in this session to re-trigger a workflow.
  • I'm not going to make it green by editing that test or its reference image inside a dependency-update PR; if maintainers want it stabilised (e.g. KNOWN_TO_FAIL/tolerance), that belongs in its own change.

@riccardobl
riccardobl marked this pull request as ready for review September 17, 2026 17:06
@riccardobl
riccardobl merged commit 37286e3 into jMonkeyEngine:master Sep 17, 2026
13 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants