Class ModuleUtil
Provides utilities for inspecting and working with the Java Platform Module System (JPMS). Helps determine whether reflective access is permitted between modules, and provides diagnostic information when access fails.
提供用于检查和使用 Java 平台模块系统 (JPMS) 的工具。 帮助确定模块之间是否允许反射访问,并在访问失败时提供诊断信息。
Features | 主要功能:
- Module accessibility checking - 模块可访问性检查
- Package export/open status inspection - 包导出/开放状态检查
- Deep reflection capability detection - 深度反射能力检测
- Access diagnostic information - 访问诊断信息
- MethodHandles.Lookup acquisition - MethodHandles.Lookup 获取
Usage Examples | 使用示例:
// Check if a class is accessible from the caller's module
boolean accessible = ModuleUtil.isAccessible(String.class, MyClass.class);
// Get module information for a class
ModuleUtil.ModuleInfo info = ModuleUtil.getModuleInfo(String.class);
// Get diagnostic info about why access might fail
String diagnostic = ModuleUtil.getAccessDiagnostic(TargetClass.class, CallerClass.class);
Security | 安全性:
- Thread-safe: Yes (stateless utility class) - 线程安全: 是(无状态工具类)
- Null-safe: Yes (validates all parameters) - 空值安全: 是(验证所有参数)
Performance | 性能特性:
- Time complexity: O(1) for most checks - 时间复杂度: 大部分检查为 O(1)
- Space complexity: O(n) for ModuleInfo (n = number of packages) - 空间复杂度: O(n)(n = 包数量)
- Since:
- JDK 25, opencode-base-reflect V1.0.3
- Author:
- Leon Soo www.LeonSoo.com
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordModule information for a class 类的模块信息 -
Method Summary
Modifier and TypeMethodDescriptionstatic booleancanDeepReflect(Class<?> targetClass, Class<?> callerClass) Checks if deep reflection (setAccessible(true)) can work on the target class from the caller.static StringgetAccessDiagnostic(Class<?> targetClass, Class<?> callerClass) Gets diagnostic information about why reflective access might fail between two classes.static ModuleUtil.ModuleInfogetModuleInfo(Class<?> clazz) Gets module information for a class.static booleanisAccessible(Class<?> targetClass, Class<?> callerClass) Checks if a package in the target class's module is accessible (exported or open) to the caller's module.static booleanisExported(Class<?> targetClass, Module callerModule) Checks if the target class's package is exported to the given module.static booleanisInNamedModule(Class<?> clazz) Checks if a class is in a named module.static booleanChecks if the target class's package is open to the given module (allows deep reflection).static Optional<MethodHandles.Lookup> tryPrivateLookup(Class<?> targetClass) Tries to get aMethodHandles.Lookupthat can access the target class with private access.
-
Method Details
-
isAccessible
Checks if a package in the target class's module is accessible (exported or open) to the caller's module. 检查目标类所在模块的包对调用方模块是否可访问(已导出或已开放)。A package is considered accessible if any of the following is true:
- Both classes are in the same module
- The target class is in an unnamed module
- The target package is exported to the caller's module
- Parameters:
targetClass- the target class to check accessibility for | 要检查可访问性的目标类callerClass- the caller class | 调用方类- Returns:
- true if the target class's package is accessible | 如果目标类的包可访问则返回 true
- Throws:
OpenReflectException- if targetClass or callerClass is null | 如果参数为 null 则抛出异常
-
isOpen
Checks if the target class's package is open to the given module (allows deep reflection). 检查目标类的包是否对给定模块开放(允许深度反射)。An open package allows
setAccessible(true)on its members.开放的包允许对其成员调用
setAccessible(true)。- Parameters:
targetClass- the target class | 目标类callerModule- the caller's module | 调用方的模块- Returns:
- true if the package is open to the caller module | 如果包对调用方模块开放则返回 true
- Throws:
OpenReflectException- if targetClass or callerModule is null | 如果参数为 null 则抛出异常
-
isExported
Checks if the target class's package is exported to the given module. 检查目标类的包是否已导出到给定模块。Exported packages allow compile-time (public API) access but not deep reflection.
导出的包允许编译时(公共 API)访问,但不允许深度反射。
- Parameters:
targetClass- the target class | 目标类callerModule- the caller's module | 调用方的模块- Returns:
- true if the package is exported to the caller module | 如果包已导出到调用方模块则返回 true
- Throws:
OpenReflectException- if targetClass or callerModule is null | 如果参数为 null 则抛出异常
-
canDeepReflect
Checks if deep reflection (setAccessible(true)) can work on the target class from the caller. 检查从调用方对目标类进行深度反射(setAccessible(true))是否可行。Deep reflection requires the target package to be open to the caller's module, either unconditionally or via a qualified opens directive.
深度反射要求目标包对调用方模块开放,可以是无条件开放或通过限定的 opens 指令。
- Parameters:
targetClass- the target class | 目标类callerClass- the caller class | 调用方类- Returns:
- true if deep reflection is possible | 如果深度反射可行则返回 true
- Throws:
OpenReflectException- if targetClass or callerClass is null | 如果参数为 null 则抛出异常
-
getAccessDiagnostic
Gets diagnostic information about why reflective access might fail between two classes. 获取关于两个类之间反射访问可能失败原因的诊断信息。Returns a human-readable string explaining module relationships, export/open status, and what module directives would be needed for access.
返回人类可读的字符串,解释模块关系、导出/开放状态以及访问所需的模块指令。
Security Warning | 安全警告: The returned string contains module topology details (module names, package names, export/open status). Do not expose this output in API responses, user-facing error messages, or unsecured log channels. Use only for internal debugging and development diagnostics.
返回的字符串包含模块拓扑详情(模块名、包名、导出/开放状态)。 不要在 API 响应、用户可见的错误消息或不安全的日志通道中暴露此输出。 仅用于内部调试和开发诊断。
- Parameters:
targetClass- the target class | 目标类callerClass- the caller class | 调用方类- Returns:
- diagnostic string | 诊断字符串
- Throws:
OpenReflectException- if targetClass or callerClass is null | 如果参数为 null 则抛出异常
-
getModuleInfo
Gets module information for a class. 获取类的模块信息。- Parameters:
clazz- the class to inspect | 要检查的类- Returns:
- module information record | 模块信息记录
- Throws:
OpenReflectException- if clazz is null | 如果 clazz 为 null 则抛出异常
-
isInNamedModule
Checks if a class is in a named module. 检查类是否在命名模块中。Classes loaded from the classpath are in unnamed modules. Classes from the JDK or explicitly declared modules are in named modules.
从类路径加载的类在未命名模块中。来自 JDK 或显式声明的模块中的类在命名模块中。
- Parameters:
clazz- the class to check | 要检查的类- Returns:
- true if the class is in a named module | 如果类在命名模块中则返回 true
- Throws:
OpenReflectException- if clazz is null | 如果 clazz 为 null 则抛出异常
-
tryPrivateLookup
Tries to get aMethodHandles.Lookupthat can access the target class with private access. 尝试获取可以以私有访问权限访问目标类的MethodHandles.Lookup。This uses
MethodHandles.privateLookupIn(Class, MethodHandles.Lookup)which requires the target class's package to be open to the caller's module.使用
MethodHandles.privateLookupIn(Class, MethodHandles.Lookup), 要求目标类的包对调用方模块开放。- Parameters:
targetClass- the target class | 目标类- Returns:
- an Optional containing the Lookup if successful, or empty if access is denied | 成功时包含 Lookup 的 Optional,访问被拒绝时返回空
- Throws:
OpenReflectException- if targetClass is null | 如果 targetClass 为 null 则抛出异常
-