Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java 9에서 클래스 로더별로 모든 모듈을 표시하는 방법

Java 9 이전에는 확장(Extension) 클래스 로더와 애플리케이션(Application) 클래스 로더가 모두 java.net.URLClassLoader 클래스의 인스턴스였습니다. 그러나 Java 9부터는 클래스 로더의 분류 체계가 변경되어, 기존의 확장 클래스 로더를 대체하는 플랫폼 클래스 로더(Platform Class Loader)가 새롭게 도입되었습니다.

플랫폼 클래스 로더가 도입된 주요 이유는 부트스트랩 클래스 로더(Bootstrap Class Loader)가 로드하는 클래스들이 기본적으로 모든 권한을 가지기 때문입니다. 따라서 일부 플랫폼 관련 클래스들을 부트스트랩이 아닌 별도의 로더로 분리하여 보안과 구조를 개선한 것입니다.

클래스 로더와 함께 모든 모듈 표시하기

아래 예제에서는 ModuleLayer.boot()를 사용하여 부트 레이어에 포함된 모든 모듈을 순회하면서, 각 모듈이 어떤 클래스 로더에 의해 로드되었는지 확인하고 출력합니다. 클래스 로더가 null인 경우 해당 모듈은 부트스트랩 클래스 로더에 의해 로드된 것으로 간주합니다.

예제 코드

import static java.util.Objects.isNull;

public class Java9ClassLoaderTest {
    public static void main(String args[]) {
        ModuleLayer layer = ModuleLayer.boot();
        layer.modules().forEach(module -> {
            ClassLoader classLoader = module.getClassLoader();
            String classLoaderName = isNull(classLoader) ? "bootstrap" : classLoader.getName();
            System.out.println(classLoaderName + ": " + module.getName());
        });
    }
}

실행 결과

app: jdk.internal.ed
platform: jdk.scripting.nashorn
platform: java.compiler
platform: java.security.jgss
platform: jdk.plugin.dom
bootstrap: jdk.net
bootstrap: java.management
app: jdk.jdeps
platform: javafx.base
app: jdk.editpad
bootstrap: java.security.sasl
platform: java.sql.rowset
bootstrap: java.datatransfer
app: jdk.compiler
platform: java.scripting
platform: jdk.naming.dns
platform: jdk.crypto.mscapi
bootstrap: java.xml
platform: jdk.localedata
platform: javafx.swing
bootstrap: jdk.unsupported
platform: jdk.plugin
bootstrap: jdk.snmp
bootstrap: jdk.naming.rmi
app: jdk.internal.le
platform: javafx.web
platform: jdk.dynalink
platform: jdk.accessibility
bootstrap: java.rmi
platform: jdk.jsobject
platform: java.sql
app: jdk.attach
bootstrap: jdk.management.cmm
platform: jdk.security.auth
platform: java.xml.crypto
bootstrap: jdk.jfr
bootstrap: jdk.management.jfr
platform: jdk.security.jgss
app: jdk.packager.services
bootstrap: java.base
app: jdk.internal.opt
bootstrap: java.prefs
bootstrap: java.management.rmi
platform: jdk.zipfs
platform: java.jnlp
app: jdk.packager
platform: oracle.net
app: jdk.jlink
bootstrap: jdk.management.agent
bootstrap: java.logging
app: jdk.jdi
app: jdk.jstatd
platform: java.se
app: jdk.javadoc
platform: jdk.charsets
platform: java.smartcardio
app: jdk.jconsole
bootstrap: jdk.sctp
platform: javafx.graphics
bootstrap: jdk.management.resource
app: jdk.jdwp.agent
app: jdk.internal.jvmstat
platform: javafx.controls
platform: jdk.crypto.cryptoki
platform: javafx.media
bootstrap: jdk.httpserver
platform: oracle.desktop
bootstrap: java.naming
app: jdk.jshell
app: jdk.jartool
platform: jdk.deploy
bootstrap: java.desktop
platform: javafx.fxml
bootstrap: java.instrument
platform: jdk.crypto.ec
bootstrap: jdk.management
platform: jdk.xml.dom
platform: jdk.javaws

결과 해석

출력 결과를 보면 각 모듈은 세 가지 유형의 클래스 로더 중 하나에 속하는 것을 알 수 있습니다.

  • bootstrap: java.base, java.desktop, java.logging 등 JDK의 핵심 기본 모듈들이 여기에 속합니다. getClassLoader()가 null을 반환하므로 코드에서 "bootstrap"으로 표시됩니다.
  • platform: java.sql, java.xml.crypto, jdk.localedata 등 플랫폼 클래스 로더가 로드하는 모듈들입니다.
  • app: jdk.compiler, jdk.jshell, jdk.jlink 등 애플리케이션 클래스 로더가 로드하는 도구성 모듈들입니다.

이처럼 Java 9의 모듈 시스템(JPMS)에서는 ModuleLayer API를 활용하면 런타임에 어떤 클래스 로더가 어떤 모듈을 담당하는지 쉽게 파악할 수 있습니다.