Apache Sling Commons Messaging Mail

Clone this repo:
  1. e3e6ab5 docs: update AGENTS.md and README.md with Jakarta/OSGi and test details (#4) by Carsten Ziegeler · 6 weeks ago master
  2. d2a84d4 Add security section to AGENTS.md by Robert Munteanu · 3 months ago
  3. 7f3103d docs: add AGENTS.md and improve README build instructions (#3) by Carsten Ziegeler · 3 months ago
  4. d0ad511 build with Java 17 and 21 by Oliver Lietz · 5 months ago
  5. 405fef3 remove unused import by Oliver Lietz · 5 months ago

Apache Sling

Build Status Test Status Coverage Sonarcloud Status JavaDoc Maven Central License

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

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