About Simple Java Mail
Simple Java Mail is a mailing library with a super clean API. It's the easiest to use (Java) mailing library in the world for sending emails using SMTP.
This library relieves you of having to deal with low level API such as MimeMessage, fuzzy try catch constructions, inner classes and other nonsense. You just want to send an email!
But don't let looks deceive you, this library does everything: it is a robust, feature complete mailing library, yet it is small and lightweight. Compare it to other popular mailing libraries!
It is fully RFC compliant and looks good in all email clients.
It's also the only java mailing library in the world that can send through authenticated SOCKS proxy or let you configure an advanced cluster of connection pools.
Over the 16+ years of open source development, Simple Java Mail has matured, adding CLI support, DKIM, SMIME, batch sending, clustering, CRLF injection protection, OAUTH2 and much more.
Simple Java Mail can also be used as a catalyst in your own project where you handle the ultimate server connections and send emails. You want to use a REST service instead of the built-in SMTP support? Go right ahead.
EmailBuilder.startingBlank()
EmailBuilder.replyingTo(email)
EmailBuilder.forwarding(email)
EmailBuilder.copying(email)
// Most essentials together (but almost everything is optional):
ConfigLoader.loadProperties("simplejavamail.properties"); // optional default
ConfigLoader.loadProperties("overrides.properties"); // optional extra
Recipient alice = new RecipientBuilder()
.withAddressAndNameOrDefault("Alice <alice@candyshop.org>", null)
.withType(TO)
.withSmimeCertificate(aliceCertificate)
.build();
Collection<Recipient> groupRecipients = new RecipientsBuilder()
.withDefaultSmimeCertificate(candyShopGroupCertificate)
.withRecipientsWithFixedName("C. Bo group", CC,
"chocobo1@candyshop.org", "chocobo2@candyshop.org")
.withRecipientsWithFixedName("Tasting Group", BCC,
"taster1@cgroup.org;taster2@cgroup.org;tester <taster3@cgroup.org>")
.withRecipient(new RecipientBuilder()
.withAddressAndNameOrDefault("Mr Sweetnose <snose@candyshop.org>", null)
.withType(BCC)
.build())
.buildRecipients();
Email email = EmailBuilder.startingBlank()
.from("lollypop", "lolly.pop@somemail.com")
.withRecipients(alice)
.withRecipients(new RecipientBuilder()
.withName("lollypop")
.withAddress("lolly.pop@somemail.com")
.withType(TO)
.build())
.withRecipients(new RecipientBuilder()
.withName("C. Cane")
.withAddress("candycane@candyshop.org")
.withType(TO)
.build())
.withRecipients(groupRecipients)
.withReplyTo("lollypop", "lolly.pop@othermail.com")
.withSubject("hey")
.withHTMLText("<img src='cid:wink1'><b>We should meet up!</b><img src='cid:wink2'>")
.withPlainText("Please view this email in a modern email client!")
.withCalendarText(CalendarMethod.REQUEST, iCalendarText)
.withEmbeddedImage("wink1", imageByteArray, "image/png")
.withEmbeddedImage("wink2.png", imageDatasource, "wink2")
.withPreEncodedEmbeddedImage("wink3.png", encodedImageData, "image/png", BASE_64)
.withAttachment("invitation", pdfByteArray, "application/pdf")
.withAttachment("dresscode", odfDatasource)
.withAttachment("spoilers", spoilerDatasource, "Spoilers", BASE_64, "spoilers-cid")
.withPreEncodedAttachment("report.pdf", encodedPdfData, "application/pdf", BASE_64)
.withHeader("X-Priority", 5)
.withReturnReceiptTo()
.withDispositionNotificationTo("notify-read-emails@candyshop.com")
.withDeliveryStatusNotification(HEADERS_ONLY, FAILURE, DELAY)
.withBounceTo("tech@candyshop.com")
.signWithDomainKey(privateKeyData, "somemail.com", "selector") // DKIM
.signWithDomainKey(dkimConfig) // fine-grained control
.signWithSmime(smimeSignConfig)
.encryptWithSmime(smimeEncryptConfig)
.dontApplyDefaultValueFor(FROM)
.dontApplyOverrideValueFor(REPLY_TO)
.withContentTransferEncoding(BASE_64)
.withPlainTextContentTransferEncoding(BIT7)
.withHTMLTextContentTransferEncoding(QUOTED_PRINTABLE)
.withCalendarTextContentTransferEncoding(BASE_64)
.buildEmail();
Mailer mailer = MailerBuilder
.withSMTPServer("smtp.host.com", 587, "user@host.com", "password")
.withTransportStrategy(TransportStrategy.SMTP_TLS)
.withProxy("socksproxy.host.com", 1080, "proxy user", "proxy password")
.withSessionTimeout(10 * 1000)
.withLocalBindAddress("203.0.113.10")
.clearEmailValidator() // turns off email validation
.withEmailValidator( // or not
JMail.strictValidator()
.requireOnlyTopLevelDomains(TopLevelDomain.DOT_COM)
.withRule(email -> email.localPart().startsWith("allowed")))
.withProperty("mail.smtp.sendpartial", true)
.withDebugLogging(true)
.withDebugOutput(SessionDebugOutput.SLF4J)
.withDefaultDkimSigning(defaultDkimConfig)
.async()
// not enough? what about this:
.withClusterKey(myPowerfulMailingCluster)
.withThreadPoolSize(20) // batch-module executor sizing
.withConnectionPoolCoreSize(10) // reusable connection(s) / multi-server sending
.withConnectionPoolLoadBalancingStrategy(ROUND_ROBIN)
.withCustomSSLFactoryClass("org.mypackage.MySSLFactory")
.withCustomSSLFactoryInstance(mySSLFactoryInstance)
.withEmailDefaults(myEmailWithADefaultBCCRecipient)
.withEmailOverrides(myEmailWithFixedFromAddress)
.manyMoreOptions()
.buildMailer();
mailer.sendMail(email);
mailer.sendMailsInSimpleBatch(Arrays.asList(email, anotherEmail), false);
mailer.withOpenConnection(sender -> {
sender.sendMail(email);
sender.sendMail(anotherEmail);
});
mailer.testConnection();
mailer.validate(email);
mailer.getServerConfig();
mailer.getOperationalConfig();
mailer.getEmailGovernance(); // default S/MIME, validation criteria, overrides etc.
mailer.getProxyConfig();
mailer.getTransportStrategy();
mailer.getSession();
S/MIME signed and/or encrypted Outlook messages? No problem!
OutlookEmailConversionResult result =
EmailConverter.outlookMsgToEmailBuilderWithOutlookData("smimeSignedEmail.msg", pkcs12Config);
Email email = result.buildEmail();
OutlookMessageData outlookData = result.getOutlookMessageData();
Boolean smimeSignatureValid = email.getOriginalSmimeDetails().getSmimeSignatureValid();
sjm --help