Kotlin 2.1.x 호환성 가이드
Kotlin 2.1.x 호환성 가이드
Keep the Language Modern과 Comfortable Updates는 Kotlin 언어 설계의 기본 원칙 두 가지예요. 전자는 언어 진화를 막는 구조는 제거해야 한다는 뜻이고, 후자는 그런 제거를 미리 잘 알려서 코드 마이그레이션을 최대한 매끄럽게 해야 한다는 뜻이에요.
대부분의 언어 변경은 이미 업데이트 변경 로그나 컴파일러 경고 같은 다른 채널을 통해 안내됐지만, 이 문서는 그 변경들을 한자리에 모아서 Kotlin 2.0에서 2.1로 마이그레이션할 때 참고할 수 있는 완전한 레퍼런스를 제공해요.
본문
기본 용어
이 문서에서는 몇 가지 종류의 호환성을 다뤄요.
- source(소스): 소스 비호환 변경은 예전에는 (경고나 오류 없이) 잘 컴파일되던 코드가 더 이상 컴파일되지 않게 만드는 변경이에요.
- binary(바이너리): 두 바이너리 아티팩트를 서로 바꿔 써도 로딩이나 링크 오류가 나지 않으면 바이너리 호환이라고 불러요.
- behavioral(동작): 같은 프로그램이 변경 적용 전후에 다르게 동작한다면 동작 비호환 변경이라고 해요.
이 정의는 순수 Kotlin에만 해당한다는 점 기억해 두세요. 다른 언어(예를 들어 Java) 관점에서 본 Kotlin 코드의 호환성은 이 문서의 범위 밖이에요.
언어
언어 버전 1.4와 1.5 제거
Issue: KT-60521
Component: Core language
Incompatible change type: source
Short summary: Kotlin 2.1은 언어 버전 2.1을 도입하고 언어 버전 1.4와 1.5에 대한 지원을 제거해요. 언어 버전 1.6과 1.7은 deprecated 처리돼요.
Deprecation cycle:
- 1.6.0: 언어 버전 1.4에 대해 경고를 보고해요.
- 1.9.0: 언어 버전 1.5에 대해 경고를 보고해요.
- 2.1.0: 언어 버전 1.6과 1.7에 대해 경고를 보고하고, 언어 버전 1.4와 1.5에 대해서는 경고를 오류로 올려요.
Kotlin/Native에서 typeOf() 함수 동작 변경
Issue: KT-70754
Component: Core language
Incompatible change type: behavioral
Short summary: Kotlin/Native의 typeOf() 함수 동작이 플랫폼 간 일관성을 위해 Kotlin/JVM과 일치하도록 맞춰져요.
Deprecation cycle:
- 2.1.0: Kotlin/Native에서
typeOf()함수 동작을 맞춰요.
타입 파라미터의 바운드를 통해 타입을 노출하는 것 금지
Issue: KT-69653
Component: Core language
Incompatible change type: source
Short summary: 더 낮은 가시성의 타입을 타입 파라미터 바운드를 통해 노출하는 것이 이제 금지돼요. 이는 타입 가시성 규칙의 불일치를 해결해요. 이 변경은 타입 파라미터의 바운드가 클래스와 같은 가시성 규칙을 따르도록 보장해서, JVM에서 IR 검증 오류 같은 문제를 방지해요.
Deprecation cycle:
- 2.1.0: 더 낮은 가시성의 타입을 타입 파라미터 바운드로 노출하면 경고를 보고해요.
- 2.2.0: 경고를 오류로 올려요.
같은 이름의 추상 var 프로퍼티와 val 프로퍼티를 함께 상속하는 것 금지
Issue: KT-58659
Component: Core language
Incompatible change type: source
Short summary: 클래스가 인터페이스에서 추상 var 프로퍼티를, 상위클래스에서 같은 이름의 val 프로퍼티를 상속받으면 이제 컴파일 오류가 발생해요. 이렇게 해서 그런 경우에 setter가 없어 발생하던 런타임 충돌을 해결해요.
Deprecation cycle:
- 2.1.0: 클래스가 인터페이스에서 추상
var프로퍼티를, 상위클래스에서 같은 이름의val프로퍼티를 상속받으면 경고(또는 progressive 모드에서는 오류)를 보고해요. - 2.2.0: 경고를 오류로 올려요.
초기화되지 않은 enum entry에 접근할 때 오류 보고
Issue: KT-68451
Component: Core language
Incompatible change type: source
Short summary: enum 클래스나 entry 초기화 중에 초기화되지 않은 enum entry에 접근하면 이제 컴파일러가 오류를 보고해요. 이는 멤버 프로퍼티 초기화 규칙과 동작을 맞춰 런타임 예외를 방지하고 일관된 로직을 보장해요.
Deprecation cycle:
- 2.1.0: 초기화되지 않은 enum entry에 접근하면 오류를 보고해요.
K2 스마트 캐스트 전파 변경
Issue: KTLC-34
Component: Core language
Incompatible change type: behavioral
Short summary: K2 컴파일러는 val x = y 같은 추론된 변수에 대해 타입 정보를 양방향으로 전파하면서 스마트 캐스트 전파 동작을 바꿔요. val x: T = y 같은 명시적 타입 변수는 더 이상 타입 정보를 전파하지 않아서 선언된 타입을 더 엄격히 따르게 해요.
Deprecation cycle:
- 2.1.0: 새 동작을 활성화해요.
Java 하위클래스에서 멤버-확장 프로퍼티 오버라이드 처리 수정
Issue: KTLC-35
Component: Core language
Incompatible change type: behavioral
Short summary: Java 하위클래스에 의해 오버라이드된 멤버-확장 프로퍼티의 getter가 이제 하위클래스 스코프에서 숨겨져서 일반 Kotlin 프로퍼티와 동작이 맞춰져요.
Deprecation cycle:
- 2.1.0: 새 동작을 활성화해요.
protected val을 오버라이드하는 var 프로퍼티의 getter/setter 가시성 정렬 수정
Issue: KTLC-36
Component: Core language
Incompatible change type: binary
Short summary: protected val 프로퍼티를 오버라이드하는 var 프로퍼티의 getter와 setter 가시성이 이제 일관되며, 둘 다 오버라이드된 val 프로퍼티의 가시성을 상속받아요.
Deprecation cycle:
- 2.1.0: K2에서 getter와 setter 모두에 일관된 가시성을 적용해요. K1은 영향받지 않아요.
JSpecify nullability 불일치 진단의 심각도를 오류로 상향
Issue: KTLC-11
Component: Core language
Incompatible change type: source
Short summary: org.jspecify.annotations의 @NonNull, @Nullable, @NullMarked 같은 nullability 불일치가 이제 경고 대신 오류로 처리돼서 Java 상호운용에서 더 엄격한 타입 안전성을 강제해요. 이 진단의 심각도를 조정하려면 -Xnullability-annotations 컴파일러 옵션을 사용해요.
Deprecation cycle:
- 1.6.0: 잠재적 nullability 불일치에 대해 경고를 보고해요.
- 1.8.20:
@Nullable,@NullnessUnspecified,@NullMarked, 그리고org.jspecify.nullness(JSpecify 0.2 이하)의 레거시 어노테이션을 포함해 특정 JSpecify 어노테이션으로 경고를 확장해요. - 2.0.0:
@NonNull어노테이션에 대한 지원을 추가해요. - 2.1.0: JSpecify 어노테이션의 기본 모드를
strict로 바꿔 경고를 오류로 변환해요.[email protected]:warning또는[email protected]:ignore를 사용해 기본 동작을 덮어쓸 수 있어요.
모호한 경우 확장 함수가 invoke 호출보다 우선하도록 오버로드 해석 변경
Issue: KTLC-37
Component: Core language
Incompatible change type: behavioral
Short summary: 오버로드 해석이 이제 모호한 경우 일관되게 확장 함수를 invoke 호출보다 우선해요. 이는 로컬 함수와 프로퍼티의 해석 로직에서의 불일치를 해결해요. 이 변경은 재컴파일 후에만 적용되며 미리 컴파일된 바이너리에는 영향을 주지 않아요.
Deprecation cycle:
- 2.1.0: 서명이 일치하는 확장 함수에 대해 확장 함수가
invoke호출보다 일관되게 우선하도록 오버로드 해석을 변경해요. 이 변경은 재컴파일 후에만 적용되고 미리 컴파일된 바이너리에는 영향을 주지 않아요.
JDK 함수 인터페이스의 SAM 생성자에서 람다가 nullable 값을 반환하는 것 금지
Issue: KTLC-42
Component: Core language
Incompatible change type: source
Short summary: 지정된 타입 인자가 non-nullable이면 JDK 함수 인터페이스의 SAM 생성자에서 람다가 nullable 값을 반환하는 것이 이제 컴파일 오류를 일으켜요. 이는 nullability 불일치로 런타임 예외가 발생할 수 있는 문제를 해결해 더 엄격한 타입 안전성을 보장해요.
Deprecation cycle:
- 2.0.0: JDK 함수 인터페이스의 SAM 생성자에서 nullable 반환 값에 대해 deprecation 경고를 보고해요.
- 2.1.0: 새 동작을 기본으로 활성화해요.
Kotlin/Native에서 public 멤버와 충돌하는 private 멤버 처리 수정
Issue: KTLC-43
Component: Core language
Incompatible change type: behavioral
Short summary: Kotlin/Native에서 private 멤버가 더 이상 상위클래스의 public 멤버를 오버라이드하거나 충돌하지 않아서 Kotlin/JVM과 동작이 맞춰져요. 이는 오버라이드 해석의 불일치를 해결하고 별도 컴파일로 인한 예기치 않은 동작을 제거해요.
Deprecation cycle:
- 2.1.0: Kotlin/Native의 private 함수와 프로퍼티가 더 이상 상위클래스의 public 멤버를 오버라이드하거나 영향을 주지 않아 JVM 동작과 맞춰져요.
public inline 함수에서 private 연산자 함수 접근 금지
Issue: KTLC-71
Component: Core language
Incompatible change type: source
Short summary: getValue(), setValue(), provideDelegate(), hasNext(), next() 같은 private 연산자 함수는 더 이상 public inline 함수에서 접근할 수 없어요.
Deprecation cycle:
- 2.0.0: public inline 함수에서 private 연산자 함수에 접근하면 deprecation 경고를 보고해요.
- 2.1.0: 경고를 오류로 올려요.
@UnsafeVariance로 주석이 달린 불변 파라미터에 잘못된 인자 전달 금지
Issue: KTLC-72
Component: Core language
Incompatible change type: source
Short summary: 컴파일러가 이제 타입 검사 중 @UnsafeVariance 어노테이션을 무시해서 불변 타입 파라미터에 대해 더 엄격한 타입 안전성을 강제해요. 이는 @UnsafeVariance에 의존해 예상 타입 검사를 우회하는 잘못된 호출을 방지해요.
Deprecation cycle:
- 2.1.0: 새 동작을 활성화해요.
경고 수준 Java 타입의 오류 수준 nullable 인자에 대한 nullability 오류 보고
Issue: KTLC-100
Component: Core language
Incompatible change type: source
Short summary: 컴파일러가 이제 경고 수준 nullable 타입에 더 엄격한 오류 수준 nullability를 가진 타입 인자가 들어 있는 Java 메서드에서 nullability 불일치를 감지해요. 이는 이전에 무시되던 타입 인자의 오류가 올바르게 보고되도록 보장해요.
Deprecation cycle:
- 2.0.0: 더 엄격한 타입 인자를 가진 Java 메서드의 nullability 불일치에 대해 deprecation 경고를 보고해요.
- 2.1.0: 경고를 오류로 올려요.
접근할 수 없는 타입의 암시적 사용 보고
Issue: KTLC-3
Component: Core language
Incompatible change type: source
Short summary: 컴파일러가 이제 함수 리터럴과 타입 인자에서 접근할 수 없는 타입의 사용을 보고해서, 불완전한 타입 정보로 인한 컴파일 및 런타임 실패를 방지해요.
Deprecation cycle:
- 2.0.0: 접근할 수 없는 비제네릭 타입의 파라미터나 리시버를 가진 함수 리터럴과, 접근할 수 없는 타입 인자를 가진 타입에 대해 경고를 보고해요. 특정 시나리오에서는 접근할 수 없는 제네릭 타입의 파라미터나 리시버를 가진 함수 리터럴과, 접근할 수 없는 제네릭 타입 인자를 가진 타입에 대해 오류를 보고해요.
- 2.1.0: 접근할 수 없는 비제네릭 타입의 파라미터와 리시버를 가진 함수 리터럴에 대해 경고를 오류로 올려요.
- 2.2.0: 접근할 수 없는 타입 인자를 가진 타입에 대해 경고를 오류로 올려요.
표준 라이브러리
Char와 String의 로케일 민감 대소문자 변환 함수 deprecated 처리
Issue: KT-43023
Component: kotlin-stdlib
Incompatible change type: source
Short summary: 다른 Kotlin 표준 라이브러리 API들 가운데 Char.toUpperCase()와 String.toLowerCase() 같은 Char와 String의 로케일 민감 대소문자 변환 함수가 deprecated 처리돼요. String.lowercase() 같은 로케일 무관 대안으로 바꾸거나, 로케일 민감 동작이 필요하면 String.lowercase(Locale.getDefault())처럼 로케일을 명시적으로 지정해요.
Kotlin 2.1.0에서 deprecated 처리된 Kotlin 표준 라이브러리 API의 전체 목록은 KT-71628을 참고하세요.
Deprecation cycle:
- 1.4.30: 로케일 무관 대안을 실험적 API로 도입해요.
- 1.5.0: 로케일 민감 대소문자 변환 함수를 경고와 함께 deprecated 처리해요.
- 2.1.0: 경고를 오류로 올려요.
kotlin-stdlib-common JAR 아티팩트 제거
Issue: KT-62159
Component: kotlin-stdlib
Incompatible change type: binary
Short summary: 레거시 멀티플랫폼 선언 메타데이터에 쓰이던 kotlin-stdlib-common.jar 아티팩트가 deprecated 처리되고, 공통 멀티플랫폼 선언 메타데이터의 표준 형식인 .klib 파일로 대체돼요. 이 변경은 메인 kotlin-stdlib.jar이나 kotlin-stdlib-all.jar 아티팩트에는 영향을 주지 않아요.
Deprecation cycle:
- 2.1.0:
kotlin-stdlib-common.jar아티팩트를 deprecated 처리하고 제거해요.
appendln()을 appendLine() 대신 deprecated 처리
Issue: KTLC-27
Component: kotlin-stdlib
Incompatible change type: source
Short summary: StringBuilder.appendln()이 StringBuilder.appendLine()을 대신 쓰도록 deprecated 처리돼요.
Deprecation cycle:
- 1.4.0:
appendln()함수가 deprecated 처리되고, 사용 시 경고를 보고해요. - 2.1.0: 경고를 오류로 올려요.
Kotlin/Native의 freezing 관련 API deprecated 처리
Issue: KT-69545
Component: kotlin-stdlib
Incompatible change type: source
Short summary: 이전에 @FreezingIsDeprecated 어노테이션으로 표시된 Kotlin/Native의 freezing 관련 API가 이제 deprecated 처리돼요. 이는 스레드 공유를 위해 객체를 freezing할 필요가 없게 만드는 새 메모리 관리자 도입과 맞물려요. 마이그레이션 방법은 Kotlin/Native 마이그레이션 가이드를 참고하세요.
Deprecation cycle:
- 1.7.20: freezing 관련 API를 경고와 함께 deprecated 처리해요.
- 2.1.0: 경고를 오류로 올려요.
구조적 수정 시 실패를 빠르게 하도록 Map.Entry 동작 변경
Issue: KTLC-23
Component: kotlin-stdlib
Incompatible change type: behavioral
Short summary: 연결된 맵이 구조적으로 수정된 뒤 Map.Entry 키-값 쌍에 접근하면 이제 ConcurrentModificationException이 발생해요.
Deprecation cycle:
- 2.1.0: 맵 구조적 수정이 감지되면 예외를 던져요.
도구
KotlinCompilationOutput#resourcesDirProvider deprecated 처리
Issue: KT-69255
Component: Gradle
Incompatible change type: source
Short summary: KotlinCompilationOutput#resourcesDirProvider 필드가 deprecated 처리돼요. 추가 리소스 디렉터리를 추가하려면 Gradle 빌드 스크립트에서 KotlinSourceSet.resources를 사용해요.
Deprecation cycle:
- 2.1.0:
KotlinCompilationOutput#resourcesDirProvider가 deprecated 처리돼요.
registerKotlinJvmCompileTask(taskName, moduleName) 함수 deprecated 처리
Issue: KT-69927
Component: Gradle
Incompatible change type: source
Short summary: registerKotlinJvmCompileTask(taskName, moduleName) 함수가 KotlinJvmCompilerOptions을 받는 새 registerKotlinJvmCompileTask(taskName, compilerOptions, explicitApiMode) 함수를 대신 쓰도록 deprecated 처리돼요. 이 새 함수는 보통 확장이나 타깃에서 가져온 compilerOptions 인스턴스를 전달할 수 있게 해주며, 그 값이 태스크 옵션의 관례로 사용돼요.
Deprecation cycle:
- 2.1.0:
registerKotlinJvmCompileTask(taskName, moduleName)함수가 deprecated 처리돼요.
registerKaptGenerateStubsTask(taskName) 함수 deprecated 처리
Issue: KT-70383
Component: Gradle
Incompatible change type: source
Short summary: registerKaptGenerateStubsTask(taskName) 함수가 deprecated 처리돼요. 새 registerKaptGenerateStubsTask(compileTask, kaptExtension, explicitApiMode) 함수를 사용해요. 이 새 버전은 관련 KotlinJvmCompile 태스크의 값을 관례로 연결할 수 있게 해서 두 태스크가 같은 옵션 집합을 사용하도록 보장해요.
Deprecation cycle:
- 2.1.0:
registerKaptGenerateStubsTask(taskName)함수가 deprecated 처리돼요.
KotlinTopLevelExtension과 KotlinTopLevelExtensionConfig 인터페이스 deprecated 처리
Issue: KT-71602
Component: Gradle
Incompatible change type: behavioral
Short summary: KotlinTopLevelExtension과 KotlinTopLevelExtensionConfig 인터페이스가 새 KotlinTopLevelExtension 인터페이스를 대신 쓰도록 deprecated 처리돼요. 이 인터페이스는 KotlinTopLevelExtensionConfig, KotlinTopLevelExtension, KotlinProjectExtension을 통합해 API 계층을 간소화하고, JVM 툴체인과 컴파일러 프로퍼티에 공식적으로 접근할 수 있게 해줘요.
Deprecation cycle:
- 2.1.0:
KotlinTopLevelExtension과KotlinTopLevelExtensionConfig인터페이스가 deprecated 처리돼요.
빌드 런타임 의존성에서 kotlin-compiler-embeddable 제거
Issue: KT-61706
Component: Gradle
Incompatible change type: source
Short summary: kotlin-compiler-embeddable 의존성이 Kotlin Gradle 플러그인(KGP) 런타임에서 제거돼요. 필요한 모듈은 이제 KGP 아티팩트에 직접 포함되고, 8.2 미만 버전의 Gradle Kotlin 런타임과의 호환성을 지원하기 위해 Kotlin 언어 버전은 2.0으로 제한돼요.
Deprecation cycle:
- 2.1.0:
kotlin-compiler-embeddable사용에 대해 경고를 보고해요. - 2.2.0: 경고를 오류로 올려요.
Kotlin Gradle 플러그인 API에서 컴파일러 심볼 숨기기
Issue: KT-70251
Component: Gradle
Incompatible change type: source
Short summary: KotlinCompilerVersion처럼 Kotlin Gradle 플러그인(KGP)에 번들된 컴파일러 모듈 심볼이 빌드 스크립트에서 의도치 않은 접근을 막기 위해 공개 API에서 숨겨져요.
Deprecation cycle:
- 2.1.0: 이 심볼에 접근하면 경고를 보고해요.
- 2.2.0: 경고를 오류로 올려요.
여러 안정성 구성 파일 지원 추가
Issue: KT-68345
Component: Gradle
Incompatible change type: source
Short summary: Compose 확장의 stabilityConfigurationFile 프로퍼티가 여러 구성 파일을 지정할 수 있는 새 stabilityConfigurationFiles 프로퍼티를 대신 쓰도록 deprecated 처리돼요.
Deprecation cycle:
- 2.1.0:
stabilityConfigurationFile프로퍼티가 deprecated 처리돼요.
deprecated 플랫폼 플러그인 ID 제거
Issue: KT-65565
Component: Gradle
Incompatible change type: source
Short summary: 다음 플랫폼 플러그인 ID에 대한 지원이 제거됐어요.
kotlin-platform-commonorg.jetbrains.kotlin.platform.common
Deprecation cycle:
- 1.3: 플랫폼 플러그인 ID가 deprecated 처리돼요.
- 2.1.0: 플랫폼 플러그인 ID가 더 이상 지원되지 않아요.