Как получить Java class 'реальную зависимость от модуля? - PullRequest
2 голосов
/ 20 февраля 2020

Моя версия JDK - OpenJDK 11. Мой класс File: 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.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?

1 Ответ

4 голосов
/ 20 февраля 2020

До JDK 9 тип com.sun.management.OperatingSystemMXBean был недокументированным расширением java.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 правильно.

...