.NET에서 Maven 패키지나 JAR 파일 직접 참조하기 (feat. IKVM)

예전에 IKVM: .NET 런타임에서 Java 8 코드 실행하기 - bugflow 님의 게시물 #2 아티클에서 IKVM이 새롭게 리뉴얼되었다는 소식을 전해 드린 적이 있는데, 여기서 더 나아가서 실질적인 예시를 소개해드리려 합니다.

C#으로 KoNLPy 활용하기 (feat. Embeddable Python) 아티클에서, 서울대 지능형 데이터 시스템 연구소의 꼬꼬마 한국어 형태소 분석기를 KoNLPy를 경유해서 사용할 수 있는 방법을 소개해드렸습니다.

그런데 여기서 한 스텝 더 나아가서, 파이썬을 경유하지 않고 IKVM을 이용해서 직접 JAR 파일이나 Maven 패키지를 .NET 프로젝트의 일부로 direct referencing을 할 수 있는 것도 확인하여 간단한 방법을 공유합니다.

.NET 8 이후 프로젝트에서, NuGet 패키지 중에서 IKVM.Maven.Sdk 패키지를 추가하고, CSPROJ에 다음과 같이 JAR 패키지 또는 Maven 레퍼런스를 추가합니다. 여기서는 꼬꼬마 한글 형태소 분석기 (여기 있는 버전을 사용했습니다.)와 Open Korean Text 분석기를 각각 참조했습니다.

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<TargetFramework>net8.0</TargetFramework>
		<ImplicitUsings>enable</ImplicitUsings>
		<Nullable>enable</Nullable>
		<OutputType>Exe</OutputType>
	</PropertyGroup>

	<ItemGroup>
		<PackageReference Include="IKVM.Maven.Sdk" Version="1.9.0" />
	</ItemGroup>

	<ItemGroup>
		<IkvmReference Include="kkma-2.0.jar" />
		<MavenReference Include="org.openkoreantext:open-korean-text" Version="2.3.1" />
	</ItemGroup>

</Project>

그리고 꼬꼬마와 OpenKoreanText가 제공하는 각각의 한글 자소 분리 유틸리티 클래스를 사용하도록 코드를 만들어봤습니다.

using KkmaHangul = org.snu.ids.ha.util.Hangul;
using OktHangul = org.openkoreantext.processor.util.Hangul;

var kkma = new KkmaHangulUtil();
kkma.Split('한', out var cho, out var jung, out var jong);
Console.WriteLine($"초성: {cho}, 중성: {jung}, 종성: {jong}");

var okt = new OktHangulUtil();
Console.WriteLine($"{okt.Combine('ㄱ', 'ㅡ', 'ㄹ')}");

public interface IHangulUtil
{
    void Split(char c, out char onset, out char vowel, out char coda);
    char Combine(char onset, char vowel, char coda);
}

public sealed class KkmaHangulUtil : IHangulUtil
{
    public void Split(char c, out char onset, out char vowel, out char coda)
    {
        var result = KkmaHangul.split(c);
        onset = result.cho;
        vowel = result.jung;
        coda = result.jong;
    }

    public char Combine(char onset, char vowel, char coda)
        => KkmaHangul.combine(onset, vowel, coda);
}

public sealed class OktHangulUtil : IHangulUtil
{
    public void Split(char c, out char onset, out char vowel, out char coda)
    {
        var result = OktHangul.decomposeHangul(c);
        onset = result.onset();
        vowel = result.vowel();
        coda = result.coda();
    }

    public char Combine(char onset, char vowel, char coda)
        => OktHangul.composeHangul(onset, vowel, coda);
}

이렇게 실행했을 때, Maven 레퍼런스 쪽의 경우에는 Maven 레퍼런스 탐색과 캐싱에 시간이 조금 걸리다보니 빌드 시간이 많이 늘어난다는 단점이 있지만 그럼에도 캐싱 이후에 원활하게 잘 실행되는 것을 볼 수 있었습니다.

참고로 IKVM의 경우 Java SE 1.8 기준의 가상 머신을 구현한 것이므로, 모든 최신 Java 코드를 100% 실행할 수 있다는 보장은 없으나, 지명도가 높은 라이브러리들이나 상호 연동을 전제로 만들고 있는 Java 라이브러리 코드는 이런 방법으로 상호 운용을 달성할 수 있으니 참고하시면 좋을 것 같습니다.

이 주제에 관심있으신 분들께 도움이 될까하여 간단한 정보지만 공유드려봅니다. :smiley:

9개의 좋아요