3 Replies Latest reply: Nov 16, 2006 8:55 AM by 807607 RSS

    Problem Closing Files - JVM Freezes

    807607
      I've been trying to figure out why my program seems to be crashing each time I close it. I am developing an agent based simulation using Repast J, which generates simEvents whenever its toolbar's buttons are pushed. I believe the problem is due to the fact that the toolkit generates events two events whenever I close the program, a STOP_EVENT and a END_EVENT. During each event I am working with files, during the STOP_EVENT I am saving the current simulation's settings and during the END_EVENT I am flushing and closing the output file which is where I write the progress of the simulation. The key bit of code where I believe it occurs is as follows:
      this.addSimEventListener(new SimEventListener() {
      
        public void simEventPerformed(SimEvent evt) {
      
          if (evt.getId() == SimEvent.STOP_EVENT) {
      
            String message;
      
            message = "Total Number of Moves: " + Household.TOTAL_MOVES;
      
            message += "\nTotal Number of Social-Rented Moves: " 
              + Household.TOTAL_SOCIAL_MOVES;
      
            System.out.println(message);
      
            Main.saveSettings();
      
          } // if (evt.getId() == SimEvent.STOP_EVENT) {
      
          if (evt.getId() == SimEvent.END_EVENT) {
      
            printStream.flush();
      
            printStream.close();
      
            System.exit(0);
      
          } // if (evt.getId() == SimEvent.END_EVENT) {
      
        } // public void simEventPerformed(SimEvent evt) {
      
      }); // this.addSimEventListener(new SimEventListener() {
      At present, if I click the stop button, which generates the STOP_EVENT, the program behaves fine. If I then click the close button, which generates the END_EVENT, the program closes, no problem. However, if I click the close button without first clicking the stop button, the program writes the message above to the console and then freezes. I then have to force it to close from inside my IDE.

      I was wondering if there was a better way to go about this? It seems to me that there ought to be a way of waiting until all file i/o operations are completed, i.e. is there somesort of file i/o listener / event notification? In otherwords, waiting to flush and close the printStream until the settings file has finished saving. I believe this will solve this problem, but I am unsure.

      Thanks in advance for your help.

      Regards,

      Craig.

      Message was edited by:
      Craig.Moore
        • 1. Re: Problem Closing Files - JVM Freezes
          807607
          Very strange behaviour since if you click the close button it generates an END_EVENT and this bit of code calls:

          System.exit(0);

          This should kill the program !

          put some more System.out.println into your code and confirm that when you press Close you do get an end event in the case where you have not pressed the stop button.

          Are you sure the code is not generating a STOP_EVENT in this case for the close where stop has not already been pressed ?
          • 2. Re: Problem Closing Files - JVM Freezes
            807607
            Hi,

            The System.exit() method calls the
            Runtime.exit() method, which calls shutdown
            hooks and then terminates all running
            threads.

            If it is useful Rate me duke dollars.

            Thanks
            • 3. Re: Problem Closing Files - JVM Freezes
              807607
              Thank you for the suggestion of adding the println statements to the code to see what is happening. I will try to do that in the future to pick up these problems. Now I understand why this was happening. I added the following code in order to see what was happening:
              this.addSimEventListener(new SimEventListener() {
              
                public void simEventPerformed(SimEvent evt) {
              
                  if (evt.getId() == SimEvent.STOP_EVENT) {
              
                    System.out.println("Stop Button Pressed");
              
                    String message;
              
                    message = "Total Number of Moves: " + Household.TOTAL_MOVES;
              
                    message += "\nTotal Number of Social-Rented Moves: "
                        + Household.TOTAL_SOCIAL_MOVES;
              
                    System.out.println("Flushing Print Stream");
              
                    printStream.flush();
              
                    System.out.println("Closing Print Stream");
              
                    printStream.close();
              
                    System.out.println("Closed Print Stream");
              
                  } // if (evt.getId() == SimEvent.STOP_EVENT) {
              
                  if (evt.getId() == SimEvent.END_EVENT) {
              
                    System.out.println("Close button pressed");
              
                    System.exit(0);
              
                  } // if(evt.getId() == SimEvent.END_EVENT) {
              
                  switch (evt.getId()) {
              
                  case (SimEvent.END_EVENT):
              
                    System.out.println("evt.getId() = SimEvent.END_EVENT");
              
                    break;
              
                  case (SimEvent.PAUSE_EVENT):
              
                    System.out.println("evt.getId() = SimEvent.PAUSE_EVENT");
              
                    break;
              
                  case (SimEvent.RNG_SEED_EVENT):
              
                    System.out.println("evt.getId() = SimEvent.RNG_SEED_EVENT");
              
                    break;
              
                  case (SimEvent.START_EVENT):
              
                    System.out.println("evt.getId() = SimEvent.START_EVENT");
              
                    break;
              
                   case (SimEvent.STOP_EVENT):
              
                     System.out.println("evt.getId() = SimEvent.STOP_EVENT");
              
                     break;
              
                  default:
              
                    System.out.println("evt.getId() = " + evt.getId());
              
                  } // switch (evt.getId()) {
              
                } // public void simEventPerformed(SimEvent evt) {
              
              }); // this.addSimEventListener(new SimEventListener() {
              The output when I pushed the close button was....
              Stop Button Pressed
              Total Number of Moves: 164
              Total Number of Social-Rented Moves: 64
              Flushing Print Stream
              Closed Print Stream
              This was the same output I received regardless of whether or not I pushed the close button first or the stop button. Therefore, the SimEvent.END_EVENT was not firing when I pushed the close button. I believe that what is happening instead is that the toolkit has its own shut down procedure for when the close button is pressed. First it fires a SimEvent.STOP_EVENT and then it attempts the shut down the GUI. However, since my code is doing file i/o while this is happening it must make the program freeze up.

              After reading the javadocs more carefully, see here:

              http://repast.sourceforge.net/api/uchicago/src/sim/engine/BaseController.html#setExitOnExit(boolean)

              I found that I could set the simulation not to exit immediately upon clicking the close button.

              Instead I added an action listener to the model see here:

              http://repast.sourceforge.net/api/uchicago/src/sim/engine/Controller.html#addExitListener(java.awt.event.ActionListener)

              that performs the file i/o operations (like I wanted it to origionally) and then it runs the System.exit(0) command.

              I hope that this is helpful for others that come across this problem.

              Regards,

              Craig.