Spring Boot 4를 활용한 Null-Safe 애플리케이션
Spring 전반에 걸친 Null 안전성 지원 현황에 대한 업데이트 공유
"10억 달러짜리 실수" 해결 중임
JSpecify 참여 조직들, Spring 팀, 그리고 Spring Boot 4로 업그레이드하는 개발자들이 함께 null 문제 해결 중임.
진짜 실수는 null 참조 자체가 아니라, null 가능성을 타입 시스템에서 명시하지 않은 것이라고 봄.
암묵적 null 때문에 프로덕션에서
NullPointerException이 남.null 가능성을 타입에 명시하면, 값 부재를 표현하는 “제로 코스트 추상화”가 됨.
기존 API와도 호환되면서 null 여부를 표현할 수 있음.
JSpecify 소개
JSpecify는 Java 코드베이스가 API의 null 가능 여부를 명시적으로 표시할 수 있는 어노테이션 세트를 제공함.
상세한 스펙과 문서를 제공해서, 여러 도구가 일관되게 구현할 수 있게 설계됨.
특정 IDE나 도구에 종속되지 않는 것이 핵심임.
대규모 코드베이스에 null-safety 도입은 큰 작업임
아무 데나
@Nullable조금 다는 건 쉬움.하지만 전체 코드베이스를 어노테이션하고, 빌드할 때 null 불일치를 컴파일 에러로 취급하게 만드는 건 매우 어려운 작업임.
Spring 팀은 이 작업을 몇 달 전부터 진행해 왔음.
지금은 Spring 포트폴리오의 대부분 API를 null-safe로 만드는 목표를 달성했다고 밝힘.
목표는 Spring 개발자가 프로덕션에서
NullPointerException위험을 줄이거나 제거하도록 돕는 것임.
이미 null-safe API를 제공하는 프로젝트들
Spring Boot 4.0
Spring Framework 7.0
Spring Data 4.0
Spring Security 7.0
Spring Batch 6.0
Spring Kafka 4.0
Spring Integration 7.0
Spring GraphQL 2.0
Spring Web Services 5.0
Spring AMQP 4.0
Spring Shell 4.0
Spring Kafka 4.0
Spring Plugin 4.0
Spring HATEOAS 3.0
Spring Modulith 2.0
Spring Vault 4.0
Spring Cloud Commons 5.0
Spring Cloud Gateway 5.0
Micrometer 1.16
Reactor 2025.0
곧 null-safe API를 제공할 예정인 프로젝트들
Spring AI (2.0에서 예정)
Spring Session
Spring LDAP
Spring gRPC (1.0에서 목표)
나머지 Spring Cloud (2026.0 타임라인 목표)
JSpecify를 도입한 외부 라이브러리들
JUnit
GraphQL
Caffeine
→ Spring이 의존하는 라이브러리에서도 점점 JSpecify 기반 null-safety를 도입 중임.
Kotlin 2와의 연동
Kotlin 2는 Spring Framework 7 / Spring Boot 4의 새 베이스라인임.
Kotlin 2는 JSpecify 어노테이션을 Kotlin의 nullability로 자동 변환함.
특히 제네릭에서 “platform type” 문제를 해결해 줌.
결과적으로 Spring API가 마치 Kotlin으로 직접 작성된 것처럼 자연스럽게 보이게 됨.
Spring API를 null-safe하게 사용하는 가장 쉬운 방법
Spring Boot 4로 업그레이드함.
JSpecify 어노테이션을 인식하는 IDE를 사용해서 Spring API 사용 시 null 가능성에 대한 피드백을 받음.
IntelliJ IDEA의 JSpecify 지원
JetBrains는 JSpecify 그룹에 초기부터 참여해 왔음.
IntelliJ IDEA 팀은 JSpecify에 대한 1급 지원을 준비해 왔고,
IntelliJ IDEA 2025.3에서 제공 예정임.JSpecify 기반 null 체크는 제네릭, 복잡한 데이터 흐름까지 분석해서 강력한 null 분석을 제공한다고 설명함.
IntelliJ IDEA 2025.3부터는 클래스패스에 JSpecify 어노테이션이 있으면, JetBrains 자체 null 어노테이션보다 JSpecify를 우선 사용함.
퀵픽스/리팩토링에서도 JSpecify 어노테이션을 자동 생성해 줌.

Eclipse / VS Code 지원
Spring Tools 팀은 Eclipse와 VS Code에서 JSpecify 설정을 자동화하는 작업을 진행 중임.
Eclipse 플랫폼의 기존 nullability 지원을 활용하고 있음.
이런 IDE 체크를 통해 런타임
NullPointerException위험을 크게 줄일 수 있음.
애플리케이션 자체를 null-safe하게 만들기
단순히 “위험 감소”가 아니라, 애플리케이션에서 NPE 가능성을 거의 제거하고 싶다면:
애플리케이션 코드에도 JSpecify 어노테이션을 적용함.
NullAway 같은 빌드 타임 nullability 체커 사용을 강하게 추천함.
다만 이건 단순히 null-safe API를 소비하는 것보다 훨씬 손이 많이 드는 작업임.
시작 전에 충분히 이해하고 도입하라고 강조함.
NullAway 팀과의 협업
Spring 팀은 NullAway 리드이자 UC Riverside 교수인 Manu Sridharan과 협업해 왔음.
NullAway 팀도 JSpecify 표준을 적극 지지하고, Java 생태계 전반의 null-safety 강화를 함께 추진 중이라고 밝힘.
일반적인 JSpecify 사용 패턴
패키지에
@NullMarked를 붙여 기본을 non-null로 둠.실제로 null 가능성이 있는 타입에만
@Nullable을 붙임.자세한 사용 가이드는 Spring Framework null-safety 문서에 정리되어 있음.
Gradle / Maven 설정
Gradle 사용 시, Spring Boot 팀이 기여한 nullability Gradle 플러그인을 사용할 수 있음.
아니면 NullAway를 직접 설정해도 됨.
Maven도 지원되지만, Gradle보다 설정이 더 장황함.
JDK 버전 요구사항
NullAway의 JSpecify 모드는 최신 javac를 요구함.
가능하면 Java 25 사용을 권장함.
그렇지 않으면 대부분의 JDK 21.0.8+ (Oracle JDK 제외)에서
-XDaddTypeAnnotationsToSymbol=true플래그를 지원하고, 이를 통해 NullAway가 제대로 동작함.Java 17에 이 플래그를 백포트하는 작업이 미래에 있을 수 있다고 언급함.
Java 17 베이스라인 유지하는 경우
Spring처럼 Java 17을 베이스라인으로 유지해야 한다면:
Java 25 툴체인을 사용하면서
--release 17옵션으로 빌드하도록 Maven/Gradle을 설정할 수 있음.
jspecify-nullaway-demo GitHub 리포지토리에 Gradle/Maven 설정 예제가 있음.
기존 Spring nullability 어노테이션
org.springframework.lang패키지에 있던 기존 Spring 전용 nullability 어노테이션은 이제 deprecated 상태임.앞으로는 JSpecify 어노테이션 사용을 권장함.
잠재적인 향후 개선점들
Cannot attach type annotations 에러
Java 25 같은 최신 Java에서, JSpecify
@Nullable,@NonNull같은 타입 어노테이션이 붙은 클래스를 관련 타입이 classpath에 없는 상태로 import하면Cannot attach type annotations에러가 발생할 수 있음.Spring 팀은 이런 부작용을 줄이려 노력했지만, javac 동작 특성상 완전히 없애긴 어려움.
OpenJDK 쪽에서 이 에러를 다시 lazy하게 처리하거나, 적어도 warning + suppress 가능한 형태로 완화하는 논의가 진행 중임.
@SuppressWarnings("nullness")표준화 논의nullability 체크를 도구 중립적으로 끌 수 있는 방법에 대해 JSpecify 워킹 그룹에서 논의 중임.
특정 상황에서 null 체크가 의미 없을 때 경고를 숨길 수 있는 공통 메커니즘을 만들려는 목적임.
NullAway 쪽 추가 개선
NullAway의 JSpecify 모드는 아직 발전 중임.
Spring / Reactor API를 람다와 함께 사용할 때 특정 이슈(예: NullAway#1290)를 만날 수 있음.
이런 경우 당장은
@SuppressWarnings("NullAway")로 경고를 끌 수 있음.JDK API의 nullability 모델도 앞으로 더 정교하게 다듬어질 예정임.
결론
이번 null-safety 작업 덕분에 Spring 코드베이스 품질과 견고성이 개선되었다고 평가함.
개발자는 이 기능을 얼마나 활용할지 스스로 결정할 수 있음:
관련 경고를 꺼버릴 수도 있음.
IDE에서 경고 나는 부분만 고쳐서 NPE 위험을 줄일 수도 있음.
아예 애플리케이션 전체를 null-safe하게 만들 수도 있음.
이 작업은 기존 API를 깨뜨리지 않고도 진행 가능함.
기존 타입에 “null 가능/불가능” 정보를 개념적으로 덧붙이는 작업이라 봄.
더 많은 오픈소스 라이브러리가 JSpecify를 채택하길 기대함.
JSpecify 도입이 JVM 생태계와 애플리케이션이 미래의 Null-Restricted / Nullable Types 기능을 받아들일 준비를 하는 데 도움이 될 거라 봄.
이런 언어 기능이 정식(비-프리뷰) 기능이 되고, 라이브러리와 애플리케이션 베이스라인이 옮겨가는 데는 수년이 걸릴 수 있음.
그 과정에서 런타임 효율성도 같이 좋아질 수 있다고 전망함.
from https://spring.io/blog/2025/11/12/null-safe-applications-with-spring-boot-4
질문: 쓸만하긴 한데, JVM이 nullability를 네이티브로 지원하게 되면 이 어노테이션들이 deprecated 되는 거 아님? 물론 그런 Java 버전의 라이브러리들의 베이스라인이 되려면 아직 오래 걸릴 것 같음(아마 10년 이상 걸릴 거라고 생각함)
답변(위 JEPS, JSpecify 작업자): 질문한 내용은 기본적으로 우리가 바라는 방향과 같음. 다만 그게 10년 안에 이 어노테이션들이 deprecated될 정도로 빨리 진행될 거라고는 생각 안 함.
중요한 포인트는, 나중에 언어 차원에서 nullability 마커가 들어왔을 때 이미 지금 애노테이션을 도입해 둔 코드베이스라면 그런 언어 기능을 받아들이기에 훨씬 유리한 위치에 서게 된다는 점임.
그때 가서는 꽤 기계적인 변환 작업 정도로 끝날 거고, 결국 이 애노테이션 단계를 거쳐서 전환할지 말지 선택의 문제임. 단점은 (a) 서드파티 도구를 채택해야 하고, (b) 빌드 타임이 늘어나고, (c) @Nullable 같은 애노테이션이 코드에서 좀 부피가 크다는 점임. 장점은 단순함. 이미 존재하고, 지금 당장 잘 동작함.
