Skip to content

Modernize Spring Boot project: Java 8 → 21, Spring Boot 2.x → 3.4.5#8

Open
devin-ai-integration[bot] wants to merge 1 commit into
masterfrom
devin/1776442611-modernize-spring-boot
Open

Modernize Spring Boot project: Java 8 → 21, Spring Boot 2.x → 3.4.5#8
devin-ai-integration[bot] wants to merge 1 commit into
masterfrom
devin/1776442611-modernize-spring-boot

Conversation

@devin-ai-integration
Copy link
Copy Markdown

Summary

Full modernization of the Spring Boot demo project from Java 8 / Spring Boot 2.0.2 to Java 21 / Spring Boot 3.4.5, along with code quality improvements and new test coverage.

Version upgrades: Java 8→21, Spring Boot 2.0.2→3.4.5, Gradle 4.6→8.12, Maven 3.3.9→3.9.9. Both pom.xml and build.gradle updated consistently. build.gradle rewritten to modern plugin DSL.

Dead code removal: Removed broken gturnquist-quoters.cfapps.io REST calls (service is offline) and associated RestTemplate bean/imports from Application.java. Removed bean inspection loop from main().

Code quality:

  • All controllers: @Autowired field injection → constructor injection; @RequestMapping → specific @GetMapping/@PostMapping/etc.
  • TopicService: unsafe Optional.get()orElseThrow() with descriptive message
  • TopicService/TimeClient: System.out.println/System.err.println → SLF4J logger
  • CustomPredicate: added @FunctionalInterface
  • Greeting and Customer: converted to Java records
  • Fixed H2 SQL syntax: DROP TABLE customers IF EXISTSDROP TABLE IF EXISTS customers

New files: GlobalExceptionHandler (@ControllerAdvice), application.properties in src/main/resources/, three JUnit 5 test files (19 tests total).

Cleanup: Deleted .idea/, .iml, .gitignore.txt; fixed .gitignore; moved temp.txt to src/main/resources/.

Review & Testing Checklist for Human

  • Verify Greeting record serialization: The class was converted to a Java record. Records expose id() not getId(), but Spring Boot 3.x Jackson should serialize them identically. Confirm GET / still returns {"id": ..., "content": ...} (not differently-named fields) by actually running the app.
  • Quote.java and Value.java are now dead code: The REST calls that used them were removed, but the model files themselves were left in the codebase. Decide if these should be deleted.
  • readFileWithStreamFunction uses a fragile relative path (Paths.get("src/main/resources/temp.txt")): This works when the working directory is the project root, but will break if the app is run from a packaged JAR. Consider loading via classpath resource instead.
  • Run ./mvnw spring-boot:run and manually test endpoints: GET /, GET /topic, GET /datetime. The tests are unit/slice tests only — there is no @SpringBootTest integration test verifying the full context loads with H2.

Notes

  • The @WebMvcTest controller tests require a @MockitoBean JdbcTemplate because Application (the @SpringBootApplication class) has JdbcTemplate as a constructor dependency. This is functional but unusual — a cleaner pattern would be to extract the CommandLineRunner logic into a separate @Component.
  • packaging in pom.xml changed from pom to jar — this was necessary for the Spring Boot Maven plugin to produce a runnable JAR.

Link to Devin session: https://app.devin.ai/sessions/c47e2bfdd24f46e3bb7a955a0d906f66
Requested by: @bnob-git

Phase 1: Upgrade Java 21, Spring Boot 3.4.5, Gradle 8.12, Maven 3.9.9
Phase 2: Remove dead gturnquist-quoters API calls, fix H2 SQL, constructor injection
Phase 3: Replace @RequestMapping with specific HTTP method annotations
Phase 4: Fix unsafe Optional.get(), add loggers, @FunctionalInterface
Phase 5: Convert Greeting and Customer to Java records
Phase 6: Move application.properties to src/main/resources
Phase 7: Add GlobalExceptionHandler with @ControllerAdvice
Phase 8: Add JUnit 5 unit tests for services and controllers
Phase 9: Clean up .iml, .idea/, .gitignore, temp.txt

Co-Authored-By: Bobby Nobakht <bobby.nobakht@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 and CI monitoring

@devin-ai-integration
Copy link
Copy Markdown
Author

End-to-End Test Results

Ran the app locally with ./mvnw spring-boot:run on Java 21 and tested all key endpoints in the browser.

Endpoint Tests (7/7 passed)
  • App startup: PASSED — Started cleanly in 1.6s, no exceptions. H2 tables created, customers inserted and queried successfully.
  • GET / (Greeting record serialization): PASSED — Returns {"id":1,"content":"Hello, World!"}. Java record fields serialize correctly.
  • GET /?name=Devin (query param): PASSED — Returns {"id":2,"content":"Hello, Devin!"}. Counter increments, param works.
  • GET /topic (topic list): PASSED — Returns JSON array with 3 topics (spring, java, javascript).
  • GET /topic/java (single topic): PASSED — Returns {"id":"java","subjectName":"Core Java","subjectDescription":"Java Description"}.
  • GET /topic/nonexistent (404 handling): PASSED — HTTP 404 with body "Topic not found with id: nonexistent". GlobalExceptionHandler works correctly.
  • GET /datetime (HelloController): PASSED — Shows greeting, current datetime, tomorrow, previous month, leap year, timezone info.
Screenshots

GET / — Greeting record JSON serialization

GET /

GET /?name=Devin

GET /?name=Devin

GET /topic — Topic list

GET /topic

GET /topic/java — Single topic lookup

GET /topic/java

GET /topic/nonexistent — 404 error handling

404

GET /datetime

GET /datetime

Devin session

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