Run process on a thread (JSF 2.2 - WELD 2.3)

453 Views Asked by At

I have this error when I try run a thread:

WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped

I tried this: No active contexts for scope type javax.enterprise.context.RequestScoped when invoking a bean from a thread

So I have this error:

2017-09-08 14:09:56,205 ERROR [br.com.ideallsistemas.obrigacoes.util.jsf.JsfExceptionHandler] Erro: #{emailCadastroBean.enviarEmail()}: java.lang.NoClassDefFoundError: org/jboss/weld/environment/se/Weldjavax.faces.FacesException: #{emailCadastroBean.enviarEmail()}: java.lang.NoClassDefFoundError: org/jboss/weld/environment/se/Weld

My method called from bean

    public void enviarEmail(Email email) {
    List<String> destinatarios = destinatariosOf(email);
    Weld weld = new Weld();
    final WeldContainer container = weld.initialize();
    RequestContext requestContext= container.instance().select(RequestContext.class, UnboundLiteral.INSTANCE).get();
        requestContext.activate();

    final EnvioEmailService pojo = container.instance().select(EnvioEmailService.class).get();
    Thread envioiEmail = new Thread() {
        public void run() {
            try {                                        
                for (String destinatario : destinatarios) {
                    pojo.envioEmailTaskDo(email, destinatario);
                }
            }catch (Exception e) {
                System.out.println(e.getMessage());
            }   
        }
    };
    envioiEmail.start();
    weld.shutdown();
}
1

There are 1 best solutions below

0
On

For JEE applications do not create threads yourself!

You must use @Asynchronous annotation.

Use in EJB like this:

@Stateless
public class NameOfEJB  {

    @Asynchronous
    public void sendEmail() {
        //send email here
    }
}

Inject and use it in other component (JSF managed bean, CDI bean, other EJB...)

@Named
@ViewScoped
public class CDIBean implements Serializable {

    private static final long serialVersionUID = 1L;

    @EJB
    private NameOfEJB nameOfEJB;

    public void processForm() {
        nameOfEJB.sendEmail();
    }

}

The container will do the async process for you.

Note that the code is more simple, clean and maintainable.