Running Oracle 19c with Java 1.8.0_451 and JavaMail 1.6.7. I'm attempting to send emails via SendGrid from a stored procedure on the database referring the the following Java class:
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED SECURITY."SendMail" as
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
public class SendMail {
static {
MailcapCommandMap mailcap = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mailcap.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mailcap.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mailcap.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mailcap.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
CommandMap.setDefaultCommandMap(mailcap);
}
public static int Send(String smtpServer,
String sender,
String recipient,
String ccRecipient,
String bccRecipient,
String subject,
String body,
String[] errorMessage,
String attachments,
final String username,
final String password) {
int errorStatus = 0;
System.setProperty("javax.net.ssl.trustStore", "/u02/sendgrid/wallet/mytruststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
System.setProperty("javax.net.ssl.trustStoreType", "JKS");
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.starttls.required", "true");
props.put("mail.smtp.ssl.protocols", "TLSv1.2");
props.put("mail.smtp.host", smtpServer);
props.put("mail.smtp.port", "587");
props.put("mail.debug", "true");
Session session = Session.getInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
session.setDebug(true);
try {
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(sender));
// To
InternetAddress[] toAddresses = InternetAddress.parse(recipient);
msg.setRecipients(Message.RecipientType.TO, toAddresses);
// CC
if (ccRecipient != null && !ccRecipient.trim().isEmpty()) {
InternetAddress[] ccAddresses = InternetAddress.parse(ccRecipient);
msg.setRecipients(Message.RecipientType.CC, ccAddresses);
}
// BCC
if (bccRecipient != null && !bccRecipient.trim().isEmpty()) {
InternetAddress[] bccAddresses = InternetAddress.parse(bccRecipient);
msg.setRecipients(Message.RecipientType.BCC, bccAddresses);
}
msg.setSubject(subject, "UTF-8");
msg.setSentDate(new Date());
Multipart mp = new MimeMultipart();
// Body part with HTML or plain text detection
MimeBodyPart mbpText = new MimeBodyPart();
if (body == null || body.trim().isEmpty()) {
body = "[No message body provided]";
}
if (body.toLowerCase().contains("<html") || body.toLowerCase().contains("<body")) {
mbpText.setContent(body, "text/html; charset=UTF-8");
} else {
mbpText.setContent(body, "text/plain; charset=UTF-8");
}
mp.addBodyPart(mbpText);
// Attachments
if (attachments != null && !attachments.trim().isEmpty()) {
int startIndex = 0, posIndex;
while ((posIndex = attachments.indexOf("///", startIndex)) != -1) {
String filePath = attachments.substring(startIndex, posIndex).trim();
addAttachment(mp, filePath);
startIndex = posIndex + 3;
}
if (startIndex < attachments.length()) {
String filePath = attachments.substring(startIndex).trim();
addAttachment(mp, filePath);
}
}
msg.setContent(mp);
Transport.send(msg);
} catch (Exception e) {
errorMessage[0] = e.toString();
errorStatus = 1;
}
return errorStatus;
}
private static void addAttachment(Multipart mp, String filePath) throws MessagingException {
File file = new File(filePath);
if (!file.exists()) return;
MimeBodyPart mbp = new MimeBodyPart();
FileDataSource fds = new FileDataSource(file);
mbp.setDataHandler(new DataHandler(fds));
mbp.setFileName(fds.getName());
mp.addBodyPart(mbp);
}
}
It runs fine on my laptop, but the problem I'm running into is that I'm seeing neither the STARTTLS command nor the 220 Begin TLS negotiation now response from SendGrid when run on the database.
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: useEhlo true, useAuth true
DEBUG: SMTPTransport trying to connect to host "smtp.sendgrid.net", port 587
DEBUG SMTP RCVD: 220 SG ESMTP service ready at geopod-ismtpd-36
DEBUG: SMTPTransport connected to host "smtp.sendgrid.net", port: 587
DEBUG SMTP SENT: EHLO database_server
DEBUG SMTP RCVD: 250-smtp.sendgrid.net
250-8BITMIME
250-PIPELINING
250-SIZE 31457280
250-SMTPUTF8
250-STARTTLS
250-AUTH PLAIN LOGIN
250 AUTH=PLAIN LOGIN
DEBUG SMTP Found extension "8BITMIME", arg ""
DEBUG SMTP Found extension "PIPELINING", arg ""
DEBUG SMTP Found extension "SIZE", arg "31457280"
DEBUG SMTP Found extension "SMTPUTF8", arg ""
DEBUG SMTP Found extension "STARTTLS", arg ""
DEBUG SMTP Found extension "AUTH", arg "PLAIN LOGIN"
DEBUG SMTP Found extension "AUTH=PLAIN", arg "LOGIN"
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP SENT: AUTH LOGIN
DEBUG SMTP RCVD: 334 VXNlcm5hbWU6
DEBUG SMTP SENT: YXBpa2V5
DEBUG SMTP RCVD: 334 UGFzc3dvcmQ6
DEBUG SMTP SENT: encoded password
DEBUG SMTP RCVD: 235 Authentication successful
DEBUG SMTP: use8bit false
DEBUG SMTP SENT: MAIL FROM:<[email protected]>
DEBUG SMTP RCVD: 250 Sender address accepted
DEBUG SMTP SENT: RCPT TO:<[email protected]>
DEBUG SMTP RCVD: 250 Recipient address accepted
Verified Addresses
[email protected]
DEBUG SMTP SENT: DATA
DEBUG SMTP RCVD: 354 Continue
DEBUG SMTP SENT:
.
*** 2025-06-10T07:58:54.209486-04:00
DEBUG SMTP RCVD: 250 Ok: queued as jYJnb995RBipUUlY_z2R5Q
DEBUG SMTP SENT: QUIT
Can anyone tell me why it's behaving this way and how I can fix it?
Thanks!