Kotlin과 OSGi

Kotlin과 OSGi (Kotlin and OSGi)

Kotlin 프로젝트를 OSGi 모듈 기반 환경에서 돌리고 싶을 때가 있죠. 그럴 때 일반 Kotlin 라이브러리 대신 kotlin-osgi-bundle을 쓰면 된다는 핵심만 기억하면 돼요. Maven과 Gradle에서 각각 어떻게 하는지 함께 살펴볼게요.

출처: Kotlin and OSGi

본문

Kotlin 프로젝트에서 OSGi 지원을 켜려면, 일반 Kotlin 라이브러리 대신 kotlin-osgi-bundle을 포함하세요. kotlin-runtime, kotlin-stdlib, kotlin-reflect 의존성은 kotlin-osgi-bundle이 이미 모두 포함하고 있으니 제거하는 것을 권장해요. 외부 Kotlin 라이브러리가 포함된 경우에도 주의해야 해요. 대부분의 일반 Kotlin 의존성은 OSGi에 맞지 않으므로 사용하지 말고 프로젝트에서 제거해야 해요.

Maven

Maven 프로젝트에 Kotlin OSGi 번들을 포함하려면 이렇게 해요.

<dependencies>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-osgi-bundle</artifactId>
        <version>${kotlin.version}</version>
    </dependency>
</dependencies>

외부 라이브러리에서 표준 라이브러리를 제외하려면 이렇게 해요. 참고로 "별표 제외(star exclusion)"는 Maven 3에서만 동작해요.

<dependency>
    <groupId>some.group.id</groupId>
    <artifactId>some.library</artifactId>
    <version>some.library.version</version>

    <exclusions>
        <exclusion>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Gradle

Gradle 프로젝트에 kotlin-osgi-bundle을 포함하려면 이렇게 해요.

dependencies {
    implementation(kotlin("osgi-bundle"))
}
dependencies {
    implementation "org.jetbrains.kotlin:kotlin-osgi-bundle:2.4.20"
}

전이 의존성(transitive dependencies)으로 따라오는 기본 Kotlin 라이브러리를 제외하려면 다음 방법을 쓸 수 있어요.

dependencies {
    implementation("some.group.id:some.library:someversion") {
        exclude(group = "org.jetbrains.kotlin")
    }
}
dependencies {
    implementation('some.group.id:some.library:someversion') {
        exclude group: 'org.jetbrains.kotlin'
    }
}

FAQ

왜 그냥 모든 Kotlin 라이브러리에 필요한 manifest 옵션을 넣지 않나요?

이것이 OSGi 지원을 제공하는 가장 선호되는 방법이긴 하지만, 아쉽게도 지금은 어렵지 않아요. 이른바 "패키지 분할(package split)" 문제 때문인데, 쉽게 제거할 수 없는 문제라서 그렇게 큰 변경은 지금 계획에 없어요. Require-Bundle 기능이 있긴 하지만 그것도 최선의 선택은 아니고 사용을 권장하지 않아요. 그래서 OSGi용으로 별도의 아티팩트를 만들기로 결정했어요.