tutorials.de Buch-Aktion 05/2012
Seite 1 von 2 12 LetzteLetzte
ERLEDIGT
JA
ANTWORTEN
15
ZUGRIFFE
637
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    ulki ulki ist offline Mitglied Gold
    Registriert seit
    Mar 2005
    Beiträge
    103
    Hi!

    Ich weiß das der Text ziemlich lang ist, aber mein Problem ist etwas unübersichtlich und ich hoffe, dass eine ausführliche Beschreibung euch hilft mir zu helfen.
    Wer schon Erfahrung mit Fehlern hat, die plötzlich (zur Laufzeit) in ungeänderten Bereichen (einer anderen Klasse) eines bis dahin lauffähigen Programms auftauchen, würde mir sehr helfen, wenn er sich die Mühe macht und die ausführlichere Beschreibung unten ließt.

    Ich arbeite zusammen mit drei weiteren Leuten an einem etwas größerem Projekt. Wir arbeiten mit NetBeans 4.0 und CVS.
    Unser Ziel ist es einen Browser zu schreiben, mit dem wir Daten von Componenten einer Serverfarm, bzw. sonstigen Anlagen die sich an den neuen Standart SMIS halten, anzeigen können. Das ganze ist für die Uni. Der ganze Code ist schon sehr umfangreich, deswegen kann ich ihn schlecht hier reinstellen.

    Nun hat sich folgendes Problem ergeben:
    Um die Ladezeiten etwas zu optimieren, und einen vernünftigen Statusbalken anzuzeigen hatte ich begonnen einen Thread zu schreiben und das schon laufende Programm darauf umzustellen. Die ersten Schritte waren auch recht erfolgversprechend. Doch plötzlich startete das Programm nicht mehr. Es meldete einen StakOverFlow und zwar an einer Stelle an der ich nicht das geringste geändert hatte. Und auch keiner der anderen hat dort etwas geändert, das habe ich gleich als erstes gefragt.

    Nach mehreren Stunden des Einfügens von Testausgaben und studiums der API und des Tutorials war ich mir sicher, das zumindest syntaktisch bei mir nichts falsch war.

    Ich habe dann einfach von vorne angefangen. Nun ist der Fehler wieder da.

    Ich hatte alles Stück für Stück eingefügt und dann jedesmal getestet. Das letzte was ich eingefügt habe ist schon wieder raus. Aber es läuft immer noch nicht (nicht wieder).

    Ich bin langsam am verzweifeln und wäre glücklich, wenn mir jemand sagen könnte ob es eine Möglichkeit gibt Fehler (laufzeit) in nicht geänderten Bereichen zu vermeiden.

    Danke schonmal für die Mühe
    Geändert von ulki (29.03.05 um 09:13 Uhr)
     

  2. #2
    Registriert seit
    Apr 2004
    Ort
    Ruhrgebiet
    Beiträge
    1.582
    Moin,
    ohne Codeschnippsel ist Fehlersuche natürlich schwierig. Ich kenne zum StackOverflow zwei Ursachen:
    1. Der Thread bläht sich durch ständiges Erzeugen neuer Objekte auf, bis es zum Overflow kommt.
    2. Es gibt irgendwo im Code eine Endlosschleife.
     

  3. #3
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo!

    StackOverFlow riecht meistens nach Endlosrekursion...

    Gruß Tom
     

  4. #4
    ulki ulki ist offline Mitglied Gold
    Registriert seit
    Mar 2005
    Beiträge
    103
    Naja wir haben 12 Klassen in der Steuerung..... Und 9 in der GUI.....
    Mittlerweile habe ich aber das Fehlergebiet weiter einkreisen können.

    Ich habe eine lauffähige Version unseres Programms ohne Threads. Nun habe ich für die Threads einige Klassen erstellt. Es scheint Probleme mit der Klasse Monitor zu geben. Zumindest taucht dieser Fehler immer auf, wenn ich die Variablendekleration von Monitor in unserem Hauptfenster einfüge.

    Kurze Zusammenfassung der gewünschten Funktionalität: Im Hauptfenster wird eine Tabelle angeklickt, dadurch wird ein Thread gestartet in dem der Inhalt einer weitern Tabelle neu geladen werden soll, damit man ihn anzeigen kann.
    Da es durchaus möglich ist, dass mehrere Tabellen gleichzeitig geladen werden existiert der Monitor (für synchronized Methoden).

    Nun habe ich also meine laufende Version. Die Klassen für den Thread sind schon vorhanden. Ich starte das Programm und es läuft. Das MainWindow wird erzeugt, und das Fenster in das die gewünschte URL eingegeben wird erscheint.

    Hier einmal die Variablendeklerationen und Konstruktoren von MainWindow:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    
    import javax.swing.*;
    import java.lang.*;
    import de.fsc.smibrowser.*;         // there is only contact via interface but there are classes nedded
    import javax.swing.tree.*;
    import java.util.*;
    import de.fsc.interfaces.*;
    import javax.swing.table.*;
    import java.awt.Cursor;
     
    import de.fsc.smibrowser.Monitor;
    import de.fsc.smibrowser.TableLoad;
    import de.fsc.smibrowser.TableObject;
     
    public class MainWindow extends javax.swing.JFrame implements ControlDataReceiver{
        
        private ConnectionDialog conBox;
        private GUIDataReceiver  receiver;
        private TreeNode         rootTreeNode;
        private Vector           lastInstanceTable;
        private String           url = "";          //initialising
        private NameSpace        selectedNameSpace;
        
        
       /** private Monitor          controlThreads = new Monitor();  //the one Monitor needed
        
        private TableLoad        instanceTableThread = new TableLoad();
        private TableLoad        propertyTableThread = new TableLoad();
        private TableLoad        poolTableThread     = new TableLoad();
        private TableLoad        portTableThread     = new TableLoad();
        private TableLoad        volumeTableThread   = new TableLoad(); */ 
        
        /** Creates new form MainWindow */
        public MainWindow(GUIDataReceiver rec) {
           System.out.println("hier ist der Konstruktor für MainWindow");
           System.out.println("GUIDataReceiver wird gesetzt");
            receiver = rec;
           System.out.println("GUIDataReceiver ist gesetzt"); 
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            }
            
            catch (Exception e) {
                JOptionPane.showMessageDialog(null, e.toString(), "Fehler", JOptionPane.ERROR_MESSAGE);
            }
            //controlThreads = new Monitor(this);
            initComponents();
            
           System.out.println("initComponents für MainWindow durchgelaufen"); 
           
            /** 
             showing the Connectiondialog
            */
           System.out.println("ConnectionDialog wird angezeigt");
            conBox = new ConnectionDialog(this, new javax.swing.JFrame(), true, receiver.getNameSpaces());
            conBox.setVisible(true);
           System.out.println("gleich wird der Knoten gesucht"); 
            rootTreeNode = receiver.getNode(); 
           System.out.println("Knoten wurde gesucht"); 
        }
        
        //public MainWindow(){ initComponents(); } ;

    Wenn ich nun die auskommentierten Bereiche hinzuneheme geht nichts mehr und der genannte StakOverflowError erscheint an beliebigen Stellen während des Parsens der xml Datei.

    Erklärung der Klassen:

    ControlDataReceiver -- wie vieleicht ersichtlich ein Interface zur Kommunikation zwischen GUI und Steuerung

    TableLoad -- Klasse des Threads

    ConnectionDialog -- Klasse für das Anzeigen des Fensters in dem die URL eingegeben wird

    TableObject --- Hält eine Identifiezierung und ein TableContent weil Threads ja nichts zurückgeben können

    TableContent --- enthält mehrere Vectoren mit denen wir die darzustellenden Daten organisieren

    Ich hoffe das hilft weiter
    Geändert von ulki (29.03.05 um 11:14 Uhr)
     

  5. #5
    ulki ulki ist offline Mitglied Gold
    Registriert seit
    Mar 2005
    Beiträge
    103
    Hi!

    Das Problem habe ich bis jetzt nicht lösen können. Ich will es jetzt von einer anderen Seite angehen und bitte nochmal um Mithilfe.

    In meiner GUI wird durch ein Event eine Anfrage ausgelöst, die an meine MainClass geht. Dort soll der Thread gestartet werden, der einen Statusbalken einblendet, der anzeigt das gearbeitet wird. Während der Statusbalken vor sich hin blinkt soll die Tabelle geladen werden (der Inhalt wird in einem Vector gespeichert). Wenn er damit fertig ist wird eine boolean Variable auf false gesetzt, alive=false; Dann soll in MainClass weiter gearbeitet werden. Nun weiß ich aber nicht, wie ich meine MainClass dazu bekomme auf den Thread zu warten.
    MainClass selbst wird von einer weiteren Klasse gestartet und hat keine main Methode. Und das kann ich auch nicht ändern.
    Es wäre klasse, wenn schnell jemand auf eine Lösung käme, oder mir einen Gedankenanstoß geben könnte. Den das ganze muss bis Freitag Nachmittag fertig sein und laufen.

    tausend Dank für die Hilfe den ich sehe den Wald vor Bäumen nicht mehr
     

  6. #6
    Registriert seit
    Apr 2004
    Ort
    Ruhrgebiet
    Beiträge
    1.582
    Was ist mit:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    boolean alive;
    deineEventMethode()
    {
     alive = true;
     while (alive)
     {
      deinThreadDerAliveAufFalseSetzt();
     }
     mainClassObjekt.jetztDarfstDu();
    }

    ?
     

  7. #7
    ulki ulki ist offline Mitglied Gold
    Registriert seit
    Mar 2005
    Beiträge
    103
    Das sieht gut aus!
    Das werde ich gleich mal im Versuch testen. Danke schonmal
     

  8. #8
    ulki ulki ist offline Mitglied Gold
    Registriert seit
    Mar 2005
    Beiträge
    103
    Leider klappt es so nicht. Kann auch sein, das ich es irgendwie falsch verstanden habe.

    Hier was ich geschrieben habe:

    Aufruf aus meiner MainClass heraus:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    public TableContent getInstanceTable(Enumeration classes){
        
        alive = true;  //Thread is living
        
        tableToBeLoad.setRepresentor("getInstanceTable"); //this is to be load
        
        content.clear();
        content.addElement(classes); //preparing the vector
        
        fetchingTable = new TableLoad(tableToBeLoad, content, cIMHandler, 1, this);
        
        while(alive)
        {
            fetchingTable.start();
        } 
        
        return tableToBeLoad.getContent();
    }

    tableToBeLoad ist ein Objekt einer selbstgeschriebenen Klasse hat einen Namen und eine Tabelle (Klasse TableContent ebenfalls von unserem Team selbst erstellt)

    content ist ein Vector

    und TableLoad der Thread.

    Ich denke die while-Schleife ist der Auslöser. Den es gibt eine: "illigal State of Thread" Meldung.

    Ach so hier noch ein Ausschnitt aus der Thread Klasse:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
    public void run() 
        {
          showing = new StatusBar(this);
          showing.setVisible(true);      //displaying a Statusbar
          
          switch(called) //the method calling is named above the case statment
          {
              //getInstanceTable
              case 1: {
                  try
                  {
                   store = handler.createInstanceTable((Enumeration)what.get(0));
                  }
                  catch(Exception e)
                  {
                    String text=("Fehler Beim Verbinden zum CIMOM "+e.getMessage());
                    JOptionPane.showMessageDialog(null, text, "Fehler beim Erstellen der Verbindung", JOptionPane.ERROR_MESSAGE);
                    Vector one = new Vector();
                    Vector two = new Vector();
                    store = new TableContent(one, two, "");
                  }
              }
     
          //es gibt noch 17 weitere case......
           }
     
          who.setContent(store);         //who ist das übergebene TableObject
          
          showing.setVisible(false);
          showing.dispose();             //eliminating the statuswindow
          
          mother.setAlive(false);        //the thread has done everything he was meant to
        }

    Das Fenster mit dem Statusbalken und die Fehlermeldung tauchen fast gleichzeitig auf. Ich denke der Thread wird einfach mehreremale gestartet. Nur habe ich keine Idee wie ich das verhindern kann.
    Ich werde nochmal nach Tutorials suchen, vieleicht habe ich da ja noch was übersehen....
    Für mehr hilfe wäre ich aber immer dankbar, schließlich ist meine Zeit begrenzt

    ulki
     

  9. #9
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo!

    Nur zur Info, man kann einen Thread nur einmal starten...
    (Nur für den Fall, dass du mit fetchingTable.start(); einen neuen Thread startest...)

    Gruß Tom
     

  10. #10
    ulki ulki ist offline Mitglied Gold
    Registriert seit
    Mar 2005
    Beiträge
    103
    Ich starte in dem Stück MainClass das oben zu sehen ist den Thread. Genau einmal.
    Gut dann ist es das also nicht, aber wie kommt es dann zu dieser Fehlermeldung?
    Da muss ich wirklich mal suchen gehen.....

    illigal state of thread. Mal sehen was ich so finden kann
     

  11. #11
    ulki ulki ist offline Mitglied Gold
    Registriert seit
    Mar 2005
    Beiträge
    103
    genaue Fehlermeldung:

    java.lang.IllegalThreadStateException
     

  12. #12
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo!

    Ich glaube du manipulierst die Swing GUI von einem anderen Thread aus als dem Event Dispatch Thread, was nicht erlaubt ist.

    Arbeite an diesen Stellen besser mit SwingUtilities.invokeLater(Runnable run)....

    Gruß Tom
     

  13. #13
    ulki ulki ist offline Mitglied Gold
    Registriert seit
    Mar 2005
    Beiträge
    103
    Mhh..... Könnte schon sein das du recht hast.

    Die Ereignisabfolge ist ja so:
    • In der GUI wird ein Klick-Event ausgelöst
    • Dann wird über das Interface eine Anfrage nach MainClass geschickt
    • Darauf startet MainClass den Thread....
    • .... der Thread holt die Tabelle und gibt sie nach Main über das TableObjekt
    • dort wird es für die GUI aufbereitet und zurückgegeben

    Ich glaube die Ursache für den Fehler ist, dass in der while-Schleife versucht wird den Thread mehr als einmal zu starten. Hier was ich im Netz gefunden habe:

    public void start( ) Der Aufruf der Methode start( ) überführt einen Thread vom Zustand „new“ in den Zustand „ready-to-run“. Wurde der Thread schon einmal gestartet, so wird eine IllegalThreadStateException geworfen.

    Wäre immerhin möglich.

    Mal schauen wie sowas mit dem funktioniert was du gerade vorgeschlagen hast. Ist sicher sauberer als meine Versuche.
     

  14. #14
    ulki ulki ist offline Mitglied Gold
    Registriert seit
    Mar 2005
    Beiträge
    103
    Das klinkt wirklich gar nicht so schlecht.
    Nun stellt sich mir noch die Frage, ob ich von dieser Methode trotzdem Code in anderen Klassen aufrufen kann. Den die Trennung von Steuerung und Anzeige muss erhalten bleiben.

    Wenn ihr dazu noch Vorschläge habt wäre ich glücklich. Ich habe damit nämlich noch überhauptnicht gearbeitet. Ich werde jetzt erstmal versuchen, ob ich es mit hilfe des Tutorials hinbekomme. Aber ich habe schon die Erfahrung gemacht, dass im Tutorial wichtige Dinge so versteckt sind, das man sie leicht beim ersten bis zehnten mal lesen übersieht.
     

  15. #15
    ulki ulki ist offline Mitglied Gold
    Registriert seit
    Mar 2005
    Beiträge
    103
    So an sich funktioniert es schonmal.

    Nur leider bekomme ich beim erstenmal keine Tabelle angezeigt, und alle folgenden male die Tabelle, die ich davor haben wollte.

    Erst hatte ich gedacht, das ich dieses Problem vieleicht mit .invokeAndWait lösen könnte, aber das darf ich von dort wo ich arbeite nicht aufrufen.

    Hier mal mein Code:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    
    public TableContent callInstanceTable(Vector element)
        {
           final Vector vectorsend = element; 
            
          //Runnable for thread--------------------------------------------------------------------- 
               Runnable fillingInstanceTable = new Runnable()
               {
                 public void run() {
                     showing.setVisible(true);
                     
                     haveSet = false; 
                     try{
                     tableobject.setContent(receiver.getInstanceTable(vectorsend.elements()));
                     }
                     catch(Exception e)
                     {JOptionPane.showMessageDialog(null, e.toString(), "Fehler", JOptionPane.ERROR_MESSAGE);}
                     haveSet = true;
                     
                     showing.setVisible(false);
                     showing.dispose();             //eliminating the statuswindow
                 }  
               };
             //Runnable end----------------------------------------------------------------------------
               
              try{
                   SwingUtilities.invokeLater(fillingInstanceTable);
                 }
              catch(Exception e)
              {}
               
              return tableobject.getContent();
        }

    callInstanceTable wird aus einem EventHandler heraus aufgerufen.

    Ich denke das erst eine NullPointerException kommt liegt daran, das die Variable tableobject noch nicht gefüllt ist, wenn er versucht sie anzuzeigen (beim zurückgeben von tableobject.getContent() wird einfach nichts zurückgegeben).

    Wie schaffe ich es nun, das erst zurückgegeben wird, wenn tableobject auch gefüllt ist?

    Langsam wachsen mir graue Haare, besonders da ich nebenbei auch noch bei der GUI Gestalltung mitarbeite und für vier Klausuren lerne.
     

Ähnliche Themen

  1. Zusammenarbeit im Bereich CSS
    Von ZodiacXP im Forum Stellenangebote (unentgeltlich)
    Antworten: 0
    Letzter Beitrag: 20.08.09, 12:29
  2. Antworten: 2
    Letzter Beitrag: 08.10.07, 11:38
  3. Bereich überdenken
    Von pontifex im Forum Photoshop
    Antworten: 3
    Letzter Beitrag: 02.04.05, 23:19
  4. Bereich neuzeichnen
    Von Waidmann im Forum .NET Archiv
    Antworten: 2
    Letzter Beitrag: 19.02.04, 22:42