diff --git a/nucleus/core/kernel/src/main/java/org/glassfish/runnablejar/InfoPrinter.java b/nucleus/core/kernel/src/main/java/org/glassfish/runnablejar/InfoPrinter.java index dc3a1b4fd3f..1e392a824a9 100644 --- a/nucleus/core/kernel/src/main/java/org/glassfish/runnablejar/InfoPrinter.java +++ b/nucleus/core/kernel/src/main/java/org/glassfish/runnablejar/InfoPrinter.java @@ -99,8 +99,10 @@ private int processApplications(List applications, final List applications, final List "GlassFish started. Welcome!"); + UberMain uberMain = new UberMain(); + try { + uberMain.run(arguments); + if (uberMain.isShutdownRequested()) { + uberMain.stopGlassFish(); + exit(0); + } + } catch (Throwable ex) { + logger.log(SEVERE, ex.getMessage()); + logger.log(FINE, ex.getMessage(), ex); + uberMain.stopGlassFish(); + exit(1); + } } } + public UberMain() { + this.shutdownLogHandlers = Logger.getLogger("").getHandlers(); + } + + + public void run(Arguments arguments) throws GlassFishException { + try { + runInternal(arguments); + } catch (Throwable ex) { + fatalErrorMessage = ex.getMessage(); + throw ex; + } + } + + public boolean isShutdownRequested() { + return shutdownRequested; + } + + private void runInternal(Arguments arguments) throws GlassFishException { addShutdownHook(); // handle Ctrt-C. GlassFishProperties gfProps = arguments.glassFishProperties; @@ -121,7 +159,9 @@ public void run(Arguments arguments) throws GlassFishException { if (arguments.shutdown) { logger.log(INFO, () -> "Shutting down after startup as requested"); - exit(0); + shutdownRequested = true; + goodByeMessage = "GlassFish shut down after startup as requested"; + return; } switch (glassFish.getStatus()) { @@ -187,24 +227,23 @@ private void executeCommandFromString(String stringCommand) { commandParams[i - 1] = split[i].trim(); } } - try { - CommandResult result = commandParams == null - ? commandRunner.run(command) : commandRunner.run(command, commandParams); - switch (result.getExitStatus()) { - case SUCCESS: - logger.log(INFO, () -> "SUCCESS: " + result.getOutput()); - break; - default: - if (result.getFailureCause() != null) { - throw result.getFailureCause(); + CommandResult result = commandParams == null + ? commandRunner.run(command) : commandRunner.run(command, commandParams); + switch (result.getExitStatus()) { + case SUCCESS: + logger.log(INFO, () -> "SUCCESS: " + result.getOutput()); + break; + default: + if (result.getFailureCause() != null) { + if (result.getFailureCause() instanceof RuntimeException runtimeException) { + throw runtimeException; } else { - throw new RuntimeException("Command completed with " + result.getExitStatus() + ": " - + result.getOutput() + ". Command was: " + stringCommand); + throw new RuntimeException(result.getFailureCause()); } - } - } catch (Throwable ex) { - logger.log(SEVERE, ex.getMessage()); - logger.log(FINE, ex.getMessage(), ex); + } else { + throw new RuntimeException("Command completed with " + result.getExitStatus() + ": " + + result.getOutput() + ". Command was: " + stringCommand); + } } } @@ -213,23 +252,38 @@ private void addShutdownHook() { @Override public void run() { - if (glassFish != null) { - stopGlassFish(); + // We restore the handlers because they are already removed from the logger in the shutdown hook + for (Handler handler : shutdownLogHandlers) { + logger.addHandler(handler); + } + + stopGlassFish(); + + for (Handler handler : logger.getHandlers()) { + logger.removeHandler(handler); } } }); } - private void stopGlassFish() { - try { - glassFish.stop(); - } catch (GlassFishException ex) { - logger.log(Level.SEVERE, ex.getMessage(), ex); - } finally { + public void stopGlassFish() { + if (glassFish != null) { try { - glassFish.dispose(); + glassFish.stop(); } catch (GlassFishException ex) { logger.log(Level.SEVERE, ex.getMessage(), ex); + } finally { + try { + glassFish.dispose(); + glassFish = null; + } catch (GlassFishException ex) { + logger.log(Level.SEVERE, ex.getMessage(), ex); + } + } + if (fatalErrorMessage != null) { + logger.severe(() -> "GlassFish shut down unexpectedly, due to an error: " + fatalErrorMessage); + } else { + logger.info(goodByeMessage); } } } diff --git a/nucleus/core/kernel/src/test/java/org/glassfish/runnablejar/UberMainTest.java b/nucleus/core/kernel/src/test/java/org/glassfish/runnablejar/UberMainTest.java index c740a8eb212..58e1de0b787 100644 --- a/nucleus/core/kernel/src/test/java/org/glassfish/runnablejar/UberMainTest.java +++ b/nucleus/core/kernel/src/test/java/org/glassfish/runnablejar/UberMainTest.java @@ -36,6 +36,8 @@ import org.junit.jupiter.api.Test; import org.jvnet.hk2.config.types.Property; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * * @author Ondro Mihalyi @@ -47,6 +49,19 @@ public void getInfoAfterStartup() throws GlassFishException { String info = new InfoPrinter().getInfoAfterStartup(List.of(app("/app1"), app("application")), List.of(listener(8080, false), listener(8181, true))); System.out.println(info); + String[] lines = info.split("\n"); + assertTrue(lines.length == 6, "Number of lines should be 6 but is " + lines.length); + assertThatLinesAreEquallyLong(lines); + } + + @Test + public void getInfoAfterStartup_noListeners() throws GlassFishException { + String info = new InfoPrinter().getInfoAfterStartup(List.of(app("/app1"), app("application")), + List.of()); + System.out.println(info); + String[] lines = info.split("\n"); + assertTrue(lines.length == 6, "Number of lines should be 6 but is " + lines.length); + assertThatLinesAreEquallyLong(lines); } @@ -55,8 +70,28 @@ public void getInfoAfterStartup_noApps() throws GlassFishException { String info = new InfoPrinter().getInfoAfterStartup(List.of(), List.of(listener(8080, false), listener(8181, true))); System.out.println(info); + String[] lines = info.split("\n"); + assertTrue(lines.length == 5, "Number of lines should be 6 but is " + lines.length); + assertThatLinesAreEquallyLong(lines); } + @Test + public void getInfoAfterStartup_noApps_noListeners() throws GlassFishException { + String info = new InfoPrinter().getInfoAfterStartup(List.of(), + List.of()); + System.out.println(info); + String[] lines = info.split("\n"); + assertTrue(lines.length == 5, "Number of lines should be 6 but is " + lines.length); + assertThatLinesAreEquallyLong(lines); + } + + private void assertThatLinesAreEquallyLong(String[] lines) { + int lineLength = lines[0].length(); + for (int i = 1; i < lines.length; i++) { + int thisLineLength = lines[i].length(); + assertTrue(thisLineLength == lineLength, "All lines should as long as the first line. The first line is " + lineLength + " long while the line number " + i + " is " + thisLineLength + " long"); + } + } private MockListener listener(int port, boolean secure) { return new MockListener(port, secure);