Apache Sling Commons Messaging Mail
July 16, 2026 · View on GitHub
Apache Sling Commons Messaging Mail
This module is part of the Apache Sling project.
It provides a simple layer on top of Jakarta Mail (package jakarta.mail) for asynchronous SMTP-over-SSL/TLS message delivery, including:
- Mail Service: sends MIME messages asynchronously (
CompletableFuture<Void>) - Message Builder: builds plain text and HTML messages with attachments and inline images
- Message ID Provider: allows replacing default message IDs with custom ones
The project is built with Java 17 and validated in CI with Java 17 and Java 21.
Build and Test
# Build and run all checks (Checkstyle, PMD, SpotBugs) + unit and integration tests
mvn clean verify
# Skip integration tests (faster local iteration)
mvn clean verify -DskipITs
# Run only unit tests
mvn test
# Run a single unit test class
mvn test -Dtest=SimpleMailServiceTest
# Run integration tests only
mvn failsafe:integration-test failsafe:verify
# Run a single integration test class
mvn failsafe:integration-test -Dit.test=SimpleMailServiceIT
# Run Checkstyle only
mvn checkstyle:check
# Run PMD only
mvn pmd:check
# Run SpotBugs only
mvn spotbugs:check
Examples
Configuration
MailService
Example factory configuration (SimpleMailServiceConfiguration) for SimpleMailService:
{
"names": ["default"],
"threadpool_name": "default",
"mail_smtps_ssl_checkserveridentity": true,
"mail_smtps_from": "envelope-from@example.org",
"mail_smtps_host": "smtp.example.org",
"mail_smtps_port": 465,
"username": "SMTP-USERNAME-PLAIN",
"password": "SMTP-PASSWORD-ENCRYPTED",
"messageIdProvider_target": "(names=hostname)",
"connectionListeners_target": "(is=used)",
"transportListeners_target": "(is=used)"
}
Optional MessageIdProvider
Example factory configuration (SimpleMessageIdProviderConfiguration) for optional SimpleMessageIdProvider:
{
"names": [
"hostname"
],
"host": "author.cms.example.org"
}
Usage
Create a multipart MIME message with an attachment (filename: song.flac) where the HTML part contains an inline image (cid: ska) and send it:
@Reference
MailService mailService;
String subject = "Rudy, A Message to You";
String text = "Stop your messing around\nBetter think of your future\nTime you straighten right out\nCreating problems in town\n…";
String html = […];
byte[] attachment = […];
byte[] inline = […];
MimeMessage message = mailService.getMessageBuilder()
.from("dandy.livingstone@kingston.jamaica.example.net", "Dandy Livingstone")
.to("the.specials@coventry.england.example.net", "The Specials")
.replyTo("rocksteady@jamaica.example.net")
.subject(subject)
.text(text)
.html(html)
.attachment(attachment, "audio/flac", "song.flac")
.inline(inline, "image/png", "ska")
.build();
mailService.sendMessage(message);
Dependencies
- Sling Commons Messaging (API)
- Sling Commons Crypto (decrypting encrypted SMTP passwords)
- Sling Commons Threads (asynchronous dispatch)
- Jakarta Mail 2.0 and ServiceMix Jakarta Activation API 2.0.1 (OSGi-compatible APIs used by the bundle)
Integration Tests
Integration tests use GreenMail by default.
An external SMTP server (for end-to-end validation with real mail clients) can be used by setting these properties:
mvn failsafe:integration-test failsafe:verify \
-Dsling.test.mail.smtps.server.external=true \
-Dsling.test.mail.smtps.ssl.checkserveridentity=true \
-Dsling.test.mail.smtps.from=envelope-from@example.org \
-Dsling.test.mail.smtps.host=localhost \
-Dsling.test.mail.smtps.port=465 \
-Dsling.test.mail.smtps.username=username \
-Dsling.test.mail.smtps.password=password \
-Dsling.test.mail.from.address=from@example.org \
-Dsling.test.mail.from.name=From\ Sender \
-Dsling.test.mail.to.address=to@example.org \
-Dsling.test.mail.to.name=To\ Recipient \
-Dsling.test.mail.replyTo.address=replyto@example.org \
-Dsling.test.mail.replyTo.name=Reply\ To
