Send email with Java (Jakarta Mail) over SMTP
Jakarta Mail (formerly JavaMail) SMTP example: mail.smtp.starttls.enable on 587 (or SSL on 465), Authenticator, MimeMessage with HTML, and the Maven dependency. Spring Boot properties included.
Install
shell
<!-- Maven --> <dependency> <groupId>com.sun.mail</groupId> <artifactId>jakarta.mail</artifactId> <version>2.0.1</version> </dependency>
Complete example
Java — STARTTLS on 587, credentials from the environment
import jakarta.mail.*;
import jakarta.mail.internet.*;
import java.util.Properties;
public class SendMail {
public static void main(String[] args) throws Exception {
String host = System.getenv().getOrDefault("SMTP_HOST", "smtp.queensmtp.com");
int port = Integer.parseInt(System.getenv().getOrDefault("SMTP_PORT", "587"));
String user = System.getenv("SMTP_USER"), pass = System.getenv("SMTP_PASS");
Properties p = new Properties();
p.put("mail.smtp.host", host);
p.put("mail.smtp.port", String.valueOf(port));
p.put("mail.smtp.auth", "true");
if (port == 465) {
p.put("mail.smtp.ssl.enable", "true"); // implicit TLS
} else {
p.put("mail.smtp.starttls.enable", "true"); // STARTTLS on 587
p.put("mail.smtp.starttls.required", "true");
}
p.put("mail.smtp.connectiontimeout", "20000");
p.put("mail.smtp.timeout", "20000");
Session session = Session.getInstance(p, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, pass);
}
});
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("hello@yourdomain.com", "Your App"));
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse("customer@example.com"));
msg.setSubject("Your receipt");
msg.setContent("<h1>Thanks for your order</h1><p>#1042 is confirmed.</p>", "text/html; charset=utf-8");
Transport.send(msg);
System.out.println("sent");
}
}
// Spring Boot: application.properties
// spring.mail.host=smtp.queensmtp.com
// spring.mail.port=587
// spring.mail.username=${SMTP_USER}
// spring.mail.password=${SMTP_PASS}
// spring.mail.properties.mail.smtp.auth=true
// spring.mail.properties.mail.smtp.starttls.enable=trueWhat to know
- Spring Boot autoconfigures JavaMailSender from spring.mail.* — inject JavaMailSender and call send(MimeMessagePreparator).
- Set both connectiontimeout and timeout; the defaults are infinite and a hung SMTP call blocks a thread forever.
- For Gmail use smtp.gmail.com + App Password; for SES use the region endpoint and SMTP credentials.
Same code, different provider
Only the host, port and credentials change. The rules per provider are on the SMTP settings hub.
| Provider | Host | Port | Username | Password | Note |
|---|---|---|---|---|---|
| QueenSMTP | smtp.queensmtp.com | 587 (STARTTLS) / 465 (SSL) / 2525 | SMTP username from the dashboard | SMTP password | $5/year + $0.10 per 1,000; 100 free/day |
| Gmail | smtp.gmail.com | 587 / 465 | you@gmail.com | App Password | 500/day, From must be the account |
| Amazon SES | email-smtp.<region>.amazonaws.com | 587 / 465 / 2587 | SES SMTP username | SES SMTP password | sandbox 200/day until approved |
| Office 365 | smtp.office365.com | 587 | user@yourdomain.com | mailbox password | SMTP AUTH must be enabled; 30/min |
| SendGrid | smtp.sendgrid.net | 587 / 465 / 2525 | apikey | API key | no free plan since 2025 |
Credentials for the example above
Create a free account, verify your sending domain (SPF + DKIM shown in the dashboard), add an SMTP credential, and paste it into the code. 100 emails a day free; $5/year plus $0.10 per 1,000 after that. Prefer HTTPS? The same account has a REST email API.
Get SMTP credentials Test your settings firstOther languages and frameworks
PHPsend email over SMTP
Laravelsend email over SMTP
WordPresssend email over SMTP
Pythonsend email over SMTP
Djangosend email over SMTP
Flasksend email over SMTP
Node.jssend email over SMTP
Next.jssend email over SMTP
C# / .NETsend email over SMTP
Gosend email over SMTP
Ruby on Railssend email over SMTP
Postfix (Linux relayhost)send email over SMTP
curl / Bashsend email over SMTP
Java SMTP — questions
STARTTLS negotiation failed — usually a wrong port (465 needs mail.smtp.ssl.enable instead of starttls) or an outdated JDK trust store.
Related Guides
Continue learning with these related articles