1

我正在尝试阅读 Windows 事件日志,因此我为此使用了 Jinterop API。

这是Java代码:

import java.io.IOException;
import java.util.logging.Level;
import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.common.JISystem;
import org.jinterop.dcom.core.JIComServer;
import org.jinterop.dcom.core.JIProgId;
import org.jinterop.dcom.core.JISession;
import org.jinterop.dcom.core.JIString;
import org.jinterop.dcom.core.JIVariant;
import org.jinterop.dcom.impls.JIObjectFactory;
import org.jinterop.dcom.impls.automation.IJIDispatch;

public class EventLogListener
{

    private static final String WMI_DEFAULT_NAMESPACE = "ROOT\\CIMV2";


    private static JISession configAndConnectDCom( String domain,       
          String user, String pass ) throws Exception
    {
         JISystem.getLogger().setLevel( Level.OFF );

        try
        {
             JISystem.setInBuiltLogHandler( false );
        }
        catch ( IOException e )
        {
            e.printStackTrace();
        }

        JISystem.setAutoRegisteration( true );

        JISession dcomSession = JISession.createSession( domain, user,    
                                                         pass );
        dcomSession.useSessionSecurity( true );
        return dcomSession;
    }


    private static IJIDispatch getWmiLocator( String host, JISession   
               dcomSession ) throws Exception
    {
        JIComServer wbemLocatorComObj = new JIComServer,   
              JIProgId.valueOf( "WbemScripting.SWbemLocator" ), host,  
                     dcomSession );
        return (IJIDispatch) JIObjectFactory.narrowObject(    
              wbemLocatorComObj.createInstance().queryInterface( 
                     IJIDispatch.IID ) );
    }


    private static IJIDispatch toIDispatch( JIVariant    
              comObjectAsVariant ) throws JIException
    {
        return (IJIDispatch) JIObjectFactory.narrowObject( 
              comObjectAsVariant.getObjectAsComObject() );
    }

    public static void main(String[] args)
    {

        String domain = DOMAIN_NAME;
        String host = IP_ADDR;
        String user = USER_NAME;
        String pass = PASSWORD;

        JISession dcomSession = null;

        try
        {
           // Connect to DCOM on the remote system, and create an        
           // instance of the WbemScripting.SWbemLocator object to 
           // talk to WMI.

         dcomSession = configAndConnectDCom( domain, user, pass );
         IJIDispatch wbemLocator = getWmiLocator( host, dcomSession );

         // Invoke the "ConnectServer" method on the SWbemLocator 
         // object via it's IDispatch COM pointer. We will connect to
        // the default ROOT\CIMV2 namespace. This will result in us 
         // having a reference to a "SWbemServices" object.

          JIVariant results[] =
          wbemLocator.callMethodA( "ConnectServer", new Object[] { new     
          JIString( host ), new JIString( WMI_DEFAULT_NAMESPACE ),
             JIVariant.OPTIONAL_PARAM(), 
             JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), 
             JIVariant.OPTIONAL_PARAM(), new Integer( 0 ),
             JIVariant.OPTIONAL_PARAM() } );

          IJIDispatch wbemServices = toIDispatch( results[ 0 ] );

          final String QUERY_FOR_ALL_LOG_EVENTS = "SELECT * FROM  
                __InstanceCreationEvent WHERE TargetInstance ISA 
               'Win32_NTLogEvent'";


           final int RETURN_IMMEDIATE = 16;
           final int FORWARD_ONLY = 32;

           JIVariant[] eventSourceSet =
              wbemServices.callMethodA( "ExecNotificationQuery", new 
                     Object[] { new JIString( QUERY_FOR_ALL_LOG_EVENTS 
                     ), new JIString( "WQL" ),
                     new JIVariant( new Integer( RETURN_IMMEDIATE + 
                     FORWARD_ONLY ) ) } );
           IJIDispatch wbemEventSource = (IJIDispatch) 
               JIObjectFactory.narrowObject( ( eventSourceSet[ 0 ] 
               ).getObjectAsComObject() );

           while ( true )
           {
              // this blocks until an event log entry appears.

             JIVariant eventAsVariant = (JIVariant) ( 
               wbemEventSource.callMethodA( "NextEvent", new Object[] 
               { JIVariant.OPTIONAL_PARAM() } ) )[ 0 ];

             IJIDispatch wbemEvent = toIDispatch( eventAsVariant );

             JIVariant objTextAsVariant = (JIVariant) ( 
                wbemEvent.callMethodA( "GetObjectText_", new Object[] 
                { new Integer( 1 ) } ) )[ 0 ];

             String asText = 
                 objTextAsVariant.getObjectAsString().getString();
             System.out.println( asText );
        }
    }
    catch ( Exception e )
    {
         e.printStackTrace();
    }
    finally
    {
         if ( null != dcomSession )
         {
             try
             {
                   JISession.destroySession( dcomSession );
             }
             catch ( Exception ex )
             {
                 ex.printStackTrace();
             }
         }
      }
   }
}

我正在使用 Ubuntu 并尝试从远程机器读取日志。当我运行以下代码时,我收到“RPC Stub”异常。

Exception in thread "main" java.lang.NoClassDefFoundError: rpc/Stub
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at    
   java.security.SecureClassLoader.defineClass(SecureClassLoader.java:  
    142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at   
    net.codejava.spring.controller.EventLogListener.getWmiLocator(   
     EventLogListener.java:45)
    at net.codejava.spring.controller.EventLogListener.main( 
     EventLogListener.java:69)
 Caused by: java.lang.ClassNotFoundException: rpc.Stub
     at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
     at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
     at java.security.AccessController.doPrivileged(Native Method)
     at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
     at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
     at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
       ... 14 more
  Exception in thread "jI_ShutdownHook" java.lang.NullPointerException
     at    
     org.jinterop.dcom.core.JIComOxidRuntime.stopResolver(  
        JIComOxidRuntime.java:577)
     at org.jinterop.dcom.core.JISession$2.run(JISession.java:267)
     at java.lang.Thread.run(Thread.java:745)

我用谷歌搜索了这个异常,发现 jar 丢失了,所以我添加了相应的 Jar 文件,但仍然遇到同样的问题。

谁能让我知道我该如何解决这个问题。谢谢。

4

2 回答 2

2

我解决了这个问题。我添加了包含 rpc.Stub 类的 jaxpc-api.jar 文件,但是还有更多包含 rpc.Stub 类的 API,所以不要包含 jaxpc-api.jar 文件。

有 j-interopdeps.jar 文件,其中包含 rpc.Stub 文件,还需要 1 个 jar 文件,即 jcifs-1.3.14.jar 文件。在构建路径中包含这两个 jar 文件之后。如果用户名、密码和主机名正确,程序将执行。

于 2015-10-21T06:38:56.557 回答
0

就我而言,我使用的是openscada lib,所以我需要做的是在我的lib中添加:

  • jcifs-xyzjar (org.samba.jcifs)
  • jinterop.deps-xyzjar (org.openscada.jinterop)
  • org.openscada.opc.dcom & org.openscada.opc.lib (org.openscada.utgard)
于 2016-03-14T23:52:33.353 回答