Details
-
Bug
-
Status: Resolved
-
Minor
-
Resolution: Duplicate
-
None
-
None
-
None
Description
A user uncovered a NullPointerException in the ExtractEmailHeaders processor and asked about it on StackOverflow.
Here is the summary: If the TO, CC, and BCC are not present in the email message, a call to javax.mail.internet.MimeMessage getAllRecipients() will return null.
While this is a rare case, the reporter has a use case in which an email account is sending automated emails to the same address as the source, and whatever email program is being used appears to not set any address fields in this case:
It is an auto email from client to their own inbox and does not have "to", "cc"and "bcc"
The javax.mail.Message getAllRecipients() method, which is called from javax.mail.internet.MimeMessage getAllRecipients(), will return null in this case, as is documented and apparent from the source code:
/** * Get all the recipient addresses for the message. * The default implementation extracts the TO, CC, and BCC * recipients using the <code>getRecipients</code> method. <p> * * This method returns <code>null</code> if none of the recipient * headers are present in this message. It may Return an empty array * if any recipient header is present, but contains no addresses. * * @return array of Address objects * @exception MessagingException */ public Address[] getAllRecipients() throws MessagingException { Address[] to = getRecipients(RecipientType.TO); Address[] cc = getRecipients(RecipientType.CC); Address[] bcc = getRecipients(RecipientType.BCC); if (cc == null && bcc == null) return to; // a common case // ...
Here is a stack trace for the NPE:
2017-08-30 16:36:05,930 ERROR [Timer-Driven Process Thread-8] o.a.n.p.email.ExtractEmailHeaders ExtractEmailHeaders [...] Could not parse the flowfile StandardFlowFileRecord [...] as an email, treating as failure: java.lang.NullPointerException: null at java.lang.reflect.Array.getLength(Native Method) at org.apache.nifi.processors.email.ExtractEmailHeaders$1.process(ExtractEmailHeaders.java:171) at org.apache.nifi.controller.repository.StandardProcessSession.read(StandardProcessSession.java:2177) at org.apache.nifi.controller.repository.StandardProcessSession.read(StandardProcessSession.java:2147) at org.apache.nifi.processors.email.ExtractEmailHeaders.onTrigger(ExtractEmailHeaders.java:146) at org.apache.nifi.processor.AbstractProcessor.onTrigger(AbstractProcessor.java:27) at org.apache.nifi.controller.StandardProcessorNode.onTrigger(StandardProcessorNode.java:1118) at org.apache.nifi.controller.tasks.ContinuallyRunProcessorTask.call(ContinuallyRunProcessorTask.java:147) at org.apache.nifi.controller.tasks.ContinuallyRunProcessorTask.call(ContinuallyRunProcessorTask.java:47) at org.apache.nifi.controller.scheduling.TimerDrivenSchedulingAgent$1.run(TimerDrivenSchedulingAgent.java:132) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
The NPE occurs as ExtractEmailHeaders:L171:
if (Array.getLength(originalMessage.getAllRecipients()) > 0) {
Array.getLength(Array array) expects a non-null argument, but originalMessage.getAllRecipients() is returning null.
One proposed solution is to check if originalMessage.getAllRecipients() is null, and if so, treat it as an empty array. That is, the condition would be:
Address[] allRecipients = originalMessage.getAllRecipients(); if (allRecipients != null && Array.getLength(allRecipients) > 0) {
A test case for ExtractEmailHeaders that reproduces this NPE should also be added.