Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FIXED JENKINS-40545] Diagnose NPE in DescriptorVisibilityFilter.apply
Before:
Jun 15, 2017 8:29:06 AM hudson.ExpressionFactory2$JexlExpression evaluate
WARNING: Caught exception evaluating: h.filterDescriptors(it, no_descriptors_here).size() in /jenkins/jenkins40545/. Reason: java.lang.NullPointerException
java.lang.NullPointerException
	at hudson.model.DescriptorVisibilityFilter.apply(DescriptorVisibilityFilter.java:72)
	at hudson.Functions.filterDescriptors(Functions.java:1863)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.commons.jexl.util.introspection.UberspectImpl$VelMethodImpl.invoke(UberspectImpl.java:258)
	...

After:
Jun 15, 2017 12:10:43 PM hudson.ExpressionFactory2$JexlExpression evaluate
WARNING: Caught exception evaluating: h.filterDescriptors(it, no_descriptors_here).size() in /jenkins/jenkins40545/. Reason: java.lang.NullPointerException: Descriptor list is null for context 'class hudson.model.DescriptorVisibilityFilterTest$Jenkins40545' in thread 'Handling GET /jenkins/jenkins40545/ from 127.0.0.1 : Jetty Thread Pool DescriptorVisibilityFilterTest/Jenkins40545/index.jelly'
java.lang.NullPointerException: Descriptor list is null for context 'class hudson.model.DescriptorVisibilityFilterTest$Jenkins40545' in thread 'Handling GET /jenkins/jenkins40545/ from 127.0.0.1 : Jetty Thread Pool DescriptorVisibilityFilterTest/Jenkins40545/index.jelly'
	at hudson.model.DescriptorVisibilityFilter.apply(DescriptorVisibilityFilter.java:73)
	at hudson.Functions.filterDescriptors(Functions.java:1863)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.commons.jexl.util.introspection.UberspectImpl$VelMethodImpl.invoke(UberspectImpl.java:258)
	...
  • Loading branch information
olivergondza committed Jun 15, 2017
1 parent 0b12bd3 commit 1167430
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
Expand Up @@ -68,6 +68,11 @@ public static <T extends Descriptor> List<T> apply(Object context, Iterable<T> s
List<T> r = new ArrayList<T>();
Class<?> contextClass = context == null ? null : context.getClass();

if (source == null) {
// JENKINS-40545: throwing instead of logging so jelly can amend the actual jelly expression that failed.
throw new NullPointerException("Descriptor list is null for context '" + contextClass + "' in thread '" + Thread.currentThread().getName() + "'");
}

OUTER:
for (T d : source) {
if (LOGGER.isLoggable(Level.FINE)) {
Expand Down
@@ -0,0 +1,61 @@
package hudson.model;

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.emptyIterable;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.allOf;
import static org.junit.Assert.*;

import com.gargoylesoftware.htmlunit.html.HtmlPage;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.LoggerRule;
import org.jvnet.hudson.test.TestExtension;

import java.util.logging.Level;
import java.util.logging.LogRecord;

public class DescriptorVisibilityFilterTest {

@Rule public JenkinsRule j = new JenkinsRule();

@Rule public LoggerRule logger = new LoggerRule();

@Test @Issue("JENKINS-40545")
public void jenkins40545() throws Exception {
logger.record("hudson.ExpressionFactory2$JexlExpression", Level.WARNING);
logger.record("hudson.model.DescriptorVisibilityFilter", Level.WARNING);
logger.capture(10);
HtmlPage page = j.createWebClient().goTo("jenkins40545");
assertThat(logger.getRecords(), not(emptyIterable()));
for (LogRecord record : logger.getRecords()) {
String message = record.getMessage();
assertThat(message, allOf(
containsString("Descriptor list is null for context 'class hudson.model.DescriptorVisibilityFilterTest$Jenkins40545'"),
containsString("DescriptorVisibilityFilterTest/Jenkins40545/index.jelly"),
not(endsWith("NullPointerException"))
));
}

assertThat(page.getWebResponse().getContentAsString(), containsString("descriptors found: .")); // No output written from expression
}

@TestExtension("jenkins40545")
public static final class Jenkins40545 implements UnprotectedRootAction {

@Override public String getIconFileName() {
return "notepad.png";
}

@Override public String getDisplayName() {
return "jenkins40545";
}

@Override public String getUrlName() {
return "jenkins40545";
}
}
}
@@ -0,0 +1,6 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:l="/lib/layout">
<l:layout norefresh="true">
descriptors found: ${h.filterDescriptors(it, no_descriptors_here).size()}.
</l:layout>
</j:jelly>

0 comments on commit 1167430

Please sign in to comment.