Expand my Community achievements bar.

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"; }