diff --git a/cli-support/core/src/main/java/org/seedstack/seed/cli/SeedRunner.java b/cli-support/core/src/main/java/org/seedstack/seed/cli/SeedRunner.java index 5c43f41b7..cc1b1a97b 100644 --- a/cli-support/core/src/main/java/org/seedstack/seed/cli/SeedRunner.java +++ b/cli-support/core/src/main/java/org/seedstack/seed/cli/SeedRunner.java @@ -55,8 +55,15 @@ public class SeedRunner implements SeedLauncher { private static final Logger LOGGER = LoggerFactory.getLogger(SeedRunner.class); @Override - public int launch(String[] args) throws Exception { - return execute(args); + public void launch(String[] args) throws Exception { + int returnCode = execute(args); + LOGGER.info("CLI command finished with return code {}", returnCode); + System.exit(returnCode); + } + + @Override + public void shutdown() throws Exception { + // nothing to do } /** diff --git a/core-support/core/src/main/java/org/seedstack/seed/core/SeedMain.java b/core-support/core/src/main/java/org/seedstack/seed/core/SeedMain.java index a458acad0..001a26d55 100644 --- a/core-support/core/src/main/java/org/seedstack/seed/core/SeedMain.java +++ b/core-support/core/src/main/java/org/seedstack/seed/core/SeedMain.java @@ -22,22 +22,22 @@ /** *

- * Main Seed Java application entry point. It searches classes implementing {@link SeedLauncher} through the - * {@link ServiceLoader} mechanism. If no class or more than one class is found, it throws an exception. If exactly one - * class is found, it delegates the Seed application startup to its {@link SeedLauncher#launch(String[])} method. + * Main Seed Java application entry point. It searches classes implementing {@link SeedLauncher} through the + * {@link ServiceLoader} mechanism. If no class or more than one class is found, it throws an exception. If exactly one + * class is found, it delegates the Seed application startup to its {@link SeedLauncher#launch(String[])} method. *

*

- * High-level exception handling and diagnostic is done directly in this class. + * High-level exception handling and diagnostic is done directly in this class. *

- * + * * @author adrien.lauer@mpsa.com */ public class SeedMain { private static final Logger LOGGER = LoggerFactory.getLogger(SeedMain.class); + private static final int EXCEPTION_RETURN_CODE = -1; public static void main(String[] args) { List entryPointServices = Lists.newArrayList(ServiceLoader.load(SeedLauncher.class)); - int returnCode = 0; if (entryPointServices.size() < 1) { throw SeedException.createNew(CoreErrorCode.MISSING_SEED_ENTRY_POINT); @@ -45,29 +45,40 @@ public static void main(String[] args) { throw SeedException.createNew(CoreErrorCode.MULTIPLE_SEED_ENTRY_POINTS); } - SeedLauncher seedLauncher = entryPointServices.get(0); + final SeedLauncher seedLauncher = entryPointServices.get(0); + + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + try { + seedLauncher.shutdown(); + LOGGER.info("Seed application stopped"); + } catch (Exception e) { + handleException(e); + LOGGER.error("Seed application failed to shutdown properly"); + } + } + }); LOGGER.info("Seed application starting with launcher {}", seedLauncher.getClass().getCanonicalName()); try { - returnCode = seedLauncher.launch(args); - } catch (SeedException e) { - handleException(e); - e.printStackTrace(System.err); + seedLauncher.launch(args); } catch (Exception e) { handleException(e); - SeedException.wrap(e, CoreErrorCode.UNEXPECTED_EXCEPTION).printStackTrace(System.err); + LOGGER.error("Seed application halted after exception"); + System.exit(EXCEPTION_RETURN_CODE); } - - // no java.lang.Error handling is done - - LOGGER.info("Seed application stopped (return code {})", String.valueOf(returnCode)); - - System.exit(returnCode); } private static void handleException(Exception e) { LOGGER.error("An exception occurred, collecting diagnostic information"); CorePlugin.getDiagnosticManager().dumpDiagnosticReport(e); + + if (e instanceof SeedException) { + e.printStackTrace(System.err); + } else { + SeedException.wrap(e, CoreErrorCode.UNEXPECTED_EXCEPTION).printStackTrace(System.err); + } } } diff --git a/core-support/specs/src/main/java/org/seedstack/seed/core/spi/SeedLauncher.java b/core-support/specs/src/main/java/org/seedstack/seed/core/spi/SeedLauncher.java index 5e830db0f..7793349c7 100644 --- a/core-support/specs/src/main/java/org/seedstack/seed/core/spi/SeedLauncher.java +++ b/core-support/specs/src/main/java/org/seedstack/seed/core/spi/SeedLauncher.java @@ -20,7 +20,15 @@ public interface SeedLauncher { * The method that launches the Seed application. * * @param args arguments of the Seed application. - * @return the return code. + * @throws Exception when something goes wrong. */ - int launch(String[] args) throws Exception; + void launch(String[] args) throws Exception; + + + /** + * This method is called when the application is requested to shutdown. + * + * @throws Exception when something goes wrong. + */ + void shutdown() throws Exception; }