What is the proper way to shutdown a Griffon Application?

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

What is the proper way to shutdown a Griffon Application?

Marcelo
Hi,
I have a close action in a GriffonController:
    public void close() {
        application.shutdown();
    }
Is that the proper way to shutdown the application? The application window closes right away, but I am confused with what happens at the command line:
[griffon-pool-1-thread-2] INFO griffon.javafx.JavaFXGriffonApplication - Shutdown is in process
[griffon-pool-1-thread-2] INFO griffon.plugins.preferences.persistors.AbstractMapBasedPreferencesPersistor - Writing preferences to /home/marcelo/.resources/preferences/default.json
> Building 96% > :launcher:run
Gradle never returns to the command line... it keeps its daemon running forever...
Thanks!

Reply | Threaded
Open this post in threaded view
|

Re: What is the proper way to shutdown a Griffon Application?

aalmiray
Administrator
AFAIK the application should shutdown as long as there are no windows managed by WindowManager that remain visible. This is a setting controlled by `application.autoShutdown` in the application's configuration.

I've checked with a simple app that this is the case by:
 - quitting the application with CMD + Q
 - closing the main window.

In both cases application.shutdown() is invoked and the Gradle process is terminated normally.

Cheers,
Andres
Reply | Threaded
Open this post in threaded view
|

Re: What is the proper way to shutdown a Griffon Application?

Marcelo
Hi Andres,

I don't know what is going on...
It's been happening for quite some time now. It does not happen all the time, but fairly often, especially during debugging and testing in the IDE (but also when the application is just run from the command line with gradle run). I do have the application.autoshutdown property set to true.
Is there any way to know what happens after the shutdown is issued? Does the call need to be made in a specific thread?
Thanks,

Marcelo.
Reply | Threaded
Open this post in threaded view
|

Re: What is the proper way to shutdown a Griffon Application?

aalmiray
Administrator
The call to `application.shutdown()` may occur on any thread. I think that the runtime does not yet enforce that the shutdown sequence must be executed outside of the UI thread though.

It's possible to react to shutdown using the Shutdown lifecycle script, but by then it's already too late to abort the sequence. You can register a ShutdownHandler which has 2 responsibilities:
 - signal if the shutdown sequence should be aborted.
 - react to the shutdown if it proceeded.

If you increase the logging verbosity (such as info or debug) you'll see more information during shutdown, which can come in handy to figure the type of events that you can consume during the shutdown sequence.

Cheers,
Andres
Reply | Threaded
Open this post in threaded view
|

Re: What is the proper way to shutdown a Griffon Application?

Marcelo
Hi Andres,

I am having trouble increasing the verbosity level for the debug task. Could you tell me how to do that?

I am debugging with the following arguments:

-PcmdLineArgs=${cmd-line-args}
--stacktrace
-Pgriffon.full.stacktrace=true

but I don't see the full stacktrace.

I did find where the program hangs: Line 579 of DefaultMVCGroupManager right after it checks if the artificat is a GriffonView. The runnable submitted by the call runInsideUISync of the UIThreadManager never gets executed.

Thanks!

Marcelo
Reply | Threaded
Open this post in threaded view
|

Re: What is the proper way to shutdown a Griffon Application?

aalmiray
Administrator
Hi Marcelo,

The `griffon.full.stacktrace` has to be set on the application's runtime, typically by adding a JVM arg or making a direct call to `System.setProperty("griffon.full.stacktrace", "true")`.

The options you posted define a Gradle project property that's not inherited by the run task as part of the application's environment.

Cheers,
Andres
Reply | Threaded
Open this post in threaded view
|

Re: What is the proper way to shutdown a Griffon Application?

Marcelo
Hi Andres,

Thanks for your help. This problem is driving me crazy...

Could you please tell me how I can increase the logging level of Griffon to get more information about this problem?
I tried editing the log4j.properties file and change all the 'info' flags for 'debug', but I still can only see a very few info messages printed to the console.

This is my log4j properties:

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d] [%t] %-5p %-c - %m%n
log4j.rootLogger=debug,stdout

# The default "info" level for all Griffon's public API
log4j.logger.griffon=debug,stdout
log4j.additivity.griffon=false

# This logger covers all of Griffon's internal API
# Enable to see whats going on underneath.
log4j.logger.org.codehaus.griffon=debug,stdout
log4j.additivity.org.codehaus.griffon=false
log4j.logger.org.codehaus.griffon.runtime.core.AbstractApplicationBootstrapper=debug,stdout
log4j.additivity.org.codehaus.griffon.runtime.core.AbstractApplicationBootstrapper=false
log4j.logger.org.codehaus.griffon.runtime.core.DefaultApplicationBootstrapper=debug,stdout
log4j.additivity.org.codehaus.griffon.runtime.core.DefaultApplicationBootstrapper=false

What I would like to do is to have the 'debug' logging level set for whenever I am debugging the application.
I also tried to add:

System.setProperty("griffon.full.stacktrace", "true")
System.setProperty("logging.level", "debug")

To the project root file, but nothing happened.

Thanks,

Marcelo.

Reply | Threaded
Open this post in threaded view
|

Re: What is the proper way to shutdown a Griffon Application?

Marcelo
In reply to this post by aalmiray
Hi Andres,

I finally know what is going on! It is probably a bug during the application shutdown procedure.

During the shutdown, JavaFXUIThreadManager schedules the execution of a task of type FutureTask<Void> via Platform.runLater(task) in line 66 and waits for the result of the task in line 68 via task.get().

The runLater call made in PlatformImpl checks in line 284 if the tookit has exited already before submitting a new runnable. Sometimes that IS the case and the method returns without executing the task, so the call of task.get() in line 68 of JavaFXUIThreadManager stalls forever, preventing the debugger to close. This has to added problem that additional cleanup never gets executed.

Shouldn't JavaFx been prevented from exiting by calling Platform.setImplicitExit(false) as soon as application.shutdown() is called? The value of Platform.isImplicitExit() could be stored at the beginning of the call and then restored later if the application was prevented from shutting down. Finally, after all the Views (or MVC Groups) have been destroyed, a call to Platform.exit() could be done before continuing the application exit until the final System.exit(0) call.

The workaround to prevent the problem is to wrap the call to the application shutdown:

final boolean implicitExit = Platform.isImplicitExit();

Platform.setImplicitExit(false);

if (!application.shutdown()) {
    Platform.setImplicitExit(implicitExit);
}

I hope it helps.

Marcelo.

Ps: I'm still fighting with the logging part...
Reply | Threaded
Open this post in threaded view
|

Re: What is the proper way to shutdown a Griffon Application?

aalmiray
Administrator
Hi Marcelo,

Thank you for the detailed explanation, this will help us a lot fixing the problem! :D

I think the Griffon runtime prefers the use of TRACE rather than DEBUG. Changing the root logger to trace should do the trick.

Cheers,
Andres
Reply | Threaded
Open this post in threaded view
|

Re: What is the proper way to shutdown a Griffon Application?

Marcelo
Hi Andres,

You're very welcome!
Thanks for the info about the use of TRACE!

Marcelo.