Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (533)
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  
  I want to restart my application  (Read 1917 times)
0 Members and 1 Guest are viewing this topic.
Offline i30817

Junior Member





« Posted 2009-11-11 19:51:13 »

Agnostically that is.

Just calling a static method (restart), then the main program exits itself (saving the persistent state - i already have a hook into the term signal) then another process started by the restart method should wait for the main application the end and restart a new instance.)
Program -creates-> Slave
Slave -waitsfor-> ProgramDeath
Slave -creates-> Program
Slave dies.

Is this possible with ProcessBuilder?
Offline i30817

Junior Member





« Reply #1 - Posted 2009-11-11 20:21:34 »

The nasty part appears to be waiting for the main app to die in the slave process.
It doesn't know.
Offline DzzD
« Reply #2 - Posted 2009-11-11 20:36:37 »

dont know about the process builder but for the slave part in you diagram you may use a thread and set it as daemon (resident program) and this daemon thread should be able to create a Process using "Runtime.exec" method

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

Junior Member





« Reply #3 - Posted 2009-11-11 20:51:36 »

Already using process builder.
I'm just using system.exit.
Then if the slave waits 2 seconds i can be more or less assured that things are in hand.

However i just had a rude problem. System exit apparently does not call either SignalHandler (sun specific) (that works with windows shutdown) or ShutdownHook (that doesn't). I use that for saving.

Throwing Error is probably doing nothing because i'm not in the main thread (in the EDT now i think).
 Lips Sealed
Offline DzzD
« Reply #4 - Posted 2009-11-11 20:56:49 »

Already using process builder.
I'm just using system.exit.
Then if the slave waits 2 seconds i can be more or less assured that things are in hand.

However i just had a rude problem. System exit apparently does not call either SignalHandler (sun specific) (that works with windows shutdown) or ShutdownHook (that doesn't). I use that for saving.

Throwing Error is probably doing nothing because i'm not in the main thread (in the EDT now i think).
 Lips Sealed

why dont you just give to the slave thread a reference to the main thread so it can check/pool if it is alive and then launch new one when it is not

Offline i30817

Junior Member





« Reply #5 - Posted 2009-11-11 21:29:20 »

If i use threads, the main app doesn't finish. The serialization process happens with a SignalHandler, and that is only called when the app is shutting down and all threads die (or something like that). A thread wouldn't cut it, and besides that wouldn't recreate the transient state.
Offline DzzD
« Reply #6 - Posted 2009-11-11 21:46:02 »

If i use threads, the main app doesn't finish.
ha ok, but this sounds strange , I would have exoect it does Huh

Quote
Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads. 


from : http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Thread.html#setDaemon(boolean)

EDIT :  but seems/maybe daemon have another meaning in Java

Offline i30817

Junior Member





« Reply #7 - Posted 2009-11-11 21:59:35 »

No, i'm mis-explaning that part. ShutdownHooks are Threads themselves, that are run when all non-demon threads die (or all i'm not sure). And the SignalHandler is a sun specific os posix signal handler that i need (because shutdown hook is terminated almost immediately on the windows shutdown). BTW a way to avoid without the signal handler that would be nice, i don't like depending on sun api.

But a demon thread created by myself wouldn't do anything useful, since it would start executing immediately. If i added it  as shutdown hook, i would still need to be sure that the others terminated before running. Maybe i can eliminate the slave process from the diagram, by combining that with a wait.

However what is really irritating me is the fact that the threads don't want to terminate (even tried stop hahha).

System.exit(0) works, however it doesn't run the shutdown hooks, or the signal  Tongue
Offline DzzD
« Reply #8 - Posted 2009-11-11 22:13:43 »

forget what I said.... java daemon thread are strange... or different that what I was thinking they was...

what about embedding the whole in another program ?
Prog 1 run Prog 2
Prog 1 restart Prog 2

Offline i30817

Junior Member





« Reply #9 - Posted 2009-11-11 22:25:03 »

Well, Well, WELL.

Apparently the main problem is that signal handler misbehaves with System.exit. The shutdownhooks are called, but the signal handler is not.

However when shutting down abruptly (such as when the os shutdowns) the shutdown hooks are interrupted VERY early (thus corrupting my saved state) and the Signal handler is not.

A dilemma.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline i30817

Junior Member





« Reply #10 - Posted 2009-11-11 22:26:10 »

forget what I said.... java daemon thread are strange... or different that what I was thinking they was...

what about embedding the whole in another program ?
Prog 1 run Prog 2
Prog 1 restart Prog 2
That is what i'm doing.

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  
62  
63  
64  
65  
    /**
     * This method kills this program and starts
     * the given one.
     */

    public static void restart(Class klass, String... args) {
        try {
            Runtime.getRuntime().addShutdownHook(new RestartProcessShutDownHook(klass, args));
            Runtime.getRuntime().exit(0);
        } catch (Exception ex) {
            Logger.getLogger(IoUtils.class.getName()).log(Level.SEVERE, "Could not restart the program", ex);
        }
    }

    private static final class RestartProcessShutDownHook extends Thread {

        Class mainKlass;
        String[] arguments;

        public RestartProcessShutDownHook(Class mainKlass, String[] arguments) {
            super();
            this.mainKlass = mainKlass;
            this.arguments = arguments;
        }

        @Override
        public void run() {
            try {
                //wait for parent to die
               synchronized (this) {
                    wait(6000);
                }
                forkJava(mainKlass, arguments);
            } catch (Exception ex) {
                Logger.getLogger(IoUtils.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    /**
     * This method creates a new process that will run a new jvm
     * on the main of the given class, with the selected arguments.
     * It already flushes the output and inputstream of the forked jvm
     * into the current jvm.
     * The forked jvm uses the same java.exe and classpath as the current
     * one.
     * @param javaClass class with main method
     * @param args jvm properties.
     * @return Process, the jvm process, already started
     */

    public static Process forkJava(Class klass, String... args) throws IOException, InterruptedException {
        String javaExe = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
        String classpath = System.getProperty("java.class.path");
        List<String> l = new ArrayList<String>(4 + args.length);
        l.add(javaExe);
        l.add("-cp");
        l.add(classpath);
        l.addAll(Arrays.asList(args));
        l.add(klass.getCanonicalName());
        ProcessBuilder pb = new ProcessBuilder(l);
        pb.redirectErrorStream(true);
        final Process p = pb.start();
        //process builder stupidity (would need 2 threads if redirectErrorStream(false))
       new Thread(new ProcessStreamConsumer(p), "ProcessBuilderInputStreamConsumer").start();
        return p;
    }
Offline i30817

Junior Member





« Reply #11 - Posted 2009-11-11 22:40:35 »

Thinking about it a little more, if i register both a SignalHandler and a ShutdownHook, but only run the SignalHandler on SIGTERM, It might work.
The guy bellow says:
"Inside the signal handler you can do anything you want to, including calling System.exit(0) or Runtime.getRuntime().halt(0) if you don't want shutdown hooks to be called. "

source: http://www.javaspecialists.eu/archive/Issue043.html

I'm off to do a Strategy.
Offline JL235

JGO Coder


Medals: 10



« Reply #12 - Posted 2009-11-11 22:42:59 »

For being able to check if the main program has died, you could have the slave program wait when it starts up listening to a local port. The final act of the main program will be to send a message to tell the slave that it's now done everything it wanted to do before dying, and that it should now be considered to be dead. The slave will then go on and do whatever it is planning to do.

If this communication is the last thing that the main program does then I don't think it matter if the slave starts working whilst the main is technically still alive (i.e. the slave doesn't need to care if the main programs process has ended or not). The slave could also die after a time out just in case something goes wrong, this is avoid the unlikely event that it sits in the background waiting forever.

Offline i30817

Junior Member





« Reply #13 - Posted 2009-11-11 22:57:00 »

I'm having a little doubt. If i catch NoClassDefFoundError, on a non-sun vm would the exception be caught, if the class was not available?

I think i did this with reflection before (instantiating a object by calling the fully qualified class name, and using a alternative if it wasn't available), but now, i want to implement a interface, so i'm hoping that this exception can be caught.
Offline i30817

Junior Member





« Reply #14 - Posted 2009-11-11 23:17:56 »

ok i have this to shutdown now:
The code adds a signal handler for the term signal, (that shutdownhooks have problems with) and a shutdown hook.
I'm not sure there is a race, (the shutdown hook use of the halt method means that they will not be called if not already started, and interrupted if so). It depends on if the SignalHandler is called before or during running the shutdownhooks.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
    public static void addShutdownHook(final Runnable r) {
        try {
            sun.misc.SignalHandler handler = new sun.misc.SignalHandler() {
                @Override
                public void handle(sun.misc.Signal sig) {
                    r.run();
                    //if this is run the shutdown hooks can't be called.
                   Runtime.getRuntime().halt(0);
                }
            };
            //only when the system is shutting down.
           sun.misc.Signal.handle(new sun.misc.Signal("TERM"), handler);
        } catch (NoClassDefFoundError ex) {
            Logger.getLogger(IoUtils.class.getName()).log(Level.WARNING, "Not on a sun vm. Can't save state reliably.");
        }
        Runtime.getRuntime().addShutdownHook(new Thread(r));
    }


Also the issue in my post above this, i also don't know how to do that. Maybe code generation?
Offline i30817

Junior Member





« Reply #15 - Posted 2009-11-11 23:47:15 »

For being able to check if the main program has died, you could have the slave program wait when it starts up listening to a local port. The final act of the main program will be to send a message to tell the slave that it's now done everything it wanted to do before dying, and that it should now be considered to be dead. The slave will then go on and do whatever it is planning to do.

If this communication is the last thing that the main program does then I don't think it matter if the slave starts working whilst the main is technically still alive (i.e. the slave doesn't need to care if the main programs process has ended or not). The slave could also die after a time out just in case something goes wrong, this is avoid the unlikely event that it sits in the background waiting forever.

Something about the socket way of using interprocess communication always confused me... It only works if the socket is opened on the correct port, so there has to be some kind of protocol or something to make sure that a port already taken by another service doesn't interfere.
I was thinking about a simple ++ on the port if the port is in use by another service.
How can the client know that it is connecting to the right port (without disrupting the hypothetical other service on that port)?


Edit: never mind, being dumb. Ofcourse i can send it as a  main String option.
Offline JL235

JGO Coder


Medals: 10



« Reply #16 - Posted 2009-11-11 23:53:18 »

Something about the socket way of using interprocess communication always confused me... It only works if the socket is opened on the correct port, so there has to be some kind of protocol or something to make sure that a port already taken by another service doesn't interfere.
I was thinking about a simple ++ on the port if the port is in use by another service.
How can the client know that it is connecting to the right port (without disrupting the hypothetical other service on that port)?
Couldn't the main program make these checks before starting and then pass in the port number to the slave process when it starts as a command line parameter.

Offline i30817

Junior Member





« Reply #17 - Posted 2009-11-12 00:10:10 »

I think that that solution is not agnostic. I can't do it for all installed shutdown hooks, since the notification process would have to be in one of them. Either i assume that all of them are controlled by me a and do a barrier to wait for them to end, or i just do one. But i want this a library method.

There is another alternative i think, using this as a shutdown hook. As this is running as a shutdown hook, the only threads running should be shutdown hooks, and those better end - (it doesn't matter that this one can not end if the others don't end - if the others don't end, the vm interrupts, and this is interrupted too. I think).
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
        public void run() {
            try {
                Thread[] t = new Thread[Thread.activeCount()];
                int var = Thread.enumerate(t);
                boolean notTerminated = true;
                outer: while (notTerminated) {
                    for (int i = 0; i < var; i++) {
                        if (t[i] != Thread.currentThread() && t[i].isAlive()) {
                            sleep(10);
                            continue outer;
                        }
                    }
                    notTerminated = false;
                }
                forkJava(mainKlass, arguments);
            } catch (Exception ex) {
                Logger.getLogger(IoUtils.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
Offline i30817

Junior Member





« Reply #18 - Posted 2009-11-12 00:22:17 »

Humm. Forgot about the AWT-Shutdown thread (that is controlling running and waiting for the shutdownhooks apparently).

Shit.

Edit. Okay here is a weaker version of that method that marks the Threads registed as shutdown hooks by the utility method that handles the TERM signal too.
The only thing missing i think is a to be sure that the NoClassDefFoundError is caught at the right place in vm's that don't have that class, or handle it another way if it is not.

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  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
    /**
     * This method kills this program and starts
     * the given one.
     */

    public static void restart(Class klass, String... args) {
        try {
            Runtime.getRuntime().addShutdownHook(new RestartProcessShutDownHook(klass, args));
            Runtime.getRuntime().exit(0);
        } catch (Exception ex) {
            Logger.getLogger(IoUtils.class.getName()).log(Level.SEVERE, "Could not restart the program", ex);
        }
    }

    private static final class RestartProcessShutDownHook extends Thread {

        Class mainKlass;
        String[] arguments;

        public RestartProcessShutDownHook(Class mainKlass, String[] arguments) {
            super();
            this.mainKlass = mainKlass;
            this.arguments = arguments;
        }

        @Override
        public void run() {
            try {
                Thread[] tds = new Thread[Thread.activeCount()];
                int var = Thread.enumerate(tds);
                for (int i = 0; i < var; i++) {
                    Thread t = tds[i];
                    if (t != Thread.currentThread() &&
                            t.isAlive() &&
                            t.getName().equals("IoUtils.ShutdownHook")) {
                        t.join();
                    }
                }
            } catch (Exception ex) {
                Logger.getLogger(IoUtils.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                forkJava(mainKlass, arguments);
            } catch (Exception ex) {
                Logger.getLogger(IoUtils.class.getName()).log(Level.SEVERE, "Couldn't fork java", ex);
            }
        }
    }

        /**
     * Adds a shutdown hook that will be run when
     * the program terminates.
     * This is not the same as Runtime.getRuntime().addShutdownHook
     * This hook will be run even if the program is terminated
     * by a TERM signal. However that functionality depends on
     * sun specific api.
     * Otherwise it tries a best effort with shutdownhook
     * (i've had shutdown hooks be terminated when running and
     * corrupting data when O.S. shuts down).
     * This method also give the guarantee that if using restart()
     * and shutdownhooks added by the method,
     * the application will be restarted only after the shutdown
     * hooks run. (The TERM signal is not user sent so waiting for
     * restart doesn't apply to it).
     * @param r
     */

    public static void addShutdownHook(final Runnable r) {
        try {
            sun.misc.SignalHandler handler = new sun.misc.SignalHandler() {

                @Override
                public void handle(sun.misc.Signal sig) {
                    r.run();
                    //if this is run the shutdown hooks can't be called.
                   Runtime.getRuntime().halt(0);
                }
            };
            //only when the system is shutting down.
           sun.misc.Signal.handle(new sun.misc.Signal("TERM"), handler);
        } catch (NoClassDefFoundError ex) {
            Logger.getLogger(IoUtils.class.getName()).log(Level.WARNING, "Not on a sun vm. Can't save state reliably.");
        }
        Thread t = new Thread(r, "IoUtils.ShutdownHook");
        Runtime.getRuntime().addShutdownHook(t);
    }
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.

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

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

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

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

ctomni231 (50 views)
2014-07-18 06:55:21

Zero Volt (45 views)
2014-07-17 23:47:54

danieldean (36 views)
2014-07-17 23:41:23

MustardPeter (39 views)
2014-07-16 23:30:00

Cero (54 views)
2014-07-16 00:42:17

Riven (55 views)
2014-07-14 18:02:53
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!