FELIX-2084: Make the display of exception stack traces available through a variable in the shell
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@910845 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/karaf/shell/console/src/main/java/org/apache/felix/karaf/shell/console/jline/Console.java b/karaf/shell/console/src/main/java/org/apache/felix/karaf/shell/console/jline/Console.java
index c8a7752..4f1ca87 100644
--- a/karaf/shell/console/src/main/java/org/apache/felix/karaf/shell/console/jline/Console.java
+++ b/karaf/shell/console/src/main/java/org/apache/felix/karaf/shell/console/jline/Console.java
@@ -32,7 +32,6 @@
import java.util.Properties;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Callable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -44,6 +43,7 @@
import org.apache.felix.karaf.shell.console.Completer;
import org.apache.felix.karaf.shell.console.completer.AggregateCompleter;
import org.apache.felix.karaf.shell.console.completer.SessionScopeCompleter;
+import org.fusesource.jansi.Ansi;
import org.osgi.service.command.CommandProcessor;
import org.osgi.service.command.CommandSession;
import org.osgi.service.command.Converter;
@@ -57,6 +57,7 @@
public static final String PROMPT = "PROMPT";
public static final String DEFAULT_PROMPT = "\u001B[1m${USER}\u001B[0m@${APPLICATION}> ";
public static final String PRINT_STACK_TRACES = "karaf.printStackTraces";
+ public static final String LAST_EXCEPTION = "karaf.lastException";
private static final Logger LOGGER = LoggerFactory.getLogger(Console.class);
@@ -72,7 +73,6 @@
private InputStream in;
private PrintStream out;
private PrintStream err;
- private Callable<Boolean> printStackTraces;
public Console(CommandProcessor processor,
InputStream in,
@@ -80,8 +80,7 @@
PrintStream err,
Terminal term,
Completer completer,
- Runnable closeCallback,
- Callable<Boolean> printStackTraces) throws Exception
+ Runnable closeCallback) throws Exception
{
this.in = in;
this.out = out;
@@ -92,7 +91,6 @@
this.session = processor.createSession(this.consoleInput, this.out, this.err);
this.session.put("SCOPE", "shell:osgi:*");
this.closeCallback = closeCallback;
- this.printStackTraces = printStackTraces;
reader = new ConsoleReader(this.consoleInput,
new PrintWriter(this.out),
@@ -191,12 +189,17 @@
catch (Throwable t)
{
try {
- if ( printStackTraces.call()) {
+ LOGGER.info("Exception caught while executing command", t);
+ session.put(LAST_EXCEPTION, t);
+ session.getConsole().print(Ansi.ansi().fg(Ansi.Color.RED).toString());
+ if ( isPrintStackTraces()) {
t.printStackTrace(session.getConsole());
}
else {
- session.getConsole().println(t.getMessage());
+ session.getConsole().println("Error executing command: "
+ + (t.getMessage() != null ? t.getMessage() : t.getClass().getName()));
}
+ session.getConsole().print(Ansi.ansi().fg(Ansi.Color.DEFAULT).toString());
} catch (Exception ignore) {
// ignore
}
@@ -209,6 +212,20 @@
}
}
+ protected boolean isPrintStackTraces() {
+ Object s = session.get(PRINT_STACK_TRACES);
+ if (s == null) {
+ s = System.getProperty(PRINT_STACK_TRACES);
+ }
+ if (s == null) {
+ return false;
+ }
+ if (s instanceof Boolean) {
+ return (Boolean) s;
+ }
+ return Boolean.parseBoolean(s.toString());
+ }
+
protected void welcome() {
Properties props = new Properties();
loadProps(props, "org/apache/felix/karaf/shell/console/branding.properties");
diff --git a/karaf/shell/console/src/main/java/org/apache/felix/karaf/shell/console/jline/ConsoleFactory.java b/karaf/shell/console/src/main/java/org/apache/felix/karaf/shell/console/jline/ConsoleFactory.java
index 756fb12..1a9d4ae 100644
--- a/karaf/shell/console/src/main/java/org/apache/felix/karaf/shell/console/jline/ConsoleFactory.java
+++ b/karaf/shell/console/src/main/java/org/apache/felix/karaf/shell/console/jline/ConsoleFactory.java
@@ -82,19 +82,13 @@
}
}
};
- final Callable<Boolean> printStackTraces = new Callable<Boolean>() {
- public Boolean call() {
- return Boolean.valueOf(bundleContext.getProperty(Console.PRINT_STACK_TRACES));
- }
- };
this.console = new Console(commandProcessor,
in,
wrap(out),
wrap(err),
terminal,
new AggregateCompleter(completers),
- callback,
- printStackTraces);
+ callback);
CommandSession session = console.getSession();
session.put("USER", "karaf");
session.put("APPLICATION", System.getProperty("karaf.name", "root"));
diff --git a/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/PrintStackTraces.java b/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/PrintStackTraces.java
new file mode 100644
index 0000000..a34c03d
--- /dev/null
+++ b/karaf/shell/dev/src/main/java/org/apache/felix/karaf/shell/dev/PrintStackTraces.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.karaf.shell.dev;
+
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.karaf.shell.console.OsgiCommandSupport;
+import org.apache.felix.karaf.shell.console.jline.Console;
+import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static java.lang.String.format;
+
+/**
+ * Command for showing the full tree of bundles that have been used to resolve
+ * a given bundle.
+ */
+@Command(scope = "dev", name = "print-stack-traces",
+ description = "Print the full stack trace in the console when the execution of a command throws an exception")
+public class PrintStackTraces extends OsgiCommandSupport {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(PrintStackTraces.class);
+
+ @Argument(name = "print", description="Print stack traces or not", required = false, multiValued = false)
+ boolean print = true;
+
+ protected Object doExecute() throws Exception {
+ session.put(Console.PRINT_STACK_TRACES, Boolean.valueOf(print));
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/karaf/shell/dev/src/main/resources/OSGI-INF/blueprint/shell-dev.xml b/karaf/shell/dev/src/main/resources/OSGI-INF/blueprint/shell-dev.xml
index d3fab7d..d19064f 100644
--- a/karaf/shell/dev/src/main/resources/OSGI-INF/blueprint/shell-dev.xml
+++ b/karaf/shell/dev/src/main/resources/OSGI-INF/blueprint/shell-dev.xml
@@ -29,6 +29,9 @@
<command name="dev/dynamic-import">
<action class="org.apache.felix.karaf.shell.dev.DynamicImport" />
</command>
+ <command name="dev/print-stack-traces">
+ <action class="org.apache.felix.karaf.shell.dev.PrintStackTraces" />
+ </command>
</command-bundle>
</blueprint>
diff --git a/karaf/shell/ssh/src/main/java/org/apache/felix/karaf/shell/ssh/ShellFactoryImpl.java b/karaf/shell/ssh/src/main/java/org/apache/felix/karaf/shell/ssh/ShellFactoryImpl.java
index 6c61af7..996a2f4 100644
--- a/karaf/shell/ssh/src/main/java/org/apache/felix/karaf/shell/ssh/ShellFactoryImpl.java
+++ b/karaf/shell/ssh/src/main/java/org/apache/felix/karaf/shell/ssh/ShellFactoryImpl.java
@@ -93,11 +93,6 @@
public void start(final Environment env) throws IOException {
try {
- final Callable<Boolean> printStackTraces = new Callable<Boolean>() {
- public Boolean call() {
- return Boolean.valueOf(System.getProperty(Console.PRINT_STACK_TRACES));
- }
- };
Console console = new Console(commandProcessor,
in,
new PrintStream(new LfToCrLfFilterOutputStream(out), true),
@@ -108,8 +103,7 @@
public void run() {
destroy();
}
- },
- printStackTraces);
+ });
CommandSession session = console.getSession();
session.put("APPLICATION", System.getProperty("karaf.name", "root"));
for (Map.Entry<String,String> e : env.getEnv().entrySet()) {
diff --git a/karaf/webconsole/gogo/src/main/java/org/apache/felix/karaf/webconsole/gogo/GogoPlugin.java b/karaf/webconsole/gogo/src/main/java/org/apache/felix/karaf/webconsole/gogo/GogoPlugin.java
index 1d72c71..bed29dc 100644
--- a/karaf/webconsole/gogo/src/main/java/org/apache/felix/karaf/webconsole/gogo/GogoPlugin.java
+++ b/karaf/webconsole/gogo/src/main/java/org/apache/felix/karaf/webconsole/gogo/GogoPlugin.java
@@ -208,20 +208,13 @@
out = new PipedInputStream();
PrintStream pipedOut = new PrintStream(new PipedOutputStream(out), true);
- final Callable<Boolean> printStackTraces = new Callable<Boolean>() {
- public Boolean call() {
- return Boolean.valueOf(bundleContext.getProperty(Console.PRINT_STACK_TRACES));
- }
- };
-
console = new Console(commandProcessor,
new PipedInputStream(in),
pipedOut,
pipedOut,
new WebTerminal(TERM_WIDTH, TERM_HEIGHT),
new AggregateCompleter(completers),
- null,
- printStackTraces);
+ null);
CommandSession session = console.getSession();
session.put("APPLICATION", System.getProperty("karaf.name", "root"));
session.put("USER", "karaf");