bom, se vc já tem o construtor de string, é só passar “/param.properties” no construtor da PropertiesLoader… deveria funcionar
Mas o VRaptor aceita uma classe @AplicationScoped injetada em outra @AplicationScoped?
sim…
não pode colocar um Request (nem Session) scoped dentro de um App scoped, o resto pode
Posso injetar um @Component dentro de outro @Component? Parece que a zica aqui é referente a injeção de dependência mesmo…
sim, pode, desde que os escopos sejam compatíveis
Escopos compatíveis seria o que?
Você só pode injetar um componente cujo escopo seja maior que o do objeto atual. Por exemplo, se você tem um objeto request você pode tranquilamente injetar um objeto application. Porém o inverso não pode.
prototype < request < flash < session < application
Opa, valeu Garcia, mas o @Component entra aonde nessa hierarquia?
na verdade o prototype é meio mágico… ele pode ser injetado no application, desde que ele só dependa de application…
prototype pode ser injetado em qqer um, desde q as dependências dele sejam compatíveis
@Component sem anotação de escopo é request (escopo padrão do VRaptor)
Poxa, não sabia que existia essa hierarquia, parece que aqui o problema é em relação a isso, pois tenho:
MyFirstApplicationTask que é @Component e @ApplicationScoped.
ParameterLoader que é @Component.
Imagens que é @Component.
News que é @Component.
A zica está na hora da aplicação instanciar o MyFirstApplicationTask, pois no construtor dele está injetado o News e ParameterLoader, por sua vez, o News possui injetado o ParameterLoader e Imagens e a classe Imagens possui o ParameterLoader.
Sacaram o drama? Um dependendo do outro…=/
Vou revisar isso aqui e tentar resolver.
Obrigado pelas dicas. o/
Uma olhada rápida na situação, se o MyFirstApplicationTask é @ApplicationScoped todos os outros tb deverão estar anotados com ApplicationScoped, pois mesmo que Imagens não esteja injetado no MyFirstApplicationTask, o News está e traz automaticamente o Imagens. O News estando como @ApplicationScoped obriga a classe Imagens estar anotada tb com @ApplicationScoped, ou seja, uma classe anotada como @ApplicationScoped faz com que toda a hierarquia de injeções tb sejam anotadas com @ApplicationScoped. É isso?
tem outra solução:
basicamente sua Task vai chamar uma URL da sua aplicação que vai fazer o serviço de verdade. Assim quem trata essa URL vai poder ser request scoped (vai ser um Controller)
Lucas, consegui colocar sua dica aqui pra rodar, está funcionando na classe Imagens e News, só não está rodando na classe MyFirstApplicationTask. =/
@Component
@ApplicationScoped
public class MyFirstApplicationTask implements ApplicationTask {
private News news;
private ParameterLoader parameterLoader;
public MyFirstApplicationTask(TaskScheduler scheduler, News news, ParameterLoader parameterLoader) {
this.schedule(scheduler);
this.news = news;
this.parameterLoader = parameterLoader;
}
public void schedule(TaskScheduler scheduler) {
String agenda = this.parameterLoader.getParameter("scheduler.mail");
scheduler.schedule(this, new CronTrigger("agenda"));
}
public void run(){
news.enviar();
}
}
O problema agora é nesta classe, pq nas outras está rodando, veja a stacktrace:
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [br.com.imobiliaria.component.MyFirstApplicationTask]: Constructor threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:141)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:105)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:278)
... 39 more
Caused by: java.lang.NullPointerException
at br.com.imobiliaria.component.MyFirstApplicationTask.schedule(MyFirstApplicationTask.java:25)
Esse NPE é justamente na linha:
String agenda = this.parameterLoader.getParameter("scheduler.mail");
Por alguma razão que desconheço, ele não esta injetando o ParameterLoader.
Vou ver esse link que vc postou…
Valeu!!
Acho que descobri o motivo de não injetar, faltou o construtor necessário exigido pelo Spring Security:
protected MyFirstApplicationTask() {
}
A aplicação sobe, mas a MyFirstApplicationTask tá morta, nada acontece.
Sabe como posso contornar isso?
É zica na injeção mesmo, instanciei o objeto ParameterLoader dentro do método de execução e a classe enviou o email:
@Component
@ApplicationScoped
public class MyFirstApplicationTask implements ApplicationTask {
private News news;
public MyFirstApplicationTask(TaskScheduler scheduler, News news) {
this.schedule(scheduler);
this.news = news;
}
public void schedule(TaskScheduler scheduler) {
ParameterLoader parameterLoader = new ParameterLoader(); // instanciando o objeto
String agenda = parameterLoader.getParameter("scheduler.mail");
scheduler.schedule(this, new CronTrigger(agenda));
}
public void run(){
news.enviar();
}
}
Não sei pq não rodou injetando o ParameterLoader, mas pelo menos enviou o email. Pelo menos não está mais usando servletContext, tá pegando o param.properties de dentro da /src.
Valeu Lucas e Garcia, vou dar por resolvido. =)
Abraço!
btw, aquele Nullpointer era pq vc fez o schedule antes de fazer
this.parameterLoader = parameterLoader;
pode voltar a colocá-lo no construtor
Putzzzzzzzzzzzzz, era isso! Aprendi mais uma! :lol:
A ordem no construtor faz diferença, eu nem tinha percebido isso, agora foi, tá td no esquema!
Valeu Lucas!!! \o/
muito provavelmente aquela história de usar o @PostConstruct funcionaria, então… mas enfim, funcionando
Entendi! =)
Em relação ao que eu tinha postado lá em cima, é aquilo mesmo?
Valeu!!