Skip to content

Upgrade to Spring Boot 3.2.5 / Java 17 (integrated: build, Jakarta, Security 6, DGS 8) - #831

Open
devin-ai-integration[bot] wants to merge 9 commits into
devin/sb3-java17-basefrom
devin/sb3-java17-integration
Open

devin-ai-integration[bot] wants to merge 9 commits into
devin/sb3-java17-basefrom
devin/sb3-java17-integration

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 16, 2026

Copy link
Copy Markdown

Summary

Upgrades the app from Spring Boot 2.6.3 / Java 11 to Spring Boot 3.2.5 / Java 17. This is the integration (workstream F) of five parallel workstreams (A–E), each of which owned a disjoint file set; this branch merges all five and adds the cross-cutting fixes needed to compile, build, and pass tests on the new stack.

Base of this PR is devin/sb3-java17-base — a snapshot of the source repo's master (commit c20e1f6) — so the diff shows exactly the migration.

Build & tooling (WS-A)

  • org.springframework.boot 2.6.33.2.5; io.spring.dependency-management 1.0.11.RELEASE1.1.4.
  • sourceCompatibility/targetCompatibility 1117; Gradle wrapper 7.48.7.
  • mybatis-spring-boot-starter(+-test) 2.2.23.0.3; DGS starter 4.9.218.5.3; DGS codegen plugin 5.0.66.2.0; jjwt 0.11.20.11.5; rest-assured 4.5.15.4.0; sqlite-jdbc → 3.45.3.0. flyway-core stays BOM-managed.

Jakarta EE namespace migration (WS-B/C/D)

  • javax.servlet.* / javax.validation.* / javax.annotation.*jakarta.* across io.spring.api, io.spring.application, io.spring.graphql, and io.spring.infrastructure. JDK javax.* (e.g. javax.crypto) left untouched.

Spring Security 6 (WS-E)

  • WebSecurityConfig no longer extends the removed WebSecurityConfigurerAdapter; it now exposes a SecurityFilterChain bean using the lambda DSL and authorizeHttpRequests() + requestMatchers(...). Behavior preserved: CSRF disabled, CORS enabled, HttpStatusEntryPoint(UNAUTHORIZED), stateless sessions, identical matcher rules, and jwtTokenFilter before UsernamePasswordAuthenticationFilter.

Integration fixes (WS-F, this branch)

Cross-cutting changes that fall between workstreams and only surface when everything is combined:

  • DGS 8 codegen now generates io.spring.graphql.types.PageInfo for connections instead of graphql.relay.PageInfo. ArticleDatafetcher/CommentDatafetcher buildXxxPageInfo(...) rewritten to build the generated type:
    PageInfo.newBuilder()
        .startCursor(...).endCursor(...)
        .hasPreviousPage(pager.hasPrevious()).hasNextPage(pager.hasNext())
        .build();
  • graphql-java (DGS 8) DataFetcherExceptionHandler: onException(...) removed. GraphQLCustomizeExceptionHandler now overrides CompletableFuture<DataFetcherExceptionHandlerResult> handleException(...) (results wrapped in CompletableFuture.completedFuture(...), default delegated via defaultHandler.handleException(...)).
  • Spring 6 MVC ResponseEntityExceptionHandler.handleMethodArgumentNotValid signature now takes HttpStatusCode (was HttpStatus) — CustomizeExceptionHandler updated.
  • Spotless on JDK 17: bumped com.diffplug.spotless 6.2.16.25.0 and pinned googleJavaFormat('1.19.2') (old google-java-format fails on JDK 17 with jdk.compiler module-access errors). Also scoped the Spotless target to src/**/*.java to satisfy Gradle 8's stricter implicit-task-dependency validation (previously it scanned build/generated).
  • CI .github/workflows/gradle.yml set up JDK 1117; refreshed actions/checkout, setup-java, cache to v4.

Validation

./gradlew clean build test passes on JDK 17 — 68 tests, 0 failures, 0 errors.

Note on repository

The task referenced ankehao-demo/spring-boot-realworld-example-app, but that fork is read-only for automation (push returns 403). All workstream branches and this integrated PR therefore live on the writable fork COG-GTM/spring-boot-realworld-example-app, based on the same source commit (c20e1f6).

Link to Devin session: https://app.devin.ai/sessions/50b23c7855044ecaa3cde259fc927351
Requested by: @scottyandrade99


Devin Review

Status Commit
⚪ Not started

Run Devin Review

Open in Devin Review (Staging)
Open in Devin Review

devin-ai-integration Bot and others added 9 commits July 16, 2026 19:28
…ing Boot 3 upgrade)

Co-Authored-By: Scotty Andrade <scotty.andrade@cognition.ai>
…plication package

Part of Spring Boot 3 / Java 17 upgrade (Session C — application package Jakarta migration). Replaces javax.validation.* imports with jakarta.validation.* across the assigned application-package files. Scoped to import prefixes only.

Co-Authored-By: Scotty Andrade <scotty.andrade@cognition.ai>
Part of Spring Boot 3 / Java 17 upgrade (workstream D). Replace
javax.validation.* with jakarta.validation.* in GraphQL exception
handler and UserMutation. JDK javax.* imports (javax.crypto in
DefaultJwtService) left intact.

Co-Authored-By: Scotty Andrade <scotty.andrade@cognition.ai>
…rChain style

Co-Authored-By: Scotty Andrade <scotty.andrade@cognition.ai>
…on-jakarta' into devin/sb3-java17-integration
…nfra-jakarta' into devin/sb3-java17-integration
…7 wrapper (WS-A)

Co-Authored-By: Scotty Andrade <scotty.andrade@cognition.ai>
…ring 6 exception handler, spotless/JDK17, CI JDK 17

Co-Authored-By: Scotty Andrade <scotty.andrade@cognition.ai>
@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

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 potential issues.

Open in Devin Review

Comment on lines +47 to +48
.requestMatchers(HttpMethod.OPTIONS, "/**")
.permitAll()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: OPTIONS matcher migration preserves behavior

The old rule .antMatchers(HttpMethod.OPTIONS).permitAll() matched all paths for the OPTIONS method (path-less overload matches any path). The new .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() is behaviorally equivalent, so CORS preflight handling is preserved. No issue.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +358 to +365
private PageInfo buildArticlePageInfo(CursorPager<ArticleData> articles) {
return PageInfo.newBuilder()
.startCursor(
articles.getStartCursor() == null ? null : articles.getStartCursor().toString())
.endCursor(articles.getEndCursor() == null ? null : articles.getEndCursor().toString())
.hasPreviousPage(articles.hasPrevious())
.hasNextPage(articles.hasNext())
.build();

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Generated PageInfo type matches schema and previous relay semantics

The schema declares its own PageInfo with non-null hasNextPage/hasPreviousPage and nullable startCursor/endCursor. The rewritten buildArticlePageInfo/buildCommentPageInfo build the DGS-generated io.spring.graphql.types.PageInfo with the same null-guarding on cursors and the same hasPrevious()/hasNext() values, preserving prior graphql.relay.DefaultPageInfo semantics. No issue.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines 63 to +69
.path(handlerParameters.getPath())
.extensions(errorsToMap(errors))
.build();
return DataFetcherExceptionHandlerResult.newResult().error(graphqlError).build();
return CompletableFuture.completedFuture(
DataFetcherExceptionHandlerResult.newResult().error(graphqlError).build());
} else {
return defaultHandler.onException(handlerParameters);
return defaultHandler.handleException(handlerParameters);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: handleException override returns CompletableFuture as required by graphql-java in DGS 8

The prior onException sync method was removed from DataFetcherExceptionHandler; the new override handleException returning CompletableFuture<DataFetcherExceptionHandlerResult> correctly wraps both custom-error results and delegates to defaultHandler.handleException(...). Consistent with the new interface contract. No issue.

(Refers to lines 31-69)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

0 participants