Skip to content

Upgrade io.jsonwebtoken JJWT family 0.11.2 -> 0.12.6 - #201

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1785171657-upgrade-jjwt-0.12.6
Open

Upgrade io.jsonwebtoken JJWT family 0.11.2 -> 0.12.6#201
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1785171657-upgrade-jjwt-0.12.6

Conversation

@devin-ai-integration

Copy link
Copy Markdown

Summary

Upgrades the JJWT artifact family 0.11.2 -> 0.12.6 (latest stable on Maven Central, published 2024-06-21) and migrates DefaultJwtService to the 0.12 fluent API, which dropped the set* builder setters and Jwts.parserBuilder(). No Spring Boot / plugin / other dependency versions were touched.

Coordinate diff (build.gradle)

-    implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
-    runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.2',
-                'io.jsonwebtoken:jjwt-jackson:0.11.2'
+    implementation 'io.jsonwebtoken:jjwt-api:0.12.6'
+    runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6',
+                'io.jsonwebtoken:jjwt-jackson:0.12.6'

BOM / ext override

None needed. The Spring Boot 2.6.3 dependency-management BOM does not manage io.jsonwebtoken, so the literal versions win outright — confirmed below. JJWT 0.12.6 targets Java 8+ and has no Spring dependency, so it is compatible with the Boot 2.6.3 / Java 11 ceiling.

dependencyInsight evidence (target version actually resolved)

$ JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 ./gradlew dependencyInsight \
    --configuration runtimeClasspath --dependency io.jsonwebtoken

io.jsonwebtoken:jjwt-api:0.12.6 (selected by rule)
io.jsonwebtoken:jjwt-api:0.12.6
+--- runtimeClasspath
+--- io.jsonwebtoken:jjwt-impl:0.12.6
|    \--- runtimeClasspath
\--- io.jsonwebtoken:jjwt-jackson:0.12.6
     \--- runtimeClasspath

io.jsonwebtoken:jjwt-impl:0.12.6 (selected by rule)
io.jsonwebtoken:jjwt-jackson:0.12.6 (selected by rule)

All three artifacts resolve at 0.12.6 — no conflict-resolution downgrade, no split family.

API migration (DefaultJwtService)

Only one file in src/ references io.jsonwebtoken (verified by grep -rn "io.jsonwebtoken" src/).

-  private final SignatureAlgorithm signatureAlgorithm;      // field removed
-  signatureAlgorithm = SignatureAlgorithm.HS512;
-  this.signingKey = new SecretKeySpec(secret.getBytes(), signatureAlgorithm.getJcaName());
+  this.signingKey = Keys.hmacShaKeyFor(secret.getBytes());

-  Jwts.builder().setSubject(id).setExpiration(exp).signWith(signingKey)
+  Jwts.builder().subject(id).expiration(exp).signWith(signingKey)

-  Jwts.parserBuilder().setSigningKey(signingKey).build().parseClaimsJws(token).getBody()
+  Jwts.parser().verifyWith(signingKey).build().parseSignedClaims(token).getPayload()

Key construction now uses the library's own Keys.hmacShaKeyFor(...) instead of a hand-built SecretKeySpec with a hard-coded HmacSHA512 JCA name. This is behaviour-preserving, not a weakening: both 0.11's signWith(Key) and Keys.hmacShaKeyFor derive the HMAC-SHA variant from the key's bit length, so the signing algorithm for a given secret is unchanged. Keys.hmacShaKeyFor additionally fails fast on secrets under 256 bits (JWA minimum).

Key-size note (no change made, no security behaviour weakened):

  • jwt.secret in src/main/resources/application.properties is 86 bytes / 688 bits — above the 512-bit HS512 minimum, so it keeps signing with HS512.
  • The secret hard-coded in DefaultJwtServiceTest is 60 bytes / 480 bits, which selected HS384 before this change and still selects HS384 after it. No test assertion, secret, or threshold was modified.

Also updated the one stale 0.11.2 reference in the repo's dependency table (.agents/skills/java-engineering-excellence/SKILL.md).

Verification gate

$ JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 \
    ./gradlew clean test spotlessCheck -x jacocoTestCoverageVerification
> Task :test
> Task :spotlessCheck
BUILD SUCCESSFUL in 17s
tests 68  failures 0  errors 0  skipped 0

Baseline recorded first-hand on untouched main (3037fa5) with the identical command: 68 tests, 0 failures, 0 errors, 0 skipped, BUILD SUCCESSFUL. Post-change counts are identical — same test count, zero new failures. spotlessApply was run before committing.

Pre-existing on base, not addressed here

  • jacocoTestCoverageVerification fails on main at ~0.33 instruction coverage against the 0.80 rule in build.gradle. CI runs the suite with -x jacocoTestCoverageVerification, and this gate is excluded here too. The threshold was not lowered and no tests were added to raise coverage.
  • Selenium E2E tests (src/test/java/io/spring/selenium, separate seleniumTest TestNG task) are excluded from the test task and are not part of this gate — unchanged by this PR.

Link to Devin session: https://partner-workshops.devinenterprise.com/sessions/6ee60a8e7e1040849adec21288dc9ff0
Requested by: @mbatchelor81

@mbatchelor81 mbatchelor81 self-assigned this Jul 27, 2026
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

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.

1 participant