如何获得Java类';真正的模块依赖关系?

如何获得Java类';真正的模块依赖关系?,java,java-11,java-platform-module-system,jlink,jdeps,Java,Java 11,Java Platform Module System,Jlink,Jdeps,我的JDK版本是OpenJDK11。 我的类文件是jmx.Main.class 这是我的密码 package jmx; import java.lang.management.ManagementFactory; import javax.management.AttributeNotFoundException; import javax.management.InstanceNotFoundException; import javax.management.MBeanException;

我的JDK版本是OpenJDK11。 我的类文件是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。然后我使用
jdep
来分析依赖关系。结果是:

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.base
java.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 windows中运行了代码。它很好用

然后在我的jre中运行代码。代码无法运行,我遇到一个错误:

javax.management.AttributeNotFoundException: No such attribute: TotalPhysicalMemorySize
所以我认为原因是缺少一些依赖模块。我运行
jlink
生成一个完整的模块jre。当我使用整个模块jre时,代码再次正确运行


如何获得真正的依赖模块?或者它是JDK的bug?

在JDK 9之前,类型
com.sun.management.OperatingSystemMXBean
java.lang.management.OperatingSystemMXBean
的未经文档化的扩展。因此,使用反射属性查询是合理的,比如
getAttribute(新对象名(“java.lang”、“type”、“OperatingSystem”)、“TotalPhysicalMemorySize”)
,它不会创建对非标准API的依赖关系

优点也是缺点。当没有依赖关系时,分析依赖关系的工具无法检测到依赖关系

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

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
报告依赖关系。

如果我问了一个愚蠢的问题,请原谅,您的JAR文件是否包含
模块信息.class
?换句话说,你的罐子是模块化的吗?我猜您只需在Windows文件资源管理器中双击该文件就可以运行它,对吗?它是单个类,而不是jar文件。我在cmd windows中运行它。我的项目不包含模块信息。项目中不需要模块信息文件。这是一个。您正在使用反射操作查询属性
“TotalPhysicalMemorySize”
。像
jdep
这样的静态代码分析无法检测动态访问。您必须添加模块
jdk.management