Seam Asynchronous Email

When you need to send an email from your web application, you should preferably send the email asynchronously. Sending email synchronously may introduce unknown wait time for the end user depending on how responsive your mail server is at that moment.

Sending email asynchronously involves starting the email action as a background job. You should not start a new thread as it may result in thread swarming. Always use a thread pool, which is a bunch of worker threads waiting for jobs in some sort of a queue.

JBoss Seam provides an easy way to do this. Simply add the @Asynchronous tag to a method to make it asynchronous! As simple as that. Let’s dive into some code now.

Write an async mailer class

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.async.Asynchronous;
import org.jboss.seam.annotations.async.Duration;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.faces.Renderer;

@Name("emailService")
@AutoCreate
public class EmailService {
    private static final Log logger = LogFactory.getLog(EmailService.class);

    @In(create = true)
    private Renderer renderer;

    @Asynchronous
    public void sendMessage(@Duration
    long delay, String template, Object infoNeededForTemplate) {
        try {
            Contexts.getEventContext().set("info", infoNeededForTemplate);
            renderer.render(template);
        } catch (Exception e) {
            // suppress information.
            logger.error(e.getMessage());
        }
    }
}

Call the mailer class

    @In
    private EmailService emailService;

    public void takeAction() {
       // do something
       // ...

       // send email asynchrously
       emailService.sendMessage(500, "location-of-template.xhtml");
    }

Common errors

could not create Component org.jboss.seam.async.dispatcher

Exception sending context initialized event to listener instance of class org.jboss.seam.servlet.SeamListener
java.lang.RuntimeException: Could not create Component: org.jboss.seam.async.dispatcher
	at org.jboss.seam.init.Initialization.addComponent(Initialization.java:989)
	at org.jboss.seam.init.Initialization.installComponents(Initialization.java:911)
	at org.jboss.seam.init.Initialization.init(Initialization.java:589)
	at org.jboss.seam.servlet.SeamListener.contextInitialized(SeamListener.java:34)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3856)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:4361)
...
Caused by: java.lang.IllegalArgumentException: You must specify org.jboss.seam.core.init.jndiPattern or use @JndiName: org.jboss.seam.async.dispatcher
	at org.jboss.seam.Component.getJndiName(Component.java:438)
	at org.jboss.seam.Component.(Component.java:243)
	at org.jboss.seam.Component.(Component.java:217)
	at org.jboss.seam.init.Initialization.addComponent(Initialization.java:974)

Cause

This error occurs if you specify the following in components.xml

Solution

Remove the above line from components.xml

name not bound

Caused by: javax.faces.el.EvaluationException: org.jboss.seam.InstantiationException: Could not instantiate Seam component: org.jboss.seam.async.dispatcher
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:91)
	at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:91)
	... 42 more
Caused by: org.jboss.seam.InstantiationException: Could not instantiate Seam component: org.jboss.seam.async.dispatcher
	at org.jboss.seam.Component.newInstance(Component.java:1986)
	at org.jboss.seam.Component.getInstance(Component.java:1876)
	... 43 more
Caused by: javax.naming.NameNotFoundException: foochal not bound
	at org.jnp.server.NamingServer.getBinding(NamingServer.java:529)
	at org.jnp.server.NamingServer.getBinding(NamingServer.java:537)
	at org.jnp.server.NamingServer.getObject(NamingServer.java:543)

Related posts:

  1. A common configuration mistake which makes Seam slow
  2. How to configure multiple page.xml files in Seam 2.2
  3. Implementing context senstive permissions and authorization in JSF Seam
  4. Spring classpath scan breaks when migrating from JBoss4 to JBoss5
  5. New Java Framework “Clickframes” 0.9 beta released!

9 comments to Seam Asynchronous Email

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Get Adobe Flash playerPlugin by wpburn.com wordpress themes