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;
}