fix: bundle SLF4J runtime deps for GeometryMappingJob standalone JVM#47
Merged
Merged
Conversation
kachosohrab
approved these changes
May 14, 2026
vibincv
approved these changes
May 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the
NoClassDefFoundError: org/slf4j/LoggerFactorythat crashes the Geometry Mapping phase ofrun-tile-pipeline.sh, seen on the dev cluster as exit-1 fromvalhalla-tile-pipelineafter the:development-latestimage was refreshed and the phase started executing for the first time.Root cause
The published
valhalla-jni-*.jaris intentionally thin — project classes + native libs only — so Spring Boot consumers liketada-routing-servicecan bring their owntransitive deps. But
deploy/scripts/run-tile-pipeline.shruns the geometry mapping job as a standalone JVM process:java -cp /app/valhalla-jni.jar global.tada.valhalla.traffic.sg.GeometryMappingJob
With only the thin JAR on the classpath,
GeometryMappingJob.kt:46'sLoggerFactory.getLogger(...)throwsNoClassDefFoundErroron the static initializer — the class neverloads, the JVM exits 1, and the pipeline's geometry mapping step bails before it can write
geometry_mapping.jsonto EFS.Changes
libs.versions.toml— addslf4j-simplelibrary alias.build.gradle.kts— addruntimeOnly(libs.slf4j.simple)(only for the standalone JVM path; Spring Boot consumers bring their own SLF4J binding via their ownruntimeClasspathand don't seeruntimeOnly). Register a newcopyRuntimeDepstask — explicitly invoked fromDockerfile.prod, not wired tojar/assembleso mavenconsumers don't pay for it.
Dockerfile.prod— invokecopyRuntimeDepsalongsidebuild; copybuild/libs/runtime/*.jarinto/app/lib/.run-tile-pipeline.sh— extend the java-cpfrom"${jar}"to"${jar}:/app/lib/*".Verification
Tested locally before committing:
./gradlew tasks --alllistscopyRuntimeDepsunder Build tasks with the right description ✓./gradlew copyRuntimeDepswrites 7 jars tobuild/libs/runtime/:slf4j-api-2.0.16.jarslf4j-simple-2.0.16.jarkotlin-stdlib-2.0.21.jarkotlin-reflect-2.0.21.jarkotlinx-coroutines-core-jvm-1.9.0.jarjson-20240303.jarannotations-23.0.0.jarProject's own
valhalla-jni-*.jaris not included (Gradle'sruntimeClasspathexcludes the project's own output by convention — confirmed empirically). ✓End-to-end class load check:
java -cp valhalla-jni-1.0.0-SNAPSHOT.jar:build/libs/runtime/* \ global.tada.valhalla.traffic.sg.GeometryMappingJob Now logs cleanly via SLF4J:[main] INFO global.tada.valhalla.traffic.sg.GeometryMappingJob - === Geometry Mapping Job starting ===
[main] ERROR global.tada.valhalla.traffic.sg.GeometryMappingJob - VALHALLA_TILE_DIR environment variable is required
The ERROR is the expected fail-fast — VALHALLA_TILE_DIR is set in production by the pipeline; here it's just proving the class loads, LoggerFactory is reachable, and the
binding emits to stderr. Before this fix, neither line appeared because the class never loaded. ✓
Impact on existing consumers
The published valhalla-jni-*.jar keeps its name, coordinates and contents. tada-routing-service's vendored copy at libs/valhalla-jni-1.0.0-SNAPSHOT.jar is unaffected by this
change.
Follow-up after merge