Problema com inicialização do VRaptor 3

Bom dia.

Aqui na empresa temos uma aplicação que está rodando com o VRaptor 3.1.1, a aplicação está hospadada na LocaWeb (infelizmente :?) em um servidor gerenciado por eles.
Não sei se é exatamente isso, mas acredito que todo dia de madrugada, por volta das 3h, o servidor é reiniciado, e como o Tomcat é um serviço já sobe automaticamente junto com o server.

Acontece que as vezes, ao subir o Tomcat, acontece algum erro que o VRaptor fica acusando como se dois métodos estavam configurados para uma mesma URI para qualquer endereço que você solicite e nada na aplicação funciona.
Não é toda vez que isso acontece, mas quando acontece a aplicação fica fora do ar até que alguém chegue aqui no escritório, veja e reinicie o server.

As vezes também acontece quando é feito o deploy de alguma alteração na aplicação e o servidor precisa ser reiniciado, nesse caso como quem está fazendo o deploy já vai ver que está dando o erro e já vai reiniciar o Tomcat novamente.
O estranho é que sem fazer nenhuma alteração em lugar nenhum, somente reiniciando o Tomcat a aplicação volta a funcionar, e mais estranho ainda é o log do erro: SEVERE: Servlet.service() for servlet default threw exception java.lang.IllegalStateException: There are two rules that matches the uri '/arquivo/download' with method POST: [[FixedMethodStrategy: /arquivo/download ArquivoController.download(Arquivo) ALL], [FixedMethodStrategy: /arquivo/download ArquivoController.download(Arquivo) ALL]] with same priority. Consider using @Path priority attribute. Como podem ver, ele está acusando que os dois métodos que estão configurados para a URI são o mesmo.

A classe está declarada como ArquivoController e o nome do método é download, não foi usando o @Path nem na classe nem no método.

Alguém teria alguma idéia de o que pode estar acontecendo??

Valeu
Abraços

[quote=guedes]A classe está declarada como ArquivoController e o nome do método é download, não foi usando o @Path nem na classe nem no método.

Alguém teria alguma idéia de o que pode estar acontecendo??

Valeu
Abraços[/quote]

provavelmente é algo assim

class ArquivoController { @Post public void download() {...} @Post public void download(...algumargumento...) {...} }

em resumo… métodos com assinatura sobrecarregada geram esse problema de path! neste caso vc tera q colocar um @Path em 1 dos 2, para diferenciar… ou … alterar o nome d um… ou alterar um deles para @Put, ou outra coisa…

Meus pesames com a Locaweb. Mas pense pelo lado positivo, sendo cliente deles você já está pagando parte dos seus pecados :smiley:

Quando ao problema, acho que você deve primeiro ver se não tem um war de alguma aplicação antiga no seu tomcat. Será que não há alguma aplicação de testes perdida?

Além disso acho legal você verificar seu codigo e ver se realmente não há algum @Path com o mesmo valor de outro. Isso pode acontecer quando você faz algum copy-and-paste e afins. Já aconteceu comigo outro dia quando copiei um controller.

Note que quando você inicializa o vraptor ele imprime uma lista de todas as rotas. Até abri uma issue para melhorar esse logging, mostrando não apenas a rota e o método, mas também a annotation @Get, @Post, @Put e afins.

Abraços

@Lavieri
O método não foi sobrecarregado, existe apenas um único método download no ArquivoController.

@garcia-jj
Por aqui não damos o deploy via WAR, jogamos o WEB-INF (classes, lib, jps, …) direto no ROOT do tomcat, ou seja, deletamos tudo do ROOT que vem por padrão no Tomcat e subimos a aplicação.

E também não tem nenhuma aplicação de testes por lá, a única aplicação que existe realmente é essa.
E até esqueci de comentar, eu deixo sempre ativado o logger do VRaptor, então em toda inicialização ele loga a lista de rotas, e por esse log nenhuma anormalidade é apresentada, ele loga apenas uma URI pra cada método.

Segue: $d [main] INFO br.com.caelum.vraptor.core.DefaultConverters - Registering bundled converters $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoSwfArquivos/identificacaoProximoArquivoParaGerarSwf -> ConversaoSwfArquivosController.identificacaoProximoArquivoParaGerarSwf() $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoSwfArquivos/downloadProximoArquivoParaGerarSwf -> ConversaoSwfArquivosController.downloadProximoArquivoParaGerarSwf(String, Arquivo) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoSwfArquivos/receberSwf -> ConversaoSwfArquivosController.receberSwf(String, Long, UploadedFile) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoSwfArquivos/atualizarStatusSwf -> ConversaoSwfArquivosController.atualizarStatusSwf(Arquivo, String, Boolean) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoSwfArquivos/informacoesArquivo -> ConversaoSwfArquivosController.informacoesArquivo(Arquivo, String) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoSwfArquivos/downloadSwf -> ConversaoSwfArquivosController.downloadSwf(Arquivo, String, String) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /arquivo/id -> ArquivoController.id(Arquivo) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /arquivo/download -> ArquivoController.download(Arquivo) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /arquivo/receber -> ArquivoController.receber(UploadedFile, Arquivo, String, ArquivoNoGrupo) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /arquivo/preview -> ArquivoController.preview(Arquivo) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /arquivo/downloadConteudoParaIndexacao -> ArquivoController.downloadConteudoParaIndexacao(Arquivo) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /correcoes/enviarArquivosEstaticosParaNovoServidor -> CorrecoesController.enviarArquivosEstaticosParaNovoServidor() $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /email/enviarEmailTeste -> EmailController.enviarEmailTeste() $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /email/emailReconvidar -> EmailController.emailReconvidar(Usuario) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /email/emailRequisicaoAmigos -> EmailController.emailRequisicaoAmigos(Usuario) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /email/emailConvite -> EmailController.emailConvite(String, String, String, String, String) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /email/emailContato -> EmailController.emailContato(String, String, String, String) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /email/emailStatusConversaoFlash -> EmailController.emailStatusConversaoFlash(Arquivo, String) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /email/emailNovoPost -> EmailController.emailNovoPost(Usuario, Topico) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /email/emailRequisicoesParaGrupo -> EmailController.emailRequisicoesParaGrupo(Usuario) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /email/emailNovaMensagemMural -> EmailController.emailNovaMensagemMural(Usuario) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /email/emailDeConfirmacao -> EmailController.emailDeConfirmacao(String) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /email/emailEsqueciASenha -> EmailController.emailEsqueciASenha(String) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /email/emailRelatorioDiario -> EmailController.emailRelatorioDiario(String) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoArquivos/identificacaoProximoArquivoParaConverter -> ConversaoArquivosController.identificacaoProximoArquivoParaConverter() $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoArquivos/downloadProximoArquivo -> ConversaoArquivosController.downloadProximoArquivo(String, Arquivo) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoArquivos/receberThumbnail -> ConversaoArquivosController.receberThumbnail(UploadedFile) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoArquivos/teste -> ConversaoArquivosController.teste() $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoArquivos/receberArquivoConvertido -> ConversaoArquivosController.receberArquivoConvertido(UploadedFile) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoArquivos/receberConteudo -> ConversaoArquivosController.receberConteudo(UploadedFile) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoArquivos/tirarArquivoDaQuarentena -> ConversaoArquivosController.tirarArquivoDaQuarentena(Arquivo, String) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoArquivos/validarPorRelacaoVogalConsoante -> ConversaoArquivosController.validarPorRelacaoVogalConsoante(String) $d [main] INFO br.com.caelum.vraptor.http.route.RouteBuilder - /conversaoArquivos/validarPorTamanhoMedioDasPalavras -> ConversaoArquivosController.validarPorTamanhoMedioDasPalavras(String) $d [main] INFO br.com.caelum.vraptor.VRaptor - VRaptor 3.1.1 successfuly initialized
Esse log acima é de uma das vezes que ao subir o Tomcat me foi apresentado o problema.

vc tá com o context-param br.com.caelum.vraptor.packages configurado no web.xml? se tiver, é só tirar… no vraptor 3.1.1 não precisa dele

Lucas, tenho sim o context-param configurado.
Mas o incluí por causa de um @Component que eu uso de dentro de um JAR.

Sem o context-param o VRaptor não está conseguindo injetar o meu DaoFactory.
Segue a configuração: <context-param> <param-name>br.com.caelum.vraptor.packages</param-name> <param-value>br.com.ebah.ebah3.dominio.repositorio.jpa</param-value> </context-param>E o erro gerado caso eu remova o context-param: 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: {}

quando acontece o erro, vc consegue ver no log se os métodos do seu controller estão sendo registrados duas vezes?

está ancontecendo o hotdeploy do tomcat quando o erro acontece?

Lucas, o log que eu postei anteriormente do registro dos métodos foi de uma inicialização que deu o problema.
Ele registra somente uma vez cada método.

Não, a gente aqui não faz hotdeploy.
A gente desliga o tomcat, sobe os classes, jsp, properties, … (o que precisar), direto na pasta ROOT da instalação do Tomcat, e depois liga novamente o Tomcat.

esse erro acontece em situações específicas (tipo logo após um deploy, logo após reniciar a máquina, etc)?

vc tá fazendo deploy com um war, ou vc descompacta a aplicação na mão? ou os dois?

se for war, tenta abrir ele como um zip e ver se ele só colocou uma entrada pra cada arquivo (em um zip é possível colocar mais de um arquivo com o mesmo nome)

Acontece as vezes em situação onde o Tomcat precisa ser reiniciado.
Por exemplo:
Quando a LocaWeb reinicia o servidor de madrugada pra dar alguma manutenção,
ou quanto logo após um deploy eu preciso reiniciar o Tomcat.

Mas não são todas as vezes que acontece, é meio que de lua, acontece quando quer.
E como já mencionei outras vezes, não fazemos deploy via war.
Subimos para o servidor as classes direto no diretorio classes do webapps/ROOT/WEB-INF dentro do Tomcat.

pelo erro, o VRaptor tá passando 2 vezes pelas suas classes, e por isso tá registrando 2 vezes as rotas…

só não vejo mto motivo pra isso acontecer =/ de qqer forma, teria que dar pra ver o vraptor subindo duas vezes, no log do servidor… olhando o log inteiro, vc consegue achar algo assim?

tenta ver se vc gerar um war chamado ROOT.war e copiá-lo pra webapps do tomcat e vê se o erro continua acontecendo…

Desculpe a ausência, acabamos deixando isso um pouco de lado ultimamente.

Respondendo à sua ultima pergunta Lucas, vendo o log não existe nada dizendo que o VRaptor está subindo duas vezes, em toda a inicialização, apenas um trecho do seguinte: $d [main] INFO br.com.caelum.vraptor.ioc.spring.VRaptorApplicationContext - Refreshing Root WebApplicationContext: startup date [Tue May 11 11:12:18 GMT-03:00 2010]; root of context hierarchy $d [main] INFO br.com.caelum.vraptor.ioc.spring.VRaptorApplicationContext - Scanning WEB-INF/classes: /home/ebah1/public_html/WEB-INF/classes $d [main] INFO br.com.caelum.vraptor.ioc.spring.VRaptorApplicationContext - Scanning packages from WEB-INF/classes and jars: [br.com.ebah.ebah3.dominio.repositorio.jpa]Mas olhando os logs aqui com mais calma,
percebi que quando o problema ocorre, antes de logar que tem a url duplicada ele loga uma exception: SEVERE: Servlet.service() for servlet default threw exception java.util.ConcurrentModificationException at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761) at java.util.LinkedList$ListItr.next(LinkedList.java:696) at com.google.common.collect.Iterators.any(Iterators.java:638) at com.google.common.collect.Collections2$FilteredCollection.isEmpty(Collections2.java:168) at br.com.caelum.vraptor.http.route.DefaultRouter.routesMatchingUri(DefaultRouter.java:134) at br.com.caelum.vraptor.http.route.DefaultRouter.routesMatchingUriAndMethod(DefaultRouter.java:116) at br.com.caelum.vraptor.http.route.DefaultRouter.parse(DefaultRouter.java:92) at br.com.caelum.vraptor.http.DefaultResourceTranslator.translate(DefaultResourceTranslator.java:51) at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:64) 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.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) 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:230) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at br.com.locaweb.tomcat.LocaWebValve.invoke(LocaWebValve.java:134) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261) at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190) at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:283) at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:767) at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:697) at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:889) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:686) at java.lang.Thread.run(Thread.java:619) May 11, 2010 11:12:24 AM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet default threw exception java.lang.IllegalStateException: There are two rules that matches the uri '/arquivo/download' with method POST: [[FixedMethodStrategy: /arquivo/download ArquivoController.download(Arquivo) ALL], [FixedMethodStrategy: /arquivo/download ArquivoController.download(Arquivo) ALL]] with same priority. Consider using @Path priority attribute. at br.com.caelum.vraptor.http.route.DefaultRouter.checkIfThereIsAnotherRoute(DefaultRouter.java:106) at br.com.caelum.vraptor.http.route.DefaultRouter.parse(DefaultRouter.java:97) at br.com.caelum.vraptor.http.DefaultResourceTranslator.translate(DefaultResourceTranslator.java:51) at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:64) 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.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) 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:230) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at br.com.locaweb.tomcat.LocaWebValve.invoke(LocaWebValve.java:134) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261) at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190) at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:283) at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:767) at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:697) at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:889) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:686) at java.lang.Thread.run(Thread.java:619)Ai em toda e qualquer requisição vem a exception seguida do SEVERE da url duplicada.

E em relação ao WAR, acredito que eu não consigo dar o deploy via war, porque esse servidor onde está hospedado a aplicação é um servidor gerenciado pela LocaWeb, e nesses servidores eles só disponibilizam uma pasta public_html, que seria o ROOT do webapps no Tomcat, e a pasta logs.

Caso não encontremos solução, iremos migrar para VRaptor 2 a aplicação, pois todas as outras aplicações que temos sempre rodaram perfeitamente. Essa primeira com o 3, acabou não dando muito certo.
Não queria ter que fazer isso mas é o que em último caso será feito.
:frowning:

— Edit —
Inclusão do resto da exception que tinha faltado.

toda vez que dá o erro de url duplicada acontece o erro abaixo?

java.util.ConcurrentModificationException

qual a versão do google collections vc tá usando?

sua aplicação tem acessos simultâneos quando acontece esse erro?

pra mesma url esse erro acontece sempre?

[quote=Lucas Cavalcanti]toda vez que dá o erro de url duplicada acontece o erro abaixo? java.util.ConcurrentModificationException [/quote]Sim, toda vez que da o erro da url duplicada é lançada a ConcurrentModificationException

Estamos usando google-collect-1.0.jar

[quote=Lucas Cavalcanti]sua aplicação tem acessos simultâneos quando acontece esse erro?

pra mesma url esse erro acontece sempre?[/quote]
Quando o erro ocorre não importa quantas requisições ele recebe e nem qual requisição foi feita,
toda e qualquer requisição gera o erro.

O único jeito de parar o problema é parar o Tomcat, subir novamente e torcer pra não acontecer denovo.
Porque ele acontece aleatoriamente em inicializações do Tomcat.

substitua o seu jar do vraptor por esse por favor:

http://oss.sonatype.org/content/repositories/snapshots/br/com/caelum/vraptor/3.1.3-SNAPSHOT/vraptor-3.1.3-20100511.222342-4.jar

acredito que esse problema seja resolvido… se não for, por favor me dê um toque que eu faço uma solução mais drástica…

o seu problema é por causa de concorrência na hora de fazer a configuração do vraptor…

Abraços

o jar anterior provavelmente só corrigiu o problema da concorrência… modifiquei mais algumas coisas, e o jar abaixo deve ter corrigido também o problema das rotas:

http://oss.sonatype.org/content/repositories/snapshots/br/com/caelum/vraptor/3.1.3-SNAPSHOT/vraptor-3.1.3-20100511.225418-5.jar

Abraços

Olá Lucas,

Obrigado pela força, acabei de atualizar o JAR.
Como nunca consegui reproduzir o problema não posso te dar certeza se resolveu ou não.

Dei uns 3 restarts seguidos no servidor e nada de anormal aconteceu.
Caso aconteça mais alguma vez eu volto a postar novamente.

Novamente obrigado a ajuda.

Abraço