Apache Sling Commons Messaging Mail

July 16, 2026 · View on GitHub

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