호환성(Compatibility) 개념 심층 분석
호환성(Compatibility) 개념 심층 분석
모든 "호환성(compatibilities)" 개념의 핵심은 결국 하나의 질문으로 귀결됩니다. "라이브러리를 업데이트했을 때, 이미 사용 중인 개발자에게 어떤 문제가 발생할 수 있는가?"
예시를 통해 살펴보겠습니다. 여러분이 인기 있는 라이브러리인 AwesomeLibrary의 저자이고, 한 개발자 "Alex"가 자신의 앱에서 이 라이브러리를 사용하고 있다고 가정해 봅시다.
1. 바이너리 호환성 (Binary Compatibility, "플러그 앤 플레이" 계약)
-
정의: 가장 엄격하고 중요한 호환성 유형입니다. 구버전 라이브러리로 컴파일된 앱(
.apk나.jar같은 바이너리 파일)이 재컴파일 없이도 신버전 라이브러리에서 정상 동작하는 것을 의미합니다. 사용자가 새 라이브러리 파일을 그대로 넣기만 해도 앱이 시작 시 크래시 없이 동작해야 합니다. -
비유: 물리적 전원 어댑터 Alex의 앱이 라이브러리의 3구 소켓에 맞는 플러그를 가지고 있다고 상상해 봅시다.
- 호환되는 변경: 라이브러리 내부 배선을 더 효율적으로 개선했습니다. 소켓은 여전히 같은 모양과 위치의 3개 구멍을 유지합니다. Alex는 구버전을 빼고 신버전을 꽂기만 하면 됩니다. 아무 문제 없이 동작합니다.
- 비호환 변경: 라이브러리를 "개선"하면서 소켓 구멍 하나를 제거했습니다. Alex의 앱이 신버전에 꽂으려 하면 플러그가 맞지 않습니다. 프로그램이 시작조차 되지 않고 즉시 크래시가 발생합니다. 이것이 바로 바이너리 비호환입니다.
-
기술적 예시:
public메서드인fun doSomething()을 삭제했다고 가정하겠습니다. Alex의 앱은 해당 메서드가 존재한다는 전제로 컴파일되었기 때문에, 런타임에doSomething()을 호출하려는 순간 JVM이 메서드를 찾지 못하고NoSuchMethodError를 발생시킵니다. 앱은 즉시 크래시됩니다. -
가장 엄격한 이유: 컴파일된 코드의 물리적 "형태(shape)"에 관한 계약이기 때문입니다. 메서드 삭제, 메서드 시그니처 변경 등 형태를 바꾸는 모든 변경은 이 계약을 위반합니다. Metalava가 바이너리 호환성에 대해 100% 검증을 목표로 하는 이유도 바로 이 때문이며, 바이너리 호환성이 깨지면 사용자에게 치명적인 영향을 미칩니다.