Migrate build.gradle from Java 11 to Java 17#354
Migrate build.gradle from Java 11 to Java 17#354devin-ai-integration[bot] wants to merge 2 commits intomasterfrom
Conversation
- Update sourceCompatibility/targetCompatibility to 17 - Upgrade Spring Boot 2.6.3 -> 2.7.18 - Upgrade Spring Dependency Management 1.0.11 -> 1.1.6 - Upgrade Netflix DGS 4.9.21 -> 5.5.1 with platform BOM - Upgrade DGS Codegen plugin 5.0.6 -> 5.6.9 - Upgrade JJWT 0.11.2 -> 0.12.6 (new API: subject/expiration/parseSignedClaims) - Upgrade MyBatis Spring Boot Starter 2.2.2 -> 2.3.2 - Upgrade SQLite JDBC 3.36.0.3 -> 3.42.0.1 - Upgrade joda-time 2.10.13 -> 2.12.7 - Upgrade Spotless 6.2.1 -> 6.25.0 - Fix DGS PageInfo type compatibility in ArticleDatafetcher and CommentDatafetcher - Use Keys.hmacShaKeyFor() for JJWT 0.12.x key handling Co-Authored-By: shayan@cognition.ai <shayan@cognition.ai>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Co-Authored-By: shayan@cognition.ai <shayan@cognition.ai>
| this.sessionTime = sessionTime; | ||
| signatureAlgorithm = SignatureAlgorithm.HS512; | ||
| this.signingKey = new SecretKeySpec(secret.getBytes(), signatureAlgorithm.getJcaName()); | ||
| this.signingKey = Keys.hmacShaKeyFor(secret.getBytes()); |
There was a problem hiding this comment.
🔴 Keys.hmacShaKeyFor() silently changes signing algorithm for secrets shorter than 64 bytes
The migration from explicit SignatureAlgorithm.HS512 + SecretKeySpec to Keys.hmacShaKeyFor() introduces an implicit algorithm selection based on key byte length. Any deployment with a jwt.secret between 32-63 bytes will silently switch from HS512 to HS256/HS384, making all previously-issued JWT tokens unverifiable.
Detailed Explanation
The old code at DefaultJwtService.java:27-28 (before this PR) always used HS512:
signatureAlgorithm = SignatureAlgorithm.HS512;
this.signingKey = new SecretKeySpec(secret.getBytes(), signatureAlgorithm.getJcaName());The new code at DefaultJwtService.java:25 uses Keys.hmacShaKeyFor() which auto-selects the algorithm:
- 32-47 bytes → HS256
- 48-63 bytes → HS384
- ≥64 bytes → HS512
The default secret in application.properties is 86 bytes (safe, maps to HS512). However, a concrete example exists in the test at DefaultJwtServiceTest.java:16:
jwtService = new DefaultJwtService("123123123123123123123123123123123123123123123123123123123123", 3600);This secret is 60 bytes, so the test now uses HS384 instead of HS512. The test still passes because should_get_null_with_expired_jwt fails for algorithm mismatch rather than expiration — masking the behavioral change.
Impact: Any production environment with a jwt.secret shorter than 64 bytes will have all existing user sessions invalidated after deployment, as tokens signed with HS512 cannot be verified with HS384/HS256. Users would need to re-authenticate.
| this.signingKey = Keys.hmacShaKeyFor(secret.getBytes()); | |
| this.signingKey = Keys.hmacShaKeyFor(java.util.Arrays.copyOf(secret.getBytes(), 64)); |
Was this helpful? React with 👍 or 👎 to provide feedback.
Migrate build.gradle from Java 11 to Java 17
Summary
Upgrades the project from Java 11 to Java 17 by bumping
sourceCompatibility/targetCompatibilityand upgrading dependencies for Java 17 compatibility. Also updates the CI workflow to build with JDK 17.Dependency changes:
Code changes:
DefaultJwtService.java: Migrated to JJWT 0.12.x API (subject(),expiration(),parseSignedClaims(),getPayload()). ReplacedSecretKeySpec+ hardcodedHS512withKeys.hmacShaKeyFor()which auto-selects HMAC algorithm based on key size.ArticleDatafetcher.java/CommentDatafetcher.java: Replacedgraphql.relay.DefaultPageInfowith DGS-generatedio.spring.graphql.types.PageInfoto fix type incompatibility in DGS 5.x.dependencyManagementblock importing the DGS platform BOM to override Spring Boot 2.7's graphql-java 18.x with 19.x (required by DGS 5.5.1's federation library)..github/workflows/gradle.yml: Updated CI from JDK 11 to JDK 17.Review & Testing Checklist for Human
Keys.hmacShaKeyFor()auto-selects HS256/HS384/HS512 based on key byte length instead of always using HS512. Existing tokens signed with HS512 will fail to verify if the new code selects a different algorithm due to a shorter key. Verify all environments have ajwt.secretof ≥64 bytes to get HS512. The default secret inapplication.propertiesis 88 chars (fine), but check staging/production.PageInfobuilder fields (startCursor,endCursor,hasPreviousPage,hasNextPage) match the GraphQL schema expectations. Test cursor-based pagination queries end-to-end (e.g., articles feed withfirst/afterarguments)../gradlew bootBuildImage --imageName spring-boot-realworld-example-appto verify Docker image builds successfully with Java 17.Suggested manual test plan:
./gradlew bootRunand verify it starts on Java 17/tagsendpoint:curl http://localhost:8080/tagsfirst: 10, after: "cursor")Notes
./gradlew bootRunstarts successfully,/tagsendpoint responds with{"tags":[]}.Link to Devin run: https://app.devin.ai/sessions/be1f0b06a6bd4bc280becc8a7302fc31
Requested by: @shayanshafii