Recipient methods were replaced
Impact: Calls to the old to(...), cc(...),
bcc(...), and related recipient overloads no longer compile.
Build recipients explicitly with RecipientBuilder, set their recipient type, and add them through
withRecipients(...).
A RecipientBuilder always produces exactly one Recipient.
Pass one RFC 2822 address to withAddress(...), optionally including a display name such as
Alice <alice@example.com>. It does not split comma- or semicolon-delimited address lists.
// Before 9.0.0:
Email email = EmailBuilder.startingBlank()
.from("me@example.com")
.to("Alice", "alice@example.com")
.cc("audit@example.com")
.withPlainText("Hello")
.buildEmail();
// Since 9.0.0:
Email email = EmailBuilder.startingBlank()
.from("me@example.com")
.withRecipients(
new RecipientBuilder()
.withName("Alice")
.withAddress("alice@example.com")
.withType(Message.RecipientType.TO)
.build(),
new RecipientBuilder()
.withAddress("audit@example.com")
.withType(Message.RecipientType.CC)
.build())
.withPlainText("Hello")
.buildEmail();
For several recipients, use RecipientsBuilder. Each String argument may contain one address or a
comma- or semicolon-delimited list; every parsed address becomes a separate Recipient:
Collection<Recipient> recipients = new RecipientsBuilder()
.withRecipientsWithDefaultName(
null,
Message.RecipientType.TO,
"alice@example.com,bob@example.com",
"Carol <carol@example.com>;dave@example.com")
.buildRecipients();
Email email = EmailBuilder.startingBlank()
.from("me@example.com")
.withRecipients(recipients)
.withPlainText("Hello")
.buildEmail();
For an existing Recipient or collection, replace
to(...), cc(...), or
bcc(...) with withRecipients(...) and make sure each recipient
already carries the intended type.
See the dedicated recipient builder examples for the current API.
Outlook InputStream conversion result
Impact: The InputStream overloads of
outlookMsgToEmailBuilder(...) are deprecated and return an internal wrapper type.
Use outlookMsgToEmailBuilderWithOutlookData(...) when you need both the email builder and source
.msg metadata. If you only need the converted email, the existing
outlookMsgToEmail(...) method remains the shorter route.
// Before 9.0.0:
EmailFromOutlookMessage result =
EmailConverter.outlookMsgToEmailBuilder(msgInputStream);
Email email = result.getEmailBuilder().buildEmail();
// Since 9.0.0:
OutlookEmailConversionResult result =
EmailConverter.outlookMsgToEmailBuilderWithOutlookData(msgInputStream);
Email email = result.buildEmail();
OutlookMessageData sourceData = result.getOutlookMessageData();
Generated attachment Content-ID values changed
Impact: Raw MIME tests or integrations that inspect automatically generated attachment
Content-ID values may need updating.
An attachment without an explicit Content-ID now receives an opaque value in the form
sjm-...@simplejavamail.generated. Earlier versions derived the value from the attachment name and a UUID.
Embedded images still use their resource name when no separate Content-ID is supplied.
// Before 9.0.0:
Content-ID: <report.pdf@...>
// Since 9.0.0:
Content-ID: <sjm-...@simplejavamail.generated>
Do not depend on a generated value. If another system requires a stable Content-ID, supply it explicitly:
emailBuilder.withAttachment(
"report.pdf",
reportData,
null,
null,
"stable-report-id");
Cluster pool defaults are scoped per cluster
Impact: Applications with more than one cluster key no longer share what effectively behaved like one JVM-wide set of pool defaults.
The first Mailer registered for each cluster key now defines that cluster's pool size, claim timeout,
expiry, and load-balancing strategy. If several clusters previously relied on settings supplied for only one of them, repeat the intended settings
on the first Mailer registered under every key.
Mailer ordersMailer = MailerBuilder
.withSMTPServer("orders-smtp.example.com", 587, "user", "password")
.withClusterKey(ordersCluster)
.withConnectionPoolMaxSize(3)
.withConnectionPoolLoadBalancingStrategy(LoadBalancingStrategy.RANDOM_ACCESS)
.buildMailer();
Property-file and Spring configurations can define the same settings per cluster under
simplejavamail.defaults.connectionpool.clusters.*. See
clustering configuration for the complete forms.
Async mailer defaults apply to testConnection
Impact: On a Mailer configured with async(), no-argument
testConnection() no longer blocks.
The no-argument method now follows the Mailer's asynchronous default, just like
sendMail(...). Replace it with
testConnection(false) wherever a blocking startup or health check is required.
Resource filenames moved out of Content-Type filename
Impact: Code or tests that inspect generated attachment and embedded-image MIME headers may need updating.
Simple Java Mail no longer adds the non-standard filename parameter to
Content-Type. The filename remains in the standard
Content-Disposition parameter, while
Content-Type keeps the legacy-compatible name parameter.
// Before 9.0.0:
Content-Type: application/pdf; filename=report.pdf; name=report.pdf
Content-Disposition: attachment; filename=report.pdf
// Since 9.0.0:
Content-Type: application/pdf; name=report.pdf
Content-Disposition: attachment; filename=report.pdf