[RESOLVIDO]Erro referencia circular + Json + Vraptor

Estou com um problema na hora de serializar um objeto de uma classe, que tem um atributo uma lista. que por sua fez, tem um atributo que faz referencia a ela mesma… esta dando erro de circular reference:

Preciso serializar esta classe, ela tem apenas 1 objeto criado… ou seja, não é uma lista:

public class Desktop {
	private Users user;
	private Configuration config;
	private List<ApplicationsWrapper> applications;
	private boolean success;
        ....

public class ApplicationsWrapper { private String text; private String name; private String application_k; private String application_parent_k; private String klass; private String description; private ApplicationConfig configurations; private String active; private String iconCls; private Boolean leaf; private List<ApplicationsWrapper> menu = new ArrayList<ApplicationsWrapper>();

o Controller:

	public void config() {
		Desktop desktop = this.desktopFactory.create();
		result.use(json()).withoutRoot().from(desktop).include("user")
				.include("config")
				.include("applications")
				.include("applications.menu")
				.include("applications.configurations")
				.serialize();
	}[/code]

Quando serialize dá o seguinte erro:
[code]GRAVE: Servlet.service() for servlet [default] in context with path [/Cygnus] threw exception
br.com.caelum.vraptor.InterceptionException: exception raised, check root cause for details: com.thoughtworks.xstream.core.TreeMarshaller$CircularReferenceException: 
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:96)
	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.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:61)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.cygnus.vraptor.interceptor.HibernateTransactionInterceptor.intercept(HibernateTransactionInterceptor.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.cygnus.vraptor.interceptor.CheckLoginInterceptor.intercept(CheckLoginInterceptor.java:37)
	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:71)
	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.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.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:23)
	at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
	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:462)
	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:395)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
	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(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: com.thoughtworks.xstream.core.TreeMarshaller$CircularReferenceException: 
	at com.thoughtworks.xstream.core.TreeMarshaller.convert(TreeMarshaller.java:83)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:63)
	at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:64)
	at com.thoughtworks.xstream.converters.collections.CollectionConverter.marshal(CollectionConverter.java:55)
	at com.thoughtworks.xstream.core.TreeMarshaller.convert(TreeMarshaller.java:86)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshallField(AbstractReflectionConverter.java:157)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.writeField(AbstractReflectionConverter.java:148)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.visit(AbstractReflectionConverter.java:118)
	at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:129)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doMarshal(AbstractReflectionConverter.java:100)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshal(AbstractReflectionConverter.java:58)
	at com.thoughtworks.xstream.core.TreeMarshaller.convert(TreeMarshaller.java:86)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:63)
	at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:64)
	at com.thoughtworks.xstream.converters.collections.CollectionConverter.marshal(CollectionConverter.java:55)
	at com.thoughtworks.xstream.core.TreeMarshaller.convert(TreeMarshaller.java:86)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshallField(AbstractReflectionConverter.java:157)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.writeField(AbstractReflectionConverter.java:148)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.visit(AbstractReflectionConverter.java:118)
	at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:129)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doMarshal(AbstractReflectionConverter.java:100)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshal(AbstractReflectionConverter.java:58)
	at com.thoughtworks.xstream.core.TreeMarshaller.convert(TreeMarshaller.java:86)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:63)
	at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:98)
	at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:38)
	at com.thoughtworks.xstream.XStream.marshal(XStream.java:837)
	at com.thoughtworks.xstream.XStream.marshal(XStream.java:826)
	at com.thoughtworks.xstream.XStream.toXML(XStream.java:801)
	at br.com.caelum.vraptor.serialization.xstream.XStreamSerializer.serialize(XStreamSerializer.java:237)
	at br.com.cygnus.desktop.controller.IndexController.config(IndexController.java:37)
	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)
	... 46 more

Dá quando eu coloco o .include("applications.menu")

Já tentei evitar esta referencia circular. mas não consigo. alguem poderia me ajudar. como fazer…

OBrigado pela ajuda…

na lista do menu tem a mesma instância da classe?

Lucas, realmente esta com erro minha logica… esta inserindo na lista a mesma instancia e não a correta. que estava comparando.

Putz. fiquei uma cara e não achei. nessas horas a programação pareada faz falta. :slight_smile:

Erro muito simples. e tem hora que pensamos no mais complexo. hehe

Valeu.

Obrigado

Rodrigo

Código Errado:

public void findParentAndAdd(List<ApplicationsWrapper> parents, ApplicationsWrapper application) { for (ApplicationsWrapper applicationsWrapper : parents) { if (applicationsWrapper.getApplication_k().equals(application.getApplication_parent_k())) { applicationsWrapper.addMenuItem(applicationsWrapper);//esta linha esta errada return; } else { if (!applicationsWrapper.getMenu().isEmpty()) { findParentAndAdd(applicationsWrapper.getMenu(), applicationsWrapper); } } } }
Código Correto:

public void findParentAndAdd(List<ApplicationsWrapper> parents, ApplicationsWrapper application) { for (ApplicationsWrapper applicationsWrapper : parents) { if (applicationsWrapper.getApplication_k().equals(application.getApplication_parent_k())) { applicationsWrapper.addMenuItem(application);//esta linha esta correta return; } else { if (!applicationsWrapper.getMenu().isEmpty()) { findParentAndAdd(applicationsWrapper.getMenu(), applicationsWrapper); } } } }