jenkinsci / slack-plugin

A Jenkins plugin for posting notifications to a Slack channel
https://plugins.jenkins.io/slack/
MIT License
670 stars 413 forks source link

NullPointerException when trying to send slack with notifyCommitters: true #665

Open liejuntao001 opened 4 years ago

liejuntao001 commented 4 years ago

Description

Send slack message like this: slackSend (color: '#FF0000', channel: channel, message: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})", notifyCommitters: true)

It failed "sometimes" with error stack below, if the changes in the build are from committer A. But it does work if the changes are from committer B.

We use LDAP accounts. I don't see difference between account A and B. The email in change/ email in LDAP/ email in slack are consistent.

I don't have a clue now...

 Slack Send Pipeline step running, values are - baseUrl: <empty>, teamDomain:  xxxx, channel: xxxx , color: #FF0000, botUser: true, tokenCredentialId: xxxxx, notifyCommitters: true, iconEmoji: <empty>, username: botuser
 [Pipeline] }
 [Pipeline] // node
 [Pipeline] }
 [Pipeline] // podTemplate
 [Pipeline] End of Pipeline
 java.lang.NullPointerException
    at hudson.ExtensionList.ensureLoaded(ExtensionList.java:312)
    at hudson.ExtensionList.iterator(ExtensionList.java:172)
    at java.util.Spliterators$IteratorSpliterator.estimateSize(Spliterators.java:1821)
    at java.util.Spliterator.getExactSizeIfKnown(Spliterator.java:408)
    at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:486)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
    at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.findAny(ReferencePipeline.java:469)
    at jenkins.plugins.slack.user.EmailSlackUserIdResolver.resolveUserId(EmailSlackUserIdResolver.java:100)
    at jenkins.plugins.slack.user.SlackUserIdResolver.findOrResolveUserId(SlackUserIdResolver.java:65)
    at jenkins.plugins.slack.user.SlackUserIdResolver.lambda$resolveUserIdsForChangeLogSet$0(SlackUserIdResolver.java:95)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at jenkins.plugins.slack.user.SlackUserIdResolver.resolveUserIdsForChangeLogSet(SlackUserIdResolver.java:97)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at jenkins.plugins.slack.user.SlackUserIdResolver.resolveUserIdsForChangeLogSets(SlackUserIdResolver.java:104)
    at jenkins.plugins.slack.user.SlackUserIdResolver.resolveUserIdsForRun(SlackUserIdResolver.java:84)
    at jenkins.plugins.slack.StandardSlackService.publish(StandardSlackService.java:157)
    at jenkins.plugins.slack.StandardSlackService.publish(StandardSlackService.java:294)
    at jenkins.plugins.slack.StandardSlackService.publish(StandardSlackService.java:289)
    at jenkins.plugins.slack.workflow.SlackSendStep$SlackSendStepExecution.run(SlackSendStep.java:342)
    at jenkins.plugins.slack.workflow.SlackSendStep$SlackSendStepExecution.run(SlackSendStep.java:248)
    at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
 Finished: FAILURE
timja commented 4 years ago

Does it fail with the same user consistently?

liejuntao001 commented 4 years ago

So far the NullPointerException happened with the same user 4 times in a row.

I enabled StandardSlackService log after that and today got this log. It's for the same user, but NullPointerException didn't happen this time.

09:51:22 Slack Send Pipeline step running, values are - baseUrl: , teamDomain: xxx, channel: xxx, color: #FF0000, botUser: true, tokenCredentialId: e66b71d7-ac18-4632-9b09-0e10d7ec6d74, notifyCommitters: true, iconEmoji: , username: xxx 09:51:22 ERROR: Slack notification failed with exception: {"ok":false,"error":"not_in_channel"} 09:51:22 ERROR: Slack notification failed. See Jenkins logs for details.

Feb 06, 2020 3:51:22 PM FINE jenkins.plugins.slack.StandardSlackService Posting: to @UCD86HTML on xxxx using https://slack.com/api/chat.postMessage: #FF0000 Feb 06, 2020 3:51:22 PM WARNING jenkins.plugins.slack.StandardSlackService publish Slack post may have failed. Response: {"ok":false,"error":"not_in_channel"}

UCD86HTML is the correct member ID for the user. I could see him in the channel.

jetersen commented 4 years ago

@liejuntao001 the botUser needs to be in the channel to post a message

liejuntao001 commented 4 years ago

The botUser is in the channel, as the botUser could query the member ID of others. The direct slack message was sent successfully for another user. So I believe the configurations/bot oauth scopes are fine.

timja commented 4 years ago

I can't understand how it could be null there, https://github.com/jenkinsci/slack-plugin/blob/master/src/main/java/jenkins/plugins/slack/user/EmailSlackUserIdResolver.java#L100 =/

liejuntao001 commented 4 years ago

@timja The crash line is https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/ExtensionList.java#L312

The NullPointerException continued to happen with more users, but not any more with the original user who had 4 crashes previously.

timja commented 4 years ago

I also don’t understand why a findAny call is going to that code =\

jtnord commented 4 years ago

I have just seen this too. things where working, but "notifyCommitters:true" the default channel still got spammed. so I removed the default channel in the global settings and the next build blew up :-(

jtnord commented 4 years ago

Ahh... the latest change coincided with mush push of the SUT but also someone pushed a change to a shared library... they user that changed the shared library does not exist (if that helps), and even if they did given it was an automation user they would not have a slack userId set in the properties.

timja commented 4 years ago

I guess I'll add more logging I still don't understand how that line could be null

timja commented 4 years ago

This might help @jtnord https://github.com/jenkinsci/slack-plugin/pull/668

jtnord commented 4 years ago

(the user did exist it was a "noreply" user - but it had no slackuser set.

jtnord commented 4 years ago

mailadressResolvers -> [hudson.plugins.jira.JiraMailAddressResolver, hudson.security.LDAPSecurityRealm$MailAdressResolverImpl]

jtnord commented 4 years ago

both MailAddressResolvers are returning null for this user.

jtnord commented 4 years ago

as far as I can tell, either jenkins is null or the init Level is null https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/ExtensionList.java#L312

Jenkins (as known by the ExtensionList should not be null (its up and running...) and given it is up and running it should not have a null initLevel either..... :-/

liejuntao001 commented 4 years ago

I'd like to report this problem happens with 2.38 I added logger for class EmailSlackUserIdResolver SlackUserIdResolver SlackUserIdsFromCommittersStep

Nothing get logged when the NullPointerException happens.

timja commented 4 years ago

I'd like to report this problem happens with 2.38 I added logger for class EmailSlackUserIdResolver SlackUserIdResolver SlackUserIdsFromCommittersStep

Nothing get logged when the NullPointerException happens.

What version of jenkins?

liejuntao001 commented 4 years ago

What version of jenkins?

Jenkins version is 2.176.4

amir-barkal commented 4 years ago

Same issue here. It seems related to the User ID Resolver setting in the global configurations. When the plugin is first initialized / installed, and the setting is set to Slack email User ID Resolver I get this error when invoking jenkins.plugins.slack.user.SlackUserIdResolver#findOrResolveUserId:

("getSlackUserId()" is a custom-homemade pipeline step utilizing the findOrResolveUserId method)

java.lang.NullPointerException
    at hudson.ExtensionList.ensureLoaded(ExtensionList.java:312)
    at hudson.ExtensionList.iterator(ExtensionList.java:172)
    at java.util.Spliterators$IteratorSpliterator.estimateSize(Spliterators.java:1821)
    at java.util.Spliterator.getExactSizeIfKnown(Spliterator.java:408)
    at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:486)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
    at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.findAny(ReferencePipeline.java:536)
    at jenkins.plugins.slack.user.EmailSlackUserIdResolver.resolveUserId(EmailSlackUserIdResolver.java:100)
    at jenkins.plugins.slack.user.SlackUserIdResolver.findOrResolveUserId(SlackUserIdResolver.java:65)
    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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
    at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:47)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
    at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20)
    at getSlackUserId.call(getSlackUserId.groovy:26)

When changing global setting to No User ID Resolver and then back to Slack email User ID Resolver - problem is fixed.

marcusphi commented 4 years ago

I am trying to use slackUserIdsFromCommitters() but it seems reasonable to guess that it's very similar to notifyCommitters.

I can confirm that it seems like switching user id resolver forth and back in Jenkins global Slack config changes behaviour.

I had a very similar same stack trace:

Error when executing success post condition:
java.lang.NullPointerException
    at hudson.ExtensionList.ensureLoaded(ExtensionList.java:312)
    at hudson.ExtensionList.iterator(ExtensionList.java:172)
    at java.util.Spliterators$IteratorSpliterator.estimateSize(Spliterators.java:1821)
    at java.util.Spliterator.getExactSizeIfKnown(Spliterator.java:408)
    at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:497)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.findAny(ReferencePipeline.java:469)
    at jenkins.plugins.slack.user.EmailSlackUserIdResolver.resolveUserId(EmailSlackUserIdResolver.java:101)
    at jenkins.plugins.slack.user.SlackUserIdResolver.findOrResolveUserId(SlackUserIdResolver.java:65)
    at jenkins.plugins.slack.user.SlackUserIdResolver.lambda$resolveUserIdsForChangeLogSet$0(SlackUserIdResolver.java:97)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at jenkins.plugins.slack.user.SlackUserIdResolver.resolveUserIdsForChangeLogSet(SlackUserIdResolver.java:99)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at jenkins.plugins.slack.user.SlackUserIdResolver.resolveUserIdsForChangeLogSets(SlackUserIdResolver.java:106)
    at jenkins.plugins.slack.user.SlackUserIdResolver.resolveUserIdsForRun(SlackUserIdResolver.java:86)
    at jenkins.plugins.slack.pipeline.SlackUserIdsFromCommittersStep$SlackUserIdsFromCommittersStepExcecution.run(SlackUserIdsFromCommittersStep.java:147)
    at jenkins.plugins.slack.pipeline.SlackUserIdsFromCommittersStep$SlackUserIdsFromCommittersStepExcecution.run(SlackUserIdsFromCommittersStep.java:100)
    at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

After forth and back, there is no error anymore.

But I get only an empty list back from slackUserIdsFromCommitters() although I can see in the Jenkins that there were changes linked to a committer. I believe what's missing is the Slack scope users:read.email on my bot user. It is needed by the users.lookupByEmail api call (that I read somewhere is used by plugin). This is however not documented on https://plugins.jenkins.io/slack/. Maybe because in Slack 'classic bot' mode this was included in the bot scope. See https://api.slack.com/methods/users.lookupByEmail.

timja commented 4 years ago

Yes, see https://github.com/jenkinsci/slack-plugin/issues/683

Vinutha-Garimella commented 4 years ago

I tried to use both slackUserIdsFromCommitters() and slackUserIdFromEmail() api's but both api's are returning null, I referred this document to mention a user in a slack channel using Jenkins pipeline https://github.com/jenkinsci/slack-plugin#user-id-look-up I checked #683 my slack bot has all the mentioned permissions

timja commented 4 years ago

that's a different issue please create a new one

jdeniau commented 3 years ago

I had the same issue here. For the record, I had the NullPointerException on ExtensionList.java:312.

Changing the global setting to No User ID Resolver and then back to Slack email User ID Resolver triggered another exception :

java.lang.NullPointerException
    at hudson.plugins.jira.JiraMailAddressResolver.findMailAddressFor(JiraMailAddressResolver.java:35)
    at jenkins.plugins.slack.user.EmailSlackUserIdResolver.lambda$resolveUserId$0(EmailSlackUserIdResolver.java:97)

I manually configured the user slack in Dashboard > Users > user.name > configure > Slack User Settings > user id and it worked.

I know that this is a workaround, and does not fix the email to slack user issue, but it might help.

timja commented 3 years ago

At least the jira specific issue in the last comment should be fixed now if not the other issue see: https://github.com/jenkinsci/slack-plugin/pull/742

If no other reports in a few weeks I'll close this