Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (536)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  System.exit(), is there any alternative?  (Read 3544 times)
0 Members and 1 Guest are viewing this topic.
Offline Kurten

Junior Member


Medals: 3
Exp: 3 years


-w-


« Posted 2011-09-09 12:54:18 »

Hello fellow Java programmers!

Im working on an application that is intended to be used by collage students, it's an educational program. Im working on some smooth way of shutting the program down when something goes wrong. I've read around a bit and System.exit(1) seems to be what I need, but I also read everywhere that it's a very drastic way of shutting down a program, is there any way of smoothly shutting down a program after a nullpointer has occurred?

The nullpointer is caught within an object which does not have any references to any other classes. I decided to catch the exception so that I could present the user with a non-cryptic error message, but since the object does not have any references to any other classes, I can't call the method I built for smoothly shutting the program down.

So, my question to you guys is: can System.exit(1) be used to shut down a program if a nullpointerexception occurs, without breaking something or messing stuff up that is?
If yes, then I'll use.
If yes but it's not recommended, what would you recommend?
If no, what should I do?

//Kurten
Offline Scarzzurs
« Reply #1 - Posted 2011-09-09 13:07:53 »

A bit more information about the problem would probably help us help you :-)
What does the program do, what is the architecture?

Normally (in a single threaded program) you would let the exception propagate to a place where it is reasonable to handle the exception and initiate a display of the non-cryptic error message you describe. If you really feel this is in your class without reference, you can try to make the error-handling method static or hand a reference to the error-handler object.
In general, I would suggest letting the exception propagate and be handled further out (by declaring that the methods in questions throws the given type of exception or a super-type).

If you're in a threaded environment things often become a bit more complicated, so again more information would be nice.

Edit: Remember that your program will normally shut down when control returns from the main method (there are some exceptions, especially using Swing)

Hope it helps for now :-)

- Scarzzurs

My games and Projects:
BlastingPixels.com,
Old website
Offline Kurten

Junior Member


Medals: 3
Exp: 3 years


-w-


« Reply #2 - Posted 2011-09-09 13:34:15 »

Thanks for the suggestions! ^_^

Ok, let's see if I can explain the architecture

Tha classes involved is: MainClass, GraphicsEngine, InputListener, Button.

MainClass implements Runnable and has references to GraphicsEngine, and InputListener. Hosts the shutdown method that looks like this:
1  
2  
3  
4  
5  
public void stopAll(){
      inLis.listening = false; //Stops input listening
     ge.looping = false; //Stops graphics drawing
     running = false; //Stops everything within this class
  }


GraphicsEngine implements Runnable and has references to MainClass and Button, it also hosts a method that forwards a shutdown command to MainClass.
InputListener implements Runnable and has references to GraphicsEngine and MainClass

All these classes has a while loop that is controlled by the booleans in the stopAll() method. Therefore the program stops quite fluently when setting them to false.

Now onto Button
Button has no references, GraphicsEngine has an Array of Buttons that is drawn onto the screen, I initialized the Button array by using an Array initializer, and due to Button's constructor, it is difficult to handle any exception thrown inside the Button class, outside it's constructor.
The constructor looks like this:
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  
public Button(String buttonsection, String filenamenotpressed, String filenamehovered, int posx, int posy){
      try{
         img = loadImage(filenamenotpressed);
      }catch(NullPointerException nullpointer){
         System.err.println("Shit just hit the fan and image " + filenamenotpressed + " can't be loaded");
         System.err.println("If you are not familiar with Java or C# programming techniques, don't panic");
         System.err.println("Simply stand up, wave your arms like a raving idiot, and scream in anguish!");
         System.err.println("If you are a Java or C# programmer, take a look at this stack trace, then give it to the developer");
         nullpointer.printStackTrace();
      }
     
      try{
         imgPressed = loadImage(filenamehovered);
      }catch(NullPointerException nullpointer){
         System.err.println("Shit just hit the fan and image " + filenamenotpressed + " can't be loaded");
         System.err.println("If you are not familiar with Java or C# programming techniques, don't panic");
         System.err.println("Simply stand up, wave your arms like a raving idiot, and scream in anguish!");
         System.err.println("If you are a Java or C# programmer, take a look at this stack trace, then give it to the developer");
         nullpointer.printStackTrace();
      }
     
      setX(posx);
      setY(posy);
      section = buttonsection;
   }


The loadImage method like this:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
@Override
   public Image loadImage(String path){
      System.out.println("Loading image: " + path);
      Image tempImg = new ImageIcon(getClass().getResource(path)).getImage();
      if(tempImg != null){
         System.out.println("Image " + path + " loaded without errors");
         return tempImg;
      }else{
         throw new NullPointerException();
      }
   }


I hope this information is useful
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline cylab

JGO Ninja


Medals: 38



« Reply #3 - Posted 2011-09-09 13:39:56 »

A NullPointerException is a RuntimeException (not a checked one) and RuntimeException normally should not be catched. If it has to be catched, System.exit(1) is a valid option in a desktop application, but not on a server.

The usual best approach is to let the Exception bubble up to either the main thread or the application container. So in a desktop application, the main thread is the right place to catch it and present a human readable message to the user.

If you have additional information to the exception, catch it and throw an appropriate RuntimeException Subtype (like e.g. IllegalArgumentException) with a helpful message and append the original Exception as cause.

If you catch a RuntimeException in a codeblock that is recoverable, the Exception should be logged or presented to the user and the program should continue. Never, ever catch-log-rethrow.

If you catch a RuntimeException in a codeblock that is not recoverable, but could be in a calling codeblock, throw an appropriate checked Exception with a helpful message and append the original Exception as cause.

If you need to do something on shutdown, use a shutdown hook: http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Runtime.html

Regarding exception handling in general, this is a must-read: http://today.java.net/article/2006/04/04/exception-handling-antipatterns

Mathias - I Know What [you] Did Last Summer!
Offline Kurten

Junior Member


Medals: 3
Exp: 3 years


-w-


« Reply #4 - Posted 2011-09-09 13:49:35 »

Thanks for the info Cylab, I'll dig into the text about Exception handling! However, I find it difficult catching the exception after it leaves Button, Button is initialized in the class body of GraphicsEngine, which stops me from catching anything there, GraphicsEngine is initialized in the class body of MainClass, which makes it difficult to catch there as well =/

But, if System.exit is a valid option as you say, i'll guess i will use it for now.

EDIT: I just noticed that I could move the GraphicsEngine initialization to a method which initializes some other stuff, so I can catch the exception there ^_^ Let's see if it works, thanks for all your help guys, I love this community! Cheesy

2nd EDIT: I just tested it and it worked perfectly, I didn't even have to call System.exit(1), the program shut itself down automatically along with the error message Cheesy Once again, thanks guys!
Offline cylab

JGO Ninja


Medals: 38



« Reply #5 - Posted 2011-09-09 14:17:43 »

Actually your example shows more like how you don't do it.  Tongue

1. You don't throw Exceptions without messages
2. You usually don't throw NullPointerExceptions yourself. In fact, only throw RuntimeExceptions at all, if you are really sure, they are not recoverable
3. In your case loadImage should declare and throw new IOException("Could not load Image from file '"+filename+"'")
4. Missing button images should be considered recoverable - just catch the IOException, log a warning and use text-buttons instead.
5. If you consider images on your buttons as mandatory in your application, the Button constructor should declare IOException and don't catch it at all, so the application code setting up the buttons knows what Exception can occur and has to handle it.

Mathias - I Know What [you] Did Last Summer!
Offline Kurten

Junior Member


Medals: 3
Exp: 3 years


-w-


« Reply #6 - Posted 2011-09-09 15:26:06 »

Hmm, I thought the code work well, but I also understand there is a reason why certain conventions should be followed, which means I will rewrite the exception handling Tongue

I would consider loading of the images critical since I have methods within them that InputListener and GraphicsEngine is dependent on. So if a button image can't be loaded I want the program to close down and not try to recover.

I will switch the Nullpointer to an IOException instead since that seems more appropriate, the reason I went with Nullpointer was that the image file that would be returned by the loadImage() would have been null.

Thanks once again for the suggestions ^_^ I will try to implement them as good as I can ^_^
Offline theagentd
« Reply #7 - Posted 2011-09-09 16:23:00 »

Hahaha...!
Quote
Crysis 2 could not load the player model. Loading text based Crysis 2 instead.
Awesome!

Myomyomyo.
Offline cylab

JGO Ninja


Medals: 38



« Reply #8 - Posted 2011-09-09 16:49:17 »

Hahaha...!
Quote
Crysis 2 could not load the player model. Loading text based Crysis 2 instead.
Awesome!
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
              ,.,
            .'   ',
            i  - -|
           ( | o o)
            |/ _")/
             \|__/
          ___|_  |__
        (^^^  .\ ^^^]
        | \   .|   | \
        |~ \  .|   |  \
        |  |  .|   |\  \
        \  |==={}==| \__]
         \_]_______\   Y\
          Y\    _  \
          l    / \__)
          |__ |   |*\
           |**|  /**/
           |**/ (**\
         __\**|  \**\
        /*****\   \*_|
        ^^^^^^^     ^^  


 Grin

Mathias - I Know What [you] Did Last Summer!
Offline theagentd
« Reply #9 - Posted 2011-09-09 18:59:09 »

Hahaha...!
Quote
Crysis 2 could not load the player model. Loading text based Crysis 2 instead.
Awesome!
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
              ,.,      [b]MAXIMUM STRENGTH![/b]
            .'   ',   /
            i  - -|  /
           ( | o o)
            |/ _")/
             \|__/
          ___|_  |__
        (^^^  .\ ^^^]
        | \   .|   | \
        |~ \  .|   |  \
        |  |  .|   |\  \
        \  |==={}==| \__]
         \_]_______\   Y\
          Y\    _  \
          l    / \__)
          |__ |   |*\
           |**|  /**/
           |**/ (**\
         __\**|  \**\
        /*****\   \*_|
        ^^^^^^^     ^^  


 Grin

FTFY xD

Myomyomyo.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #10 - Posted 2011-09-09 19:59:38 »

Yeah I would never ever call System.exit() in a GUI-based program. At the very worst, show a popup that says "You must restart the app" with an OK button that then calls System.exit() only after relaunching the app automatically. You should always let the user decide what to do, and you should always try to recover from errors if possible. A user will never care unless their experience gets so bad they can't do what they want to do. You forcibly make it that bad if you quit the app.

See my work:
OTC Software
Offline Kurten

Junior Member


Medals: 3
Exp: 3 years


-w-


« Reply #11 - Posted 2011-09-09 20:38:33 »

I do not expect this exception to be generated very often, there is only 2 possible errors that can trigger it, that I can think of anyway. One of those is sloppyness by me, in case I have misspelled something in the image path. In this case, the user can't do anything with the application and I will have to fix it, which requires me to be notified.
The other one is if one of the user messes around inside the jar file for some reason and move or delete an image file. In this case the error can be fixed by the user, but I doubt that regular students will understand what went wrong, I also plan to supervise the early tests so in case of a crash, I want the user to grab hold of me instead of believing that everything is well.

But for later versions of the program Im building I will try to work around the problem of contacting me every time the program crashes, so I will probably try to build some kind of recovery code later on.
Offline theagentd
« Reply #12 - Posted 2011-09-10 11:04:27 »

System.exit(1); doesn't sound that bad in a small educational program IMO. Sure, it is kind of a shock to the JVM, but as long as you don't use shutdown hooks or similar stuff it shouldn't be a problem.

Another solution is to just use DOUBLE COMPILE!!!

Myomyomyo.
Offline cylab

JGO Ninja


Medals: 38



« Reply #13 - Posted 2011-09-10 13:43:07 »

(..) but as long as you don't use shutdown hooks (...)

Why should a shutdown hook be a problem on System.exit()?

Mathias - I Know What [you] Did Last Summer!
Offline theagentd
« Reply #14 - Posted 2011-09-10 15:59:18 »

(..) but as long as you don't use shutdown hooks (...)

Why should a shutdown hook be a problem on System.exit()?
Oh. They are apparently executed before exiting. My bad. Ignore that.

Myomyomyo.
Offline Kurten

Junior Member


Medals: 3
Exp: 3 years


-w-


« Reply #15 - Posted 2011-09-11 19:41:00 »

Another solution is to just use DOUBLE COMPILE!!!

Offline ra4king

JGO Kernel


Medals: 338
Projects: 2
Exp: 5 years


I'm the King!


« Reply #16 - Posted 2011-09-12 04:53:42 »

The exit status of this program is OVER 9000!!!! Cool

Offline theagentd
« Reply #17 - Posted 2011-09-12 12:07:42 »

... but there is no reason to do something like that. *poke*
Hehe.

Myomyomyo.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Riven (18 views)
2014-07-29 18:09:19

Riven (13 views)
2014-07-29 18:08:52

Dwinin (12 views)
2014-07-29 10:59:34

E.R. Fleming (31 views)
2014-07-29 03:07:13

E.R. Fleming (12 views)
2014-07-29 03:06:25

pw (42 views)
2014-07-24 01:59:36

Riven (41 views)
2014-07-23 21:16:32

Riven (28 views)
2014-07-23 21:07:15

Riven (29 views)
2014-07-23 20:56:16

ctomni231 (60 views)
2014-07-18 06:55:21
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!