diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index b7506ecf39..2de31671dc 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -831,7 +831,7 @@ public final class FilePath implements Serializable { return true; } catch (IOException x) { if (listener != null) { - listener.error("Failed to download " + archive + " from agent; will retry from master").print(Functions.printThrowable(x)); + Functions.printStackTrace(x, listener.error("Failed to download " + archive + " from agent; will retry from master")); } } } diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index f2863b5905..6e435834fc 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -156,6 +156,7 @@ import com.google.common.base.Predicate; import com.google.common.base.Predicates; import hudson.model.PasswordParameterDefinition; import hudson.util.RunList; +import java.io.PrintStream; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; @@ -1505,6 +1506,26 @@ public class Functions { } } + /** + * Like {@link Throwable#printStackTrace(PrintWriter)} but using {@link #printThrowable} format. + * @param t an exception to print + * @param pw the log + * @since FIXME + */ + public static void printStackTrace(@CheckForNull Throwable t, @Nonnull PrintWriter pw) { + pw.println(printThrowable(t).trim()); + } + + /** + * Like {@link Throwable#printStackTrace(PrintStream)} but using {@link #printThrowable} format. + * @param t an exception to print + * @param ps the log + * @since FIXME + */ + public static void printStackTrace(@CheckForNull Throwable t, @Nonnull PrintStream ps) { + ps.println(printThrowable(t).trim()); + } + /** * Counts the number of rows needed for textarea to fit the content. * Minimum 5 rows. diff --git a/core/src/main/java/hudson/Proc.java b/core/src/main/java/hudson/Proc.java index 48d5d2741d..8561bdbd64 100644 --- a/core/src/main/java/hudson/Proc.java +++ b/core/src/main/java/hudson/Proc.java @@ -159,7 +159,7 @@ public abstract class Proc { kill(); } } catch (InterruptedException | IOException | RuntimeException x) { - listener.error("Failed to join a process").print(Functions.printThrowable(x)); + Functions.printStackTrace(x, listener.error("Failed to join a process")); } } }); diff --git a/core/src/main/java/hudson/Util.java b/core/src/main/java/hudson/Util.java index 46c707da67..73d6156713 100644 --- a/core/src/main/java/hudson/Util.java +++ b/core/src/main/java/hudson/Util.java @@ -1367,7 +1367,7 @@ public class Util { PrintStream log = listener.getLogger(); log.printf("ln %s %s failed%n",targetPath, new File(baseDir, symlinkPath)); Util.displayIOException(e,listener); - log.print(Functions.printThrowable(e)); + Functions.printStackTrace(e, log); } } diff --git a/core/src/main/java/hudson/cli/CLICommand.java b/core/src/main/java/hudson/cli/CLICommand.java index 6bc650a07c..a2fb8bc51f 100644 --- a/core/src/main/java/hudson/cli/CLICommand.java +++ b/core/src/main/java/hudson/cli/CLICommand.java @@ -299,7 +299,7 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { stderr.println(""); stderr.println("ERROR: " + errorMsg); LOGGER.log(Level.WARNING, errorMsg, e); - stderr.print(Functions.printThrowable(e)); + Functions.printStackTrace(e, stderr); return 1; } finally { if(sc != null) @@ -333,7 +333,7 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { return new ClientAuthenticationCache(channel).get(); } catch (IOException e) { stderr.println("Failed to access the stored credential"); - stderr.print(Functions.printThrowable(e)); // recover + Functions.printStackTrace(e, stderr); // recover } return Jenkins.ANONYMOUS; } diff --git a/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java b/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java index d0f5244f2e..2d17d1b29b 100644 --- a/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java +++ b/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java @@ -270,7 +270,7 @@ public class CLIRegisterer extends ExtensionFinder { stderr.println(""); stderr.println("ERROR: " + errorMsg); LOGGER.log(Level.WARNING, errorMsg, e); - stderr.print(Functions.printThrowable(e)); + Functions.printStackTrace(e, stderr); return 1; } } diff --git a/core/src/main/java/hudson/model/AbstractBuild.java b/core/src/main/java/hudson/model/AbstractBuild.java index 2d22548c76..a096635dfc 100644 --- a/core/src/main/java/hudson/model/AbstractBuild.java +++ b/core/src/main/java/hudson/model/AbstractBuild.java @@ -633,7 +633,7 @@ public abstract class AbstractBuild

,R extends Abs throw (InterruptedException)new InterruptedException().initCause(e); } catch (IOException e) { // checkout error not yet reported - listener.getLogger().print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.getLogger()); } if (retryCount == 0) // all attempts failed @@ -749,7 +749,7 @@ public abstract class AbstractBuild

,R extends Abs listener.error("Step ‘" + buildStep + "’ failed: " + e.getMessage()); } else { String msg = "Step ‘" + buildStep + "’ aborted due to exception: "; - listener.error(msg).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error(msg)); LOGGER.log(WARNING, msg, e); } @@ -784,7 +784,7 @@ public abstract class AbstractBuild

,R extends Abs // Channel is closed, do not continue reportBrokenChannel(listener); } catch (RuntimeException ex) { - listener.error("Build step failed with exception").print(Functions.printThrowable(ex)); + Functions.printStackTrace(ex, listener.error("Build step failed with exception")); } for (BuildStepListener bsl : BuildStepListener.all()) { diff --git a/core/src/main/java/hudson/model/AbstractProject.java b/core/src/main/java/hudson/model/AbstractProject.java index f00668a173..b3d9413635 100644 --- a/core/src/main/java/hudson/model/AbstractProject.java +++ b/core/src/main/java/hudson/model/AbstractProject.java @@ -1370,11 +1370,11 @@ public abstract class AbstractProject

,R extends A SCMPollListener.firePollingFailed(this, listener,e); return NO_CHANGES; } catch (IOException e) { - listener.fatalError(e.getMessage()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.fatalError(e.getMessage())); SCMPollListener.firePollingFailed(this, listener,e); return NO_CHANGES; } catch (InterruptedException e) { - listener.fatalError(Messages.AbstractProject_PollingABorted()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.fatalError(Messages.AbstractProject_PollingABorted())); SCMPollListener.firePollingFailed(this, listener,e); return NO_CHANGES; } catch (RuntimeException e) { diff --git a/core/src/main/java/hudson/model/AsyncAperiodicWork.java b/core/src/main/java/hudson/model/AsyncAperiodicWork.java index 02c108bb65..1d295fa716 100644 --- a/core/src/main/java/hudson/model/AsyncAperiodicWork.java +++ b/core/src/main/java/hudson/model/AsyncAperiodicWork.java @@ -120,9 +120,9 @@ public abstract class AsyncAperiodicWork extends AperiodicWork { execute(l); } catch (IOException e) { - l.fatalError(e.getMessage()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, l.fatalError(e.getMessage())); } catch (InterruptedException e) { - l.fatalError("aborted").print(Functions.printThrowable(e)); + Functions.printStackTrace(e, l.fatalError("aborted")); } finally { stopTime = System.currentTimeMillis(); try { diff --git a/core/src/main/java/hudson/model/AsyncPeriodicWork.java b/core/src/main/java/hudson/model/AsyncPeriodicWork.java index 383786c8cb..f3ffcc6497 100644 --- a/core/src/main/java/hudson/model/AsyncPeriodicWork.java +++ b/core/src/main/java/hudson/model/AsyncPeriodicWork.java @@ -100,9 +100,9 @@ public abstract class AsyncPeriodicWork extends PeriodicWork { execute(l); } catch (IOException e) { - l.fatalError(e.getMessage()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, l.fatalError(e.getMessage())); } catch (InterruptedException e) { - l.fatalError("aborted").print(Functions.printThrowable(e)); + Functions.printStackTrace(e, l.fatalError("aborted")); } finally { stopTime = System.currentTimeMillis(); try { diff --git a/core/src/main/java/hudson/model/Build.java b/core/src/main/java/hudson/model/Build.java index 3a8fd35e73..2b8b764931 100644 --- a/core/src/main/java/hudson/model/Build.java +++ b/core/src/main/java/hudson/model/Build.java @@ -196,7 +196,7 @@ public abstract class Build

,B extends Build> performAllBuildSteps(listener, project.getPublishersList(), false); performAllBuildSteps(listener, project.getProperties(), false); } catch (Exception x) { - listener.error(Messages.Build_post_build_steps_failed()).print(Functions.printThrowable(x)); + Functions.printStackTrace(x, listener.error(Messages.Build_post_build_steps_failed())); } super.cleanUp(listener); } diff --git a/core/src/main/java/hudson/model/Executor.java b/core/src/main/java/hudson/model/Executor.java index a42b723dba..83345726be 100644 --- a/core/src/main/java/hudson/model/Executor.java +++ b/core/src/main/java/hudson/model/Executor.java @@ -290,7 +290,7 @@ public class Executor extends Thread implements ModelObject { } else { pw.println("Termination trace follows:"); for (Computer.TerminationRequest request : owner.getTerminatedBy()) { - pw.print(Functions.printThrowable(request)); + Functions.printStackTrace(request, pw); } } } diff --git a/core/src/main/java/hudson/model/FingerprintCleanupThread.java b/core/src/main/java/hudson/model/FingerprintCleanupThread.java index fffd8db483..59187a3a40 100644 --- a/core/src/main/java/hudson/model/FingerprintCleanupThread.java +++ b/core/src/main/java/hudson/model/FingerprintCleanupThread.java @@ -114,7 +114,7 @@ public final class FingerprintCleanupThread extends AsyncPeriodicWork { return fp.trim(); } } catch (IOException e) { - listener.error("Failed to process " + fingerprintFile).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error("Failed to process " + fingerprintFile)); return false; } } diff --git a/core/src/main/java/hudson/model/Run.java b/core/src/main/java/hudson/model/Run.java index 81fb8a07fa..eb0f7a63b1 100644 --- a/core/src/main/java/hudson/model/Run.java +++ b/core/src/main/java/hudson/model/Run.java @@ -1864,7 +1864,7 @@ public abstract class Run ,RunT extends Run, ExtensionPoint { createEmptyChangeLog(changelogFile, (TaskListener) listener, rootTag); return true; } catch (IOException e) { - listener.error(e.getMessage()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error(e.getMessage())); return false; } } diff --git a/core/src/main/java/hudson/slaves/CommandLauncher.java b/core/src/main/java/hudson/slaves/CommandLauncher.java index 1a152e55a9..4f7c075a06 100644 --- a/core/src/main/java/hudson/slaves/CommandLauncher.java +++ b/core/src/main/java/hudson/slaves/CommandLauncher.java @@ -144,11 +144,11 @@ public class CommandLauncher extends ComputerLauncher { LOGGER.info("agent launched for " + computer.getDisplayName()); } catch (InterruptedException e) { - listener.error(Messages.ComputerLauncher_abortedLaunch()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error(Messages.ComputerLauncher_abortedLaunch())); } catch (RuntimeException e) { - listener.error(Messages.ComputerLauncher_unexpectedError()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error(Messages.ComputerLauncher_unexpectedError())); } catch (Error e) { - listener.error(Messages.ComputerLauncher_unexpectedError()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error(Messages.ComputerLauncher_unexpectedError())); } catch (IOException e) { Util.displayIOException(e, listener); @@ -160,14 +160,14 @@ public class CommandLauncher extends ComputerLauncher { } msg = hudson.model.Messages.Slave_UnableToLaunch(computer.getDisplayName(), msg); LOGGER.log(Level.SEVERE, msg, e); - listener.error(msg).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error(msg)); if(_proc!=null) { reportProcessTerminated(_proc, listener); try { ProcessTree.get().killAll(_proc, _cookie); } catch (InterruptedException x) { - listener.error(Messages.ComputerLauncher_abortedLaunch()).print(Functions.printThrowable(x)); + Functions.printStackTrace(x, listener.error(Messages.ComputerLauncher_abortedLaunch())); } } } diff --git a/core/src/main/java/hudson/slaves/SlaveComputer.java b/core/src/main/java/hudson/slaves/SlaveComputer.java index 57662bc18b..36bd1478cb 100644 --- a/core/src/main/java/hudson/slaves/SlaveComputer.java +++ b/core/src/main/java/hudson/slaves/SlaveComputer.java @@ -265,13 +265,13 @@ public class SlaveComputer extends Computer { throw e; } catch (IOException e) { Util.displayIOException(e,taskListener); - taskListener.error(Messages.ComputerLauncher_unexpectedError()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, taskListener.error(Messages.ComputerLauncher_unexpectedError())); throw e; } catch (InterruptedException e) { - taskListener.error(Messages.ComputerLauncher_abortedLaunch()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, taskListener.error(Messages.ComputerLauncher_abortedLaunch())); throw e; } catch (Exception e) { - taskListener.error(Messages.ComputerLauncher_unexpectedError()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, taskListener.error(Messages.ComputerLauncher_unexpectedError())); throw e; } } finally { @@ -495,7 +495,7 @@ public class SlaveComputer extends Computer { // Orderly shutdown will have null exception if (cause!=null) { offlineCause = new ChannelTermination(cause); - taskListener.error("Connection terminated").print(Functions.printThrowable(cause)); + Functions.printStackTrace(cause, taskListener.error("Connection terminated")); } else { taskListener.getLogger().println("Connection terminated"); } diff --git a/core/src/main/java/hudson/tasks/ArtifactArchiver.java b/core/src/main/java/hudson/tasks/ArtifactArchiver.java index 2b8f3d4865..407dadaa39 100644 --- a/core/src/main/java/hudson/tasks/ArtifactArchiver.java +++ b/core/src/main/java/hudson/tasks/ArtifactArchiver.java @@ -263,7 +263,7 @@ public class ArtifactArchiver extends Recorder implements SimpleBuildStep { } } catch (IOException e) { Util.displayIOException(e,listener); - listener.error(Messages.ArtifactArchiver_FailedToArchive(artifacts)).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error(Messages.ArtifactArchiver_FailedToArchive(artifacts))); build.setResult(Result.FAILURE); return; } diff --git a/core/src/main/java/hudson/tasks/CommandInterpreter.java b/core/src/main/java/hudson/tasks/CommandInterpreter.java index 5170aff8e8..3056b71cde 100644 --- a/core/src/main/java/hudson/tasks/CommandInterpreter.java +++ b/core/src/main/java/hudson/tasks/CommandInterpreter.java @@ -94,7 +94,7 @@ public abstract class CommandInterpreter extends Builder { script = createScriptFile(ws); } catch (IOException e) { Util.displayIOException(e,listener); - listener.fatalError(Messages.CommandInterpreter_UnableToProduceScript()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.fatalError(Messages.CommandInterpreter_UnableToProduceScript())); return false; } @@ -114,7 +114,7 @@ public abstract class CommandInterpreter extends Builder { } } catch (IOException e) { Util.displayIOException(e, listener); - listener.fatalError(Messages.CommandInterpreter_CommandFailed()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.fatalError(Messages.CommandInterpreter_CommandFailed())); } return r==0; } finally { @@ -133,10 +133,10 @@ public abstract class CommandInterpreter extends Builder { LOGGER.log(Level.FINE, "Script deletion failed", e); } else { Util.displayIOException(e,listener); - listener.fatalError(Messages.CommandInterpreter_UnableToDelete(script)).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.fatalError(Messages.CommandInterpreter_UnableToDelete(script))); } } catch (Exception e) { - listener.fatalError(Messages.CommandInterpreter_UnableToDelete(script)).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.fatalError(Messages.CommandInterpreter_UnableToDelete(script))); } } } diff --git a/core/src/main/java/hudson/tasks/Fingerprinter.java b/core/src/main/java/hudson/tasks/Fingerprinter.java index beda443bf3..fb45ef9cc2 100644 --- a/core/src/main/java/hudson/tasks/Fingerprinter.java +++ b/core/src/main/java/hudson/tasks/Fingerprinter.java @@ -138,7 +138,7 @@ public class Fingerprinter extends Recorder implements Serializable, DependencyD Jenkins.getInstance().rebuildDependencyGraphAsync(); } } catch (IOException e) { - listener.error(Messages.Fingerprinter_Failed()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error(Messages.Fingerprinter_Failed())); build.setResult(Result.FAILURE); } diff --git a/core/src/main/java/hudson/tasks/Maven.java b/core/src/main/java/hudson/tasks/Maven.java index 4939ea7044..4e8b4f4eed 100644 --- a/core/src/main/java/hudson/tasks/Maven.java +++ b/core/src/main/java/hudson/tasks/Maven.java @@ -366,7 +366,7 @@ public class Maven extends Builder { } } catch (IOException e) { Util.displayIOException(e,listener); - listener.fatalError(Messages.Maven_ExecFailed()).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.fatalError(Messages.Maven_ExecFailed())); return false; } startIndex = endIndex + 1; diff --git a/core/src/main/java/hudson/triggers/SCMTrigger.java b/core/src/main/java/hudson/triggers/SCMTrigger.java index d3c7074eb6..7a8afe26b2 100644 --- a/core/src/main/java/hudson/triggers/SCMTrigger.java +++ b/core/src/main/java/hudson/triggers/SCMTrigger.java @@ -569,7 +569,7 @@ public class SCMTrigger extends Trigger { logger.println("No changes"); return result; } catch (Error | RuntimeException e) { - listener.error("Failed to record SCM polling for " + job).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error("Failed to record SCM polling for " + job)); LOGGER.log(Level.SEVERE,"Failed to record SCM polling for "+job,e); throw e; } finally { diff --git a/core/src/main/java/hudson/util/RemotingDiagnostics.java b/core/src/main/java/hudson/util/RemotingDiagnostics.java index 02184c3397..d38fa7170e 100644 --- a/core/src/main/java/hudson/util/RemotingDiagnostics.java +++ b/core/src/main/java/hudson/util/RemotingDiagnostics.java @@ -143,7 +143,7 @@ public final class RemotingDiagnostics { if(output!=null) pw.println("Result: "+output); } catch (Throwable t) { - pw.print(Functions.printThrowable(t)); + Functions.printStackTrace(t, pw); } return out.toString(); } diff --git a/core/src/main/java/hudson/util/SecretRewriter.java b/core/src/main/java/hudson/util/SecretRewriter.java index 08bf646c67..565aca7fcd 100644 --- a/core/src/main/java/hudson/util/SecretRewriter.java +++ b/core/src/main/java/hudson/util/SecretRewriter.java @@ -170,7 +170,7 @@ public class SecretRewriter { rewritten++; } } catch (IOException e) { - listener.error("Failed to rewrite " + child).print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error("Failed to rewrite " + child)); } } if (child.isDirectory()) { diff --git a/core/src/main/java/jenkins/management/AsynchronousAdministrativeMonitor.java b/core/src/main/java/jenkins/management/AsynchronousAdministrativeMonitor.java index 47a682cd98..4e621ab53b 100644 --- a/core/src/main/java/jenkins/management/AsynchronousAdministrativeMonitor.java +++ b/core/src/main/java/jenkins/management/AsynchronousAdministrativeMonitor.java @@ -126,7 +126,7 @@ public abstract class AsynchronousAdministrativeMonitor extends AdministrativeMo } catch (AbortException e) { listener.error(e.getMessage()); } catch (Throwable e) { - listener.error(getName() + " failed").print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error(getName() + " failed")); LOGGER.log(Level.WARNING, getName() + " failed", e); } } diff --git a/core/src/main/java/jenkins/security/RekeySecretAdminMonitor.java b/core/src/main/java/jenkins/security/RekeySecretAdminMonitor.java index c486193c9c..684849b308 100644 --- a/core/src/main/java/jenkins/security/RekeySecretAdminMonitor.java +++ b/core/src/main/java/jenkins/security/RekeySecretAdminMonitor.java @@ -153,7 +153,7 @@ public class RekeySecretAdminMonitor extends AsynchronousAdministrativeMonitor i LOGGER.info("Secret re-keying completed"); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Fatal failure in re-keying secrets",e); - listener.error("Fatal failure in rewriting secrets").print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error("Fatal failure in rewriting secrets")); } } diff --git a/core/src/main/java/jenkins/slaves/DefaultJnlpSlaveReceiver.java b/core/src/main/java/jenkins/slaves/DefaultJnlpSlaveReceiver.java index 3b7cdd2ba0..686ed005e3 100644 --- a/core/src/main/java/jenkins/slaves/DefaultJnlpSlaveReceiver.java +++ b/core/src/main/java/jenkins/slaves/DefaultJnlpSlaveReceiver.java @@ -172,7 +172,7 @@ public class DefaultJnlpSlaveReceiver extends JnlpAgentReceiver { computer.setChannel(event.getChannel(), state.getLog(), null); } catch (IOException | InterruptedException e) { PrintWriter logw = new PrintWriter(state.getLog(), true); - logw.print(Functions.printThrowable(e)); + Functions.printStackTrace(e, logw); IOUtils.closeQuietly(event.getChannel()); } } diff --git a/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java b/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java index d271a37913..1eb68dcc6f 100644 --- a/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java +++ b/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java @@ -94,7 +94,7 @@ public class JnlpSlaveRestarterInstaller extends ComputerListener implements Ser LOGGER.log(FINE, "Effective SlaveRestarter on {0}: {1}", new Object[] {c.getName(), effective}); } catch (Throwable e) { - listener.error("Failed to install restarter").print(Functions.printThrowable(e)); + Functions.printStackTrace(e, listener.error("Failed to install restarter")); } } diff --git a/core/src/main/resources/META-INF/upgrade/Functions.hint b/core/src/main/resources/META-INF/upgrade/Functions.hint index c2316aef02..149d172c4b 100644 --- a/core/src/main/resources/META-INF/upgrade/Functions.hint +++ b/core/src/main/resources/META-INF/upgrade/Functions.hint @@ -1,2 +1,2 @@ -$t.printStackTrace($s) :: $s instance java.io.PrintStream && $t instanceof Throwable => $s.print(hudson.Functions.printThrowable($t));; -$t.printStackTrace($s) :: $s instance java.io.PrintWriter && $t instanceof Throwable => $s.print(hudson.Functions.printThrowable($t));; +$t.printStackTrace($s) :: $s instance java.io.PrintStream && $t instanceof Throwable => hudson.Functions.printStackTrace($t, $s);; +$t.printStackTrace($s) :: $s instance java.io.PrintWriter && $t instanceof Throwable => hudson.Functions.printStackTrace($t, $s);;