7

Due to a bug in the sigar library version I am using (returns bogus values for swap), I tried using com.sun.management.OperatingSystemMXBean instead. This worked fine and gave me the desired results (on Windows).

Class<?> sunMxBeanClass = Class.forName("com.sun.management.OperatingSystemMXBean");
sunMxBeanInstance = sunMxBeanClass.cast(ManagementFactory.getOperatingSystemMXBean());
getFreeSwapSpaceSize = getMethodWithName(sunMxBeanClass, "getFreeSwapSpaceSize");
getTotalSwapSpaceSize = getMethodWithName(sunMxBeanClass, "getTotalSwapSpaceSize");

However this breaks with java 9. Is there another way to query swap file / partition information using java? I don't want to introduce a new library or version of sigar.

Cross platform solutions appreciated but windows is enough :--)

Thanks

Selim
  • 1,064
  • 11
  • 23

2 Answers2

9

You may try to discover available MX attributes dynamically:

public class ExtendedOsMxBeanAttr {
    public static void main(String[] args) {
        String[] attr={ "TotalPhysicalMemorySize", "FreePhysicalMemorySize",
                        "FreeSwapSpaceSize", "TotalSwapSpaceSize"};
        OperatingSystemMXBean op = ManagementFactory.getOperatingSystemMXBean();
        List<Attribute> al;
        try {
            al = ManagementFactory.getPlatformMBeanServer()
                                  .getAttributes(op.getObjectName(), attr).asList();
        } catch (InstanceNotFoundException | ReflectionException ex) {
            Logger.getLogger(ExtendedOsMxBeanAttr.class.getName())
                  .log(Level.SEVERE, null, ex);
            al = Collections.emptyList();
        }
        for(Attribute a: al) {
            System.out.println(a.getName()+": "+a.getValue());
        }
    }
}

There is no dependency to com.sun classes here, not even a reflective access.

Holger
  • 285,553
  • 42
  • 434
  • 765
8

The jdk.management module exports the com.sun.management API and it works the same way in JDK 9 as it did in JDK 8. So either of the following should work:

com.sun.management.OperatingSystemMXBean mbean
    = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
long free = mbean.getFreePhysicalMemorySize();
long swap = mbean.getTotalSwapSpaceSize();

or

OperatingSystemMXBean mbean = ManagementFactory.getOperatingSystemMXBean();
Class<?> klass = Class.forName("com.sun.management.OperatingSystemMXBean");
Method freeSpaceMethod = klass.getMethod("getFreeSwapSpaceSize");
Method totalSpaceMethod = klass.getMethod("getTotalSwapSpaceSize");
long free = (long) freeSpaceMethod.invoke(mbean);
long swap = (long) totalSpaceMethod.invoke(mbean);
Alan Bateman
  • 5,283
  • 1
  • 20
  • 25
  • 4
    Might be worth to emphasize that there are two different (easy to confuse) modules, `java.management` and `jdk.management`. Using the latter inevitably adds more dependencies to an application, but makes `com.sun.management.OperatingSystemMXBean` directly available. Using the former requires dynamic discovery of these extensions. (Why they don’t just offer these properties in the base interface is above me; it’s not as if there weren’t already tons of optional properties…) – Holger Jan 18 '18 at 17:49