Accessing Windows Management Instrumentation (WMI) from Java

Java/J2EE COM Interoperability Products Page

This example demonstrates how to access Windows Management Instrumentation (WMI) from Java. J-Integra® for COM is a Java interoperability component that bridges Java and Windows Management Instrumentation (WMI). It provides bi-directional access of Java objects and COM components.

Contents

  1. Introduction
  2. Run the Java Client on Local Windows Machine
    1. Generate Java Proxies
    2. Create the Example
    3. Compile and Run the example
  3. Run the Java Client on Remote Machine, e.g. Windows, UNIX, Linux and etc
  4. Troubleshooting
  5. More about WMI programming

1 Introduction

This Java example either locally or remotely creates a WMI SWbemLocator object on a Windows machine named managing machine, and then connects to anther remote Windows machine named managed machine via the SWbemLocator object to print out all processes running on the managed machine. The Java client can run on any platform (such as Linux) with a Java Virtual Machine.

Overview

You will not have to install any software on the managed machine at runtime, although you will need to make a couple of configuration changes.

We assume that you are familiar with Java -- no COM knowledge should be required. We assume you have downloaded and expanded the J-Integra® kit from http://j-integra.intrinsyc.com/ and installed it correctly.

2 Run the Java Client on Local Windows Machine

You can try this example on local Windows machine first to get a feel for how easy it is to use J-Integra® to access WMI from Java. Once you make it working on local machine, you can then try to run the Java client on a non-Windows machine to remotly access WMI on another Windows machine.

2.1 Generate the Java proxies

Run J-Integra®'s com2java tool on the Windows machine, and select c:\windows\system32\wbem\wbemdisp.tlb as the type library, choose an empty directory (e.g. C:\wbemdisp) as output directory, and use wbemdisp as Java package name. Click the Generate Proxies button to generate Java proxies from Word type library.

2.2 Create the example

Create a .java file named JavaSWBEM.java. Then copy and paste the Java code below:

import com.linar.jintegra.*;
import wbemdisp.*;
import java.util.Enumeration;

public class JavaSWBEM {

  public static void main(String args[]){
    // Uncomment this line if JavaSWBEM.java is running on another remote machine.
    // String NtDomain   = "MANAGING_MACHINE_NT_DOMAIN";
    // String NtUser     = "MANAGING_MACHINE_NT_USER";
    // String NtPassword = "MANAGING_MACHINE_NT_PASSWORD";

    // Any Windows machine with WMI installed and configured for DCOM access.
    // For this example we use local machine where JavaSWBEM.java is running as the managing machine.
    String managingMachine = "localhost";

    // A Windows machine we need to manage. Can be any machine - can be same as or different from the managing machine.
    String managedMachine  = "MANAGED_MACHINE_NETWORK_NAME";

    try{
      // Enable logging:
      com.linar.jintegra.Log.logImmediately(3, "jintegra.log");

      // DCOM authentication: Make sure NtDomain, NtUser, NtPassword are valid credentials.
      // Uncomment this line if JavaSWBEM.java remotely accesses WMI:
      // com.linar.jintegra.AuthInfo.setDefault(NtDomain, NtUser, NtPassword);

      // Create Service Locator on a Windows machine
      // This Locator object will be obtain WBEM services.
      wbemdisp.SWbemLocator wLoc = new wbemdisp.SWbemLocator(managingMachine);

      // An object representing WBEM services of the managed machine.
      ISWbemServices wbemServices  = null;
      // Obtain the service from the specified machine.
      wbemServices = wLoc.connectServer(
        managedMachine,
        null,
        null,
        null,
        null,
        null,
        0,
        null
      );

      // Get all the Processes running on the machine.
      ISWbemObjectSet processesSet = wbemServices.instancesOf("Win32_Process", 0, null);

      java.util.Enumeration processEnum = processesSet.get_NewEnum();

      try{
        while(true){
        // Get an individual process
        ISWbemObject process = new ISWbemObjectProxy(processEnum.nextElement());
        // Print out process information.
          System.out.println(process.getObjectText_(1));
        }
      }catch(java.util.NoSuchElementException nselex){
        System.out.println("No more processes found");
      }
    }catch(AutomationException aex){
      System.out.println("WMI has raised an exception:");
      aex.printStackTrace();
    }catch(Exception ex){
      ex.printStackTrace();
    }finally{
      // Release all the COM objects:
      com.linar.jintegra.Cleaner.releaseAll();
    }
  }
}

The above Java code is based on and equivalent to the VB code below:

Dim loc As WbemScripting.SWbemLocator
Dim svcs As WbemScripting.SWbemServices
Set loc = New WbemScripting.SWbemLocator
Set strServerName = "." 'localhost
Set svcs = loc.ConnectServer(strServerName)

Dim objs As WbemScripting.SWbemObjectSet
Dim obj As WbemScripting.SWbemObject
' Retrieve the SWbemObjectSet containing
' all the instances.
Set objs = svcs.InstancesOf ("Win32_Process")
' Iterate through the collection of
' instances.
For Each obj In objs
    Debug.Print obj.ProcessID, obj.Name, obj.ExecutablePath
Next obj

2.3 Compile and run the example

On the Java client machine, make sure your CLASSPATH and PATH environment variables are set up according to J-Integra® installation instructions. Compile and run the example in  J-Integra®'s native mode (you need to use DCOM mode if remotely accessing Word):

javac JavaSWBEM.java
java
-DJINTEGRA_NATIVE_MODE JavaSWBEM

3 Run the Java Client on Remote Machine, e.g. Windows, UNIX, Linux and etc

You can also run the Java client on a remote machine, such as Linux, Solaris, UNIX and AIX. For instance, if you run it on a Linux machine, then you must do the following.:

  1. Move the com2java tool to the Windows machine to generate the Java proxies from WMI, and then move the Java proxies from the Windows machine to the Linux machine.
  2. Install J-Integra® (the jintegra.jar file) on the Linux machine and include the jintegra.jar file and generated Java proxies in CLASSPATH.
  3. Use setdllhost to configure a surrogate for WMI on the Windows managing machine. You only need to do this once on the managing machine and the other managed machines are intact.
    c:\WINDOWS\system32>setdllhost wbemdisp.dll "WMI wbemdisp.dll"
  4. Use DCOMCNFG to configure WMI on the Windows machine.
  5. Assign the IP address or computer name of the WMI managing machine to the String host in JavaSWBEM.java:
    String managingMachine = "123.456.78.9";
  6. Pass correct login credentials to com.linar.jintegra.AuthInfo.setDefault(NtDomain, NtUser, NtPassword);
    Refer to Configuring DCOM for Remote Access for more information about AuthInfo.setDefault.
  7. Move JavaSWBEM.java to the Linux machine. Compile and run it in DCOM mode without using DJINTEGRA_NATIVE_MODE property:
    java JavaSWBEM

4 Troubleshooting

4.1 If you see one of the following errors

"Package "com.linar.jintegra not found";
"cannot resolve symbol"
"Class Not Registered"
Or any other Java exception, please search these key words in J-Integra® Knowledge Base.

4.2 If you see "Access Denied / General Access Denied" error

Please refer to Configuring DCOM for Remote Access.

4.3 If you see : "AutomationException: 0x80041003 - Access Denied"

This means WMI has rejected your connection request. This is not a J-Integra® related problem. Make sure you have access to WMI on both the managing and the managed machines. On the WMI enabled machines, open "Control Panel/Administrative Tools/Computer Management/", then click on  "Services and Applications", then right-click on the "WMI Control", choose "Properties"; open the "Security" pane, click on the "Security" Button, and add the necessary account. If you are still having troubles, please consult WMI documentation at Platform SDK: Windows Management Instrumentation

5 More about WMI programming

Knowledge Base example of Shutting Down a Managed Windows Machine Using WMI.

We do not provide the documentation of the generated Java proxies since the Java proxies are just mapped from the programming API of the COM component. For more information about WMI programming, please refer to WMI Reference from MSDN. It's also easier to find a VB example first, and then covert the VB example to Java program using the reference Mapping VB Code to Java Code.