[RESOLVIDO] Erro de "IllegalStateException" para a classe "EnhancedList" no RESTFulie

Olá pessoal!

Estou novamente aqui para reportar um erro que estou encontrando quando tento executar o RESTFulie no servidor do meu cliente.

Vou contextualizar para ficar mais fácil o entendimento do erro.

Eu tenho o meu serviço no VRaptor e disponibilizo este para um cliente em RESTFulie. Até então, tudo bem. Este cliente estava executando os testes usando uma classe standalone e estava tudo certo.

Após vermos que a comunicação estava acontecendo, fizemos a “migração” deste para a aplicação propriamente dita, ou seja, incorporamos a mesma chamada (digo copy/paste) para dentro do projeto que usará o meu serviço no VRaptor (abaixo tem o exemplo do código de chamada)…

[code] RestClient restfulie = Restfulie.custom();
restfulie.getMediaTypes().register(
new XmlMediaType().withTypes(
LoteDispensacaoDto.class,
LoteDispensacaoSolicitacaoDto.class,
ItemAprazamentoHorarioDto.class,
ItemAprazamentoDispensacaoDto.class
)
);

	String servico = getProperties().getProperty("ws.baixaLote");
	Response response = restfulie.at(servico).accept( XML ).as( XML ).post(loteDispensacaoDto);
	return response.getCode();[/code]

… e esta passou a dar erro no momento da recuperação do RestClient, ou seja, nessa linha:

Nem chega a registrar os tipos. Vendo que este erro passou a acontecer quando fizemos a mudança da chamada para dentro do servidor de aplicação (incorporado ao projeto propriamente dito), fizemos o teste com o standalone novamente, e esse não apresentou erro algum. O servidor de aplicação deste projeto é o Tomcat versão 5.5.

O erro apresentado é este:

[quote]10:24:42,787 ERROR DispatchActionAb:250 - Exception :Unable to extend type br.com.caelum.restfulie.mediatype.EnhancedList
java.lang.IllegalStateException: Unable to extend type br.com.caelum.restfulie.mediatype.EnhancedList
at br.com.caelum.restfulie.relation.Enhancer.enhanceResource(Enhancer.java:24)
at br.com.caelum.restfulie.mediatype.XStreamHelper.getXStream(XStreamHelper.java:120)
at br.com.caelum.restfulie.mediatype.JsonMediaType.<init>(JsonMediaType.java:33)
at br.com.caelum.restfulie.http.DefaultRestClient.<init>(DefaultRestClient.java:55)
at br.com.caelum.restfulie.Restfulie.custom(Restfulie.java:45)
at br.scmba.prontus.dispensacao.view.action.DispensacaoDispatchAction.executeWS(DispensacaoDispatchAction.java:1013)
at br.scmba.prontus.dispensacao.view.action.DispensacaoDispatchAction.salvarBaixaSolicitacao(DispensacaoDispatchAction.java:518)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:270)
at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:187)
at org.springframework.web.struts.DelegatingActionProxy.execute(DelegatingActionProxy.java:110)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at net.sf.jguard.jee.authentication.http.AccessFilter.authorize(AccessFilter.java:536)
at net.sf.jguard.jee.authentication.http.AccessFilter.doFilter(AccessFilter.java:292)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at br.scmba.prontus.core.util.EncodingFilter.doFilter(EncodingFilter.java:26)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:870)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)
at java.lang.Thread.run(Thread.java:619)
Caused by: javassist.NotFoundException: br.com.caelum.restfulie.mediatype.EnhancedList
at javassist.ClassPool.get(ClassPool.java:436)
at br.com.caelum.restfulie.relation.Enhancer.enhanceResource(Enhancer.java:18)
… 44 more[/quote]
Estou com o fonte do projeto e vi que ao executar o standalone o Restfulie faz o registro corretamente da classe EnhancedList corretamente, mas não consegui entender o motivo pelo qual ele não consegue fazer o mesmo dentro do servidor de aplicação.

Se puderem me ajudar com mais esse problema, ficarei grato.

Desde então, obrigado!

Abraço!

onde vc está executando esse código do restfulie client?

onde está o jar do restfulie client?

o que pode estar acontecendo é que o EnnhancedList esteja em um ClassLoader diferente do do código do cliente, daí o javassist falha em conseguir carregar a classe.

Lucas,

De antemão, obrigado pela ajuda!

Esse código do Resfulie está dentro de um projeto que utiliza Struts, ou seja, esse código está sendo executado dentro de uma Action do Struts.

Tanto esse execução de dentro de uma Action como o standalone estão sendo executados de dentro do mesmo projeto (o desenvolvedor que está criando o cliente do meu serviço - a Action - está fazendo essa chamada como teste - o standalne) e o projeto está utilizando o Maven, ou seja, a lib do Restfulie, Javassist, etc. está tudo dentro do próprio projeto em questão. Isso responde as suas perguntas?

Essa questão do ClassLoader eu não cheguei a olhar, apesar de que o argumento é pertinente. Irei olhar agora mesmo. Mas, de antemão, caso esteja em um outro ClassLoader, o que eu poderia estar fazendo para solucionar esse erro?

Abraço!

pode ser que exista algum jar do javassist na lib do servidor, que tem precedência…

o mesmo código no standalone funciona normalmente, é isso?

Lucas,

Fiz um teste e depurando vi que é exatamente isso que disse. Essa classe EnhancedList não encontra-se no ClassLoader. Na linha 2072 da classe java.lang.Class (como pode ser visto abaixo), onde o name seria br.com.caelum.restfulie.mediatype.EnhancedList está retornando null.

Estou pensando que isso pode estar ligado ao fato de estar no contexto do Tomcat e este estar se perdendo lá dentro. Tem alguma dica de como eu posso resolver esse problema?

Mais uma vez, obrigado!

Lucas,

Exatamente isso. O mesmo código, exatamente o mesmo (copy / paste), funciona perfeitamente no standalone.

Vou checar se existe essa mesma biblioteca no Tomcat.

Abraço!

faz na sua action:

System.out.println(javassist.NotFoundException.class.getClassLoader());
System.out.println(getClass().getClassLoader());
System.out.println(EnhancedList.class.getClassLoader());

Lucas,

Coloquei o código que você informou na minha Action e no meu standalone.

Na Action o resultado é:

[quote]WebappClassLoader
delegate: false
repositories:
/WEB-INF/classes/
----------> Parent Classloader:
org.apache.catalina.loader.StandardClassLoader@190d8e1

WebappClassLoader
delegate: false
repositories:
/WEB-INF/classes/
----------> Parent Classloader:
org.apache.catalina.loader.StandardClassLoader@190d8e1

WebappClassLoader
delegate: false
repositories:
/WEB-INF/classes/
----------> Parent Classloader:
org.apache.catalina.loader.StandardClassLoader@190d8e1[/quote]
E no meu standalone é:

[quote]sun.misc.Launcher$AppClassLoader@1a7bf11
sun.misc.Launcher$AppClassLoader@1a7bf11
sun.misc.Launcher$AppClassLoader@1a7bf11[/quote]
Ou seja, para ambos os casos o ClassLoader é o mesmo. Fiquei encucado agora o porque que ele não reconhece o EnhancedList no contexto da web. Alguma outra dica?

Obrigado mais uma vez!

no web o parent é o mesmo, mas não sei se é o mesmo classloader…

imprime o hashCode dos classloaders ou algum outro identificador único.

se ainda assim for igual, tenta criar um projeto web simples, com uma servlet, e coloca o código do restfulie dentro dessa servlet. ve se funciona

[]'s

Lucas,

Fiz o teste que pediu e o hashCode de todos os ClassLoader são iguais.

Dando seguimento, fiz o teste junto ao Servlet e está dando o mesmo erro listado.

Servlet:

[code]@WebServlet( “/test” )
public class ServletTest extends HttpServlet {

private static final long serialVersionUID = 3252472787742396400L;

public void doGet( HttpServletRequest request, HttpServletResponse response )
		throws ServletException, IOException {

	LoteDispensacaoDto loteDispensacaoDto = new LoteDispensacaoDto();
	
	ItemAprazamentoDispensacaoDto dispensacao1 = new ItemAprazamentoDispensacaoDto();
	dispensacao1.setIdMaterial( 940L );
	dispensacao1.setQtdMaterial( 1.0 );
	
	ItemAprazamentoDispensacaoDto dispensacao2 = new ItemAprazamentoDispensacaoDto();
	dispensacao2.setIdMaterial( 25271L );
	dispensacao2.setQtdMaterial( 1.0 );
	
	ItemAprazamentoDispensacaoDto dispensacao3 = new ItemAprazamentoDispensacaoDto();
	dispensacao3.setIdMaterial( 1324L );
	dispensacao3.setQtdMaterial( 1.0 );
	
	ItemAprazamentoDispensacaoDto dispensacao4 = new ItemAprazamentoDispensacaoDto();
	dispensacao4.setIdMaterial( 25263L );
	dispensacao4.setQtdMaterial( 1.0 );
	
	ItemAprazamentoDispensacaoDto dispensacao5 = new ItemAprazamentoDispensacaoDto();
	dispensacao5.setIdMaterial( 994L );
	dispensacao5.setQtdMaterial( 1.0 );
	
	List&lt;ItemAprazamentoDispensacaoDto&gt; dispensacoes = new ArrayList&lt;ItemAprazamentoDispensacaoDto&gt;( 5 );
	dispensacoes.add( dispensacao1 );
	dispensacoes.add( dispensacao2 );
	dispensacoes.add( dispensacao3 );
	dispensacoes.add( dispensacao4 );
	dispensacoes.add( dispensacao5 );
	
	ItemAprazamentoHorarioDto horario = new ItemAprazamentoHorarioDto();
	horario.setDtcHorAprazamento( Calendar.getInstance().getTime() );
	horario.setItemAprazamentoDispensacao( dispensacoes );

	List&lt;ItemAprazamentoHorarioDto&gt; horarios = new ArrayList&lt;ItemAprazamentoHorarioDto&gt;( 1 );
	horarios.add( horario );
	
	LoteDispensacaoSolicitacaoDto solicitacaoDto = new LoteDispensacaoSolicitacaoDto();
	solicitacaoDto.setNumSolicitacao( 197L );
	solicitacaoDto.setIdInternamento( 2765155L );
	solicitacaoDto.setIdPlanoConvenio( 1131L );
	solicitacaoDto.setItemAprazamentoHorario( horarios );
	
	RestClient restfulie = Restfulie.custom();
	restfulie.getMediaTypes().register(
			new XmlMediaType().withTypes(
					LoteDispensacaoDto.class));

	Response resp = restfulie.at( "http://10.32.1.22:8080/genhio/baixaLoteEmConta" ).accept( MediaTypes.XML ).as( MediaTypes.XML )
		.post( loteDispensacaoDto );

	response.setContentType("text/html");
	PrintWriter out = response.getWriter();
	out.println("&lt;!DOCTYPE html&gt;\n" 
			+ "&lt;html&gt;\n"
			+ "&lt;head&gt;&lt;title&gt;A Test Servlet&lt;/title&gt;&lt;/head&gt;\n"
			+ "&lt;body bgcolor=\"#fdf5e6\"&gt;\n" 
			+ "&lt;h1&gt;Test&lt;/h1&gt;\n"
			+ "<p>Simple servlet for testing.</p>\n" 
			+ "<p>Code returned: </p>\n" + resp.getCode() 
			+ "&lt;/body&gt;&lt;/html&gt;");
}

}[/code]
E faço a chamada [quote]http://localhost:8089/app/test[/quote] e o erro é o mesmo e na mesma linha.
Tem alguma outra dica?

Mais uma vez, obrigado.

Abraço!

consegui reproduzir o bug aqui, to tentando corrigir

testa com o jar que está em anexo, por favor

Lucas,

Muito obrigado!

Problema resolvido com essa nova versão.

Abraço!

Boa tarde,

tenho exactamente o mesmo problema usando a versão 1.0.1 restfulie com versao 3.5 do vraptor.

Imprimi tambem o classLoader :

[quote]Shared ClassLoader Chain parentCL :: sun.misc.Launcher$AppClassLoader@169e11 URLs ::
, file:/C:/Work/glassfish/lib/javaee.jar, file:/C:/Work/jdk1.5.0_22/jre/…/lib/tools.jar, file:/C:/Work/glassfish/lib/install/applications/jmsra/imqjmsra.jar, file:/C:/Work/glassfish/lib/com-sun-commons-launcher.jar, file:/C:/Work/glassfish/lib/com-sun-commons-logging.jar, file:/C:/Work/glassfish/imq/lib/jaxm-api.jar, file:/C:/Work/glassfish/imq/lib/fscontext.jar, file:/C:/Work/glassfish/imq/lib/imqbroker.jar, file:/C:/Work/glassfish/imq/lib/imqjmx.jar, file:/C:/Work/glassfish/imq/lib/imqxm.jar, file:/C:/Work/glassfish/lib/webservices-rt.jar, file:/C:/Work/glassfish/lib/webservices-tools.jar, file:/C:/Work/glassfish/lib/mail.jar, file:/C:/Work/glassfish/lib/appserv-jstl.jar, file:/C:/Work/glassfish/lib/jmxremote_optional.jar, file:/C:/Work/glassfish/lib/SUNWjdmk/5.1/lib/jdmkrt.jar, file:/C:/Work/glassfish/lib/activation.jar, file:/C:/Work/glassfish/lib/appserv-rt.jar, file:/C:/Work/glassfish/lib/appserv-admin.jar, file:/C:/Work/glassfish/lib/appserv-cmp.jar, file:/C:/Work/glassfish/updatecenter/lib/updatecenter.jar, file:/C:/Work/glassfish/jbi/lib/jbi.jar, file:/C:/Work/glassfish/imq/lib/imqjmx.jar, file:/C:/Work/glassfish/lib/ant/lib/ant.jar, file:/C:/Work/glassfish/lib/dbschema.jar, file:/C:/Work/glassfish/lib/activation.jar, file:/C:/Work/glassfish/lib/admin-cli-ee.jar, file:/C:/Work/glassfish/lib/admin-cli.jar, file:/C:/Work/glassfish/lib/antlr-2.7.6.jar, file:/C:/Work/glassfish/lib/appserv-admin.jar, file:/C:/Work/glassfish/lib/appserv-cmp.jar, file:/C:/Work/glassfish/lib/appserv-deployment-client.jar, file:/C:/Work/glassfish/lib/appserv-ee.jar, file:/C:/Work/glassfish/lib/appserv-ext.jar, file:/C:/Work/glassfish/lib/appserv-jstl.jar, file:/C:/Work/glassfish/lib/appserv-jwsacc.jar, file:/C:/Work/glassfish/lib/appserv-launch.jar, file:/C:/Work/glassfish/lib/appserv-rt.jar, file:/C:/Work/glassfish/lib/appserv-se.jar, file:/C:/Work/glassfish/lib/appserv-tags.jar, file:/C:/Work/glassfish/lib/appserv-upgrade.jar, file:/C:/Work/glassfish/lib/appserv-ws.jar, file:/C:/Work/glassfish/lib/com-sun-commons-launcher.jar, file:/C:/Work/glassfish/lib/com-sun-commons-logging.jar, file:/C:/Work/glassfish/lib/commons-collections-3.1.jar, file:/C:/Work/glassfish/lib/dbschema.jar, file:/C:/Work/glassfish/lib/dom4j-1.6.1.jar, file:/C:/Work/glassfish/lib/hibernate-annotations.jar, file:/C:/Work/glassfish/lib/hibernate-commons-annotations.jar, file:/C:/Work/glassfish/lib/hibernate-entitymanager.jar, file:/C:/Work/glassfish/lib/hibernate3.jar, file:/C:/Work/glassfish/lib/j2ee-svc.jar, file:/C:/Work/glassfish/lib/j2ee.jar, file:/C:/Work/glassfish/lib/javaee.jar, file:/C:/Work/glassfish/lib/javassist-3.4.GA.jar, file:/C:/Work/glassfish/lib/jesmf-plugin.jar, file:/C:/Work/glassfish/lib/jhall.jar, file:/C:/Work/glassfish/lib/jmac-api.jar, file:/C:/Work/glassfish/lib/jmxremote_optional.jar, file:/C:/Work/glassfish/lib/jsf-impl.jar, file:/C:/Work/glassfish/lib/jxta.jar, file:/C:/Work/glassfish/lib/lib.zip, file:/C:/Work/glassfish/lib/log4j-1.2.16.jar, file:/C:/Work/glassfish/lib/mail.jar, file:/C:/Work/glassfish/lib/ojdbc5.jar, file:/C:/Work/glassfish/lib/Pack200Task.jar, file:/C:/Work/glassfish/lib/shoal-gms.jar, file:/C:/Work/glassfish/lib/slf4j-api-1.5.3.jar, file:/C:/Work/glassfish/lib/slf4j-log4j12-1.5.3.jar, file:/C:/Work/glassfish/lib/sun-appserv-ant.jar, file:/C:/Work/glassfish/lib/toplink-essentials-agent.jar, file:/C:/Work/glassfish/lib/toplink-essentials.jar, file:/C:/Work/glassfish/lib/webservices-rt.jar, file:/C:/Work/glassfish/lib/webservices-tools.jar, file:/C:/Work/glassfish/
WebappClassLoader
delegate: true
repositories:
/WEB-INF/classes/
----------> Parent Classloader:
EJBClassLoader :
urlSet = []
doneCalled = false
Parent -> java.net.URLClassLoader@a7c45e
WebappClassLoader
delegate: true
repositories:
/WEB-INF/classes/
----------> Parent Classloader:
EJBClassLoader :
urlSet = []
doneCalled = false
Parent -> java.net.URLClassLoader@a7c45e[/quote]

Será possivel usar o restfulie client em simultaneo com o vratpor?
Obrigado.

Já verifiquei que tenho outro javassist no classpath do servidor.
Nomeadamente javassist-3.4.GA.

Dá para dar a volta a esta questão sem apagar a lib do servidor? Sem ela nao arranca :frowning:

o que acontece se vc tirar a lib da sua aplicação?

Obrigado desde ja pela resposta :slight_smile:

Sinceramente nao posso confirmar mas pelo que me recordo tb nao funcionava.

O que acabei por fazer foi atualizar a lib no servidor ( faz parte das libs necessarias para o hibernate no servidor ) e tudo ficou a funcionar.

Tive tambem um outro problema com o xtream visto que inclui a dependecia do Refletions, que possui uma versão mas antiga do xtream. Resolvi colocando o xtream nas exclusões da dependencia ( Refletions ).

Mais uma vez obrigado.