Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Issue with referencing of MailService | returns NullPointerException

Avatar

Level 1

Hi,

I am facing some issues with the MailService (com.day.cq.mailer.MailService), while sending a simple SMTP HtmlEmail via Java Servlet (OSGI Bundle).

MailService has been referenced and bound as accordingly; however, it throws me with a java.lang.NullPointerException error at the point when I try to get “MailService - mailer.send(email)”.

My codes are as follows:

*******************************************************************************************************

@Component(immediate = true) @Service(EmailService.class) @Properties({ @Property(name = Constants.SERVICE_DESCRIPTION, value = " Send Email Service"), @Property(name = Constants.SERVICE_VENDOR, value = "XXX"), @Property(name = "process.label", value = "Send Email via SMTP; Configurable in Config Manager (Day CQ Mail Service)") }) public class EmailService { @Reference SlingRepository repository; @Reference(cardinality=ReferenceCardinality.OPTIONAL_UNARY, policy=ReferencePolicy.DYNAMIC) private MailService mailer; private Session session; private BundleContext bundleContext; public String sendEmail(String subject, String message, Map<String, String> recipients, String fromName, String fromAddress) { // Declaration HtmlEmail email = new HtmlEmail(); String emailSubject = subject; try { // Set recipients for (Map.Entry entry : recipients.entrySet()) { String key = (String) entry.getKey(); String value = (String) entry.getValue(); if (key.indexOf("@") > -1 && key.indexOf(".") > -1) email.addTo(key, value); else email.addTo(value, key); } // Set email content email.setCharset("UTF-8"); email.setSubject(emailSubject); email.setHtmlMsg(emailMessage); email.setFrom(fromAddress, fromName); this.mailer.send(email); return "success"; } catch (EmailException e) { e.printStackTrace(); LOGGER.error("sendEmail: EmailException", e); } catch (Exception e) { e.printStackTrace(); LOGGER.error("sendEmail: Fatal error while sending email", e); } return "fail"; } protected void activate (ComponentContext context) throws RepositoryException{ session = repository.loginAdministrative(null); this.bundleContext = context.getBundleContext(); } protected void deactivate(ComponentContext context) throws RepositoryException{ this.mailer = null; this.bundleContext = null; if (session != null) { session.logout(); session = null; } } protected void bindMailer(MailService paramMailService){ this.mailer = paramMailService; } protected void unbindMailer(MailService paramMailService){ if(this.mailer == paramMailService) this.mailer = null; } }

*******************************************************************************************************

There is a NullPointerException shown at line 41 - "this.mailer.send(email);" as MailService has not been successfully referenced.

However, it is shown in the CQ System Console Component that the default mail service has been bound to our EmailService component:

                             

    Default State

enabled

    Activation

immediate

    Configuration Policy

optional

    Service Type

service

    Services

xxx.xxx.xxx.service.EmailService

    Reference repository

["Satisfied","Service Name: org.apache.sling.jcr.api.SlingRepository","Multiple: single","Optional: mandatory","Policy: static","Bound Service ID 141 (Adobe CRX Repository)"]

    Reference mailer

["Satisfied","Service Name: com.day.cq.mailer.MailService","Multiple: single","Optional: optional","Policy: dynamic","Bound Service ID 707 (com.day.cq.mailer.DefaultMailService)"]

 

CQ Mail Service has also been configured as accordingly as shown in image [day-cq-mail-service.jpg].

Could someone explain to me why is the referenced MailService still throwing NullPointerException?

Should there be an alternative way to send a HTMLEmail via SMTP from a CQ OSGI Bundle, please kindly share it with me.

Many thanks. smiley

1 Accepted Solution

Avatar

Correct answer by
Employee

How is the service invoked?

Two other notes:

  • I'd suggest removing the bind/unbind methods as those will be generated for you.
  • I wonder why you have an optional reference if the reference isn't actually optional. Or is that code you have yet to write?

View solution in original post

3 Replies

Avatar

Correct answer by
Employee

How is the service invoked?

Two other notes:

  • I'd suggest removing the bind/unbind methods as those will be generated for you.
  • I wonder why you have an optional reference if the reference isn't actually optional. Or is that code you have yet to write?

Avatar

Level 1

Thanks both. I've solved the issue. My careless mistake for adding an optional reference and invoking the service in the wrong way.

Amended my code as follow:

@Reference private MailService mailService; private SlingHttpServletRequest slingRequest; /** * For JSP call via sling.getService(EmailService.class) * */ public String sendEmail(SlingHttpServletRequest request, String subject, String message, Map<String, String> recipients, String fromName, String fromAddress) { // Set slingRequest if (request != null) { this.slingRequest = request; } else { LOGGER.error("SlingHttpServletRequest is null."); return "fail"; } // Set CQ Mail Service if (mailService == null && request != null) { mailService = getMailService(); } return sendEmail (subject, message, recipients, fromName, fromAddress); } /** * For Java Servlet call via @Reference EmailService - emailService.sendEmail(...) * */ public String sendEmail(String subject, String message, Map<String, String> recipients, String fromName, String fromAddress) { // Check MailService if (mailService == null) { LOGGER.error("MailService is null."); return "fail"; } // Declaration HtmlEmail email = new HtmlEmail(); String emailSubject = subject; try { // Set recipients for (Map.Entry entry : recipients.entrySet()) { String key = (String) entry.getKey(); String value = (String) entry.getValue(); email.addTo(key, value); } // Set email content email.setCharset("UTF-8"); email.setSubject(emailSubject); email.setHtmlMsg(emailMessage); email.setFrom(fromAddress, fromName); // Send email mailService.send(email); return "success"; } catch (EmailException e) { e.printStackTrace(); LOGGER.error("EmailException", e); } catch (Exception e) { e.printStackTrace(); LOGGER.error("Fatal error while sending email", e); } return "fail"; }