Search code examples
javawmievent-logj-interop

Exception in thread "main" java.lang.NoClassDefFoundError: rpc/Stub


I am trying to read windows event logs so I am using Jinterop API for that.

Here is the java code :

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();
             }
         }
      }
   }
}

I am using Ubuntu and trying to read logs from remote machine. When I am running the below code I am getting "RPC Stub" Exception.

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)

I googled about the exception and found that jar is missing so I added respective Jar file but still getting the same issue.

Could anyone please let me know how can I resolve this issue. Thanks.


Solution

  • I resolved this issue. I added jaxpc-api.jar file which contains rpc.Stub class but there are more API's which contain rpc.Stub class so don't include jaxpc-api.jar file.

    There is j-interopdeps.jar file which contains rpc.Stub file for this and 1 more jar file required which is jcifs-1.3.14.jar file. After including these 2 jar files in the build path. Program will execute if username, password and host name would be correct.