- Meta는 수년간의 프로젝트를 통해 Android 코드베이스를 Java에서 Kotlin으로 전환 중
- 현재 세계 최대 Android 코드베이스 중 하나를 관리하며, 절반 이상을 성공적으로 Kotlin으로 변환했음
- Meta는 2020년부터 Kotlin-first 개발 전략을 채택
- 전체 코드를 변환한 이유:
- Kotlin의 "생산성 향상"과 "Null 안정성"의 이점을 최대한 활용하기 위해 기존 천만라인의 Java 코드까지 변환을 결정
- Null 안정성을 강화하고 혼합 코드베이스 문제 해결
- 혼합 컴파일(Java와 Kotlin 동시 컴파일)은 빌드 속도를 가장 느리게 만듦
- 남아 있는 Java 코드는 Null 안정성 문제를 유발: Null 안전하지 않은 Java 코드는 의존성 그래프에서 NullPointerException(NPE)의 잠재적 원인이 됨
- Kotlin은 런타임 검증으로 Null 안전성을 보장
자동화 과정
- 초기에는 Intellij IDE의 J2K 변환 도구를 반복적으로 실행했음
- Meta의 대규모 코드베이스에서는 100,000번 이상 클릭이 필요하며, 각 실행에 몇 분 소요
- 결과적으로 이 방식은 확장성 부족으로 비효율적
-
자동화 도구: Kotlinator를 개발
- 6단계 변환 프로세스
- Deep Build: 변환할 코드를 빌드해 모든 심볼을 IDE가 해결 가능하도록 준비. 서드파티 의존성 및 생성 코드 포함
- Preprocessing: Meta의 맞춤 도구 Editus 기반. Null 안정성 및 종속성 처리, J2K 워크어라운드 수행 등 약 50단계 포함
- Headless J2K: J2K를 서버 환경에서 실행 가능하도록 수정
- Postprocessing: Android 특화 변경, Null 안정성, Kotlin 스타일 적용등 약 150단계
- Linters: 자동 수정을 통한 지속적인 변환 품질 향상
- Build Error-based Fixes: 빌드 에러를 분석해 추가 수정 적용
J2K를 헤드리스화 하기
- J2K를 원격에서 실행 가능하도록 수정:
- J2K는 Intellij IDE와 긴밀히 결합되어 있어 독립 실행이 어려웠음
- 초기에는 Intellij 테스트 환경을 활용해 실행을 고려했으나 JetBrains의 J2K 전문가(Ilya Kirillov)와 협의 후, 헤드리스 검사 방식으로 전환
- Intellij 플러그인을 만들어
ApplicationStarter
클래스를 확장하고, J2K의 JavaToKotlinConverter
클래스를 호출하여 구현
-
헤드리스 방식의 장점
- 로컬 IDE 문제 해결: 개발자들이 IDE 버튼을 직접 클릭하지 않아도 작업 가능
- 여러 파일 동시 변환: 대규모 파일 처리가 가능해짐
- 시간 소요 감소: 변환 시간 자체는 약 30분으로 늘어났으나, 개발자들이 소비하는 시간은 크게 줄어듦
- 빌드 및 에러 수정 지원: 시간 소모가 크지만 유용한 작업 단계(빌드 후 수정)를 원격에서 자동 실행 가능
- 자동화와 코드 리뷰
- Meta 내부 시스템을 활용해 일일 배치 작업 생성:
- 사용자 정의 기준에 따라 배치로 diffs 생성 (Meta의 pull request 버전)
- 자동으로 리뷰어를 할당하고 테스트 및 검증 수행 후, 최종적으로 승인된 diff를 배포
- 웹 UI 제공: 개발자가 특정 파일 또는 모듈 변환을 원격으로 트리거 가능
-
변환 순서 결정
- 특정 순서를 강제하지 않음:
-
활성 개발 파일 우선 처리
- Kotlinator가 종속성 그래프를 자동 처리하여 외부 파일의 호환성 문제 해결
- 예:
foo.getName()
를 foo.name
으로 자동 업데이트
그외
- 커스텀 Preprocessing (Java->Java) & Postprocessing (Kotlin->Kotlin 단계 추가
- Meta의 내부 툴 Editus와 JetBrains PSI 라이브러리를 활용해 변환 품질 향상
- Nullsafe와 NullAway
Kotlin 변환의 현재와 미래
- Meta의 Android Java 코드의 절반 이상이 Kotlin으로 변환 완료 (혹은 일부 코드 삭제)
- 하지만, 쉬운 절반은 끝났음:
- 남은 작업은 복잡하고 규모가 큼
-
완전 자동화 가능한 변환을 위해 맞춤 단계를 추가하거나 J2K 개선에 기여해야 함
-
반자동 변환의 경우, Kotlinator 개선으로 매끄럽고 안전한 배포가 목표
- 다른 기업들도 유사한 Android 코드 변환 문제를 겪고 있을거라 생각
- Meta는 변환 도구 개선과 최적화 과정을 통해 얻은 해결책을 공유함
-
협력 제안:
- Kotlinlang Slack의 #j2k 채널에서 다른 개발자들과 논의
- 서로의 사례와 솔루션 공유로 더 나은 변환 경험 구축이 가능할 것