|
7 | 7 | */ |
8 | 8 | package org.seedstack.seed.core; |
9 | 9 |
|
10 | | -import static com.google.common.base.Preconditions.checkState; |
11 | | -import static org.seedstack.shed.misc.PriorityUtils.sortByPriority; |
12 | | - |
13 | 10 | import com.google.common.base.Strings; |
14 | 11 | import com.google.common.collect.Lists; |
15 | 12 | import io.nuun.kernel.api.Kernel; |
16 | 13 | import io.nuun.kernel.api.config.KernelConfiguration; |
17 | | -import java.io.IOException; |
18 | | -import java.io.InputStream; |
19 | | -import java.nio.charset.StandardCharsets; |
20 | | -import java.util.HashMap; |
21 | | -import java.util.List; |
22 | | -import java.util.Map; |
23 | | -import java.util.Optional; |
24 | | -import java.util.Scanner; |
25 | | -import java.util.ServiceLoader; |
26 | 14 | import org.fusesource.jansi.Ansi; |
27 | 15 | import org.fusesource.jansi.AnsiRenderer; |
28 | 16 | import org.seedstack.coffig.Coffig; |
|
33 | 21 | import org.seedstack.seed.core.internal.CoreErrorCode; |
34 | 22 | import org.seedstack.seed.core.internal.ToolLauncher; |
35 | 23 | import org.seedstack.seed.core.internal.diagnostic.DiagnosticManagerImpl; |
36 | | -import org.seedstack.seed.core.internal.init.AutodetectLogManager; |
37 | | -import org.seedstack.seed.core.internal.init.BaseConfigurationFactory; |
38 | | -import org.seedstack.seed.core.internal.init.ConsoleManager; |
39 | | -import org.seedstack.seed.core.internal.init.KernelManager; |
40 | | -import org.seedstack.seed.core.internal.init.LogManager; |
41 | | -import org.seedstack.seed.core.internal.init.ProxyManager; |
| 24 | +import org.seedstack.seed.core.internal.init.*; |
42 | 25 | import org.seedstack.seed.diagnostic.DiagnosticManager; |
43 | 26 | import org.seedstack.seed.spi.SeedExceptionTranslator; |
44 | 27 | import org.seedstack.seed.spi.SeedInitializer; |
|
49 | 32 | import org.seedstack.shed.reflect.Classes; |
50 | 33 | import org.seedstack.shed.text.TextTemplate; |
51 | 34 |
|
| 35 | +import java.io.IOException; |
| 36 | +import java.io.InputStream; |
| 37 | +import java.nio.charset.StandardCharsets; |
| 38 | +import java.util.*; |
| 39 | + |
| 40 | +import static com.google.common.base.Preconditions.checkState; |
| 41 | +import static org.seedstack.shed.misc.PriorityUtils.sortByPriority; |
| 42 | + |
52 | 43 | /** |
53 | 44 | * This class is the SeedStack framework entry point, which is used create and dispose kernels. |
54 | 45 | * It handles global initialization and cleanup. |
55 | 46 | */ |
56 | 47 | public class Seed { |
| 48 | + private static final int EXIT_FAILURE = 1; |
57 | 49 | private static final String WELCOME_MESSAGE = "\n" + |
58 | 50 | " ____ _ ____ _ _ \n" + |
59 | 51 | "/ ___| ___ ___ __| / ___|| |_ __ _ ___| | __\n" + |
@@ -118,7 +110,7 @@ private Seed() { |
118 | 110 | } |
119 | 111 | diagnosticManager.dumpDiagnosticReport(throwable); |
120 | 112 | translated.printStackTrace(System.err); |
121 | | - } catch(Throwable t) { |
| 113 | + } catch (Throwable t) { |
122 | 114 | throwable.printStackTrace(); |
123 | 115 | } |
124 | 116 | }); |
@@ -181,6 +173,50 @@ static void markLifecycleExceptionHandlerEnabled() { |
181 | 173 | hasLifecycleExceptionHandler = true; |
182 | 174 | } |
183 | 175 |
|
| 176 | + /** |
| 177 | + * <p> |
| 178 | + * Main SeedStack Java application entry point. It searches classes implementing {@link SeedLauncher} through the |
| 179 | + * {@link ServiceLoader} mechanism. If no class or more than one class is found, it throws an exception. If exactly one |
| 180 | + * class is found, it delegates the SeedStack application startup to its {@link SeedLauncher#launch(String[])} method. |
| 181 | + * </p> |
| 182 | + * <p> |
| 183 | + * Exception handling and diagnostic during startup and shutdown is done directly in this class. This is materialized |
| 184 | + * by the fact that {@link Seed#hasLifecycleExceptionHandler()} returns true when {@link SeedMain} is used. |
| 185 | + * </p> |
| 186 | + * <p> |
| 187 | + * If an exception occurs during startup or shutdown, it is translated using {@link Seed#translateException(Exception)} |
| 188 | + * and its stack trace is printed on the standard error output. During startup only a diagnostic report is also dumped. |
| 189 | + * </p> |
| 190 | + * |
| 191 | + * @param args The launch arguments. |
| 192 | + */ |
| 193 | + public static void launch(String[] args) { |
| 194 | + try { |
| 195 | + final SeedLauncher seedLauncher; |
| 196 | + final String toolName = System.getProperty("seedstack.tool"); |
| 197 | + if (!Strings.isNullOrEmpty(toolName)) { |
| 198 | + seedLauncher = Seed.getToolLauncher(toolName); |
| 199 | + } else { |
| 200 | + seedLauncher = Seed.getLauncher(); |
| 201 | + } |
| 202 | + |
| 203 | + Runtime.getRuntime().addShutdownHook(new Thread(() -> { |
| 204 | + try { |
| 205 | + seedLauncher.shutdown(); |
| 206 | + Seed.close(); |
| 207 | + } catch (Exception e) { |
| 208 | + handleException(e); |
| 209 | + } |
| 210 | + }, "shutdown")); |
| 211 | + Seed.markLifecycleExceptionHandlerEnabled(); |
| 212 | + |
| 213 | + seedLauncher.launch(args); |
| 214 | + } catch (Exception e) { |
| 215 | + handleException(e); |
| 216 | + System.exit(EXIT_FAILURE); |
| 217 | + } |
| 218 | + } |
| 219 | + |
184 | 220 | /** |
185 | 221 | * Returns if a global exception handler for startup and shutdown is present or not. |
186 | 222 | * |
@@ -290,7 +326,7 @@ public static Kernel createKernel() { |
290 | 326 | * @return the {@link Kernel} instance. |
291 | 327 | */ |
292 | 328 | public static Kernel createKernel(Object runtimeContext, KernelConfiguration kernelConfiguration, |
293 | | - boolean autoStart) { |
| 329 | + boolean autoStart) { |
294 | 330 | Seed instance = getInstance(); |
295 | 331 | return instance.kernelManager.createKernel( |
296 | 332 | SeedRuntime.builder() |
@@ -443,6 +479,12 @@ private void dispose() { |
443 | 479 | Thread.setDefaultUncaughtExceptionHandler(null); |
444 | 480 | } |
445 | 481 |
|
| 482 | + private static void handleException(Exception e) { |
| 483 | + BaseException translated = Seed.translateException(e); |
| 484 | + Seed.diagnostic().dumpDiagnosticReport(translated); |
| 485 | + translated.printStackTrace(System.err); |
| 486 | + } |
| 487 | + |
446 | 488 | private static class Holder { |
447 | 489 | private static final Seed INSTANCE = new Seed(); |
448 | 490 | } |
|
0 commit comments