Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

How to send email from Java Callout

Not applicable

We need to send emails from within Java Callouts and currently fail to do so. We are receiving the following error on the message processor when trying to send SMTP emails:

javax.mail.NoSuchProviderException: Unable to load class for provider: protocol=smtp; type=javax.mail.Provider$Type@aee111a; class=com.sun.mail.smtp.SMTPTransport; vendor=Oracle 
at javax.mail.Session.getService(Session.java:494) 

We tried adding activation and java-mail-api jar to our proxy but we get the same error.

What do we need to do?
Solved Solved
3 3 1,293
1 ACCEPTED SOLUTION

Are you using Edge SaaS ? If so, it's possible that the JVM security policy for a Java callout prohibits the loading of the SMTP class. Without access to the message processor logs, I cannot know for sure, but this is what it seems like. It's not a matter of availability of the java-mail-api JAR, etc.

I will try some tests on my own. In the meantime, a possible workaround may be to use an HTTP-accessible mail service.

EDIT:

Upon further review I think this should work for you. I've tested this. I produced my own Java callout that uses SMTP to send an email, synchronously. It works on my Edge SaaS organization.

The callout code looks like this:

public ExecutionResult execute(MessageContext msgCtxt, ExecutionContext exeCtxt) {
  ExecutionResult calloutResult = ExecutionResult.ABORT;
  boolean debug = getDebug();

  try {
    final String messageText = getMessageText(msgCtxt);
    final String subjectText = getSubjectText(msgCtxt);
    final String host = getHost(msgCtxt);
    final String port = getPort(msgCtxt);
    final String authUsername = getUsername(msgCtxt);
    final String authPassword = getPassword(msgCtxt);
    final String toUsername = getTo(msgCtxt);


    Properties props = new Properties();
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", "true");
    props.put("mail.smtp.host", host); // eg, "smtp.gmail.com"
    props.put("mail.smtp.port", port); // eg, "587"


    Session session =
        Session.getInstance(props,
                            new javax.mail.Authenticator() {
                                protected PasswordAuthentication getPasswordAuthentication() {
                                    return new PasswordAuthentication(authUsername, authPassword);
                                }
                            });


    Message message = new MimeMessage(session);
    message.setFrom(new InternetAddress(authUsername));
    message.setRecipients(Message.RecipientType.TO,
                          InternetAddress.parse(toUsername));
    message.setSubject(subjectText);
    message.setText(messageText);
    Transport.send(message);
    calloutResult = ExecutionResult.SUCCESS;
  }
  ...

The JARs I included into this proxy bundle are:

  • javax.mail-1.6.0.jar
  • commons-lang3-3.6.jar (for ExceptionUtils)
  • activation-1.1.jar
  • edge-custom-smtpmail-1.0.1.jar (my custom jar)

It's not sufficient to add javax.mail-api-x.y.z.jar to the bundle. That JAR is good to satisfy compilation requirements. What you need is javax.mail-x.y.z.jar . The maven dependency i used was:

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.0</version>
</dependency>

<!-- NOT SUFFICIENT FOR RUNTIME 

<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>javax.mail-api</artifactId>
    <version>1.6.0</version>
</dependency>

-->

View solution in original post

3 REPLIES 3