[RESOLVIDO] UnsatisfiedDependencyException - VRaptor 3

Olá pessoal, já venho alguns dias tentando resolver um problema com minha aplicação. Vi em diversos posts do GUJ erros parecidos, fiz diversos procedimentos e no entando não consegui resolver.
Tenho uma aplicação web utilizando Vraptor 3. Quanodo meu interceptor tenta “interceptar” uma requisição no Controller, gera o seguinte erro:

SEVERE: Servlet.service() for servlet default threw exception
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'repositorioFactoryInterceptor' defined in file [/home/tomcat_garcom/webapps/ROOT/WEB-INF/classes/br/com/ebah/ebah3/logica/vraptor3/controllers/RepositorioFactoryInterceptor.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [br.com.ebah.ebah3.dominio.repositorio.jpa.DaoFactory]: : No matching bean of type [br.com.ebah.ebah3.dominio.repositorio.jpa.DaoFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [br.com.ebah.ebah3.dominio.repositorio.jpa.DaoFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:698)
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:192)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:984)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:886)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:479)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
        at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:328)
        at org.springframework.web.context.request.AbstractRequestAttributesScope.get(AbstractRequestAttributesScope.java:43)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:385)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:375)
        at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1069)
        at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:221)
        at br.com.caelum.vraptor.ioc.spring.VRaptorApplicationContext.getBean(VRaptorApplicationContext.java:244)
        at br.com.caelum.vraptor.ioc.spring.SpringBasedContainer.instanceFor(SpringBasedContainer.java:59)
        at br.com.caelum.vraptor.util.collections.Functions$1.apply(Functions.java:32)
        at br.com.caelum.vraptor.util.collections.Functions$1.apply(Functions.java:30)
        at com.google.common.collect.Lists$TransformingRandomAccessList.get(Lists.java:431)
        at java.util.AbstractList$Itr.next(AbstractList.java:359)
        at com.google.common.collect.Iterators$7.computeNext(Iterators.java:602)
        at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:135)
        at com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:130)
        at com.google.common.collect.Lists.newArrayList(Lists.java:131)
        at com.google.common.collect.Collections2$FilteredCollection.toArray(Collections2.java:219)
        at br.com.caelum.vraptor.interceptor.DefaultInterceptorRegistry.interceptorsFor(DefaultInterceptorRegistry.java:50)
        at br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:42)
        at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
        at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
        at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:80)
        at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
        at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
        at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
        at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
        at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
        at br.com.caelum.vraptor.interceptor.multipart.MultipartInterceptor.intercept(MultipartInterceptor.java:98)
        at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
        at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
        at br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
        at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
        at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
        at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
        at java.lang.Thread.run(Thread.java:636)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [br.com.ebah.ebah3.dominio.repositorio.jpa.DaoFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:896)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:765)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:680)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:771)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:691)
        ... 53 more

Meu DaoFactory está anotado com @Component .
Segue fonte do Interceptor:

@Intercepts
@RequestScoped
public class RepositorioFactoryInterceptor implements Interceptor {
	
	private DaoFactory factory;

	public RepositorioFactoryInterceptor(DaoFactory factory) {
		this.factory = factory;
	}

	public boolean accepts(ResourceMethod arg0) {
		return true;
	}

	public void intercept(InterceptorStack stack, ResourceMethod method, Object obj) throws InterceptionException {
		try {
			stack.next(method, obj);
		} finally {
			if (factory.hasTransaction()) {
				factory.rollback();
			}
			factory.close();
		}
	}

}

To achando que deve ser um erro mto “bobo” na minha aplicação, pois não consigo encontrar motivo algum para este problema.
Desde já agradeço a atenção de todos.

o DaoFactory está anotado com @Component? se não estiver é só anotá-lo

Tá sim Lucas…

@Component
public class DaoFactory implements RepositorioFactoryInterface {

	protected final EntityManager em;
	private EntityTransaction transaction;

	public DaoFactory() {
		em = JPAUtil.getEntityManager();
       }
......
......
}

Oi leandro

qual é o import da anotacao @Component que voce fez pro seu DaoFactory?

no log do vraptor ele avisa que reconheceu a classe como componente?

abracos

Nos logs do Vraptor, ele não achou esse candidato a component (DaoFactory). Detalhe: seria pq essa classe está dentro de um Jar? ela faz parte de um java project que foi criado, e colocado no WEB-INF/lib da minha aplicação
Coloquei esse trecho no web.xml e tbm não adiantou:

<context-param>
	    <param-name>br.com.caelum.vraptor.packages</param-name>
	    <param-value>br.com.ebah.ebah3.dominio.repositorio.jpa</param-value>
</context-param>

O import do @Component é => import br.com.caelum.vraptor.ioc.Component;

Ah, rodando essa aplicação na minha máquina (localhost), o varptor encontra o DaoFactory como component, pois está setado na entrada do Eclipse.
Não está funcionando no tomcat que está em produção.

Como vc disse seu DaoFactory está dentro de um jar que está dentro do WEB-INF/lib?

ele está abaixo desse pacote?
br.com.ebah.ebah3.dominio.repositorio.jpa

Isso mesmo. Ele está dentro de um jar que está na WEB-INF/lib.

E está abaixo do pacote br.com.ebah.ebah3.dominio.repositorio.jpa

Você ta sendo acessorado pelos 2 mestres do VRaptor ai, mas deixa eu me intrometer rapidinho. Se falar besteira eles avisam, mas espero poder ajudar.

Se sua classe ta dentro de um outro jar, pode ser interessante você criar um ComponentFactory para esse seu componente.

Quando rpecisei de classes que estavam em outros jars como Compnente, foi essa abordagem que utilizei e funcionou legal.

Abs

Não deveria precisar de component factory…

o estranho é estar funcionando no eclipse e não no tomcat de produçao…

no tomcat o jar também está em WEB-INF/lib? ele foi exportado junto com seu war?

no tomcat de producao o jar está na estrutura WEB-INF/lib…eu não fiz um war export, eu subi os classes na pasta ROOT/WEB-INF/classes do tomcat e meus jars de dependencia (e jar de outros projetos) na pasta WEB-INF/lib.

Ontem eu fiz uma coisa aqui que não resolver o problema, mas contornou, pois acho que deve ter uma forma de fazer o VRaptor enxergar esse meu component dentro do jar.

Eu criei no projeto web uma classe que se chama DaoFactoryNomeDoServidor, anotada com @component e recebendo o enitityManager no construtor. Esse EntityManager o Vraptor injeta.
Esta classe factory consegue acessar os daos que estão no jar.

Desta forma funcinoou, mas creio que não seja a melhor, pois pra cada projeto web que eu for fazer, teria que criar um DaoFactory especial pra cada um. E a ideia é deixar o DaoFactory isolado em outro projeto de repositorio.

acho que sei qual é o problema…

qdo vc gerou o jar que tem o daofactory, vc marcou pra ele exportar entradas de diretório? Se não tiver com os diretórios dentro do jar o vraptor não consegue achar os arquivos que estão dentro…

Valeu Lucas, era isso mesmo. Abraço