Skip to content
Browse files

[JENKINS-42861] - Properly deprecate the HudsonExceptionNote implemen…

…tation (#2811)

* [JENKINS-42861] - Properly deprecate the HudsonExceptionNote implementation

It is a replacement of the original fix in #2808.

The implementation provides deprecates the annotation of the new stacktraces, but it retains the binary and the persisted data compatibility, which were missing in the original PR.
In the longer-term the hyperlinks should be replaced by the best possible equivalent (JIRA search, grepcode or whatever).

* [JENKINS-42861] - Cleanup the deprecated functionality

(cherry picked from commit 77a9f02)
  • Loading branch information
oleg-nenashev authored and olivergondza committed May 2, 2017
1 parent ce7d2ae commit e91a82d27c67b194113fba6ac805cd4d6193cbfb
@@ -30,6 +30,8 @@
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

* Annotates one line of console output.
@@ -71,15 +73,16 @@
* Annotates one line.
* @param context
* The object that owns the console output. Never null.
* The object that owns the console output. Never {@code null}.
* @param text
* Contains a single line of console output, and defines convenient methods to add markup.
* The callee should put markup into this object. Never null.
* The callee should put markup into this object. Never {@code null}.
* @return
* The {@link ConsoleAnnotator} object that will annotate the next line of the console output.
* To indicate that you are not interested in the following lines, return null.
* To indicate that you are not interested in the following lines, return {@code null}.
public abstract ConsoleAnnotator annotate(T context, MarkupText text );
public abstract ConsoleAnnotator annotate(@Nonnull T context, @Nonnull MarkupText text );

* Cast operation that restricts T.
@@ -1,7 +1,7 @@
* The MIT License
* Copyright (c) 2010-2011, CloudBees, Inc.
* Copyright (c) 2010-2017, CloudBees, Inc.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -27,73 +27,31 @@
import hudson.MarkupText;
import org.jenkinsci.Symbol;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

// TODO: the implementation has been deprecated due to JENKINS-42861
// Consider providing alternate search mechanisms (JIRA, grepcode, etc.) as proposed in
// (JENKINS-43612)
* Placed on the beginning of the exception stack trace produced by Hudson, which in turn produces hyperlinked stack trace.
* Placed on the beginning of the exception stack trace produced by Jenkins,
* which in turn produces hyperlinked stack trace.
* <p>
* Exceptions in the user code (like junit etc) should be handled differently. This is only for exceptions
* that occur inside Hudson.
* that occur inside Jenkins.
* @author Kohsuke Kawaguchi
* @since 1.349
* @since 1.349 - produces search hyperlinks to the service
* @since TODO - does nothing due to JENKINS-42861
* @deprecated This ConsoleNote used to provide hyperlinks to the
* <code></code> service, which is dead now (JENKINS-42861).
* This console note does nothing right now.
public class HudsonExceptionNote extends ConsoleNote<Object> {

public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) {
// An exception stack trace looks like this:
// org.acme.FooBarException: message
// <TAB>at org.acme.Foo.method(
// Caused by: java.lang.ClassNotFoundException:
String line = text.getText();
int end = line.indexOf(':',charPos);
if (end<0) {
if (CLASSNAME.matcher(line.substring(charPos)).matches())
end = line.length();
return null; // unexpected format. abort.

return new ConsoleAnnotator() {
public ConsoleAnnotator annotate(Object context, MarkupText text) {
String line = text.getText();

Matcher m = STACK_TRACE_ELEMENT.matcher(line);
if (m.find()) {// allow the match to happen in the middle of a line to cope with prefix. Ant and Maven put them, among many other tools.
return this;

int idx = line.indexOf(CAUSED_BY);
if (idx>=0) {
int s = idx + CAUSED_BY.length();
int e = line.indexOf(':', s);
if (e<0) e = line.length();
return this;

if (AND_MORE.matcher(line).matches())
return this;

// looks like we are done with the stack trace
return null;

// TODO; separate out the annotations and mark up

private String annotateMethodName(String className, String methodName, String sourceFileName, int lineNumber) {
return ""+className+'.'+methodName+"&entity=method";

private String annotateClassName(String className) {
return ""+className;
return null;

@Extension @Symbol("stackTrace")
@@ -103,21 +61,4 @@ public String getDisplayName() {
return "Exception Stack Trace";

* Regular expression that represents a valid class name.
private static final String CLASSNAME_PATTERN = "[\\p{L}0-9$_.]+";

private static final Pattern CLASSNAME = Pattern.compile(CLASSNAME_PATTERN+"\r?\n?");

* Matches to the line like "\tat org.acme.Foo.method("
* and captures class name, method name, source file name, and line number separately.
private static final Pattern STACK_TRACE_ELEMENT = Pattern.compile("\tat ("+CLASSNAME_PATTERN+")\\.([\\p{L}0-9$_<>]+)\\((\\S+):([0-9]+)\\)");

private static final String CAUSED_BY = "Caused by: ";

private static final Pattern AND_MORE = Pattern.compile("\t... [0-9]+ more\n");
@@ -142,7 +142,7 @@ private PrintWriter _error(String prefix, String msg) {

// the idiom in Hudson is to use the returned writer for writing stack trace,
// the idiom in Jenkins is to use the returned writer for writing stack trace,
// so put the marker here to indicate an exception. if the stack trace isn't actually written,
// HudsonExceptionNote.annotate recovers gracefully.
try {

0 comments on commit e91a82d

Please sign in to comment.
You can’t perform that action at this time.