[Vraptor] Conversor

67 respostas
G

Olá,

Eu estou tentando implementar um conversor do Vraptor para minhas classes de modelo. Mas meu conversor não está sendo chamado:
@Convert(Model.class)
public class ModelConverter implements Converter<Model> {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	private Session session;

	public ModelConverter(Session session) {
		this.session = session;
	}

	public Model convert(String value, Class<? extends Model> type, ResourceBundle bundle) {
		if (value == null || value.equals("")) {
			return null;
		}

		try {
			long modelId = Long.parseLong(value);
			ModelDao<Model> modelDao = new ModelDao<Model>(session, type);
			return modelDao.visualizar(modelId);
		} catch (Exception e) {
			logger.error("Erro ao converter Convênio. Valor: " + value, e);
			throw new ConversionError(bundle.getString("is_not_a_valid_value"));
		}
	}
}
Está lançando a seguinte exceção:
br.com.caelum.vraptor.http.InvalidParameterException: Exception when trying to instantiate Target(name=paciente, type=class br.com.metamorfosevirtual.models.Paciente) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.handleException(VRaptorInstantiator.java:96) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:88) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:81) at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.instantiateOrAddError(IogiParametersProvider.java:80) at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.instantiateParameters(IogiParametersProvider.java:73) at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.getParametersFor(IogiParametersProvider.java:63) at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.getParametersFor(ParametersInstantiatorInterceptor.java:132) at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:86) at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:67) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.metamorfosevirtual.interceptors.HibernateInterceptor.intercept(HibernateInterceptor.java:27) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44) at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:93) at br.com.caelum.vraptor.ioc.guice.GuiceProvider.provideForRequest(GuiceProvider.java:82) at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:99) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.NullPointerException at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator$VRaptorTypeConverter.setPropertiesAfterConversions(VRaptorInstantiator.java:144) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator$VRaptorTypeConverter.instantiate(VRaptorInstantiator.java:135) at br.com.caelum.iogi.MultiInstantiator.instantiate(MultiInstantiator.java:20) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:86) ... 47 more
O que tem de errado com ele?

67 Respostas

Rafael_Guerreiro

Acredito que você esteja se confundindo…

O seu converter é da classe Model
O erro está dando na hora de instanciar a class br.com.metamorfosevirtual.models.Paciente

A única explicação para isso funcionar é se Model for superClass de Paciente, mas para isso, preciso ver o que você está passando como parâmetro na requisição, a sua action e a classe Paciente…

G

Ah sim, esqueci de falar: Model é superclass de Paciente sim.
Não entendi o que eu teria que passar como parâmetro na requisição.

Rafael_Guerreiro

Se você quer converter uma String em um Model (Paciente) você precisa ter uma estrutura parecida com isso:
Html:

&lt;input type="text" name="paciente" value="123"&gt;

Action

@Post("/faz/algo")
public void fazAlgo(Paciente paciente) {
//...
}
G
Sim, eu to fazendo isso. Mas em algumas actions eu preciso "preencher" o model. E aí não funciona. Por exemplo, eu tenho o seguinte código:
var url = $(this).attr("data-url");
			var data = {
				"paciente.cpf" : $("#lightbox-login input[name='cpf']").val(),
				"paciente.senha" : $("#lightbox-login input[name='senha']").val()
			};
			
			$.post(url, data, function(data) {
				enviando = false;
				
				if(data === "true") {
					window.location.pathname = consultasURL;
				} else if (data === "false") {
					$("#lightbox-login .validacao").text("Dados incorretos");
					$("#lightbox-login .validacao").removeClass("esconder");
				} else {
					$("#lightbox-login .validacao").text("Ocorreu um erro. Tente novamente");
					$("#lightbox-login .validacao").removeClass("esconder");
				}
			}, "text");
Com a seguinte action:
@Post("/login")
	public void login(Paciente paciente) {
		if (pacienteDao.login(paciente)) {
			result.use(Results.http()).body("true");
		} else {
			result.use(Results.http()).body("false");
		}
	}
E não está funcionando. Mas quando eu comento meu conversor de model, funciona. Tem 2 coisas que eu não entendo: 1- Porque o conversor de model impede o funcionamento do código acima, já que no código acima eu só preciso converter o cpf e a senha, que são strings? 2- Porque quando eu descomento o conversor de Model e passo um model da maneira que você falou não funciona? Acredito que as duas estejam relacionadas...
Lucas_Cavalcanti

O que o VRaptor faria nesse caso é o seguinte:

  • Chama o Converter
  • Pega o objeto gerado e seta as outras propriedades.

Talvez, dependendo da ordem em que vc está mandando os parâmetros, ele tá tentando setar as outras propriedades antes de chamar o converter.

Ou ainda, o Converter está retornando null.

Pode verificar por favor se o converter está retornando null?

como vc tá setando o valor que vai passar pelo converter?

G

Oi Lucas, valeu pela ajuda.

Lucas Cavalcanti:
Pode verificar por favor se o converter está retornando null?

Então, eu coloco um breakpoint na primeira linha do meu controller e na primeira linha do meu converter. E quando rodo dá a NullPointerException antes de cair neles. Ou seja, meu converter nem é chamado.

Lucas Cavalcanti:
como vc tá setando o valor que vai passar pelo converter?

Só um detalhe: nessa action que tá dando erro, eu não espero que passe pelo converter. Eu preciso do converter em outras actions do sistema, que estão funcionando certinho. Nessa action eu faço o seguinte:

var url = $(this).attr("data-url");  
var data = {  
    "paciente.cpf" : $("#lightbox-login input[name='cpf']").val(),  
    "paciente.senha" : $("#lightbox-login input[name='senha']").val()  
};  
  
$.post(url, data, function(data) {  
    enviando = false;  
      
    if(data === "true") {  
        window.location.pathname = consultasURL;  
    } else if (data === "false") {  
        $("#lightbox-login .validacao").text("Dados incorretos");  
        $("#lightbox-login .validacao").removeClass("esconder");  
    } else {  
        $("#lightbox-login .validacao").text("Ocorreu um erro. Tente novamente");  
        $("#lightbox-login .validacao").removeClass("esconder");  
    }  
}, "text");

Ou seja, eu não espero que o meu converter crie o Paciente. Eu espero que o Vraptor crie e popule com os campos que eu mandei.

Lucas_Cavalcanti

tente fazer isso:

var data = {    
    "paciente" : "",
    "paciente.cpf" : $("#lightbox-login input[name='cpf']").val(),    
    "paciente.senha" : $("#lightbox-login input[name='senha']").val()    
};

E veja se passa pelo seu converter. E se passar, tente trocar o primeiro if dele por:

if (Strings.isNullOrEmpty(value)) return new Paciente();

O problema é que se vc criou um converter pro tipo, o VRaptor vai tentar usar esse converter sempre.

G

Agora funcionou. Mas ainda não entendi algumas coisas:

1- Quando eu fiz o que você falou, o converter só foi chamado 1 vez, pra resolver o “paciente”. Ele não foi chamado pra resolver o “paciente.cpf” nem “paciente.senha”. Então, porque quando eu tiro a linha do paciente não funciona, já que eu só to setando strings e nenhum modelo?

2- Pra cada lugar do meu código que eu populo meus modelos eu teria que passar uma string vazia pro modelo em si? Não teria como fazer de outra forma?

3- Como fica a questão de segurança nesse caso: esse javascript fica no front-end. A pessoa poderia alterar o código pra mandar o vraptor popular o “paciente” que eu recebo no controller com o id de um outro paciente. Nesse caso ela poderia se logar como outra pessoa, sem ter a senha dela. Bastaria saber o id.

Lucas_Cavalcanti

1- Isso pq o converter só é chamado para os parâmetros que caem em um Paciente. “paciente.cpf” e “paciente.senha” são strings.
Não funciona, pq qdo vc tem um converter pra um tipo, o VRaptor vai sempre usar esse converter. A mudança de retornar new Paciente() deveria funcionar, em todo caso.

2 - Só se vc tiver converters pra esses modelos

3 - Isso vale pra qqer formulário que vc submeter também. Você tem que controlar a permissão do usuário, para que ele não altere um paciente que ele não controla.

Você criou converters pra todos os tipos?

G

A ideia era criar 1 converter de Model para que todos os meus modelos (que herdam Model) possam ter um converter. Mas nesse caso eu teria que mudar praticamente todas as views e javascript do sistema. Não vejo muito sentido de não funcionar apenas o seguinte:

var data = { "paciente.cpf" : $("#lightbox-login input[name='cpf']").val(), "paciente.senha" : $("#lightbox-login input[name='senha']").val() };

Eu não entendi uma coisa ainda: porque no exemplo acima o Vraptor não chama nem meu conversor e nem dá um new Paciente() por si só? Porque eu penso o seguinte: pra setar o cpf de um paciente, vc precisa antes “ter” esse paciente. Então eu diria que o Vraptor teria que fazer um dos dois: ou chamar meu conversor de Paciente pra ele “ter” o paciente ou criar um Paciente por si só. Mas ele não faz nenhum dos dois. O que ele faz exatamente nesse caso?

Lucas_Cavalcanti

Tem certeza que não está chamando o converter?

vc testou isso na primeira linha do convert?

chegou a fazer a modificação do if que eu te falei?

Lucas_Cavalcanti

o código que faz isso são esses 3 métodos:

de acordo com isso, ele deveria tentar converter antes de setar os outros parâmetros.

G

Sim, na primeira linha. E não caiu lá não. Mesmo com seu if não funcionou.

G

Lucas Cavalcanti:
o código que faz isso são esses 3 métodos:

de acordo com isso, ele deveria tentar converter antes de setar os outros parâmetros.

Em que trecho ele criaria o Paciente antes de setar o cpf?

Lucas_Cavalcanti

no setPropertiesAfterConversion…

vc consegue colocar um breakpoint nesse trecho do código?

vc precisa colocar o source do VRaptor no eclipse antes de fazer isso.

G
Aconteceu o seguinte em cada um dos metodos:
public boolean isAbleToInstantiate(Target<?> target) {
			return !String.class.equals(target.getClassType()) && converters.existsFor(target.getClassType());
		}
Aqui, o target é "paciente" e o retorno do método é "true".
public Object instantiate(Target<?> target, Parameters parameters) {
			try {
				Parameter parameter = parameters.namedAfter(target);
				return converterForTarget(target).convert(parameter.getValue(), target.getClassType(), localization.getBundle());
			} catch (ConversionError ex) {
				errors.add(new ValidationMessage(ex.getMessage(), target.getName()));
			} catch (IllegalStateException e) {
				return setPropertiesAfterConversions(target, parameters);
			}
			return null;
		}
Nesse outro, o target ainda é "paciente" e parameter é "Parameters(Parameter(paciente.senha -> 1234), Parameter(paciente.cpf -> [telefone removido]))". O método "namedAfter" lança uma IllegalStateException e a execução cai no segundo catch (IllegalStateException) e vai para o outro método.
private Object setPropertiesAfterConversions(Target<?> target, Parameters parameters) {
			List<Parameter> params = parameters.forTarget(target);
			Parameter parameter = findParamFor(params, target);

			Object converted = converterForTarget(target).convert(parameter.getValue(), target.getClassType(), localization.getBundle());

			return new NewObject(this, parameters.focusedOn(target), converted).valueWithPropertiesSet();
		}
É aqui que dá o problema. Na segunda linha, o método findParamFor é chamado. O problema é que ele tenta buscar um parâmetro pra "paciente" e não existe nenhum. Então ele retorna null e guarda na variável "parameter". Aí na linha de baixo ele faz "parameter.getValue()" e dá NullPointerException.

Isso tudo acontece antes do meu controller ou meu conversor ser chamado.

Acho que a raiz do problema está na classe Parameters, no método "assertFoundAtMostOneTarget". Nesse método, ele diz que espera apenas 1 parâmetro para a classe Paciente, mas ele considera que eu passei 2: "paciente.cpf" e "paciente.senha". E aí dá IllegalStateException. Seria um bug?

Lucas_Cavalcanti

Então, se parameter.getValue() é null, ele deveria simplesmente passar null pro seu converter.

então se no seu converter ele fizesse:

if (value == null) return new Paciente();

deveria funcionar sem problemas.

O converterForTarget tá retornando o seu converter mesmo?

Lucas_Cavalcanti

Entendi o problema… o Parameter está null, não o getValue dele.

Faça o seguinte então:
copie essa classe pro seu projeto:

mude a linha 144 pra:

Object converted = converterForTarget(target).convert(parameter == null ? null : parameter.getValue(), target.getClassType(), localization.getBundle());

Isso deve funcionar.

Se puder, abra uma issue:

Ou melhor ainda, faça essa correção no próprio VRaptor e mande um pull request, de preferência com um teste associado.

Obrigado!

G

Isso, é o parameter que chega null. Eu só discordo da sua solução. Acho que a causa do problema não está exatamente aí não. Acho que o erro tá no método anterior (instantiate). O que acontece é o seguinte: a execução cai no método instantiate com os parâmentros:

(br.com.caelum.iogi.reflection.Target) Target(name=paciente, type=class br.com.caelum.vraptor.blank.model.Paciente)
(br.com.caelum.iogi.parameters.Parameters) Parameters(Parameter(paciente.senha -> Teste), Parameter(paciente.nome -> Teste))

Aí ele chama o parameters.namedAfter(target). O que você esperaria que essa linha retornasse? Eu esperaria um null, já que não tem nenhum parametro para a target “paciente”. Eu NÃO considero que a target de “paciente.senha” e “paciente.nome” seja paciente. Porém esse método considera que existem 2 parâmetros para essa target. E logo depois disso ele faz um “assertFoundAtMostOneTarget(target, named);”. E aí dá IllegalStateException. Essa IllegalStateException é capturada lá fora.

Ou seja, o Vraptor considera que a target de “paciente.senha” seja a classe paciente. Ele também considera que a target de “paciente.nome” seja a classe paciente. Depois ele tenta garantir que não existam 2 parâmetros pra mesma target (e nesse caso há). E aí dá IllegalStateException que vai ser capturado.

Tem algum motivo especial pra isso ser tratado dessa forma ou é um bug mesmo?

Agora, agora eu estou meio sem tempo, mas assim que der um tempinho posso criar o teste e a correção sim. Enquanto isso vale a pena cadastrar a issue ou não precisaria?

Lucas_Cavalcanti

O ponto é: se existe um converter pra um tipo, eu tenho que usar esse converter.

se eu passo null para o converter, isso significa que o parâmetro não veio na requisição, daí o converter consegue tratar isso de acordo.

O IllegalStateException não é um problema, faz parte do algoritmo (meio estranho, mas blz). Ou seja, se existe um converter para Paciente e existem dois parâmetros para um paciente, eu tenho que converter e chamar os setters. Se existir um parâmetro só, só preciso converter.

A mudança que eu propus é a mais simples de implementar e a semântica é boa o suficiente:
se o cara não passou o parâmetro, vai null, se ele passou o parâmetro sem nada, vai vazio.

Se puder criar a issue, eu agradeço. Daí dá pra linkar a issue no Pull Request.

G

Ah, entendi. Realmente a IllegalStateException ficou bem estranho aí, já que cair lá não é um estado inválido. Poderia ter usado um if só: if(moreThanOneTarget)

Mas já entendi. Só tem um outro problema: se eu passar só o seguinte parâmetro na requisição:

Nesse ele vai chamar erradamente o meu converter. O certo mesmo seria ele ver se o parâmetro que eu passei na requisição tem como destino a classe target mesmo ou se é uma property da classe target.

Inclusive eu vi aqui que estou tendo justamente esse problema: o meu converter só espera receber números (que representa o id dos meus models). Aí ele busca no banco o model correspondente e retorna. Mas se eu faço uma requisição como eu mostrei acima, ele tenta chamar meu converter passando a string “Teste”. Aí meu converter não entende e acaba retornando null.

PS: Vou criar a issue então.

G

Issue criada: https://github.com/caelum/vraptor/issues/594
Se quiser, dá uma conferida lá e vê se é isso mesmo.

Lucas_Cavalcanti

É isso mesmo, valeu!

G

Po, não to conseguindo me entender com esse converter do Vraptor de jeito nenhum :confused:

Recapitulando: quando criei um conversor genérico para as minhas classes de modelo, algumas rotas pararam de funcionar. Isso porque eu estava fazendo apenas assim:

E quando eu criei um conversor pra superclasse de Paciente, isso parou de funcionar. Chegamos à conclusão que eu teria que fazer assim:

<input type="hidden" name="paciente" value="${paciente.id}"> <input type="text" name="paciente.nome" value="${paciente.nome}">
Dessa forma, o meu conversor criaria uma instância vazia de Paciente. O problema agora é quando o meu modelo tem uma lista de modelos. Por exemplo: um paciente com uma lista de Convenios (que também é uma classe de modelo). Na documentação do Vraptor diz o seguinte:

Se um atributo do objeto ou parâmetro do método for uma lista (List<> ou array), você pode passar vários parâmetros usando colchetes e índices:
cliente.telefones[0]=([telefone removido] #no caso de ser uma lista de String
cliente.dependentes[0].id=1 #no caso de ser qualquer objeto, você pode continuar a navegação
cliente.dependentes[3].id=1 #os índices não precisam ser sequenciais
cliente.dependentes[0].nome=Cicrano #se usar o mesmo índice, vai ser setado no mesmo objeto
clientes[1].id=23 #funciona se você receber uma lista de clientes no método

Mas isso não funciona com o conversor que eu criei. Estou fazendo assim:

<input type="hidden" name="paciente" value="${paciente.id}"> <input type="text" name="paciente.nome" value="${paciente.nome}"> <input type="text" name="paciente.convenios[0]" value="2"> <input type="text" name="paciente.convenios[1]" value="9">
Nesse caso estou recebendo a seguinte exception:

br.com.caelum.vraptor.http.InvalidParameterException: Exception when trying to instantiate Target(name=medico, type=class br.com.metamorfosevirtual.models.Medico) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.handleException(VRaptorInstantiator.java:96) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:88) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:81) at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.instantiateOrAddError(IogiParametersProvider.java:80) at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.instantiateParameters(IogiParametersProvider.java:73) at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.getParametersFor(IogiParametersProvider.java:63) at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.getParametersFor(ParametersInstantiatorInterceptor.java:132) at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:86) at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.metamorfosevirtual.interceptors.DaoInterceptor.intercept(DaoInterceptor.java:36) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.multipart.CommonsUploadMultipartInterceptor.intercept(CommonsUploadMultipartInterceptor.java:138) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:67) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.metamorfosevirtual.interceptors.HibernateInterceptor.intercept(HibernateInterceptor.java:27) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44) at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:93) at br.com.caelum.vraptor.ioc.guice.GuiceProvider.provideForRequest(GuiceProvider.java:82) at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:99) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: br.com.caelum.vraptor.VRaptorException: Unable to find converter for java.util.List at br.com.caelum.vraptor.core.DefaultConverters.to(DefaultConverters.java:59) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator$VRaptorTypeConverter.converterForTarget(VRaptorInstantiator.java:159) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator$VRaptorTypeConverter.instantiate(VRaptorInstantiator.java:131) at br.com.caelum.iogi.reflection.NewObject.setProperty(NewObject.java:57) at br.com.caelum.iogi.reflection.NewObject.populateProperties(NewObject.java:51) at br.com.caelum.iogi.reflection.NewObject.valueWithPropertiesSet(NewObject.java:41) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator$VRaptorTypeConverter.setPropertiesAfterConversions(VRaptorInstantiator.java:146) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator$VRaptorTypeConverter.instantiate(VRaptorInstantiator.java:135) at br.com.caelum.iogi.MultiInstantiator.instantiate(MultiInstantiator.java:20) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:86) ... 51 more
O que é mais estranho é que se eu colocar essa lista como parâmetro direto do método, funciona. Assim:

<input type="hidden" name="paciente" value="${paciente.id}"> <input type="text" name="paciente.nome" value="${paciente.nome}"> <input type="text" name="convenios[0]" value="2"> <input type="text" name="convenios[1]" value="9">
Mas o problema dessa forma é que eu teria que ficar “montando” o paciente na mão e o método ficaria cheio de parâmetros. Tem alguma forma de resolver isso?

Lucas_Cavalcanti

se vc só quer fazer o relacionamento do convenio com o paciente, vc não precisaria do converter. Só setar o id já seria o suficiente:

<input type="text" name="paciente.convenios[0].id" value="2">  
<input type="text" name="paciente.convenios[1].id" value="9">

em todo caso, verifica se vc tá dando um new ArrayList() ou coisa do tipo pra inicializar a lista de convênios. Se tiver, tenta retirar isso, o IOGI (que o VRaptor usa pra popular os objetos) não gosta muito disso.

G

Não é só pro relacionamento não. Preciso do “Convenio” inteiro, pois preciso validar algumas regras de negócio.

Eu tava inicializando a lista sim (dentro da classe de modelo), mas já removi e continuou dando o mesmo erro.

Lucas_Cavalcanti

habilita o log de debug do VRaptor e veja o que acontece durante a requisição

troca o INFO do vraptor pra DEBUG

G

Cara, me pareceu estar tudo certinho… Mas acho que você saberia dizer melhor:

Logo depois disso, vem a exceção.

Lucas_Cavalcanti

convenios é uma lista de Medico?

G

Não… É uma lista de planos de saúde.

Lucas_Cavalcanti

o erro que vc mandou é:

br.com.caelum.vraptor.http.InvalidParameterException: Exception when trying to instantiate Target(name=medico, type=class br.com.metamorfosevirtual.models.Medico)

ou seja, não é dessa requisição…

posta o erro que acontece nessa requisição, por favor.

G

É que eu tenho 2 trechos do código na mesma situação: um paciente com uma lista de convênios e um médico com uma lista de especialidades. O erro é o mesmo. Aqui na thread eu usei o paciente como exemplo, mas mandei a stack errada mesmo. Segue a stack de quando eu crio o paciente (com o debug do Vraptor):

11:06:53,404 DEBUG [DefaultResourceTranslator] trying to access /novo-paciente 11:06:53,408 DEBUG [DefaultResourceTranslator] found resource [DefaultResourceMethod: PacienteController.cadastrar(Paciente, String)] 11:06:53,408 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor HibernateInterceptor 11:06:53,409 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ExceptionHandlerInterceptor 11:06:53,410 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor FlashInterceptor 11:06:53,413 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor InstantiateInterceptor 11:06:53,413 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor DaoInterceptor 11:06:53,417 DEBUG [DefaultResult ] including attribute conveniosList: [Amil, Bradesco Saúde, Dix, Golden Cross, Unimed] 11:06:53,417 DEBUG [DefaultResult ] including attribute convenios: {Amil=false, Bradesco Saúde=false, Dix=false, Golden Cross=false, Unimed=false} 11:06:53,418 DEBUG [IogiParametersProvider] IogiParametersProvider is up 11:06:53,418 DEBUG [LazyInterceptorHandler] Invoking interceptor ParametersInstantiatorInterceptor 11:06:53,419 DEBUG [ParanamerNameProvider] Found parameter names with paranamer for PacienteController.cadastrar(Paciente, String) as [paciente, confirmarSenha] 11:06:53,419 DEBUG [ParanamerNameProvider] Found parameter names with paranamer for PacienteController.cadastrar(Paciente, String) as [paciente, confirmarSenha] 11:06:53,420 DEBUG [IogiParametersProvider] getParametersFor() called with parameters Parameters(Parameter(paciente.senha -> felipe), Parameter(paciente.email -> [email removido]), Parameter(paciente.sexo -> Masculino), Parameter(paciente.convenios[0] -> 3), Parameter(paciente -> ), Parameter(paciente.convenios[1] -> 5), Parameter(paciente.telefone -> ([telefone removido]), Parameter(paciente.nome -> Felipe), Parameter(paciente.cpf -> [CPF removido]), Parameter(paciente.celular -> ([telefone removido]), Parameter(confirmarSenha -> felipe)) and targets [Target(name=paciente, type=class br.com.metamorfosevirtual.models.Paciente), Target(name=confirmarSenha, type=class java.lang.String)]. Jan 30, 2014 11:06:53 AM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet [default] in context with path [/marque-agora] threw exception br.com.caelum.vraptor.http.InvalidParameterException: Exception when trying to instantiate Target(name=paciente, type=class br.com.metamorfosevirtual.models.Paciente) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.handleException(VRaptorInstantiator.java:96) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:88) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:81) at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.instantiateOrAddError(IogiParametersProvider.java:80) at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.instantiateParameters(IogiParametersProvider.java:73) at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.getParametersFor(IogiParametersProvider.java:63) at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.getParametersFor(ParametersInstantiatorInterceptor.java:132) at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:86) at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.metamorfosevirtual.interceptors.DaoInterceptor.intercept(DaoInterceptor.java:36) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:67) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.metamorfosevirtual.interceptors.HibernateInterceptor.intercept(HibernateInterceptor.java:30) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44) at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:93) at br.com.caelum.vraptor.ioc.guice.GuiceProvider.provideForRequest(GuiceProvider.java:82) at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:99) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: br.com.caelum.vraptor.VRaptorException: Unable to find converter for java.util.List at br.com.caelum.vraptor.core.DefaultConverters.to(DefaultConverters.java:59) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator$VRaptorTypeConverter.converterForTarget(VRaptorInstantiator.java:159) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator$VRaptorTypeConverter.setPropertiesAfterConversions(VRaptorInstantiator.java:144) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator$VRaptorTypeConverter.instantiate(VRaptorInstantiator.java:135) at br.com.caelum.iogi.reflection.NewObject.setProperty(NewObject.java:57) at br.com.caelum.iogi.reflection.NewObject.populateProperties(NewObject.java:51) at br.com.caelum.iogi.reflection.NewObject.valueWithPropertiesSet(NewObject.java:41) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator$VRaptorTypeConverter.setPropertiesAfterConversions(VRaptorInstantiator.java:146) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator$VRaptorTypeConverter.instantiate(VRaptorInstantiator.java:135) at br.com.caelum.iogi.MultiInstantiator.instantiate(MultiInstantiator.java:20) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:86) ... 50 more

Lucas_Cavalcanti

br.com.caelum.vraptor.VRaptorException: Unable to find converter for java.util.List

O IOGI está achando que paciente.convenios[0] é uma List, ao invés de um plano de saúde.

Abre uma issue no VRaptor por favor?

Por enquanto, uma solução seria receber a lista separada do paciente mesmo, e depois fazer o setConvenios manualmente.

G

Criada: https://github.com/caelum/vraptor/issues/596

Em quanto tempo mais ou menos você estima que estaria disponível numa versão final?

Lucas_Cavalcanti

A gente achou alguns outros bugs como esse no IOGI, então a gente provavelmente vai gerar uma versão do IOGI e outra do VRaptor 3 após fazer isso.

Não sei quanto tempo isso demoraria, mas se você estiver a fim, pode tentar corrigir e mandar um Pull Request =)
Se optar por isso posso te dar todo o suporte necessário e você com certeza vai aprender bastante sobre o VRaptor e sobre reflection em java.

G

Agora, agora estou um pouco sem tempo, terminando vários projetos. Mas assim que terminar, vou dar uma olhada sim. Vou tentar corrigir as 2 issues que criei nessa thread. Aí provavelmente vou precisar da sua ajuda sim :slight_smile:

G

Cara, eu acho que encontrei outro bug no Vraptor. To achando um pouco bizarro. Eu fiz o que você falou: to recebendo uma lista separada de Convenios. Aí não funcionou. Só que eu achei estranho, porque com Especialidades tinha funcionado. Revi o código e não achei nenhum problema. Quando eu renomeei o nome da variável que eu recebo pra “convs” ao invés de “convenios”, aí funcionou. Faz sentido o nome da variável influenciar assim no comportamento?

PS: o erro que deu foi “IllegalArgumentException: argument type mismatch”

Lucas_Cavalcanti

só faz sentido se existir algum tipo de cache no browser ou no código…
talvez foi falta de um clean no código e no servidor.

G

Dei clean no projeto, no servidor e limpei o cache do browser e o problema continuou. Mas eu acho que entendi o que tá acontecendo. Eu tenho um interceptor que faz o seguinte:

Ou seja ele dá um include de convênios pra todas as rotas. Mas o que é estranho de dar conflito é que result.include adiciona um uma variável ao “request”? Ele podia tratar o caso de já existir uma variável com o mesmo nome, mas tipo diferente…

Lucas_Cavalcanti

o result.include é um atalho pro request.setAttribute.

se fosse pra tratar esse caso, como vc faria? ${convenios} seria o que?

G

Então, são 2 convênios diferentes: um que eu recebo como parâmetro na requisição e outro que eu dou “include” no meu interceptor com o Vrator. O do include eu acho que teria que ser isso mesmo: um atalho pra setAttribute. Mas o que eu recebo na requisição era pra estar nos “parameters” do request. Eu acredito que o Vraptor esteja fazendo algum do tipo em algum momento:

Caso contrário, não vejo sentido de uma coisa influenciar na outra :confused:

Se o Vraptor estiver fazendo isso, quando eu desse um “result.include” o Vraptor poderia verificar se já existe um atributo na requisição com o mesmo nome. Se sim, poderia lançar um warn no console, sei lá. Melhor ainda seria se ele descobrisse se o atributo que está na requisição foi colocado por ele mesmo ou não. Aí só lançaria o warn pros casos em que ele colocou o atributo lá.

Lucas_Cavalcanti

O VRaptor só faz isso se der algum erro de validação… aí ele pega todos os parâmetros que foram mandados para o request e deixa como atributos.

Mas em requisições normais isso não acontece.

Se o result.include fizesse essa lógica, como seria possível sobrescrever um atributo do request? Ia ser bem estranho para a pessoa que incluiu explicitamente o atributo “x” no result e ele foi ignorado.

G

Lucas Cavalcanti:
O VRaptor só faz isso se der algum erro de validação… aí ele pega todos os parâmetros que foram mandados para o request e deixa como atributos.

Mas em requisições normais isso não acontece.

Pelo que eu vi aqui está fazendo mesmo sem erro de validação :confused:

Acho que não expliquei direito: o warn não iria impedir a sobrescrita do atributo. Ele só iria avisar ao programador que foi sobrescrito pra pessoa ver se é isso mesmo que ela espera.

É que no meu caso, isso fez com que gerasse um erro “argument type mismatch”. Eu poderia demorar pra descobrir que o erro é que eu recebi uma variável por parâmetro com o mesmo nome que uma variável que eu dei include na mão. Na verdade nem entendi ainda porque isso gera um erro, mas enfim :slight_smile:

Lucas_Cavalcanti

Você pode me falar o fluxo da requisição que está acontecendo o problema?

redirects, forwards, validações, etc.

G

Segue o debug do Vraptor:

12:35:01,032 DEBUG [VRaptor ] VRaptor received a new request 12:35:01,032 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ResourceLookupInterceptor 12:35:01,032 DEBUG [DefaultResourceTranslator] trying to access /cadastrar-medico 12:35:01,033 DEBUG [DefaultResourceTranslator] found resource [DefaultResourceMethod: MedicoController.cadastrar(Medico, String, UploadedFile, List, List)] 12:35:01,033 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor HibernateInterceptor 12:35:01,033 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor InstantiateInterceptor 12:35:01,036 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor CommonsUploadMultipartInterceptor 12:35:01,036 INFO [CommonsUploadMultipartInterceptor] Request contains multipart data. Try to parse with commons-upload. 12:35:01,040 DEBUG [CommonsUploadMultipartInterceptor] Using repository C:\Users\Guto\AppData\Local\Temp for file upload 12:35:01,081 DEBUG [CommonsUploadMultipartInterceptor] Found 19 attributes in the multipart form submission. Parsing them. 12:35:01,081 DEBUG [CommonsUploadMultipartInterceptor] A file field was empty: foto 12:35:01,081 DEBUG [CommonsUploadMultipartInterceptor] medico is a field 12:35:01,082 DEBUG [CommonsUploadMultipartInterceptor] medico.nome is a field 12:35:01,082 DEBUG [CommonsUploadMultipartInterceptor] medico.cpf is a field 12:35:01,082 DEBUG [CommonsUploadMultipartInterceptor] medico.crm is a field 12:35:01,082 DEBUG [CommonsUploadMultipartInterceptor] medico.crm.numero is a field 12:35:01,083 DEBUG [CommonsUploadMultipartInterceptor] convenios is a field 12:35:01,083 DEBUG [CommonsUploadMultipartInterceptor] convenios is a field 12:35:01,083 DEBUG [CommonsUploadMultipartInterceptor] medico.endereco is a field 12:35:01,083 DEBUG [CommonsUploadMultipartInterceptor] medico.endereco.endereco is a field 12:35:01,083 DEBUG [CommonsUploadMultipartInterceptor] medico.endereco.cidade is a field 12:35:01,083 DEBUG [CommonsUploadMultipartInterceptor] medico.endereco.cidade.nome is a field 12:35:01,083 DEBUG [CommonsUploadMultipartInterceptor] medico.telefonePrincipal is a field 12:35:01,083 DEBUG [CommonsUploadMultipartInterceptor] medico.telefoneSecundario is a field 12:35:01,083 DEBUG [CommonsUploadMultipartInterceptor] medico.celular is a field 12:35:01,083 DEBUG [CommonsUploadMultipartInterceptor] medico.uri is a field 12:35:01,084 DEBUG [CommonsUploadMultipartInterceptor] medico.email is a field 12:35:01,084 DEBUG [CommonsUploadMultipartInterceptor] medico.senha is a field 12:35:01,084 DEBUG [CommonsUploadMultipartInterceptor] confirmarSenha is a field 12:35:01,090 DEBUG [VRaptorRequest ] Setting medico with [] 12:35:01,090 DEBUG [VRaptorRequest ] Setting medico.nome with [] 12:35:01,090 DEBUG [VRaptorRequest ] Setting medico.cpf with [] 12:35:01,090 DEBUG [VRaptorRequest ] Setting medico.crm with [] 12:35:01,090 DEBUG [VRaptorRequest ] Setting medico.crm.numero with [] 12:35:01,090 DEBUG [VRaptorRequest ] Setting convenios with [3, 2] 12:35:01,090 DEBUG [VRaptorRequest ] Setting medico.endereco with [] 12:35:01,091 DEBUG [VRaptorRequest ] Setting medico.endereco.endereco with [] 12:35:01,091 DEBUG [VRaptorRequest ] Setting medico.endereco.cidade with [] 12:35:01,091 DEBUG [VRaptorRequest ] Setting medico.endereco.cidade.nome with [] 12:35:01,091 DEBUG [VRaptorRequest ] Setting medico.telefonePrincipal with [] 12:35:01,091 DEBUG [VRaptorRequest ] Setting medico.telefoneSecundario with [] 12:35:01,091 DEBUG [VRaptorRequest ] Setting medico.celular with [] 12:35:01,091 DEBUG [VRaptorRequest ] Setting medico.uri with [] 12:35:01,091 DEBUG [VRaptorRequest ] Setting medico.email with [] 12:35:01,091 DEBUG [VRaptorRequest ] Setting medico.senha with [] 12:35:01,091 DEBUG [VRaptorRequest ] Setting confirmarSenha with [] 12:35:01,091 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor FlashInterceptor 12:35:01,091 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ExceptionHandlerInterceptor 12:35:01,091 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor DaoInterceptor 12:35:01,094 DEBUG [DefaultResult ] including attribute conveniosList: [Amil, Bradesco Saúde, Dix, Golden Cross, Unimed] 12:35:01,095 DEBUG [DefaultResult ] including attribute convenios: {Amil=false, Bradesco Saúde=false, Dix=false, Golden Cross=false, Unimed=false} 12:35:01,095 DEBUG [IogiParametersProvider] IogiParametersProvider is up 12:35:01,095 DEBUG [LazyInterceptorHandler] Invoking interceptor ParametersInstantiatorInterceptor 12:35:01,095 DEBUG [ParanamerNameProvider] Found parameter names with paranamer for MedicoController.cadastrar(Medico, String, UploadedFile, List, List) as [medico, confirmarSenha, foto, especialidades, convenios] 12:35:01,096 DEBUG [ParanamerNameProvider] Found parameter names with paranamer for MedicoController.cadastrar(Medico, String, UploadedFile, List, List) as [medico, confirmarSenha, foto, especialidades, convenios] 12:35:01,097 DEBUG [IogiParametersProvider] getParametersFor() called with parameters Parameters(Parameter(medico.endereco.endereco -> ), Parameter(medico.endereco.cidade.nome -> ), Parameter(medico.crm.numero -> ), Parameter(medico.nome -> ), Parameter(medico.uri -> ), Parameter(medico.email -> ), Parameter(medico.telefoneSecundario -> ), Parameter(medico.endereco.cidade -> ), Parameter(medico.crm -> ), Parameter(medico.cpf -> ), Parameter(medico.telefonePrincipal -> ), Parameter(medico -> ), Parameter(medico.endereco -> ), Parameter(medico.celular -> ), Parameter(medico.senha -> ), Parameter(confirmarSenha -> ), Parameter(convenios -> 3), Parameter(convenios -> 2)) and targets [Target(name=medico, type=class br.com.metamorfosevirtual.models.Medico), Target(name=confirmarSenha, type=class java.lang.String), Target(name=foto, type=interface br.com.caelum.vraptor.interceptor.multipart.UploadedFile), Target(name=especialidades, type=interface java.util.List), Target(name=convenios, type=interface java.util.List)]. 12:35:01,112 DEBUG [ParametersInstantiatorInterceptor] Parameter values for [DefaultResourceMethod: MedicoController.cadastrar(Medico, String, UploadedFile, List, List)] are [br.com.metamorfosevirtual.models.Medico@1f, null, null, null, {Amil=false, Bradesco Saúde=false, Dix=false, Golden Cross=false, Unimed=false}] 12:35:01,112 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ExecuteMethodInterceptor 12:35:01,112 DEBUG [ExecuteMethodInterceptor] Invoking MedicoController.cadastrar(Medico, String, UploadedFile, List, List) 12:35:01,113 DEBUG [DefaultExceptionMapper] find for exception class java.lang.IllegalArgumentException Jan 31, 2014 12:35:01 PM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet [default] in context with path [/marque-agora] threw exception br.com.caelum.vraptor.InterceptionException: java.lang.IllegalArgumentException: argument type mismatch at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:87) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:61) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:96) at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.metamorfosevirtual.interceptors.DaoInterceptor.intercept(DaoInterceptor.java:35) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:67) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.multipart.CommonsUploadMultipartInterceptor.intercept(CommonsUploadMultipartInterceptor.java:138) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.metamorfosevirtual.interceptors.HibernateInterceptor.intercept(HibernateInterceptor.java:30) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44) at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:93) at br.com.caelum.vraptor.ioc.guice.GuiceProvider.provideForRequest(GuiceProvider.java:82) at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:99) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.IllegalArgumentException: argument type mismatch at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:61) ... 50 more
Pelo que eu entendi, o problema é o seguinte: quando ele chama o DaoInterceptor, eu crio um atributo chamado “convenios”. Repara que tem 2 parâmetros que eu mandei com o nome “convenios”. O IOGI consegue lidar com eles e monta certinho os parâmetros (é uma lista de convênios). Depois ele diz que chama meu método: Invoking MedicoController.cadastrar(Medico, String, UploadedFile, List, List). Mas eu coloco um breakpoint na primeira linha do meu controller e não para lá. Ou seja, eu nem chego a validar nada. Acredito que o Vraptor esteja jogando os parâmetros do request na lista de atributos mesmo sem validação. Aí o conflito que dá é porque eu já tinha colocado um atributo “convenios” que era do tipo Map e ele tenta colocar um atributo “convenios” do tipo List. Aí dá “argument type mismatch”. Acho que é isso…

Lucas_Cavalcanti

O VRaptor tem uma lógica que se ele achar um atributo do request com o nome do parâmetro e esse parâmetro for uma interface (List é uma interface), ele usa o atributo.

Por isso é que ele tá tentando colocar o atributo.

A solução mais simples é trocar o parametro de convenios pra outra coisa, como convenioList.

G

É o que eu fiz :slight_smile:

G

A thread ficou enorme e mistura vários casos. Deixe-me tentar entender o que você precisa:

Você tem um converter genérico que faz o load dos objetos no banco. Então se você passar cliente=5, o converter lê o cliente 5 do banco. E se você passar o cliente.nome, ele deveria ler o registro do banco, e depois popular o novo nome, correto?

Além disso, quando você está incluindo um cliente, você quer apenas passar cliente.nome, e o vraptor deve criar um cliente transient com o nome populado.

É isso mesmo?

G

Exato. Toda classe de modelo minha herda uma classe chamada Model. Eu fiz um converter pra essa classe model. Então se eu passar cliente=5 ele lê, na tabela de clientes, o registro que tem id 5.

Se eu passar “cliente=5” e “cliente.nome=Guto”, aí sim, eu espero que o Vraptor chame o meu conversor passando o valor 5 e depois que meu conversor retornasse um objeto o Vraptor populasse o campo nome do objeto retornado com o valor “Guto”.

Exatamente. Espero que o Vraptor crie um Cliente vazio e popule seu nome. E é justamente aí que está o problema. Se eu faço isso eu tomo um InvalidParameterException sem nem ao menos o fluxo de execução cair no meu converter.

Ah, só uma observação: eu to tendo muitos problemas com o converter do Vraptor. Não sei se esses problemas que eu to tendo é mais por ser um converter genérico, mas aconselharia uma olhada com cuidado no código que trata disso. So nessa thread eu abri 2 issues com o pedido do Lucas. E além dessas 2 issues, to vendo que o Vraptor não se comporta de uma forma muito padronizada com a presença ou ausência de um converter.

G

Me passe a versão do vraptor que você usa. E veja se você tem os jars IOGI ou OGNL no classpath.

G

Uso a versão 3.5.3.

Tenho o jar do IOGI, mas não tenho do OGNL. Era pra eu ter? Eu importei o blank-project. Tá do jeito que veio.

G

Na verdade você deve ter ou um ou outro. Vou montar aqui os cenários que você me descreveu e fazer alguns testes.

Abraço

G

Olá pessoal,

Estou tendo mais problemas com o converter. Quando eu tento criar uma lista de Models vazios e preenche-los, eu tomo um NullPointerException. É o mesmo que o NullPointer lá de trás, mas agora eu não to conseguindo contorná-lo.

Seguinte: eu quero receber por parâmetro uma lista de horários. Aí to fazendo assim:

View:
$("#agenda td .horario").each(function(index) {
	data["horarios[" + index + "]"] = "";
	data["horarios[" + index + "].diaSemana"] = dia;
	data["horarios[" + index + "].inicio"] = inicio;
	data["horarios[" + index + "].fim"] = fim;
});
		
$.post(url, data, function(data) {
	...
}, "json");
Controller:
public void agendaSemanal(List<Horario> horarios) {
	...
}
Como posso fazer nesse caso? PS: conseguiu criar os testes e reproduzir os erros?
G

Eu ainda não consegui ver essa questão com calma, mas não vejo muito bem essa questão de usar um converter para ler um objeto do banco de dados.

O converter serve para você fazer uma conversão String > Objeto. Vários frameworks usam assim, como por exemplo o JSF e o agora o JPA.

Penso que o ideal é você usar a anotação @Load dos plugins de JPA e do Hibernate. Se você não usa eles, você pode fazer um copy and paste das classes.

G

garcia-jj:
Eu ainda não consegui ver essa questão com calma, mas não vejo muito bem essa questão de usar um converter para ler um objeto do banco de dados.

O converter serve para você fazer uma conversão String > Objeto. Vários frameworks usam assim, como por exemplo o JSF e o agora o JPA.

Entendi. Pra dizer a verdade eu não tenho opinião formada sobre o assunto. A priori não me parece uma prática ruim :confused:
Mas de qualquer forma isso não elimina os bugs do Vraptor. Eu poderia estar fazendo qualquer outra coisa dentro do meu Converter que os bugs continuariam existindo. Acredito que o pessoal não tenho muito esse problema por aí porque é raro eles criarem um converter pra uma superclasse. Geralmente eles criam pra classe final mesmo.

Eu uso o Hibernate sim, mas não tem essa annotation aqui. Num seria @Loader? Essa annotation carregaria meu model object automaticamente?

G

A anotação @Load é do plugin do vraptor. Existe tanto no plugin de JPA quanto no do Hibernate.


Claro, os bugs devem ser resolvidos. É só uma questão de juntarmos os cenários que geram os erros para poder ver como corrigir. Se você quiser nos ajudar, você pode fazer um pull request. Nos docs do vraptor tem um guia de como fazer.

Quanto ao conversor, normalmente conversores são usados quando você quer converter um tipo para o outro. Exemplo, na aplicação você usa o CPF formatado como [CPF removido] mas grava como numeric na base de dados. Sendo assim você faz um converter String > Long e vice versa. Para mim é novo ver um converter para fazer load. E como você, realmente não tenho uma opinião formada.

Tenta usar o @Load por enquanto, até conseguirmos simular os cenários e fazer uma correção. Se você tiver dúvidas no Load, pergunte-nos.

Abraço

G

Então, como falei com o Lucas, estou um pouco sem tempo agora agora. Mas assim que sobrar um tempinho eu crio os testes e faço um pull request. :slight_smile:
E se for tranquilo de resolve-los também.

Num próximo projeto vou usar o @Load. Mas no atual não tem como pois o projeto já está enorme. Ele foi todo projetado para usar o converter. Eu ficaria dias só pra fazer essa alteração. Aí eu acho que perde um pouco o sentido. Mas num próximo projeto tentar usar o @Load sim. E eu tiver dúvida, perturbo vocês mais um pouco =P

Mas enquanto isso, como eu poderia fazer pra resolver esse último problema. Nos casos anteriores o Lucas Cavalcanti indicou como contornar os bugs. Mas nesse caso, todas as dicas que ele deu não funcionaram. Será que tem algo que eu possa fazer pra contornar?

G

Cola o stacktrace em um pastebin, gist, ou cola aqui mesmo. Aí podemos ver certinho o que pode causar o erro.

G

br.com.caelum.vraptor.http.InvalidParameterException: Exception when trying to instantiate Target(name=agendaSemanal, type=interface java.util.List) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.handleException(VRaptorInstantiator.java:96) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.handleException(VRaptorInstantiator.java:98) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:88) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:81) at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.instantiateOrAddError(IogiParametersProvider.java:80) at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.instantiateParameters(IogiParametersProvider.java:73) at br.com.caelum.vraptor.http.iogi.IogiParametersProvider.getParametersFor(IogiParametersProvider.java:63) at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.getParametersFor(ParametersInstantiatorInterceptor.java:132) at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:86) at br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.metamorfosevirtual.interceptors.DaoInterceptor.intercept(DaoInterceptor.java:35) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:67) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.metamorfosevirtual.interceptors.HibernateInterceptor.intercept(HibernateInterceptor.java:30) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44) at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:93) at br.com.caelum.vraptor.ioc.guice.GuiceProvider.provideForRequest(GuiceProvider.java:82) at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:99) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.NullPointerException at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator$VRaptorTypeConverter.setPropertiesAfterConversions(VRaptorInstantiator.java:144) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator$VRaptorTypeConverter.instantiate(VRaptorInstantiator.java:135) at br.com.caelum.iogi.MultiInstantiator.instantiate(MultiInstantiator.java:20) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:86) at br.com.caelum.iogi.collections.IndexedListInstantiator.instantiate(IndexedListInstantiator.java:34) at br.com.caelum.iogi.collections.ListInstantiator.instantiate(ListInstantiator.java:25) at br.com.caelum.iogi.collections.ListInstantiator.instantiate(ListInstantiator.java:10) at br.com.caelum.vraptor.http.iogi.NullDecorator.instantiate(NullDecorator.java:39) at br.com.caelum.iogi.MultiInstantiator.instantiate(MultiInstantiator.java:20) at br.com.caelum.vraptor.http.iogi.VRaptorInstantiator.instantiate(VRaptorInstantiator.java:86) ... 48 more

Lucas_Cavalcanti

essa agendaSemanal está dentro de um objeto? ou é um parâmetro do método?

se estiver dentro do objeto, vc está instanciando a lista na mão, no setter ou no atributo?

G

Ih é, foi mal, esqueci de falar: essa “Agenda Semanal” é como eu estou chamando um “Horario” que eu tinha dito anteriormente. Preciso preencher um List na verdade, entende?

Eu andei pensando: uma forma de resolver o problema acho que seria ter no método uma lista pra cada campo de AgendaSemanal e montar o objeto dentro do controller. Não é a melhor solução, mas funciona. Vou tentar fazer isso e posto se funcionou.

G

Não funcionou. Pelo que parece o Vraptor não garante a ordem de inserção nas listas. Mas criei um DTO pra AgendaSemanal e funcionou. É até mais indicado…

Lucas_Cavalcanti

esse bug da ordem de inserção das listas já foi corrigido no IOGI, vamos lançar uma versão na segunda feira provavelmente =)

G

Boa! :slight_smile:

Lucas_Cavalcanti

Pode testar com essa versão por favor?

https://oss.sonatype.org/service/local/repositories/brcomcaelum-1050/content/br/com/caelum/iogi/1.0.0/iogi-1.0.0.jar

G

Sim, com essa versão chega certo. :slight_smile:

Lucas_Cavalcanti

Já está no maven! =)

Criado 9 de janeiro de 2014
Ultima resposta 11 de fev. de 2014
Respostas 67
Participantes 4