java - 如何获取Java类的真实模块依赖关系?

标签 java java-11 java-platform-module-system jlink jdeps

我的 JDK 版本是 OpenJDK 11。 我的类文件是 jmx.Main.class

这是我的代码。

package jmx;
import java.lang.management.ManagementFactory;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;

public class Main {
    public static void main(String[] args) throws InstanceNotFoundException, AttributeNotFoundException, MalformedObjectNameException, ReflectionException, MBeanException  {
        /* Total number of processors or cores available to the JVM */
        MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
        Object attribute = mBeanServer.getAttribute(new ObjectName("java.lang","type","OperatingSystem"), "TotalPhysicalMemorySize");
        Object attribute2 = mBeanServer.getAttribute(new ObjectName("java.lang","type","OperatingSystem"), "FreePhysicalMemorySize");
        System.out.println("Total memory: "+ Long.parseLong(attribute.toString()) / 1024  +"MB");
        System.out.println("Free  memory: "+ Long.parseLong(attribute2.toString()) / 1024  +"MB");
    }
}

在 IDE 中运行时工作正常。我想使用自定义的jre。然后我使用 jdeps 来分析依赖关系。结果是:

Main.class -> java.base
Main.class -> java.management
   jmx                                        -> java.io                                            java.base
   jmx                                        -> java.lang                                          java.base
   jmx                                        -> java.lang.invoke                                   java.base
   jmx                                        -> java.lang.management                               java.management
   jmx                                        -> javax.management                                   java.management

所以我认为java.basejava.management是依赖模块。

然后我使用 jlink 生成我的自定义 jre。

jlink --module-path "C:\Program Files\Java\jdk-11.0.6\jmods" --add-modules java.base,java.management --output jre11

在使用自定义 jre 之前,我已在 cmd 窗口中运行代码。效果很好。

然后我在 jre 中运行代码。代码无法运行,出现错误:

javax.management.AttributeNotFoundException: No such attribute: TotalPhysicalMemorySize

所以我认为原因是缺少一些依赖模块。我运行jlink来生成整个模块jre。当我使用整个模块jre时,代码再次正确运行。

如何获取真正的依赖模块?或者这是 JDK 的错误?

最佳答案

在 JDK 9 之前,类型 com.sun.management.OperatingSystemMXBeanjava.lang.management.OperatingSystemMXBean 的未记录扩展。因此,使用像 getAttribute(new ObjectName("java.lang","type","OperatingSystem"), "TotalPhysicalMemorySize") 这样的反射属性查询是合理的,它不会创建对非标准的依赖API。

优点也是缺点。当不存在依赖关系时,依赖关系分析工具无法检测到依赖关系。

当您添加模块jdk.management时,扩展将可用。作为已记录模块的一部分还意味着,当您愿意接受对该模块的永久依赖时,您可以使用扩展 OperatingSystemMXBean直接。

import com.sun.management.OperatingSystemMXBean;
import java.lang.management.ManagementFactory;

public class OSMX {
    public static void main(String[] args) {
        OperatingSystemMXBean osBean
            = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
        System.out.println("Total memory: "
            + osBean.getTotalPhysicalMemorySize() / (1024*1024)  +"MB");
        System.out.println("Free  memory: "
            + osBean.getFreePhysicalMemorySize() / (1024*1024)  +"MB");
    }
}

然后,jdeps 将正确向 jdk.management 报告依赖关系。

关于java - 如何获取Java类的真实模块依赖关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60312707/

相关文章:

java - 无法使用 JMOD 打包已签名的 Java 安全提供程序

java - Java 10 : annotations not found in maven 上的 maven lombok 插件

java - Eclipse - 添加 module-info.java 时未找到模块

unit-testing - 使用 java 11 进行 pojo 测试

java - Java 中的 JAVA_OPTS "-D"标志的值是否有最大大小限制?

java - java 将 arraylist 元素的值增加 1

java - 使用 JDBC 更新多行

java - 您如何在模块化 Java 项目中组织测试?

从未选择用于多个 OP 代码的 Java SocketChannel register()

java - 将阿拉伯语文本从文本框写入java文件