views:

316

answers:

11

I'm upgrading an app that registers the time employees arrive and leave the office. I would like not to install this app into one of our current servers, which are somewhat important, beacuse I would have to leave a session open and i'd like to keep things separated. So all I have is cheap, cheap hardware. Basically a 500MHz, 64MB RAM Debian Lenny with nothing but the app, and MySQL database to store the information, oh yes, and i'ts inside a stove.

Currently the app is written in Java. Just a console program with a Dilbert's face ascii art on it asking for the employee's ID. The actual line, that does the 'waiting' is :

id = cin.nextInt();

When the first employee arrives monday morning and types he's id, about 40 hours of no usage since last employee left, the app crashes. Cant remember the actual exception thrown.

So my question is: Is there a nice way to loop a Java app forever ? Or maybe a better question is, which programming language is better for this task ?

I guess it would seem obvious at first not to use big 'ol java on such poor system, but lets just say, I kinda like Java.


Edit: Thanks for all your replies. However I do all the try/catching there is. I'm the problem is an Error the app can not recover from such as OutOfMemoryError.

The actual code looks something like :

static boolean start() {
    Scanner cin = new Scanner(System.in);
    int id; 
    try{
        id = cin.nextInt();
        doStuff( id );
        return true;
    }catch (Exception e){
        //which would trap all recoverable exceptions
        System.out.println("Something is wrong. Try again.");
        return false;               
    }
}

public static void main(String ... args){
    boolean first = true;
    while(true) {
        if(first) showDilbert();
        first = start();
    }
}

I'm sorry I did not pay more attention to the actual exception, but I thought Java would be discarded quite faster from the hardware description.

+3  A: 
while(true)
{
}

or

for(;;)
{
}

Should both loop infinitely and cause the application to continue running. You'll have to add some kind of code to make sure that your app doesn't peg the resources of the machine your running on though.

Justin Niessner
I actually use the while(true) now, but how do i go about the "add some kind of code to make sure that your app doesn't peg the resources of the machine your running on" part. Any idea ?
alanboy
You should use Thread.sleep if you want to do that. But this answer hardly seems like a solution to the problem.
Erick Robertson
@Erick Robertson - The question that was asked was "Is there a nice way to loop a Java app forever?". I'd make suggestions on how to fix his Exception, but without the Exception detials...I have no way to know how to fix it.
Justin Niessner
A: 

There's nothing inherently wrong with Java for this task - although your machine specs are pretty limiting and I expect that memory consumption is your main issue - the JVM alone probably uses up most of your available RAM.

The technique I would use in Java to keep something running is:

while (true) {
  try {
    // do stuff here

    Thread.sleep(1); // sleep a bit just to be nice to other processes
  } catch (Throwable t) {
    t.printStackTrace();
  }
}

This way any exceptions get caught and you will see the errors, but the app will keep running.

Of course there is a big caveat emptor here - if you keep running after a critical exception and trash your data by having the code in an unstable state, you only have yourself to blame :-)

mikera
If you get an OutOfMemoryError and can't do anything about it, it's much better to let the process die and start from scratch so at least you have resources to run on. This will just work real hard at failing to get resources.
Mark Peters
Hence the caveat?
Pete
Saying this is a good answer because it also lists the caveat is like saying that it's a good thing to recommend jumping off of a 500 foot cliff into a river to cool off, while also noting that it will kill you. Considering the caveat makes this answer completely useless. Never, ever, ever, **ever** catch throwable without looking at the error was and doing something useful in response.
Mark Peters
I agree that it's usually better to let a process die. But since the question was about how to try to force a process to keep running, this is an approach that you can take assuming you can live with the downsides. As for OutOfMemoryErrors, at least you'll see them and realise that this is your real problem if they occur.
mikera
A: 

As everyone has said, there's no reason your app can't run forever. Well, nuclear holocaust would bring it to a screeching halt, but Dilbert and his tie would be the least of your concerns at that point.

Have you considered using an embedded system? You're using a general purpose computer and OS to do only one thing. It would be more economical and a great experience to implement this using Arduino or even some GP-DSP like Analog Devices' Blackfin. You can still program in C/C++ and even have an embedded OS such as ucLinux. Much much cheaper, and rock solid.

Chris
+2  A: 

Do you think perhaps that the input to your program is not in fact an integer, and you're getting an InputMismatchedException or something? Maybe over the weekend somebody hit a key that wasn't a number, and then when the first person on Monday types their number and presses Enter, it's got some extra cruft before it. Blammo, exception.

Greg Hewgill
+2  A: 

The simplest way I know of to give your Java application high availability is to just launch it from a bash script in a loop. Maybe put a sleep in there so that if your app goes into a state where it can't launch it doesn't try a million times a second. Something like this:

#!/bin/bash
while [ 1 ]
do
        java ... MyApp    
        sleep 5
done

Doesn't matter WHAT happens in your JVM then...internal error, out of memory exception, JVM bug (they happen!) whatever. It's still going to boot right back up 5 seconds later.

Obviously this doesn't preclude steps to handle things cleanly within your application. This is the fallback.

Mark Peters
+1  A: 

Are you trying to write a time entry kiosk yourself?

This problem is well solved, I'm sure you can find an affordable commercial solution.

Dustin Getz
This is so true. Alanboy has a choice - pay software engineers for their expertise or pay lawyers for their expertise. When alanboy's workers realize a subtle bug is reducing their pay or the government finds alanboy is underwithholding, then the fun begins.
emory
+4  A: 

There's absolutely no reason your program needs to maintain an open connection to the database. You can get by simply opening the connection, doing your work, and closing it every time the user enters their ID.

The truth is that the exception that you are getting is vitally important as to why it's crashing.

Your program should be little more than:

public class Go {
    public static void main(String args[]) {
        while(true) {
            try {
                String userID = getUserId();
                Connection con = getConnection();
                processUserId(connection, userId);
                con.close();
            catch(Exception e) {
                logException(e);
            }
        }
    }
}

If you're getting exceptions you need to hunt down and prevent those exceptions. Save MySQL going out to lunch, there's no reason you should be getting any exceptions at all in this program. And if MySQL goes to lunch, getting a new Connection each time solves that problem once MySQL is back up and running.

And, no, getting a new Connection each time is not "slow", unless you happen to be processing 100s or 1000s of employees per second.

Will Hartung
Jupp. My guess would be that the connection to MySQL has been closed by the server on Mondays due to inactivity. +1
Henning
With `getUserId()` being a blocking function that sleeps until it receives input, right?
Brian
Yea, I assume getUserId() is stuck at a blinking block cursor on some display.
Will Hartung
A: 

I would suggest that you write the application in something like C rather than Java.

fpmurphy
Can you comment as to why you think that? Java has a lot more mechanisms to recover from programmer error than C does. It also prevents at compile time many programmer errors that result in crashes in a similar C program.
Mark Peters
C is far closer to the hardware than Java. If you want reliability and uptime you code closer to the hardware and remove as many layers of code as possible.
fpmurphy
A: 

and what about migrating your app to a web based service, a simple html page will do the interface. Run a apache server behind it, that will handle your scripts (written in perl of course ;) ), and connection with bdd.

this is very light, reliable, and will run as long as you wish

benzebuth
I assume there is some programming error in alanboy's app. Migrating the app would also migrate the programming error.There are also disadvantages to a web based service. If the app were migrated to a web based service, then (1) alanboy's lazier employees would wake up each morning at 4:55AM, clock in on time for their 5:00AM shift, and be back in bed by 5:05AM. (2) the app would depend on reliable network connections.
emory
i don't really undrestand the thing about the lazy ones waking up and so on... a web based app does not have to be accessed from the world wide web... a local server can just run ...well...locally... and so be accessed from the office...
benzebuth
A: 

I would suggest you edit your code as below. This will not make the program run longer, but you will know why it is crashing. Only then can you fix the problem.

Is this homework?

static boolean start() {
    Scanner cin = new Scanner(System.in);
    int id; 
    try{
        id = cin.nextInt();
        doStuff( id );
        return true;
    }catch (Exception e){
        //which would trap all recoverable exceptions
        System.out.println("Something is wrong. Try again.");
        return false;               
    }catch(Throwable e){
        // Add this.
        System . err . println ( e ) ; // come back to SO with this
        e . printStackTrace ( ) ; // come back to SO with this
        System . exit ( 1 ) ;
    }
}

public static void main(String ... args){
    boolean first = true;
    while(true) {
        if(first) showDilbert();
        first = start();
    }
}
emory
I've never heard of homework being tested for 30 days, so I'll hazard a "no".
Amadan
A: 

Programming language for an app that needs to be running forever

Answer: Java , you just have to be careful about the code.

Alternative answer: Any language will do, you just have to be careful about the code

OscarRyz