繁体   English   中英

如何获得Java类的真正模块依赖?

[英]How to get Java class' real module dependency?

我的 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM