org.apache.wiki.util
Class MailUtil

java.lang.Object
  extended by org.apache.wiki.util.MailUtil

public final class MailUtil
extends Object

Contains static methods for sending e-mails to recipients using JNDI-supplied JavaMail Sessions supplied by a web container (preferred) or configured via jspwiki.properties; both methods are described below. Because most e-mail servers require authentication, for security reasons implementors are strongly encouraged to use container-managed JavaMail Sessions so that passwords are not exposed in jspwiki.properties.

To enable e-mail functions within JSPWiki, administrators must do three things: ensure that the required JavaMail JARs are on the runtime classpath, configure JavaMail appropriately, and (recommdended) configure the JNDI JavaMail session factory.

JavaMail runtime JARs

The first step is easy: JSPWiki bundles recent versions of the required JavaMail mail.jar and activation.jar into the JSPWiki WAR file; so, out of the box this is already taken care of. However, when using JNDI-supplied Session factories, these should be moved, not copied, to a classpath location where the JARs can be shared by both the JSPWiki webapp and the container. For example, Tomcat 5 provides the directory $CATALINA_HOME/common/lib for storage of shared JARs; move mail.jar and activation.jar there instead of keeping them in /WEB-INF/lib.

JavaMail configuration

Regardless of the method used for supplying JavaMail sessions (JNDI container-managed or via jspwiki.properties, JavaMail needs certain properties set in order to work correctly. Configurable properties are these:

Property Default Definition
jspwiki.mail.jndiname mail/Session The JNDI name of the JavaMail session factory
mail.smtp.host 127.0.0.1 The SMTP mail server from which messages will be sent.
mail.smtp.port 25 The port number of the SMTP mail service.
mail.smtp.account (not set) The user name of the sender. If this value is supplied, the JavaMail session will attempt to authenticate to the mail server before sending the message. If not supplied, JavaMail will attempt to send the message without authenticating (i.e., it will use the server as an open relay). In real-world scenarios, you should set this value.
mail.smtp.password (not set) The password of the sender. In real-world scenarios, you should set this value.
mail.from ${user.name}@${mail.smtp.host}* The e-mail address of the sender.
mail.smtp.timeout 5000* Socket I/O timeout value, in milliseconds. The default is 5 seconds.
mail.smtp.connectiontimeout 5000* Socket connection timeout value, in milliseconds. The default is 5 seconds.
mail.smtp.starttls.enable true* If true, enables the use of the STARTTLS command (if supported by the server) to switch the connection to a TLS-protected connection before issuing any login commands. Note that an appropriate trust store must configured so that the client will trust the server's certificate. By default, the JRE trust store contains root CAs for most public certificate authorities.

*These defaults apply only if the stand-alone Session factory is used (that is, these values are obtained from jspwiki.properties). If using a container-managed JNDI Session factory, the container will likely supply its own default values, and you should probably override them (see the next section).

Container JNDI Session factory configuration

You are strongly encouraged to use a container-managed JNDI factory for JavaMail sessions, rather than configuring JavaMail through jspwiki.properties. To do this, you need to two things: uncomment the <resource-ref> block in /WEB-INF/web.xml that enables container-managed JavaMail, and configure your container's JavaMail resource factory. The web.xml part is easy: just uncomment the section that looks like this:

<resource-ref>
   <description>Resource reference to a container-managed JNDI JavaMail factory for sending e-mails.</description>
   <res-ref-name>mail/Session</res-ref-name>
   <res-type>javax.mail.Session</res-type>
   <res-auth>Container</res-auth>
 </resource-ref>

To configure your container's resource factory, follow the directions supplied by your container's documentation. For example, the Tomcat 5.5 docs state that you need a properly configured <Resource> element inside the JSPWiki webapp's <Context> declaration. Here's an example shows how to do it:

<Context ...>
 ...
 <Resource name="mail/Session" auth="Container"
           type="javax.mail.Session"
           mail.smtp.host="127.0.0.1"/>
           mail.smtp.port="25"/>
           mail.smtp.account="your-account-name"/>
           mail.smtp.password="your-password"/>
           mail.from="Snoop Dogg <snoop@dogg.org>"/>
           mail.smtp.timeout="5000"/>
           mail.smtp.connectiontimeout="5000"/>
           mail.smtp.starttls.enable="true"/>
 ...
 </Context>

Note that with Tomcat (and most other application containers) you can also declare the JavaMail JNDI factory as a global resource, shared by all applications, instead of as a local JSPWiki resource as we have done here. For example, the following entry in $CATALINA_HOME/conf/server.xml creates a global resource:

<GlobalNamingResources>
   <Resource name="mail/Session" auth="Container"
             type="javax.mail.Session"
             ...
             mail.smtp.starttls.enable="true"/>
 </GlobalNamingResources>

This approach — creating a global JNDI resource — yields somewhat decreased deployment complexity because the JSPWiki webapp no longer needs its own JavaMail resource declaration. However, it is slightly less secure because it means that all other applications can now obtain a JavaMail session if they want to. In many cases, this is what you want.

NOTE: Versions of Tomcat 5.5 later than 5.5.17, and up to and including 5.5.23 have a b0rked version of $CATALINA_HOME/common/lib/naming-factory.jar that prevents usage of JNDI. To avoid this problem, you should patch your 5.5.23 version of naming-factory.jar with the one from 5.5.17. This is a known issue and the bug report (#40668) is here.


Nested Class Summary
protected static class MailUtil.SmtpAuthenticator
          Simple Authenticator subclass that authenticates a user to an SMTP server.
 
Field Summary
protected static String DEFAULT_MAIL_CONN_TIMEOUT
           
protected static String DEFAULT_MAIL_HOST
           
protected static String DEFAULT_MAIL_JNDI_NAME
           
protected static String DEFAULT_MAIL_PORT
           
protected static String DEFAULT_MAIL_TIMEOUT
           
protected static String DEFAULT_SENDER
           
protected static org.apache.log4j.Logger log
           
protected static String PROP_MAIL_ACCOUNT
           
protected static String PROP_MAIL_CONNECTION_TIMEOUT
           
protected static String PROP_MAIL_HOST
           
protected static String PROP_MAIL_JNDI_NAME
           
protected static String PROP_MAIL_PASSWORD
           
protected static String PROP_MAIL_PORT
           
protected static String PROP_MAIL_SENDER
           
protected static String PROP_MAIL_STARTTLS
           
protected static String PROP_MAIL_TIMEOUT
           
protected static String PROP_MAIL_TRANSPORT
           
 
Method Summary
protected static javax.mail.Session getJNDIMailSession(String jndiName)
          Returns a JavaMail Session instance from a JNDI container-managed factory.
protected static String getSenderEmailAddress(javax.mail.Session pSession, Properties pProperties)
          Gets the Sender's email address from JNDI Session if available, otherwise from the jspwiki.properties or lastly the default value.
protected static javax.mail.Session getStandaloneMailSession(Properties props)
          Returns a stand-alone JavaMail Session by looking up the correct mail account, password and host from a supplied set of properties.
static void sendMessage(Properties props, String to, String subject, String content)
          Sends an e-mail to a specified receiver using a JavaMail Session supplied by a JNDI mail session factory (preferred) or a locally initialized session based on properties in jspwiki.properties.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

log

protected static final org.apache.log4j.Logger log

DEFAULT_MAIL_JNDI_NAME

protected static final String DEFAULT_MAIL_JNDI_NAME
See Also:
Constant Field Values

DEFAULT_MAIL_HOST

protected static final String DEFAULT_MAIL_HOST
See Also:
Constant Field Values

DEFAULT_MAIL_PORT

protected static final String DEFAULT_MAIL_PORT
See Also:
Constant Field Values

DEFAULT_MAIL_TIMEOUT

protected static final String DEFAULT_MAIL_TIMEOUT
See Also:
Constant Field Values

DEFAULT_MAIL_CONN_TIMEOUT

protected static final String DEFAULT_MAIL_CONN_TIMEOUT
See Also:
Constant Field Values

DEFAULT_SENDER

protected static final String DEFAULT_SENDER
See Also:
Constant Field Values

PROP_MAIL_JNDI_NAME

protected static final String PROP_MAIL_JNDI_NAME
See Also:
Constant Field Values

PROP_MAIL_HOST

protected static final String PROP_MAIL_HOST
See Also:
Constant Field Values

PROP_MAIL_PORT

protected static final String PROP_MAIL_PORT
See Also:
Constant Field Values

PROP_MAIL_ACCOUNT

protected static final String PROP_MAIL_ACCOUNT
See Also:
Constant Field Values

PROP_MAIL_PASSWORD

protected static final String PROP_MAIL_PASSWORD
See Also:
Constant Field Values

PROP_MAIL_TIMEOUT

protected static final String PROP_MAIL_TIMEOUT
See Also:
Constant Field Values

PROP_MAIL_CONNECTION_TIMEOUT

protected static final String PROP_MAIL_CONNECTION_TIMEOUT
See Also:
Constant Field Values

PROP_MAIL_TRANSPORT

protected static final String PROP_MAIL_TRANSPORT
See Also:
Constant Field Values

PROP_MAIL_SENDER

protected static final String PROP_MAIL_SENDER
See Also:
Constant Field Values

PROP_MAIL_STARTTLS

protected static final String PROP_MAIL_STARTTLS
See Also:
Constant Field Values
Method Detail

sendMessage

public static void sendMessage(Properties props,
                               String to,
                               String subject,
                               String content)
                        throws javax.mail.internet.AddressException,
                               javax.mail.MessagingException

Sends an e-mail to a specified receiver using a JavaMail Session supplied by a JNDI mail session factory (preferred) or a locally initialized session based on properties in jspwiki.properties. See the top-level JavaDoc for this class for a description of required properties and their default values.

The e-mail address used for the to parameter must be in RFC822 format, as described in the JavaDoc for InternetAddress and more fully at http://www.freesoft.org/CIE/RFC/822/index.htm. In other words, e-mail addresses should look like this:

Snoop Dog <snoop.dog@shizzle.net>
snoop.dog@shizzle.net

Note that the first form allows a "friendly" user name to be supplied in addition to the actual e-mail address.

Parameters:
props - the properties that contain mail session properties
to - the receiver
subject - the subject line of the message
content - the contents of the mail message, as plain text
Throws:
javax.mail.internet.AddressException - If the address is invalid
javax.mail.MessagingException - If the message cannot be sent.

getSenderEmailAddress

protected static String getSenderEmailAddress(javax.mail.Session pSession,
                                              Properties pProperties)
Gets the Sender's email address from JNDI Session if available, otherwise from the jspwiki.properties or lastly the default value.

Parameters:
pSession - Session
pProperties - Properties
Returns:
String

getStandaloneMailSession

protected static javax.mail.Session getStandaloneMailSession(Properties props)
Returns a stand-alone JavaMail Session by looking up the correct mail account, password and host from a supplied set of properties. If the JavaMail property "mail.smtp.account" is set to a value that is non-null and of non-zero length, the Session will be initialized with an instance of Authenticator.

Parameters:
props - the properties that contain mail session properties
Returns:
the initialized JavaMail Session

getJNDIMailSession

protected static javax.mail.Session getJNDIMailSession(String jndiName)
                                                throws NamingException
Returns a JavaMail Session instance from a JNDI container-managed factory.

Parameters:
jndiName - the JNDI name for the resource. If null, the default value of mail/Session will be used
Returns:
the initialized JavaMail Session
Throws:
NamingException - if the Session cannot be obtained; for example, if the factory is not configured


Copyright © {inceptionYear}-2014 The Apache Software Foundation. All rights reserved.