Skip to content

JavaMail Bridge Extension Swiftlet

Overview

The JavaMail Bridge Extension Swiftlet provides integration between SwiftMQ queues/topics and email systems using the JavaMail API. It enables bidirectional message exchange: inbound bridges retrieve emails and convert them into JMS messages, while outbound bridges consume JMS messages and send them as emails via SMTP.

Features

Inbound Mail Bridges

Inbound bridges poll a configured mail server (using POP3, IMAP, or their secure variants) and convert incoming emails into JMS messages, which are then delivered to a specified queue or topic. Each bridge is highly configurable, supporting custom property mappings, default properties, and mail filtering.

Mail filters can be defined to reject or accept messages based on header values, body content, attachment MIME types, or message size. Filters can be set to reject on match or not, return rejected messages to the sender, and specify custom rejection messages. When a message is rejected, it can be optionally forwarded to a configured queue for further processing or auditing.

Transformers are used to convert email content into JMS messages. Several built-in transformers are provided (e.g., text-only, multipart), and custom transformers can be implemented by extending the Transformer interface. The transformer is responsible for enforcing maximum message size and for mapping email content to the appropriate JMS message type.

Mail Filters

Mail filters can be defined per inbound bridge to validate incoming emails before they are converted to JMS messages. Filter types include header, body, attachment, and size. Each filter supports properties relevant to its type (e.g., regex for headers, MIME type for attachments, max size for size filter). Filters can be set to reject on match or not, and can optionally return rejected messages to the sender with a custom message.

Property Translations and Default Properties

Property translations allow mapping of email headers (such as from, to, subject) to JMS message properties. Default properties can be set to assign constant values to JMS properties for all messages processed by the bridge.

Custom Transformers

Inbound bridges use a transformer class to convert emails into JMS messages. The transformer must implement the com.swiftmq.extension.javamail.inbound.Transformer interface, which defines methods for setting the maximum message size, creating a JMS message, and transforming the email into the JMS message. Built-in transformers include text and multipart variants, but users can supply their own for specialized processing.

Configuration Example:

<swiftlet name="xt$javamail">
  <inbound-bridges>
    <inbound-bridge name="mail2queue" enabled="true" mail-host="mail.example.com" mail-host-account-name="user" mail-host-account-password="secret" target-name="orders"/>
  </inbound-bridges>
</swiftlet>

Outbound Mail Bridges

Outbound bridges consume JMS messages from a configured queue or topic and send them as emails via SMTP. Each bridge can be configured with SMTP server details, authentication, and message transformation logic. Outbound bridges support error handling policies that determine what happens if a message cannot be sent (delete, retry, or forward to an error queue).

Transformers are used to convert JMS messages into email content and attachments. Built-in transformers handle text and multipart messages, and users can implement custom transformers by extending the com.swiftmq.extension.javamail.outbound.Transformer or Transformer2 interfaces. Header translations and default headers allow mapping JMS properties to email headers and setting constant header values.

Error Handling Policies

Outbound bridges support three error handling policies: delete (discard the message), retry (attempt to resend after a configured interval), and error_queue (forward the message to a designated error queue for further analysis).

Header Translations and Default Headers

Header translations map JMS message properties to email headers, allowing for flexible integration with external email systems. Default headers can be set to assign constant values to email headers for all outgoing messages.

Custom Transformers

Outbound bridges use a transformer class to convert JMS messages into email format. The transformer must implement the com.swiftmq.extension.javamail.outbound.Transformer interface (for message/attachment extraction) or the Transformer2 interface (for full control over JavaMail message creation).

Configuration Example:

<swiftlet name="xt$javamail">
  <outbound-bridges>
    <outbound-bridge name="queue2mail" enabled="true" smtp-host="smtp.example.com" source-name="alerts"/>
  </outbound-bridges>
</swiftlet>

Job Integration for Bridge Activation

The Swiftlet registers jobs for activating and deactivating inbound and outbound bridges with the SwiftMQ Scheduler Swiftlet. These jobs can be triggered manually or scheduled, enabling dynamic control over bridge operation without requiring a router restart.

Usage and Statistics Collection

The Swiftlet maintains a usage section that tracks active inbound and outbound bridges, including statistics such as the number of messages transferred and the last transfer time. The collection interval for these statistics can be configured globally.

Configuration Example:

<swiftlet name="xt$javamail" collect-interval="20000"/>

Custom Transformer Interfaces

For inbound bridges, custom transformers must implement the com.swiftmq.extension.javamail.inbound.Transformer interface, which requires methods for setting the maximum message size, creating a JMS message, and transforming a JavaMail message into a JMS message. For outbound bridges, custom transformers must implement either the com.swiftmq.extension.javamail.outbound.Transformer interface (for extracting content and attachments from JMS messages) or the Transformer2 interface (for full JavaMail message creation).

Inbound Transformer Interface

Implement com.swiftmq.extension.javamail.inbound.Transformer with methods: - void setMaxMessageSize(int size): Enforce maximum allowed message size (in KB). - MessageImpl createMessage(): Create a new JMS message instance (e.g., TextMessageImpl, ObjectMessageImpl). - void transform(MessageImpl jmsMessage, Message mailMessage): Convert the JavaMail message into the JMS message, throwing an exception if conversion fails or size is exceeded.

Outbound Transformer Interfaces

Implement either: - com.swiftmq.extension.javamail.outbound.Transformer with methods for setting the JMS message, extracting content, counting and retrieving attachments, and getting filenames. - Or Transformer2, which defines MimeMessage transform(Session session, MessageImpl message), allowing full control over JavaMail message creation.

Internal Queue Naming

  • mail-filter-reject-queue — Queue to which rejected inbound emails are forwarded when a mail filter rejects a message and forwarding is enabled.
  • javamail-outbound-error — Default error queue for outbound bridges when error-policy is set to error_queue.

Configuration Guide

Configure an Inbound Bridge to Forward Emails to a Queue

Use this scenario to automatically retrieve emails from a mail server and forward them as JMS messages to a SwiftMQ queue. This is useful for integrating email-based workflows with messaging applications.

  1. Define an inbound bridge under the xt$javamail swiftlet.
  2. Set the mail server connection properties (mail-host, mail-host-account-name, mail-host-account-password, protocol, etc.).
  3. Specify the target queue name in target-name and set enabled="true".
<swiftlet name="xt$javamail">
  <inbound-bridges>
    <inbound-bridge name="mail2queue" enabled="true" mail-host="mail.example.com" mail-host-account-name="user" mail-host-account-password="secret" target-name="orders"/>
  </inbound-bridges>
</swiftlet>

Configure an Outbound Bridge to Send Queue Messages as Email

Use this scenario to consume messages from a SwiftMQ queue and send them as emails via SMTP. This is commonly used for alerting or notification systems.

  1. Define an outbound bridge under the xt$javamail swiftlet.
  2. Set the SMTP server properties (smtp-host, smtp-authentication-enabled, smtp-username, smtp-password, etc.).
  3. Specify the source queue name in source-name and set enabled="true".
<swiftlet name="xt$javamail">
  <outbound-bridges>
    <outbound-bridge name="queue2mail" enabled="true" smtp-host="smtp.example.com" source-name="alerts"/>
  </outbound-bridges>
</swiftlet>

Scheduler Jobs

Inbound Bridge

Description: Activates an Inbound Bridge

Outbound Bridge

Description: Activates an Outbound Bridge

Custom Message Transformer API

The JavaMail Bridge uses transformer interfaces to convert messages between JMS and JavaMail formats. Implement a custom transformer by implementing one of the interfaces below.

Inbound Transformer

Package: com.swiftmq.extension.javamail.inbound

Converts an incoming JavaMail Message into a JMS MessageImpl. The bridge creates one instance and calls setMaxMessageSize initially. For each incoming mail, createMessage is called first to get the JMS message, then transform populates it from the JavaMail message.

public interface Transformer {

    /**
     * Sets the maximum message size in KB. The transformer must throw an
     * exception if the mail message exceeds this size.
     *
     * @param size maximum size in KB (-1 means unlimited)
     */
    void setMaxMessageSize(int size);

    /**
     * Creates the appropriate JMS message instance. Must return one of:
     *   - com.swiftmq.jms.TextMessageImpl
     *   - com.swiftmq.jms.ObjectMessageImpl
     *   - com.swiftmq.jms.MapMessageImpl
     *   - com.swiftmq.jms.StreamMessageImpl
     *   - com.swiftmq.jms.MessageImpl
     *
     * @return a new JMS message
     */
    MessageImpl createMessage();

    /**
     * Transforms the JavaMail message into the JMS message returned
     * by createMessage().
     *
     * @param jmsMessage  the JMS message to populate
     * @param mailMessage the incoming JavaMail message
     */
    void transform(MessageImpl jmsMessage, Message mailMessage)
        throws Exception;
}

Outbound Transformer

Package: com.swiftmq.extension.javamail.outbound

Converts an outgoing JMS MessageImpl into email content. The bridge calls setMessage, then getContent for the body, and getNumberAttachments / getAttachment / getAttachmentFilename for each attachment.

public interface Transformer {

    /**
     * Sets the JMS message to transform. Can be cast to the
     * appropriate javax.jms.Message type.
     *
     * @param message JMS message (SwiftMQ implementation)
     */
    void setMessage(MessageImpl message) throws Exception;

    /**
     * Returns the mail body content (MIME type text/plain).
     *
     * @return mail body text
     */
    String getContent() throws Exception;

    /**
     * Returns the number of attachments.
     *
     * @return attachment count
     */
    int getNumberAttachments() throws Exception;

    /**
     * Returns a DataSource to access the attachment at the given index.
     *
     * @param index attachment index (starts at 0)
     * @return javax.activation.DataSource for the attachment
     */
    DataSource getAttachment(int index) throws Exception;

    /**
     * Returns the filename of the attachment at the given index.
     *
     * @param index attachment index (starts at 0)
     * @return filename, or null if not specified
     */
    String getAttachmentFilename(int index) throws Exception;
}

Outbound Transformer (Alternative)

Package: com.swiftmq.extension.javamail.outbound

An alternative interface that gives full control over the JavaMail MimeMessage creation. The bridge calls transform once per JMS message.

public interface Transformer2 {

    /**
     * Transforms a JMS message into a JavaMail MimeMessage.
     *
     * @param session the JavaMail session
     * @param message the JMS message (SwiftMQ implementation)
     * @return the constructed MimeMessage
     */
    MimeMessage transform(javax.mail.Session session, MessageImpl message)
        throws Exception;
}

Built-in Transformers

Transformer Direction Description
inbound.TextMessageTransformer Inbound Converts text/plain mail content into a JMS TextMessage
inbound.MultipartTransformer Inbound Converts multipart mail with attachments into a JMS ObjectMessage containing an ArrayList of HashMap entries
inbound.GenericTextMessageTransformer Inbound Like TextMessageTransformer but accepts any text/* MIME type
inbound.GenericMultipartTransformer Inbound Like MultipartTransformer but accepts any text/* MIME type for the body part
outbound.TextMessageTransformer Outbound Extracts text from a JMS TextMessage as mail body (no attachments)
outbound.MultipartTransformer Outbound Extracts content and attachments from a JMS ObjectMessage (ArrayList of HashMap entries with keys: content-type, content, filename)

Configuring a Custom Transformer

Set the transformer-class property on an inbound or outbound bridge:

<swiftlet name="xt$javamail">
  <bridges>
    <outbound-bridges>
      <outbound-bridge name="my-bridge"
        transformer-class="com.example.MyOutboundTransformer"
        .../>
    </outbound-bridges>
    <inbound-bridges>
      <inbound-bridge name="my-bridge"
        transformer-class="com.example.MyInboundTransformer"
        transformer-max-message-size="-1"
        .../>
    </inbound-bridges>
  </bridges>
</swiftlet>

Configuration Reference

The top-level entity in routerconfig.xml is <swiftlet name="xt$javamail">.

<swiftlet name="xt$javamail"> Properties

These properties are attributes of the <swiftlet name="xt$javamail"> entity.

Parameter Type Default Mandatory Reboot Required Description
collect-interval Long 10000 No No Collect Interval (ms) for the Usage Section
<swiftlet name="xt$javamail" collect-interval="10000"/>

<outbound-bridges> in <swiftlet name="xt$javamail">

Outbound Bridges

Each <outbound-bridge> entry is identified by its name attribute (the Outbound Bridge).

Parameter Type Default Mandatory Reboot Required Description
enabled Boolean false No No Enables/Disables this Bridge
maillog-enabled Boolean false No No Enables/Disables this the Mail Log of this Bridge
smtp-host String Yes No DNS Name of the SMTP Host
smtp-authentication-enabled Boolean false No No Enables/Disables SMTP Authentication
smtp-username String No No SMTP Username
reuse-transport Boolean true No No Specifies whether the SMTP Transport is reused
send-multipart-text-as-html Boolean false No No Specifies whether multipart mail text should be send as text/html
smtp-password String No No SMTP Password
error-policy String error_queue Yes No How to handle errorneous Input Messages (choices: delete, error_queue, retry)
error-queue String javamail-outbound-error Yes No Name of the Error Queue for this Bridge
retryinterval Long 60000 No No Retry Interval (ms) for Re-Connect
source-name String Yes No Name of the Source
source-type String queue No No Type of the Source (choices: queue, topic)
transformer-class String com.swiftmq.extension.javamail.outbound.TextMessageTransformer No No Name of the Transformer Class
<swiftlet name="xt$javamail">
  <outbound-bridges>
    <outbound-bridge name="..." smtp-host="..." error-policy="..." error-queue="..." source-name="..."/>
  </outbound-bridges>
</swiftlet>

<header-translations> in <outbound-bridges>

Header Translations

Each <header-translation> entry is identified by its name attribute (the Header Translation).

Parameter Type Default Mandatory Reboot Required Description
message-property String Yes No Message Property Name
mail-header String from Yes No Mail Header Name
<swiftlet name="xt$javamail">
  <outbound-bridges>
    <outbound-bridge name="...">
      <header-translations>
        <header-translation name="..." message-property="..." mail-header="..."/>
      </header-translations>
    </outbound-bridge>
  </outbound-bridges>
</swiftlet>

<default-headers> in <outbound-bridges>

Default Headers

Each <default-header> entry is identified by its name attribute (the Default Header).

Parameter Type Default Mandatory Reboot Required Description
value String Yes No Value
<swiftlet name="xt$javamail">
  <outbound-bridges>
    <outbound-bridge name="...">
      <default-headers>
        <default-header name="..." value="..."/>
      </default-headers>
    </outbound-bridge>
  </outbound-bridges>
</swiftlet>

<javamail-properties> in <outbound-bridges>

JavaMail Properties

Each <javamail-property> entry is identified by its name attribute (the JavaMail Property).

Parameter Type Default Mandatory Reboot Required Description
value String Yes No Value
<swiftlet name="xt$javamail">
  <outbound-bridges>
    <outbound-bridge name="...">
      <javamail-properties>
        <javamail-property name="..." value="..."/>
      </javamail-properties>
    </outbound-bridge>
  </outbound-bridges>
</swiftlet>

<inbound-bridges> in <swiftlet name="xt$javamail">

Inbound Bridges

Each <inbound-bridge> entry is identified by its name attribute (the Inbound Bridge).

Parameter Type Default Mandatory Reboot Required Description
enabled Boolean false No No Enables/Disables this Bridge
maillog-enabled Boolean false No No Enables/Disables this the Mail Log of this Bridge
error-policy String flag Yes No How to handle errorneous Input Mails (choices: delete, flag)
mail-host String Yes No DNS Name of the Mail Host
mail-host-port Integer 110 Yes No Port Number (pop3: 110, pop3s: 995, imap: 143, imaps: 993)
mail-host-account-name String No No Mail Host Account Name
mail-host-account-password String No No Mail Host Account Password
mail-host-account-folder String INBOX No No Mail Host Account Folder
protocol String pop3 No No Protocol (choices: pop3, pop3s, imap, imaps)
retrieveinterval Long 600000 Yes No Retrieve Interval (ms)
retrieve-max-messages Integer 10 Yes No Max. Messages to process per Interval
target-name String Yes No Name of the Target
target-type String queue No No Type of the Target (choices: queue, topic)
target-message-deliverymode String persistent No No Target Message Delivery Mode (choices: persistent, non-persistent)
target-message-ttl Long 0 No No Target Message Time To Live (min: 0)
target-message-priority Integer 4 No No Target Message Priority (range: 0–9)
target-respect-flowcontrol Boolean true No No Respect Flow Control of the Target
transformer-class String com.swiftmq.extension.javamail.inbound.TextMessageTransformer No No Name of the Transformer Class
transformer-max-message-size Integer 1024 No No Max Message Size (KB) (min: -1)
<swiftlet name="xt$javamail">
  <inbound-bridges>
    <inbound-bridge name="..." error-policy="..." mail-host="..." mail-host-port="..." retrieveinterval="..." retrieve-max-messages="..." target-name="..."/>
  </inbound-bridges>
</swiftlet>

<property-translations> in <inbound-bridges>

Property Translations

Each <property-translation> entry is identified by its name attribute (the Property Translation).

Parameter Type Default Mandatory Reboot Required Description
message-property String Yes No Message Property Name
mail-header String from Yes No Mail Header Name
<swiftlet name="xt$javamail">
  <inbound-bridges>
    <inbound-bridge name="...">
      <property-translations>
        <property-translation name="..." message-property="..." mail-header="..."/>
      </property-translations>
    </inbound-bridge>
  </inbound-bridges>
</swiftlet>

<default-properties> in <inbound-bridges>

Default Properties

Each <default-property> entry is identified by its name attribute (the Default Property).

Parameter Type Default Mandatory Reboot Required Description
value String Yes No Value
<swiftlet name="xt$javamail">
  <inbound-bridges>
    <inbound-bridge name="...">
      <default-properties>
        <default-property name="..." value="..."/>
      </default-properties>
    </inbound-bridge>
  </inbound-bridges>
</swiftlet>

<javamail-properties> in <inbound-bridges>

JavaMail Properties

Each <javamail-property> entry is identified by its name attribute (the JavaMail Property).

Parameter Type Default Mandatory Reboot Required Description
value String Yes No Value
<swiftlet name="xt$javamail">
  <inbound-bridges>
    <inbound-bridge name="...">
      <javamail-properties>
        <javamail-property name="..." value="..."/>
      </javamail-properties>
    </inbound-bridge>
  </inbound-bridges>
</swiftlet>

<mail-filter-definition> in <inbound-bridges>

Definitions of inbound Mail Filters

Parameter Type Default Mandatory Reboot Required Description
mail-filter-reject-from-address String noreply@domain.com Yes No The Mail Address used as from in rejected Messages
mail-filter-reject-queue String mail-filter-reject-queue Yes No Name of the Queue to forward rejected Messages