[java] Jigsaw 모듈의 동적 로딩과 리플렉션 사용 방법

Java 9에서 도입된 Jigsaw 모듈 시스템은 애플리케이션의 모듈화를 통해 더욱 견고하고 유지보수가 용이한 소프트웨어 개발을 지원합니다. Jigsaw 모듈 시스템을 사용하면 모듈 간의 의존성을 명확하게 정의하고, 불필요한 클래스들을 숨기는 등의 장점을 얻을 수 있습니다.

이번 포스트에서는 Jigsaw의 동적 로딩과 리플렉션을 사용하여 모듈 간 상호작용을 구현하는 방법을 알아보겠습니다.

1. 모듈 정의하기

먼저 모듈을 정의해야 합니다. 아래와 같이 모듈 디스크립터 파일(module-info.java)을 생성하고, 모듈의 의존성과 내보내는 패키지를 명시해야 합니다.

module com.example.mymodule {
    requires com.example.dependencymodule;
    exports com.example.mymodule.package;
}

위 예제에서는 com.example.mymodule이라는 모듈이 com.example.dependencymodule 모듈을 의존하며, com.example.mymodule.package 패키지를 외부에 공개합니다.

2. 모듈 동적 로딩하기

이제 모듈을 동적으로 로드하는 방법을 알아보겠습니다. 아래 예제는 com.example.mymodule 모듈을 로드하고 해당 모듈의 클래스를 사용하는 방법을 보여줍니다.

ModuleLayer layer = ModuleLayer.boot();
ModuleFinder finder = layer.finder();
ModuleReference reference = finder.find("com.example.mymodule");
Module module = reference.get().orElseThrow();

Class<?> MyClass = module.getClassLoader().loadClass("com.example.mymodule.package.MyClass");

위의 코드는 com.example.mymodule 모듈을 로드하고, 해당 모듈의 com.example.mymodule.package.MyClass 클래스를 가져옵니다. 이렇게 가져온 클래스를 사용하여 필요한 기능을 실행할 수 있습니다.

3. 모듈 리플렉션 사용하기

리플렉션을 사용하면 런타임에 클래스의 정보를 조회하고 메서드를 호출할 수 있습니다. 모듈 리플렉션을 사용하기 위해서는 모듈 디스크립터 파일에 opens 키워드로 열려있는 패키지를 선언해야 합니다.

module com.example.mymodule {
    requires com.example.dependencymodule;
    exports com.example.mymodule.package;
    opens com.example.mymodule.package;
}

이제 모듈 리플렉션을 사용하여 클래스의 정보를 조회하고 메서드를 호출할 수 있습니다.

Class<?> MyClass = Class.forName("com.example.mymodule.package.MyClass");
Object instance = MyClass.getDeclaredConstructor().newInstance();

Method method = MyClass.getDeclaredMethod("doSomething");
method.invoke(instance);

위의 코드는 com.example.mymodule.package.MyClass 클래스를 로드하고, 해당 클래스의 인스턴스를 생성하여 doSomething 메서드를 호출하는 예제입니다.

결론

Jigsaw 모듈 시스템을 사용하면 애플리케이션의 모듈화를 통해 코드의 격리와 모듈 간의 명확한 의존성 관리를 가능하게 합니다. 동적 로딩과 리플렉션을 활용하면 런타임에 모듈을 로드하고, 클래스의 정보를 조회하며, 메서드를 호출할 수 있습니다.

더 많은 정보와 예제는 Java 9 모듈 시스템 문서를 참고하세요.