[RESOLVIDO] VRaptor3 + java.io.InputStream + ServletOutputStream

8 respostas
L

Tenho uma aplicação que utiliza os frameworks VRaptor e Hibernate.
Tenho algumas colunas tipo BYTEA no banco de dados.
Essas colunas estavam mapeadas com o tipo byte[] e fetch=FetchType.LAZY.
Logo, se faço upload de um arquivo para inserir numa dessas colunas, tenho de ler o InputStream para um byte[].
E toda vez que for disponibilizar para download, tenho que carregar o byte[] do banco.

Essa situação estava fazendo com que o meu servidor travasse várias vezes por java.lang.OutOfMemoryError: Java heap space.

Decidi então Utilizar JDBC somente para esse caso, através dos métodos PreparedStatement.setBinaryStream() e ResultSet.getBinaryStream().

Até aí tudo OK. Está tudo funcionando muito bem.
Só estou com uma exceção, que não está interferindo no funcionamento da minha aplicação, porém está gerando muito lixo nos LOGs.

Segue a exceção:

04/08/2011 20:15:57 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet [default] in context with path [/iatende] threw exception
java.lang.IllegalStateException: Cannot forward after response has been committed
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:339)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
	at br.com.caelum.vraptor.view.DefaultPageResult.forward(DefaultPageResult.java:67)
	at br.com.caelum.vraptor.extra.ForwardToDefaultViewInterceptor.intercept(ForwardToDefaultViewInterceptor.java:59)
	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.interceptor.OutjectResult.intercept(OutjectResult.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:75)
	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.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
	at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:80)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.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:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:498)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)

8 Respostas

L

Me esqueci de uma observação importante. Não estou mais utilizando o tipo br.​com.​caelum.​vraptor.​interceptor.​download.Download como retorno dos meus métodos de download. Estou escrevendo diretamente na ServletOutputStream, através de um BufferedInputStream.

Lucas_Cavalcanti

pq vc não está retornando um InputStream? o VRaptor já faz esse código do OutputStream pra vc…

em todo caso, se vc for fazer na mão precisa colocar um result.nothing() no final do método.

L

Até tentei utilizar dessa maneira… ± assim:

Connection con…

try{

return new InputStreamDownload(resultSet.getBinaryStream(), contentType, filename);

}finally{

con.close();

}

Mas estava retornando a mesma exceção, porém sem retornar o arquivo ao cliente.
Quando passei a escrever o InputStream diretamente no OutputStream consegui devolver o arquivo ao cliente, porém a exceção continuou em background…

Pelo que percebi, essa exceção é lançada antes de chamar o método do recurso… acho que é chamada por algum Interceptor default…

Lucas_Cavalcanti

entendi, é pq o download não acontece no retorno do método, então vc fecha a conexão antes de ter o stream inteiro carregado…

vai ter que copiar pro response mesmo =(

só use o result.nothing() pro vraptor não tentar redirecionar pra nenhum lugar

L

Fui olhar no meu classpath e ainda estou com o vraptor 3.1.1…
Não existe aqui esse método Result.nothing().

Vou baixar a última versão…

L

Só tive problemas com a classe “CustomPathResolver extends DefaultPathResolver”, pois não foi mais encontrado o construtor “super(request, acceptHeaderToFormat);”.
Fui na documentação e vi que o exemplo da CustomPathResolver não usa mais aquele construtor. Estou usando agora “super(FormatResolver resolver);”.

Fora isso tudo perfeito!!!

Usei o result.nothing() e a exceção parou de ser lançada.

Lucas Cavalcanti, muito obrigado pela ajuda.

Só mais uma dúvida, antes de implantar no servidor: a 3.3.1 é 100% compatível com a 3.1.1?

Lucas_Cavalcanti

se vc não abusou de usar APIs internas do VRaptor, é compatível sim…

pros usos externos é 100% compatível sim.

L

Ok!!! Perfeito… já implantei no servidor… tudo beleza.

Vou dar conferida na documentação da 3.3.1…
Olhei rapidinho e já vi que tem algumas coisas novas…

Mais uma vez ,muito obrigado!

Criado 4 de agosto de 2011
Ultima resposta 5 de ago. de 2011
Respostas 8
Participantes 2