XStream : método alias() funciona, mas anotação @XStreamAlias não

Estou adaptando uns exercícios da apostila FJ22 da Caelum para fazer uns testes com XML.

Tenho um model Conta (conta de banco) e uma classe ProcessaXML, que tem um método para receber um XML e retornar um List de Conta e outro método que transforma um List de Conta em XML. Estou fazendo testes com JUnit, então também tenho uma classe ProcessaXMLTest.

Tudo estava funcionando bem até que eu substituí o método alias() da classe XStream pela anotação @XStreamAlias no model comecei a ter vários erros do tipo Conversion.Exception.

Vocês podem me dizer se tem algo além desta anotação que eu preciso fazer para voltar a funcionar ?

Valeu!

Conta.java

import com.thoughtworks.xstream.annotations.XStreamAlias;

@XStreamAlias("conta")
public class Conta {
		
	private int numero;
	private int agencia;
	private String nome_titular;
	private String cpf_titular;
	private double saldo;
	private double limite;

public Conta() {
		this.saldo = 0.0;
		this.limite = 500.0;
	}

	public int getNumero() {
		return numero;
	}
	public void setNumero(int numero) {
		this.numero = numero;
	}
	public int getAgencia() {
		return agencia;
	}
	public void setAgencia(int agencia) {
		this.agencia = agencia;
	}
	public String getNome_Titular() {
		return nome_titular;
	}
	public void setNome_Titular(String nome_titular) {
		this.nome_titular = nome_titular;
	}
	public String getCpf_Titular() {
		return cpf_titular;
	}
	public void setCpf_Titular(String cpf_titular) {
		this.cpf_titular = cpf_titular;
	}
	public double getSaldo() {
		return saldo;
	}
	public void setSaldo(double saldo) {
		this.saldo = saldo;
	}
	public double getLimite() {
		return limite;
	}
	public void setLimite(double limite) {
		this.limite = limite;
	}
	
	public String deposita(double deposito) {
		String mensagem = null;
		if (deposito <= 0) {
			mensagem = "Não é possível depositar valores negativos ou iguais a zero.";			
			}		
		else {
			this.saldo = this.saldo + deposito;
			mensagem = "Depósito de " + deposito + " efetuado com sucesso! Seu saldo agora é de : " + this.saldo + " ."; 
		}
		return mensagem;
	}
	
	public String saca(double saque) {
		String mensagem = null;
		if (saque <= 0) {
			mensagem="Não é possível sacar valores negativos ou iguais a zero.";
		}
		
		else if (saque > (this.saldo + this.limite)) {
			mensagem="Este valor excede o limite da conta. Transação não efetuada!";
			}
		else if (saque <= this.saldo) {
			this.saldo = this.saldo - saque;
			mensagem = "Saque de " + saque + " efetuado com sucesso! Seu saldo agora é de : " + this.saldo + " .";			
			}
		else if(saque < (this.saldo + this.limite)) {
			double saldo_total = this.saldo + this.limite;
			double saldo_restante = 0.0;
			saldo_restante = saque - saldo_total; 
			this.saldo = 0;
			this.limite =  saldo_restante;
			 mensagem = "Saque de " + saque + " efetuado com sucesso! Seu saldo agora é de : " + this.saldo + " e seu limite de : " + this.limite + " .";
			}
		return mensagem;
	}

}

ProcessaXML.java

import java.io.InputStream;
import java.util.List;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class ProcessaXML {
	    	
	public List<Conta> carrega(InputStream inputStream) {
		XStream stream = new XStream(new DomDriver());
		stream.autodetectAnnotations(true);
		return (List<Conta>) stream.fromXML(inputStream);
	}
	
	public String devolve(List<Conta> conta) {
		XStream stream = new XStream(new DomDriver());
		stream.autodetectAnnotations(true);
		return stream.toXML(conta);
		
	}

}

ProcessaXMLTest.java

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.List;
import org.junit.Test;

public class ProcessaXMLTest {

	@Test
	public void recebeXML() {
		String xmlDeTeste = "<list>" +
							"<conta>" + 
							"<numero>0001</numero>" +
							"<agencia>1222</agencia>" +
							"<nome_titular>Fulano da Silva</nome_titular>" +
							"<cpf_titular>100200300-40</cpf_titular>" +
							"<saldo>300.0</saldo>" +
							"<limite>500.0</limite>" +
							"</conta>" +
							"<conta>" + 
							"<numero>0002</numero>" +
							"<agencia>1222</agencia>" +
							"<nome_titular>Beltrano de Oliveira</nome_titular>" +
							"<cpf_titular>400500600-70</cpf_titular>" +
							"<saldo>500.0</saldo>" +
							"<limite>1000.0</limite>" +
							"</conta>" +
							"</list>";
		    	
		ProcessaXML leitor = new ProcessaXML();
		InputStream xml = new ByteArrayInputStream(xmlDeTeste.getBytes());
		List<Conta> contas = leitor.carrega(xml);
			
		Assert.assertEquals(2, contas.size(), 0.01);
			
	}

O erro no console é este

com.thoughtworks.xstream.converters.ConversionException: 
---- Debugging information ----
cause-exception     : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message       : conta
class               : java.util.ArrayList
required-type       : java.util.ArrayList
converter-type      : com.thoughtworks.xstream.converters.collections.CollectionConverter
path                : /list/conta
version             : 1.4.12
-------------------------------
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:77)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
	at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
	at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1487)
	at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1467)
	at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1347)
	at fj22_JUnit.ProcessaXML.carrega(LeitorXML.java:21)
	at fj22_JUnit.ProcessaXMLTest.recebeXML(LeitorXMLTest.java:35)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: com.thoughtworks.xstream.mapper.CannotResolveClassException: conta
	at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:81)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:79)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:74)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:71)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47)
	at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29)
	at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readBareItem(AbstractCollectionConverter.java:131)
	at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readItem(AbstractCollectionConverter.java:117)
	at com.thoughtworks.xstream.converters.collections.CollectionConverter.addCurrentElementToCollection(CollectionConverter.java:98)
	at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:91)
	at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:85)
	at com.thoughtworks.xstream.converters.collections.CollectionConverter.unmarshal(CollectionConverter.java:80)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
	... 36 more
1 curtida

Posso estar enganado, mas como vc quer deserializar o xml para objeto, acho que não precisa desse @XStreamAlias("conta").

Pode ser que vc tenha razão, o meu método carrega(), da classe ProcessaXML, talvez não dependa da anotação no model Conta. Mas o fato é q ele não funciona mesmo q eu tire o método stream.autodetectAnnotations(true);.

E o outro método da classe Conta, o devolve(), ele está usando a anotação e funciona normalmente.

Então eu queria manter a anotação, já que é uma técnica recomendada.

Mas devo estar fazendo algo de errado no método que “carrega()” q ainda não descobri o que é.

Com a anotação, o console começa a indicar erro especificamente na linha
return (List) stream.fromXML(inputStream); do método carrega.