Skip to content

Commit 007e9ef

Browse files
committed
unexpected npe fixes for findbugs
1 parent 73fccae commit 007e9ef

File tree

11 files changed

+76
-47
lines changed

11 files changed

+76
-47
lines changed

src/main/java/com/cloudbees/jenkins/GitHubPushCause.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package com.cloudbees.jenkins;
22

33
import hudson.triggers.SCMTrigger.SCMTriggerCause;
4+
45
import java.io.File;
56
import java.io.IOException;
67

8+
import static java.lang.String.format;
9+
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
10+
711
/**
812
* UI object that says a build is started by GitHub post-commit hook.
913
*
@@ -31,7 +35,7 @@ public GitHubPushCause(File pollingLog, String pusher) throws IOException {
3135

3236
@Override
3337
public String getShortDescription() {
34-
String pusher = pushedBy != null ? pushedBy : "";
35-
return "Started by GitHub push by " + pusher;
38+
return format("Started by GitHub push by %s", trimToEmpty(pushedBy));
3639
}
3740
}
41+

src/main/java/com/cloudbees/jenkins/GitHubRepositoryNameContributor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ protected EnvVars buildEnv(AbstractProject<?, ?> job) {
5656
try {
5757
contributor.buildEnvironmentFor(job, env, TaskListener.NULL);
5858
} catch (Exception e) {
59-
LOGGER.debug("{} failed to build environment ({})", contributor.getClass(), e.getMessage());
59+
LOGGER.debug("{} failed to build env ({}), skipping", contributor.getClass(), e.getMessage(), e);
6060
}
6161
}
6262
return env;

src/main/java/org/jenkinsci/plugins/github/config/GitHubPluginConfig.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.Collections;
3333
import java.util.List;
3434

35+
import static com.google.common.base.Charsets.UTF_8;
3536
import static java.lang.String.format;
3637
import static org.jenkinsci.plugins.github.config.GitHubServerConfig.allowedToManageHooks;
3738
import static org.jenkinsci.plugins.github.config.GitHubServerConfig.loginToGithub;
@@ -195,7 +196,7 @@ public FormValidation doCheckHookUrl(@QueryParameter String value) {
195196
+ "Are you running your own app?", value);
196197
}
197198
RSAPublicKey key = identity.getPublic();
198-
String expected = new String(Base64.encodeBase64(key.getEncoded()));
199+
String expected = new String(Base64.encodeBase64(key.getEncoded()), UTF_8);
199200
if (!expected.equals(v)) {
200201
// if it responds but with a different ID, that's more likely wrong than correct
201202
return FormValidation.error("%s is connecting to different Jenkins instances", value);

src/main/java/org/jenkinsci/plugins/github/config/GitHubTokenCredentialsCreator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.cloudbees.plugins.credentials.domains.DomainSpecification;
1010
import com.cloudbees.plugins.credentials.domains.HostnameSpecification;
1111
import com.cloudbees.plugins.credentials.domains.SchemeSpecification;
12+
import com.google.common.collect.ImmutableList;
1213
import hudson.Extension;
1314
import hudson.model.Describable;
1415
import hudson.model.Descriptor;
@@ -67,7 +68,7 @@ public class GitHubTokenCredentialsCreator extends Descriptor<GitHubTokenCredent
6768
* - repo - to see private repos
6869
* - repo:status - to manipulate commit statuses
6970
*/
70-
public static final List<String> GH_PLUGIN_REQUIRED_SCOPE = asList(
71+
public static final List<String> GH_PLUGIN_REQUIRED_SCOPE = ImmutableList.of(
7172
AMIN_HOOK,
7273
REPO,
7374
REPO_STATUS

src/main/java/org/jenkinsci/plugins/github/extension/GHEventsSubscriber.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@
66
import hudson.ExtensionPoint;
77
import hudson.model.AbstractProject;
88
import jenkins.model.Jenkins;
9+
import org.jenkinsci.plugins.github.util.misc.NullSafeFunction;
10+
import org.jenkinsci.plugins.github.util.misc.NullSafePredicate;
911
import org.kohsuke.github.GHEvent;
1012
import org.slf4j.Logger;
1113
import org.slf4j.LoggerFactory;
1214

15+
import javax.annotation.Nonnull;
16+
import javax.annotation.Nullable;
1317
import java.util.Collections;
1418
import java.util.Set;
1519

@@ -37,7 +41,7 @@ public abstract class GHEventsSubscriber implements ExtensionPoint {
3741
*
3842
* @return true to provide events to register and subscribe for this project
3943
*/
40-
protected abstract boolean isApplicable(AbstractProject<?, ?> project);
44+
protected abstract boolean isApplicable(@Nullable AbstractProject<?, ?> project);
4145

4246
/**
4347
* Should be not null. Should return only events which this extension can parse in {@link #onEvent(GHEvent, String)}
@@ -73,9 +77,9 @@ public static ExtensionList<GHEventsSubscriber> all() {
7377
* @return converter to use in iterable manipulations
7478
*/
7579
public static Function<GHEventsSubscriber, Set<GHEvent>> extractEvents() {
76-
return new Function<GHEventsSubscriber, Set<GHEvent>>() {
80+
return new NullSafeFunction<GHEventsSubscriber, Set<GHEvent>>() {
7781
@Override
78-
public Set<GHEvent> apply(GHEventsSubscriber subscriber) {
82+
protected Set<GHEvent> applyNullSafe(@Nonnull GHEventsSubscriber subscriber) {
7983
return defaultIfNull(subscriber.events(), Collections.<GHEvent>emptySet());
8084
}
8185
};
@@ -89,9 +93,9 @@ public Set<GHEvent> apply(GHEventsSubscriber subscriber) {
8993
* @return predicate to use in iterable filtering
9094
*/
9195
public static Predicate<GHEventsSubscriber> isApplicableFor(final AbstractProject<?, ?> project) {
92-
return new Predicate<GHEventsSubscriber>() {
96+
return new NullSafePredicate<GHEventsSubscriber>() {
9397
@Override
94-
public boolean apply(GHEventsSubscriber subscriber) {
98+
protected boolean applyNullSafe(@Nonnull GHEventsSubscriber subscriber) {
9599
return subscriber.isApplicable(project);
96100
}
97101
};
@@ -105,9 +109,9 @@ public boolean apply(GHEventsSubscriber subscriber) {
105109
* @return predicate to match against {@link GHEventsSubscriber}
106110
*/
107111
public static Predicate<GHEventsSubscriber> isInterestedIn(final GHEvent event) {
108-
return new Predicate<GHEventsSubscriber>() {
112+
return new NullSafePredicate<GHEventsSubscriber>() {
109113
@Override
110-
public boolean apply(GHEventsSubscriber subscriber) {
114+
protected boolean applyNullSafe(@Nonnull GHEventsSubscriber subscriber) {
111115
return defaultIfNull(subscriber.events(), emptySet()).contains(event);
112116
}
113117
};
@@ -122,9 +126,9 @@ public boolean apply(GHEventsSubscriber subscriber) {
122126
* @return function to process {@link GHEventsSubscriber} list. Returns null on apply.
123127
*/
124128
public static Function<GHEventsSubscriber, Void> processEvent(final GHEvent event, final String payload) {
125-
return new Function<GHEventsSubscriber, Void>() {
129+
return new NullSafeFunction<GHEventsSubscriber, Void>() {
126130
@Override
127-
public Void apply(GHEventsSubscriber subscriber) {
131+
protected Void applyNullSafe(@Nonnull GHEventsSubscriber subscriber) {
128132
try {
129133
subscriber.onEvent(event, payload);
130134
} catch (Throwable t) {

src/main/java/org/jenkinsci/plugins/github/util/JobInfoHelpers.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ private JobInfoHelpers() {
3434
public static Predicate<AbstractProject> withTrigger(final Class<? extends Trigger> clazz) {
3535
return new Predicate<AbstractProject>() {
3636
public boolean apply(AbstractProject job) {
37-
return job.getTrigger(clazz) != null;
37+
return job != null && job.getTrigger(clazz) != null;
3838
}
3939
};
4040
}
@@ -47,7 +47,7 @@ public boolean apply(AbstractProject job) {
4747
public static Predicate<Job> isBuildable() {
4848
return new Predicate<Job>() {
4949
public boolean apply(Job job) {
50-
return job.isBuildable();
50+
return job != null && job.isBuildable();
5151
}
5252
};
5353
}

src/main/java/org/jenkinsci/plugins/github/util/misc/NullSafeFunction.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package org.jenkinsci.plugins.github.util.misc;
22

33
import com.google.common.base.Function;
4-
import com.google.common.base.Preconditions;
54

65
import javax.annotation.Nonnull;
7-
import javax.annotation.Nullable;
6+
7+
import static com.google.common.base.Preconditions.checkNotNull;
88

99
/**
1010
* This abstract class calls {@link #applyNullSafe(Object)} only after success validation of inner object for null
@@ -14,8 +14,8 @@
1414
public abstract class NullSafeFunction<F, T> implements Function<F, T> {
1515

1616
@Override
17-
public T apply(@Nullable F input) {
18-
return applyNullSafe(Preconditions.checkNotNull(input, "This function not allows to use null as argument"));
17+
public T apply(F input) {
18+
return applyNullSafe(checkNotNull(input, "This function not allows to use null as argument"));
1919
}
2020

2121
/**

src/main/java/org/jenkinsci/plugins/github/webhook/GHEventPayload.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
import com.google.common.base.Function;
66
import com.google.common.collect.ImmutableMap;
77
import org.apache.commons.io.IOUtils;
8+
import org.jenkinsci.plugins.github.util.misc.NullSafeFunction;
89
import org.kohsuke.stapler.AnnotationHandler;
910
import org.kohsuke.stapler.InjectedParameter;
1011
import org.kohsuke.stapler.StaplerRequest;
1112
import org.slf4j.Logger;
1213

14+
import javax.annotation.Nonnull;
1315
import javax.servlet.ServletException;
1416
import java.io.IOException;
1517
import java.lang.annotation.Documented;
@@ -19,6 +21,7 @@
1921

2022
import static java.lang.annotation.ElementType.PARAMETER;
2123
import static java.lang.annotation.RetentionPolicy.RUNTIME;
24+
import static org.apache.commons.lang3.Validate.notNull;
2225
import static org.slf4j.LoggerFactory.getLogger;
2326

2427
/**
@@ -54,7 +57,7 @@ class PayloadHandler extends AnnotationHandler<GHEventPayload> {
5457
*/
5558
@Override
5659
public Object parse(StaplerRequest req, GHEventPayload a, Class type, String param) throws ServletException {
57-
if (req.getHeader(GitHubWebHook.URL_VALIDATION_HEADER) != null) {
60+
if (notNull(req, "Why StaplerRequest is null?").getHeader(GitHubWebHook.URL_VALIDATION_HEADER) != null) {
5861
// if self test for custom hook url
5962
return null;
6063
}
@@ -78,9 +81,9 @@ public Object parse(StaplerRequest req, GHEventPayload a, Class type, String par
7881
* @return function to extract payload from form request parameters
7982
*/
8083
protected static Function<StaplerRequest, String> fromForm() {
81-
return new Function<StaplerRequest, String>() {
84+
return new NullSafeFunction<StaplerRequest, String>() {
8285
@Override
83-
public String apply(StaplerRequest request) {
86+
protected String applyNullSafe(@Nonnull StaplerRequest request) {
8487
return request.getParameter("payload");
8588
}
8689
};
@@ -92,9 +95,9 @@ public String apply(StaplerRequest request) {
9295
* @return function to extract payload from body
9396
*/
9497
protected static Function<StaplerRequest, String> fromApplicationJson() {
95-
return new Function<StaplerRequest, String>() {
98+
return new NullSafeFunction<StaplerRequest, String>() {
9699
@Override
97-
public String apply(StaplerRequest request) {
100+
protected String applyNullSafe(@Nonnull StaplerRequest request) {
98101
try {
99102
return IOUtils.toString(request.getInputStream(), Charsets.UTF_8);
100103
} catch (IOException e) {

src/main/java/org/jenkinsci/plugins/github/webhook/RequirePostWithGHHookPayload.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import java.security.interfaces.RSAPublicKey;
2121
import java.util.logging.Logger;
2222

23+
import static com.cloudbees.jenkins.GitHubWebHook.X_INSTANCE_IDENTITY;
24+
import static com.google.common.base.Charsets.UTF_8;
2325
import static com.google.common.base.Predicates.instanceOf;
2426
import static com.google.common.collect.Lists.newArrayList;
2527
import static java.lang.annotation.ElementType.FIELD;
@@ -84,7 +86,7 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod
8486
throws IOException, ServletException {
8587
RSAPublicKey key = new InstanceIdentity().getPublic();
8688
rsp.setStatus(HttpServletResponse.SC_OK);
87-
rsp.setHeader(GitHubWebHook.X_INSTANCE_IDENTITY, new String(encodeBase64(key.getEncoded())));
89+
rsp.setHeader(X_INSTANCE_IDENTITY, new String(encodeBase64(key.getEncoded()), UTF_8));
8890
}
8991
});
9092
}

src/main/java/org/jenkinsci/plugins/github/webhook/WebhookManager.java

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
import hudson.model.AbstractProject;
77
import org.apache.commons.lang.Validate;
88
import org.jenkinsci.plugins.github.extension.GHEventsSubscriber;
9+
import org.jenkinsci.plugins.github.util.misc.NullSafeFunction;
10+
import org.jenkinsci.plugins.github.util.misc.NullSafePredicate;
911
import org.kohsuke.github.GHEvent;
1012
import org.kohsuke.github.GHException;
1113
import org.kohsuke.github.GHHook;
1214
import org.kohsuke.github.GHRepository;
1315
import org.slf4j.Logger;
1416
import org.slf4j.LoggerFactory;
1517

18+
import javax.annotation.Nonnull;
1619
import java.io.IOException;
1720
import java.net.URL;
1821
import java.util.Collection;
@@ -135,9 +138,9 @@ public void unregisterFor(GitHubRepositoryName name, List<GitHubRepositoryName>
135138
* @return function to register hooks for given events
136139
*/
137140
protected Function<GitHubRepositoryName, GHHook> createHookSubscribedTo(final List<GHEvent> events) {
138-
return new Function<GitHubRepositoryName, GHHook>() {
141+
return new NullSafeFunction<GitHubRepositoryName, GHHook>() {
139142
@Override
140-
public GHHook apply(GitHubRepositoryName name) {
143+
protected GHHook applyNullSafe(@Nonnull GitHubRepositoryName name) {
141144
try {
142145
GHRepository repo = checkNotNull(
143146
from(name.resolve(allowedToManageHooks())).firstMatch(withAdminAccess()).orNull(),
@@ -181,9 +184,9 @@ public GHHook apply(GitHubRepositoryName name) {
181184
* @return always true predicate
182185
*/
183186
private Predicate<GHHook> log(final String format) {
184-
return new Predicate<GHHook>() {
187+
return new NullSafePredicate<GHHook>() {
185188
@Override
186-
public boolean apply(GHHook input) {
189+
protected boolean applyNullSafe(@Nonnull GHHook input) {
187190
LOGGER.debug(format("%s {} (events: {})", format), input.getUrl(), input.getEvents());
188191
return true;
189192
}
@@ -196,9 +199,9 @@ public boolean apply(GHHook input) {
196199
* @return true if we have admin rights for repo
197200
*/
198201
protected Predicate<GHRepository> withAdminAccess() {
199-
return new Predicate<GHRepository>() {
202+
return new NullSafePredicate<GHRepository>() {
200203
@Override
201-
public boolean apply(GHRepository repo) {
204+
protected boolean applyNullSafe(@Nonnull GHRepository repo) {
202205
return repo.hasAdminAccess();
203206
}
204207
};
@@ -212,8 +215,8 @@ public boolean apply(GHRepository repo) {
212215
* @return true if hook is service hook
213216
*/
214217
protected Predicate<GHHook> serviceWebhookFor(final URL url) {
215-
return new Predicate<GHHook>() {
216-
public boolean apply(GHHook hook) {
218+
return new NullSafePredicate<GHHook>() {
219+
protected boolean applyNullSafe(@Nonnull GHHook hook) {
217220
return hook.getName().equals("jenkins")
218221
&& hook.getConfig().get("jenkins_hook_url").equals(url.toExternalForm());
219222
}
@@ -228,8 +231,8 @@ public boolean apply(GHHook hook) {
228231
* @return true if hook is standard webhook
229232
*/
230233
protected Predicate<GHHook> webhookFor(final URL url) {
231-
return new Predicate<GHHook>() {
232-
public boolean apply(GHHook hook) {
234+
return new NullSafePredicate<GHHook>() {
235+
protected boolean applyNullSafe(@Nonnull GHHook hook) {
233236
return hook.getName().equals("web")
234237
&& hook.getConfig().get("url").equals(url.toExternalForm());
235238
}
@@ -240,9 +243,9 @@ public boolean apply(GHHook hook) {
240243
* @return converter to extract events from each hook
241244
*/
242245
protected Function<GHHook, Iterable<GHEvent>> eventsFromHook() {
243-
return new Function<GHHook, Iterable<GHEvent>>() {
246+
return new NullSafeFunction<GHHook, Iterable<GHEvent>>() {
244247
@Override
245-
public Iterable<GHEvent> apply(GHHook input) {
248+
protected Iterable<GHEvent> applyNullSafe(@Nonnull GHHook input) {
246249
return input.getEvents();
247250
}
248251
};
@@ -256,9 +259,9 @@ public Iterable<GHEvent> apply(GHHook input) {
256259
* @return converter to fetch from GH hooks list for each repo
257260
*/
258261
protected Function<GHRepository, List<GHHook>> fetchHooks() {
259-
return new Function<GHRepository, List<GHHook>>() {
262+
return new NullSafeFunction<GHRepository, List<GHHook>>() {
260263
@Override
261-
public List<GHHook> apply(GHRepository repo) {
264+
protected List<GHHook> applyNullSafe(@Nonnull GHRepository repo) {
262265
try {
263266
return repo.getHooks();
264267
} catch (IOException e) {
@@ -275,8 +278,8 @@ public List<GHHook> apply(GHRepository repo) {
275278
* @return converter to create GH hook for given url with given events
276279
*/
277280
protected Function<GHRepository, GHHook> createWebhook(final URL url, final Set<GHEvent> events) {
278-
return new Function<GHRepository, GHHook>() {
279-
public GHHook apply(GHRepository repo) {
281+
return new NullSafeFunction<GHRepository, GHHook>() {
282+
protected GHHook applyNullSafe(@Nonnull GHRepository repo) {
280283
try {
281284
return repo.createWebHook(url, events);
282285
} catch (IOException e) {
@@ -290,8 +293,8 @@ public GHHook apply(GHRepository repo) {
290293
* @return annihilator for hook, returns true if deletion was successful
291294
*/
292295
protected Predicate<GHHook> deleteWebhook() {
293-
return new Predicate<GHHook>() {
294-
public boolean apply(GHHook hook) {
296+
return new NullSafePredicate<GHHook>() {
297+
protected boolean applyNullSafe(@Nonnull GHHook hook) {
295298
try {
296299
hook.delete();
297300
return true;

0 commit comments

Comments
 (0)