L'application Java SNMP4J Trap gèle l'interface graphique


J'ai une application de trap SNMP en Java qui vise à écouter un agent SNMP et à imprimer les messages SNMP reçus sur une JTextArea dans une fenêtre JFrame.

Partie I ci-dessous est mon code source montrant le contenu de la classe TrapReceiver. Dans cette classe, la méthode listen est l'endroit qui tire le meilleur parti du travail. La classe est intantiée dans une classe JFrame sur laquelle j'ai l'intention d'afficher les messages sur JTeaxtArea ainsi mentionné. J'envoie la référence de l'objet JTextArea, le SNMP URL de l'agent et le port dans le constructeur de la classe TrapReceiver, puis appelez la méthode run de l'objet TrapReceiver pour démarrer l'exécution dans un thread séparé autre que l'instance JFrame. La partie II ci-dessous montre comment j'instancie la classe TrapReeceiver dans l'instance JFrame.

Lorsque j'exécute l'application, j'ai remarqué que l'instance JFrame (c'est-à-dire l'interface graphique) se fige et qu'aucun message n'est imprimé sur JTeaxtArea mentionné dans l'instance JFrame qui instancie la classe TrapReeceiver montré dans la partie I ci-dessous.

Ma question est de savoir pourquoi l'instance JFrame (c'est-à-dire l'interface graphique) gèle bien que le TRapReceiver lui-même soit exécuté en tant que thread séparé? En outre, je me demande quelle pourrait être la solution possible à ce problème de gel. Merci à l'avance.

PS: J'ai vérifié que TrapReceiver fonctionne bien et peut imprimer des messages sur une sortie standard lors de l'exécution en tant qu'application autonome sans interface graphique, mais c'est cette interface graphique qui gèle en quelque sorte en raison de certains possibles fil de synchronisation question. J'ai essayé d'exécuter le TrapReceiver sans mettre sur un thread et même dans ce cas, l'interface graphique gelait toujours.

PARTIE I

 package com.[Intenionally removed].snmp;

 import java.io.IOException;
 import javax.swing.JTextArea;
 import org.snmp4j.*;
 import org.snmp4j.mp.MPv1;
 import org.snmp4j.mp.MPv2c;
 import org.snmp4j.security.Priv3DES;
 import org.snmp4j.security.SecurityProtocols;
 import org.snmp4j.smi.OctetString;
 import org.snmp4j.smi.TcpAddress;
 import org.snmp4j.smi.TransportIpAddress;
 import org.snmp4j.smi.UdpAddress;
 import org.snmp4j.transport.AbstractTransportMapping;
 import org.snmp4j.transport.DefaultTcpTransportMapping;
 import org.snmp4j.transport.DefaultUdpTransportMapping;
 import org.snmp4j.util.MultiThreadedMessageDispatcher;
 import org.snmp4j.util.ThreadPool;

 public class TrapReceiver implements CommandResponder, Runnable {

   private String targetSnmpAgentURL;
   private int targetSnmpAgentPort;
   private JTextArea outConsole;

   public TrapReceiver() {
   } 

   public TrapReceiver(JTextArea outConsole) {
       this.outConsole = outConsole;
   }


   public TrapReceiver(JTextArea outConsole, String targetSnmpAgentURL, int  targetSnmpAgentPort) {
       this.targetSnmpAgentURL = targetSnmpAgentURL;
       this.targetSnmpAgentPort = targetSnmpAgentPort;
       this.outConsole = outConsole;

       try {
           listen(new UdpAddress(targetSnmpAgentURL + "/" + targetSnmpAgentPort));
       } catch (IOException e) {
           e.printStackTrace();
       }
    }

    public final synchronized void listen(TransportIpAddress address) throws IOException {


        AbstractTransportMapping transport;
        if (address instanceof TcpAddress) {
            transport = new DefaultTcpTransportMapping((TcpAddress) address);
        } else {
            transport = new DefaultUdpTransportMapping((UdpAddress) address);
        }

        ThreadPool threadPool = ThreadPool.create("DispatcherPool", 10);
        MessageDispatcher mDispathcher = new MultiThreadedMessageDispatcher(
            threadPool, new MessageDispatcherImpl());

        // add message processing models
        mDispathcher.addMessageProcessingModel(new MPv1());
       mDispathcher.addMessageProcessingModel(new MPv2c());

        // add all security protocols
        SecurityProtocols.getInstance().addDefaultProtocols();
        SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());

        // Create Target
        CommunityTarget target = new CommunityTarget();
        target.setCommunity(new OctetString("public"));

        Snmp snmp = new Snmp(mDispathcher, transport);
        snmp.addCommandResponder(this);

        transport.listen();
        System.out.println("Listening on " + address);

        try {
           this.wait();
        } catch (InterruptedException ex) {
           Thread.currentThread().interrupt();
        }
        }

    /**
    * This method will be called whenever a pdu is received on the given port
    * specified in the listen() method
    */
    @Override
    public synchronized void processPdu(CommandResponderEvent cmdRespEvent) {
        //System.out.println("Received PDU...");
        outConsole.append("Received PDU...\n");
        PDU pdu = cmdRespEvent.getPDU();

        if (pdu != null) {            
        outConsole.append("Trap Type = " + pdu.getType() + "\n");
        outConsole.append("Alarm Type: " + pdu.getVariableBindings().get(4) + "\n");
        outConsole.append("Alarm Message:  " + pdu.getVariableBindings().get(9) +  "\n\n");

        }
     }


     @Override
     public void run() {
        try {           
            listen(new UdpAddress(targetSnmpAgentURL + "/" + targetSnmpAgentPort));
        } catch (IOException e) {
            outConsole.append("\nError occured while listening to SNMP messages: \n" + e.getMessage() + "\n\n");
        }
     }

} //end of class TrapReceiver

PARTIE II

Dans ce qui suit, j'exécute une instance de classe TrapReceiver dans un thread.

   private void jButtonStartListeningSNMPActionPerformed(java.awt.event.ActionEvent evt)   {                                                          

    Thread snmpThread = 
           new Thread(new TrapReceiver(jTextAreaSNMPAlarmOutput, jTextFieldSnmpAgentUrl.getText().trim(), Integer.parseInt(jTextFieldSnmpAgentPort.getText().trim())));
    snmpThread.start()

   }
Author: kleopatra, 2012-03-08

1 answers

Le problème est que vous appelez listen() dans le constructeur TrapReceiver, ce qui se produit sur le thread gui. vous voulez seulement appeler listen() dans la méthode run(), car c'est la partie qui se passe dans le nouveau thread.

 5
Author: jtahlborn, 2012-03-08 13:28:55