Vraptor - NPE (ComponentFactory)

2 respostas
wpivotto

Pessoal estou tempo um problema no Vraptor 3.3.1.
Tenho o seguinte componente que funciona perfeitamente

@Component
@ApplicationScoped
public class TaskValidatorFactory {

	private final Container container;
	
	public TaskValidatorFactory(Container container) {
		this.container = container;
	}

	public Validator getInstance() {
		return new TaskValidator(buildBeanValidator());
	}
	
	public BeanValidator buildBeanValidator(){
		if(isClassPresent("javax.validation.Validation")){
			ValidatorFactory factory = container.instanceFor(ValidatorFactory.class);
			return new CustomJSR303Validator(factory.getValidator(), factory.getMessageInterpolator());
		}
		else
			return new NullBeanValidator();
	}
	
	private boolean isClassPresent(String className) {
        try {
            Class.forName(className);
            return true;
        } catch (ClassNotFoundException e) {
            return false;
        }
    }
}

Porém quando transformo ele em um ComponentFactory recebo uma NPE (somente no Guice)

Caused by: java.lang.NullPointerException
	at br.com.caelum.vraptor.ioc.guice.GuiceProvider$GuiceContainer.instanceFor(GuiceProvider.java:61)
	at br.com.caelum.vraptor.tasks.validator.TaskValidatorFactory.buildBeanValidator(TaskValidatorFactory.java:35)
	at br.com.caelum.vraptor.tasks.validator.TaskValidatorFactory.getInstance(TaskValidatorFactory.java:29)
	at br.com.caelum.vraptor.tasks.validator.TaskValidatorFactory.getInstance(TaskValidatorFactory.java:15)
	at br.com.caelum.vraptor.ioc.guice.ComponentFactoryProviderAdapter.get(ComponentFactoryProviderAdapter.java:40)
	at com.google.inject.internal.BoundProviderFactory.get(BoundProviderFactory.java:56)
	at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38)
	at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62)
	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:84)
	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
	at com.google.inject.internal.InjectorImpl$4$1.call(InjectorImpl.java:968)
	at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1021)
	at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:964)
	at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1003)
	at br.com.caelum.vraptor.ioc.guice.AllImplementationsProvider.get(AllImplementationsProvider.java:26)
	at br.com.caelum.vraptor.ioc.guice.AllImplementationsProvider.get(AllImplementationsProvider.java:13)
	at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
	at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38)
	at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62)
	at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:84)
	at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
	at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1021)
	at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
	at com.google.inject.Scopes$1$1.get(Scopes.java:65)
	at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
	at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:204)
	at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:198)
	at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1014)
	at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:198)
	at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:179)
	... 18 more

Este componente é invocado sempre que uma task é executada. Se eu adicionar um delay na execução da task (por exemplo 5 seg), o problema é resolvido.
Parece que se eu invocar o getInstance logo após o vraptor subir, o injector do guice ainda não está setado…

É isso mesmo ou eu estou fazendo algo de errado?

2 Respostas

Lucas_Cavalcanti

parece que é isso mesmo… acho que a invocação desse método está acontecendo no momento da criação do injector, então vc não consegue usar o container… isso acontece nos Appscoped

troca o container.instanceFor(ValidatorFactory.class) por:

new ValidatorFactoryCreator().getInstance();
wpivotto

Lucas Cavalcanti:
parece que é isso mesmo… acho que a invocação desse método está acontecendo no momento da criação do injector, então vc não consegue usar o container… isso acontece nos Appscoped

troca o container.instanceFor(ValidatorFactory.class) por:

new ValidatorFactoryCreator().getInstance();

Assim funcionou. Chamei diretamente o ValidatorFactoryCreator().getInstance() que o próprio Vraptor utiliza internamente.
Valeu Lucas

Criado 12 de setembro de 2011
Ultima resposta 12 de set. de 2011
Respostas 2
Participantes 2