If you are using Seam’s MailSession to send out going e-mail from your Seam application you can run into trouble if you have a mail server in any environment (dev, test, stage, prod) that allows outgoing mail based on the client’s IP address and does not use username and password based authentication.

The standard configuration for the MailSession is in the components.xml file and looks like this (if you’ve used SeamGen to create your project):

	<mail:mail-session host="@mailhost@" port="@mailport@" username="@mailusername@" password="@mailpassword@" />

Then each of your environments has a components-{env}.properties file, which is deployed out and used to populate the @variable@ placeholders in the components.xml file. For instance your components.dev.properties file might look like this:

jndiPattern=YourApp/#{ejbName}/local
debug=true
mailhost=mail.mydomain.com
mailport=25
mailusername=mailus3r
mailpassword=mailp4ss

Which works great. However, if for instance your production environment uses IP based mail authentication for outbound e-mail, you might try to set your components-prod.properties file to look like this:

jndiPattern=YourApp/#{ejbName}/local
debug=false
mailhost=prodmail.mydomain.com
mailport=25
mailusername=
mailpassword=

However, that ends up setting empty strings into the username and password member variables of the MailSession component, and unfortunately the logic which determines whether or not to authenticate with the mail server checks for nulls only. So with empty strings, it attempts to authenticate with the mail server using a blank username and password. Which fails, and causes an unhelpful Faces error (unless you turn on debug on the MailSession component).

I’ve logged a Jira ticket about it here: JBSEAM-4176

You can do a simple workaround by overriding the MailSession component with your own sub-class of the MailSession class. In your sub-class you can override the setUsername and setPassword methods, check for empty strings and set null into the member variable if the parameter is null or empty. Luckily the Seam Install precedence system makes it very easy to override the default Seam component.

package com.myapp.mail;

import static org.jboss.seam.ScopeType.APPLICATION;

import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;

/**
 * The Class MailSession. This is an overriding class designed to work around
 * https://jira.jboss.org/jira/browse/JBSEAM-4176
 */
@Name("org.jboss.seam.mail.mailSession")
@Install(precedence = org.jboss.seam.annotations.Install.APPLICATION, classDependencies = "javax.mail.Session")
@Scope(APPLICATION)
@BypassInterceptors
public class MailSession extends org.jboss.seam.mail.MailSession {

    @Override
    public void setPassword(String pPassword) {
	if (pPassword == null || pPassword.trim().length() == 0) {
	    super.setPassword(null);
	} else {
	    super.setPassword(pPassword);
	}
    }

    @Override
    public void setUsername(String pUsername) {
	if (pUsername == null || pUsername.trim().length() == 0) {
	    super.setUsername(null);
	} else {
	    super.setUsername(pUsername);
	}
    }

}