Исключение в потоке "main" java.lang.NoClassDefFoundError: rpc/Stub

Я пытаюсь читать журналы событий 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, но все еще получаю ту же проблему.

Может кто-нибудь, пожалуйста, дайте мне знать, как я могу решить эту проблему. Благодарю.

2 ответа

Решение

Я решил эту проблему. Я добавил файл jaxpc-api.jar, который содержит класс rpc.Stub, но есть и другие API, которые содержат класс rpc.Stub, поэтому не включайте файл jaxpc-api.jar.

Для этого существует файл j-interopdeps.jar, в котором содержится файл rpc.Stub, и требуется еще 1 файл jar - файл jcifs-1.3.14.jar. После включения этих 2-х jar-файлов в путь сборки. Программа будет выполнена, если имя пользователя, пароль и имя хоста будут правильными.

В моем случае я использую 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)
Другие вопросы по тегам