JSF/CDI com thread

191 views
Skip to first unread message

Rogério Cruz Sousa

unread,
Aug 19, 2015, 4:04:35 PM8/19/15
to jav...@googlegroups.com
Olá pessoal !

Tenho uma aplicação JSF com CDI, a ideia é bem simples:

Tenho um formulário que cadastra uma prova, quando clico em salvar chamo um método no managedbean que salva a prova e depois quero mandar e-mail para todos os alunos que irão fazer essa prova.

Como a rotina que manda e-mail demora, quero fazer um método assíncrono para destravar a tela do usuário.

Tentei com Thread ... mas o CDI não injeta nela.

Tentei passar os parâmetros para a Thread quando inicio, mas ai dá o erro:
org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped


Depois pesquisei e fiz a iniciação manual do Weld:
Weld weld = new Weld();
WeldContainer container = weld.initialize();
RequestContext requestContext = container.instance().select(RequestContext.class, UnboundLiteral.INSTANCE).get();
requestContext.activate();            

contaEmailService = container.instance().select(ContaEmailService.class).get();
this.rotinaMandaEmails();
weld.shutdown();


Nesse momento funciona, manda os e-mails .. só que depois a aplicação web para de funcionar, ele perde o CDI.
org.omnifaces.cdi.eager.EagerBeansWebListener.requestInitialized Could not instantiate eager request scoped beans for request /javax.faces.resource/images/ui-icons_333333_256x240.png.xhtml. Possibly the CDI request scope is not active. If this is indeed the case, see JavaDoc on org.omnifaces.cdi.Eager on how to remedy this.


Alguém já fez algo assim? Não precisa ser desse jeito .. mas alguma forma de usar método assíncrono no CDI ( não uso EJB e nem Spring)

Qualquer luz será bem vinda
Obrigado


Arthur Gregório

unread,
Aug 19, 2015, 4:21:44 PM8/19/15
to jav...@googlegroups.com

Se não estou enganado, na nova revisão do CDI teremos eventos assíncronos..

Por agora, tem uma solução usando Ejb que vc pode encontrar aqui: http://piotrnowicki.com/2013/05/asynchronous-cdi-events/

Ou ainda usar o alpha/beta da nova versão do CDI com o weld 3.

--
Você recebeu essa mensagem porque está inscrito no grupo "javasf: JavaServer Faces Group" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para javasf+un...@googlegroups.com.
Acesse esse grupo em http://groups.google.com/group/javasf.
Para ver essa discussão na Web, acesse https://groups.google.com/d/msgid/javasf/CAE90AEZ%3DguGbSmtS1FY%3DKaZCxDvAKBRQZbiH%2B2XfuJiDDE73Cg%40mail.gmail.com.
Para mais opções, acesse https://groups.google.com/d/optout.

Rogério Cruz Sousa

unread,
Aug 19, 2015, 4:34:32 PM8/19/15
to jav...@googlegroups.com
Opa !

Sim, na nova versão do CDI terá um fireAsync -> http://blog.caelum.com.br/novidades-do-java-ee-8/  mas só em dezembro do ano que vem.

EJB não dá pra eu usar pois estou no Tomcat8.




Everton Fujimoto

unread,
Aug 19, 2015, 4:45:22 PM8/19/15
to jav...@googlegroups.com

Tentaste fazer um lockup no beanmanager do cdi dentro da thread.?

Rogério Cruz Sousa

unread,
Aug 19, 2015, 4:54:29 PM8/19/15
to jav...@googlegroups.com
olá Everton .. tentei: contaEmailService = CDIServiceLocator.getBean(ContaEmailService.class);

ele até acha o objeto, mas dé o erro de context request

org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped


Nilson Uehara

unread,
Aug 19, 2015, 4:59:33 PM8/19/15
to Grupo JSF
E se você criasse um serviço de envio de emails que roda em background no servidor lendo um banco de dados de emails (tipo um cron que acorda de tempos em tempos)?
Assim vc só precisa gravar o email que será disparado nessa fila e deixar o serviço lidar com ela.

Um abraço,
Nilson Uehara

Everton Fujimoto

unread,
Aug 19, 2015, 5:32:59 PM8/19/15
to jav...@googlegroups.com

Tentou usar com applicationscope.?

Ricardo Pestana

unread,
Aug 20, 2015, 5:05:22 AM8/20/15
to jav...@googlegroups.com

Use a concurrency API que você consegue tranquilamente

Charles Queiroz

unread,
Aug 20, 2015, 8:27:36 AM8/20/15
to jav...@googlegroups.com
Bom… algumas sugestões: 

Fila JMS

Já que tem que ser assíncrono, pq não usar uma fila pra isso? Ao logar, você dispara o evento como normalmente está fazendo, só que ao invés de já tentar enviar o email, coloca isso em uma fila onde o seu serviço (o que envia o email) irá processar. 

É interessante pois caso os envios dos emails passem a ser um gargalo (em termos de processamento) você consegue escalar isso facilmente pois basta registrar mais instancias do seu serviço como ouvintes dessa fila de emails a serem enviados. Uma vez persistido na fila, você terá garantias que o email será enviado. 

Outro ponto é que você pode agendar esses envios usando batch processing, e faz com que toda a solução seja assíncrona e totalmente a parte do seu sistema de login. A única responsabilidade dele será disparar o evento que o Observer irá escutar para mandar pra fila, de lá, o seu serviço que envia o email (que pode ser outra aplicação específica pra isso - microservice). Dai você tem o desacoplamento entre a solução de envio de emails, e a sua aplicação. 

Você, ao separar isso em outro serviço específico, poderá usar para qualquer outra aplicação que você queira que tenha a capacidade de enviar emails, pois basta que tal app notifique o evento. 

Enfim, CDI só virá com eventos assíncronos na próxima versão como já explicado, e para atingir esse objetivo, eu faria dessa forma. Extraio essa funcionalidade de envio de emails para um serviço a parte, e como é uma caracteristica assincrona, eu consumo essa fila e vou processando-a. Dai, você poderá atribuir status aos emails, já que é um mecanismo assíncrono, você precisará posteriormente de um feedback se funcionou ou não o envio, ou quem está pendente. 

É uma abordagem que não é a mais trivial do mundo, mas é simples. inclusive o servidor de aplicação te dá grande parte disso ai prontinho (JMS, Batch, CDI, Emails, etc..) é só usar.

:D  

Atenciosamente,

Charles Queiroz 


Dazen™ IT Services
Technology - Software Development 

cha...@dazen.com.br

Fortaleza - CE

Phone: +55 85 9933 1585 

Twitter: @CharlesQueiiroz


Rafael Ponte

unread,
Aug 20, 2015, 8:46:31 AM8/20/15
to jav...@googlegroups.com
Oi Charles,

O rapaz só quer enviar alguns emails numa thread separada, só isso. :-)

A abordagem de usar a API de concorrência do Java acaba sendo a mais simples. Só basta ter cuidado para passar o objeto prontinho para o envio do email. Se ele tiver problemas com a entrega dos emails ele pode optar por uma fila de emails (como você sugeriu), seja ela usando JMS ou mesmo banco de dados.

Um abraço!



Para mais opções, acesse https://groups.google.com/d/optout.
--
Rafael Ponte
TriadWorks | Formação Java
http://cursos.triadworks.com.br

Charles Queiroz

unread,
Aug 20, 2015, 9:26:15 AM8/20/15
to jav...@googlegroups.com
Eu concordo Rafael. É mais simples. Como eu disse, a que falei não é a mais trivial, mas ainda sim é simples ( configura a fila no AS, cria a classe com o método que a consome na própria app se for o caso e done). 

Mas eu sou suspeito, pois sou preguiçoso e odeio ter que voltar a mesma problemática… eu geralmente separo as coisas pq posso montar a app como um lego. Já tem um bom tempo que fiz isso e hoje, qualquer app que faço que precise enviar email, pra mim já é um requisito atendido. tá pronto. Só preciso enviar a mensagem (pois é assincrono, se tivesse que saber de imediato se funcionou ou não, usaria REST), e pronto. 

Eu meio que tenho preguiça de ficar refazendo as coisas. As vezes investir um pouco mais de “esforço” em algo que vai resolver "de vez” é mais jogo (eu acho). Faço isso pra importação de arquivos, imagens, criptografia, logs, etc.. eu mando pros caras especializados (serviços que as vezes se resumem a um método em uma classe) com os parâmetros que preciso e ele faz o serviço pra mim. 

Mas ai sou eu.. como é rápido pra mim fazer isso eu não vejo tanta complexidade, mas de fato, só mandar um email em uma thread é mais simples com a API de concorrência, concordo, desde que se saiba trabalhar corretamente com concorrência pois não é tão trivial como parece. Há certas cascas de banana que só pipoca em produção.. lembro-me de um certo projeto em um banco que participei que tive muita dores de cabeça com isso… 

:D

Existem varias formas de esfolar um gato.. foi só uma sugestão. Pense que estamos em um brainstorm, já havia dado como resolvido, mas pq não pensar em mais coisas? Vai que alguém da outra solução, e outra, e outra… ideias geram ideias.. é disso que gosto ao discutir. hahaha.. 

Vlw!

Atenciosamente,

Charles Queiroz 


Dazen™ IT Services
Technology - Software Development 

cha...@dazen.com.br

Fortaleza - CE

Phone: +55 85 9933 1585 

Twitter: @CharlesQueiiroz

Douglas

unread,
Sep 24, 2015, 4:20:04 PM9/24/15
to jav...@googlegroups.com
Boa tarde!

Charles, tenho uma necessidade de envio de e-mails.
Nesse momento são poucos, mas me interessa mandar para fila e ser processado pelo AS.
Criei no Glassfish a configuração do JavaMail Sessions. Pesquisei e encontrei algumas formas, mas não sei ao certo qual forma seguir.
Você poderia dar um exemplo da forma que usa?

Obrigado

DRauber

Reply all
Reply to author
Forward
0 new messages