Skip to content

refactor: Java, SpringBoot 버전 업 & JJWT 버전 업#702

Merged
sukangpunch merged 6 commits intodevelopfrom
refactor/658-springboot-java-version-up
Mar 22, 2026
Merged

refactor: Java, SpringBoot 버전 업 & JJWT 버전 업#702
sukangpunch merged 6 commits intodevelopfrom
refactor/658-springboot-java-version-up

Conversation

@sukangpunch
Copy link
Contributor

관련 이슈

작업 내용

버전 업그레이드

❯ - Java 17 → 21

  • Spring Boot 3.1.5 → 3.5.11
  • Flyway 9.16.3 → 10.15.0
  • io.spring.dependency-management 1.1.4 → 1.1.7

JJWT 라이브러리 교체

❯ - jjwt:0.9.1 (단일 jar) → jjwt-api/impl/jackson:0.12.6 (모듈 분리)

  • javax.xml.bind:jaxb-api 의존성 제거 (jjwt 0.9.x 전용 workaround)
  • deprecated API 마이그레이션:
    • SignatureAlgorithmJwts.SIG.ES256 / Keys.hmacShaKeyFor()
    • setSigningKey/parseClaimsJws/getBodyverifyWith/parseSignedClaims/getPayload
    • Jwts.claims().setSubject() → 빌더 체이닝 방식
    • org.apache.tomcat.Base64java.util.Base64 (표준 라이브러리)

의존성 추가

❯ - commons-lang3 추가

CI/CD 및 인프라

❯ - GitHub Actions (ci.yml, dev-cd.yml, prod-cd.yml): JDK 17 → 21

  • Dockerfile: eclipse-temurin:17-jdkeclipse-temurin:21-jdk

특이 사항

리뷰 요구사항 (선택)

- SpringBoot 버전업 (-> 3.5.11)
- Java 버전업 (-> 21)
- JJWT 버전업 (-> 0.12.6)
- 기존 EnumUtils deprecate 대응을 위해 org.apache.commons:commons-lang3 의존성 추가
@coderabbitai
Copy link

coderabbitai bot commented Mar 19, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ca42a004-5d5e-4da0-a097-d19b4270ef77

📥 Commits

Reviewing files that changed from the base of the PR and between d03f945 and 8373e2f.

📒 Files selected for processing (1)
  • src/test/java/com/example/solidconnection/security/authentication/TokenAuthenticationProviderTest.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/test/java/com/example/solidconnection/security/authentication/TokenAuthenticationProviderTest.java

Walkthrough

  1. 모든 CI/CD 워크플로우와 Dockerfile에서 JDK 17을 JDK 21로 업데이트했습니다.
  2. build.gradle에서 Java 호환성을 17 → 21로 변경하고 Spring Boot, dependency-management, Flyway 버전을 상향 조정했습니다.
  3. JJWT 의존성을 단일 패키지에서 분리된 모듈(jjwt-api, jjwt-impl, jjwt-jackson v0.12.6)로 교체했습니다.
  4. JJWT 사용 코드를 기존의 setSigningKey/parseClaimsJws 패턴에서 verifyWith(...).build().parseSignedClaims(...).getPayload() 등 새로운 fluent API로 변환했습니다.
  5. 비밀키/개인키 처리에서 Apache Tomcat Base64 대신 Java 표준 Base64Keys.hmacShaKeyFor(...)/SecretKey 사용으로 전환했습니다.
  6. 테스트 코드의 Mockito 관련 어노테이션을 다수 @MockBean/@SpyBean@MockitoBean/@MockitoSpyBean으로 교체하고 JWT 테스트 헬퍼를 새로운 API에 맞게 리팩터링했습니다.
  7. Dockerfile 베이스 이미지를 eclipse-temurin:17-jdkeclipse-temurin:21-jdk로 변경했습니다.
  8. Apache Commons Lang3를 새 구현 의존성으로 추가했습니다.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Suggested reviewers

  • wibaek
  • whqtker
  • Gyuhyeok99
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 변경의 핵심(Java/Spring Boot 버전 업그레이드 및 JJWT 마이그레이션)을 명확하고 간결하게 요약하고 있습니다.
Description check ✅ Passed PR 설명이 템플릿 대부분을 충족하며, 관련 이슈(#658), 작업 내용(버전 업, JJWT 마이그레이션, 의존성 추가, CI/CD 변경)을 명확히 구성했습니다.
Linked Issues check ✅ Passed PR의 모든 변경사항(Java 21, Spring Boot 3.5.11, Docker API 호환성 개선)이 #658의 CI/Docker API 버전 충돌 해결 목표를 충족합니다.
Out of Scope Changes check ✅ Passed 모든 코드 변경이 버전 업그레이드 및 JJWT 마이그레이션 범위 내에 있으며, 비관련 기능 추가나 불필요한 수정은 없습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/658-springboot-java-version-up

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can make CodeRabbit's review stricter and more nitpicky using the `assertive` profile, if that's what you prefer.

Change the reviews.profile setting to assertive to make CodeRabbit's nitpick more issues in your PRs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sukangpunch sukangpunch added the 진행 중 자유롭게 merge 가능 label Mar 19, 2026
@sukangpunch sukangpunch marked this pull request as ready for review March 19, 2026 08:56
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
claude.md (1)

170-170: ⚠️ Potential issue | 🟡 Minor

2. 문서 내 Spring Boot 버전 불일치 발견 📝

Line 11에서는 Spring Boot 3.5.11로 업데이트되었지만, "기술 스택 상세" 섹션(Line 170)에서는 여전히 Spring Boot 3.1.5로 표기되어 있습니다. 문서의 일관성을 위해 수정이 필요합니다.

📝 수정 제안
 ### Core Framework

-- **Spring Boot 3.1.5**: 스프링 부트
+- **Spring Boot 3.5.11**: 스프링 부트
 - **Spring Security**: JWT 기반 인증
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@claude.md` at line 170, Update the outdated Spring Boot version text "Spring
Boot 3.1.5" in the "기술 스택 상세" section to match the document's updated version
"Spring Boot 3.5.11" (as referenced earlier in the doc), ensuring all
occurrences of "Spring Boot 3.1.5" are replaced and the version string is
consistent throughout the file.
🧹 Nitpick comments (2)
src/test/java/com/example/solidconnection/security/filter/TokenAuthenticationFilterTest.java (1)

94-101: JJWT 0.12.6 마이그레이션에 따른 테스트 코드의 deprecated API 사용 확인

프로덕션 코드에서 JJWT 0.12.6의 새 API로 이미 마이그레이션이 완료되었으나, 테스트 코드에서는 deprecated API가 여전히 사용 중입니다. 이 파일의 createTokenWithExpiration 메서드에서 다음과 같은 개선이 필요합니다:

  1. Claim 설정 메서드 변경

    • setSubject()subject()
    • setIssuedAt()issuedAt()
    • setExpiration()expiration()
  2. 서명 방식 업데이트

    • signWith(SignatureAlgorithm.HS256, secret)signWith(key, Jwts.SIG.HS256) 형태로 변경하여 SecretKey 객체 사용 필요
♻️ 적용 예시
+import io.jsonwebtoken.security.Keys;
+import javax.crypto.SecretKey;
+import java.nio.charset.StandardCharsets;

 private String createTokenWithExpiration(Date expiration) {
+    SecretKey key = Keys.hmacShaKeyFor(jwtProperties.secret().getBytes(StandardCharsets.UTF_8));
     return Jwts.builder()
-            .setSubject("1")
-            .setIssuedAt(new Date())
-            .setExpiration(expiration)
-            .signWith(SignatureAlgorithm.HS256, jwtProperties.secret())
+            .subject("1")
+            .issuedAt(new Date())
+            .expiration(expiration)
+            .signWith(key, Jwts.SIG.HS256)
             .compact();
 }

참고: 유사한 deprecated API 사용이 SignOutCheckFilterTest.java, TokenAuthenticationProviderTest.java에도 있으니 함께 검토하길 권장합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/test/java/com/example/solidconnection/security/filter/TokenAuthenticationFilterTest.java`
around lines 94 - 101, The test method createTokenWithExpiration uses deprecated
JJWT APIs; update it to use the new builder methods and a SecretKey: replace
setSubject/setIssuedAt/setExpiration with subject()/issuedAt()/expiration(), and
replace signWith(SignatureAlgorithm.HS256, jwtProperties.secret()) by creating a
SecretKey (e.g., Keys.hmacShaKeyFor(jwtProperties.secret().getBytes())) and
calling signWith(secretKey, Jwts.SIG.HS256); update the Jwts.builder() call
accordingly in createTokenWithExpiration and apply the same pattern to
SignOutCheckFilterTest and TokenAuthenticationProviderTest.
src/main/java/com/example/solidconnection/auth/token/JwtTokenProvider.java (1)

48-50: Keys.hmacShaKeyFor() 사용에 대한 참고 사항

Keys.hmacShaKeyFor()는 키 길이에 따라 HMAC 알고리즘을 자동으로 선택합니다:

  • 32+ 바이트 → HS256
  • 48+ 바이트 → HS384
  • 64+ 바이트 → HS512

현재 설정된 JWT 시크릿이 최소 32바이트 이상인지 확인해주세요. 테스트 환경의 시크릿 "1234567-1234-1234-1234-12345678901"은 34바이트로 HS256이 적용됩니다.

💡 보안 강화를 위한 권장 사항 (선택적)

프로덕션 환경에서는 더 긴 시크릿 키(64+ 바이트)를 사용하여 HS512 알고리즘을 적용하는 것을 권장합니다. 이는 현재 기능에 영향을 주지 않으며 향후 보안 강화를 위한 제안입니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/example/solidconnection/auth/token/JwtTokenProvider.java`
around lines 48 - 50, The getSigningKey() method uses
Keys.hmacShaKeyFor(jwtProperties.secret().getBytes(...)) which selects
HS256/384/512 based on secret length; ensure jwtProperties.secret() is at least
32 bytes (preferably 64+ for HS512 in production) by validating its byte length
in JwtTokenProvider (e.g., in getSigningKey() or during JwtTokenProvider
initialization) and throw a clear exception or log an error if the secret is too
short so the application fails fast instead of producing a weaker-than-expected
algorithm; reference getSigningKey(), Keys.hmacShaKeyFor, and
jwtProperties.secret() when adding the validation or documentation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@build.gradle`:
- Around line 46-48: Three test files still use the old JJWT builder/signing API
and must be updated to the 0.12.6 API: in TokenAuthenticationProviderTest,
TokenAuthenticationFilterTest, and SignOutCheckFilterTest replace uses of
signWith(SignatureAlgorithm.HS256, key) with signWith(secretKey) (ensure the
test creates a SecretKey instance as used in production), and rename JWT builder
setters setSubject(...), setIssuedAt(...), setExpiration(...) to the new fluent
names subject(...), issuedAt(...), expiration(...); update imports/usages
accordingly so the tests compile against the jjwt-api 0.12.6 methods.

---

Outside diff comments:
In `@claude.md`:
- Line 170: Update the outdated Spring Boot version text "Spring Boot 3.1.5" in
the "기술 스택 상세" section to match the document's updated version "Spring Boot
3.5.11" (as referenced earlier in the doc), ensuring all occurrences of "Spring
Boot 3.1.5" are replaced and the version string is consistent throughout the
file.

---

Nitpick comments:
In `@src/main/java/com/example/solidconnection/auth/token/JwtTokenProvider.java`:
- Around line 48-50: The getSigningKey() method uses
Keys.hmacShaKeyFor(jwtProperties.secret().getBytes(...)) which selects
HS256/384/512 based on secret length; ensure jwtProperties.secret() is at least
32 bytes (preferably 64+ for HS512 in production) by validating its byte length
in JwtTokenProvider (e.g., in getSigningKey() or during JwtTokenProvider
initialization) and throw a clear exception or log an error if the secret is too
short so the application fails fast instead of producing a weaker-than-expected
algorithm; reference getSigningKey(), Keys.hmacShaKeyFor, and
jwtProperties.secret() when adding the validation or documentation.

In
`@src/test/java/com/example/solidconnection/security/filter/TokenAuthenticationFilterTest.java`:
- Around line 94-101: The test method createTokenWithExpiration uses deprecated
JJWT APIs; update it to use the new builder methods and a SecretKey: replace
setSubject/setIssuedAt/setExpiration with subject()/issuedAt()/expiration(), and
replace signWith(SignatureAlgorithm.HS256, jwtProperties.secret()) by creating a
SecretKey (e.g., Keys.hmacShaKeyFor(jwtProperties.secret().getBytes())) and
calling signWith(secretKey, Jwts.SIG.HS256); update the Jwts.builder() call
accordingly in createTokenWithExpiration and apply the same pattern to
SignOutCheckFilterTest and TokenAuthenticationProviderTest.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5ad9c635-8f52-4383-b53a-b009b66270bf

📥 Commits

Reviewing files that changed from the base of the PR and between b58d893 and fe9287b.

📒 Files selected for processing (22)
  • .github/workflows/ci.yml
  • .github/workflows/dev-cd.yml
  • .github/workflows/prod-cd.yml
  • Dockerfile
  • build.gradle
  • claude.md
  • src/main/java/com/example/solidconnection/auth/client/AppleOAuthClient.java
  • src/main/java/com/example/solidconnection/auth/client/AppleOAuthClientSecretProvider.java
  • src/main/java/com/example/solidconnection/auth/token/JwtTokenProvider.java
  • src/test/java/com/example/solidconnection/admin/service/AdminHostUniversityServiceTest.java
  • src/test/java/com/example/solidconnection/auth/controller/RefreshTokenCookieManagerTest.java
  • src/test/java/com/example/solidconnection/auth/service/JwtTokenProviderTest.java
  • src/test/java/com/example/solidconnection/auth/service/oauth/OAuthServiceTest.java
  • src/test/java/com/example/solidconnection/auth/service/signup/SignUpTokenProviderTest.java
  • src/test/java/com/example/solidconnection/chat/service/ChatServiceTest.java
  • src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java
  • src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java
  • src/test/java/com/example/solidconnection/news/service/NewsCommandServiceTest.java
  • src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java
  • src/test/java/com/example/solidconnection/security/filter/TokenAuthenticationFilterTest.java
  • src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java
  • src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@src/test/java/com/example/solidconnection/security/authentication/TokenAuthenticationProviderTest.java`:
- Line 121: 테스트의 토큰 만료 시간이 너무 짧아 간헐적 실패를 유발하므로 TokenAuthenticationProviderTest에서
Date(System.currentTimeMillis() + 1000)로 생성한 만료 시간을 늘리세요: expiration(...)에 더 긴
TTL(예: 몇 만 밀리초 또는 Duration/TimeUnit을 사용해 30s~5min 범위)으로 변경하거나 상수(EXPIRATION_MS)로
추출해 안정적인 값으로 설정하고, 필요하면 테스트 전용 고정 Clock/시간 제어를 도입해 토큰 만료 타이밍을 안정화하세요; 변경 대상 식별자:
TokenAuthenticationProviderTest, expiration(...) 호출,
Date(System.currentTimeMillis() + ...).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d6c228ef-fa3b-43a8-9364-6a01490514b6

📥 Commits

Reviewing files that changed from the base of the PR and between fe9287b and d03f945.

📒 Files selected for processing (3)
  • src/test/java/com/example/solidconnection/security/authentication/TokenAuthenticationProviderTest.java
  • src/test/java/com/example/solidconnection/security/filter/SignOutCheckFilterTest.java
  • src/test/java/com/example/solidconnection/security/filter/TokenAuthenticationFilterTest.java
✅ Files skipped from review due to trivial changes (1)
  • src/test/java/com/example/solidconnection/security/filter/SignOutCheckFilterTest.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/test/java/com/example/solidconnection/security/filter/TokenAuthenticationFilterTest.java

@whqtker
Copy link
Member

whqtker commented Mar 20, 2026

오늘 리뷰 달아볼게요 ! 혹시나 안 달면 머지하셔도 됩니다

Copy link
Member

@whqtker whqtker left a comment

Choose a reason for hiding this comment

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

코드래빗 리뷰 하나만 수정해주시면 될 거 같습니다 ! 고생하셨습니다 ~!

- 테스트에서 Token 생성 시, TTL을 30초로 수정
- TTL이 너무 짧으면 테스트가 간헐적으로 꺠질 위험 존재
@sukangpunch sukangpunch merged commit 48821f4 into develop Mar 22, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

리팩터링 진행 중 자유롭게 merge 가능

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: spring boot 버전 업

2 participants