Erro ao reconectar a um SessionBean Stateful

2 respostas
martui

:scrambleup: Estou criando um Session Bean Stateful.
Ao tentar reconectar ao bean usando um id obtido do service locator obtenho a exceção:

"Saída":
java.io.InvalidClassException: org.jboss.util.id.UID; local class incompatible: stream classdesc serialVersionUID = 4588799618105892224, local class serialVersionUID = -8093336932569424512
/*** Método utilizado para reconectar ao EJB **/
public EJBObject getService(String id) 
  		throws ServiceLocatorException {
		if (id == null) {
	  		throw new ServiceLocatorException("NULL");
		}
		try {
	  		System.out.println(id);
	  		byte[] bytes = id.getBytes();
	  		InputStream io = new ByteArrayInputStream(bytes);
	  		ObjectInputStream os = new ObjectInputStream(io);	  
			Object o = os.readObject();
	  		javax.ejb.Handle handle = (javax.ejb.Handle) o;
	  		return handle.getEJBObject();
		} catch(Exception ex) {
			ex.printStackTrace();
	  		throw new ServiceLocatorException("Location Fail");
		}
}
    	
/*** Método utilizado para obter o Id do EJB **/		
public String getId(EJBObject session) 
	  throws ServiceLocatorException {
	try {
		javax.ejb.Handle handle = session.getHandle();
		 ByteArrayOutputStream fo = new ByteArrayOutputStream();
		 ObjectOutputStream so = new ObjectOutputStream(fo);		  
		 so.writeObject(handle);
		 so.flush();		  
		 so.close();
		 return new String(fo.toByteArray());
		  
	} catch(RemoteException ex) {
		  throw new ServiceLocatorException("Falha na Comunicação");
	} catch(IOException ex) {
		  throw new ServiceLocatorException("Falha na Leitura");
	}
}

Uso:

J2sdk1.4.2
JBoss 4

2 Respostas

T

Quando vi o seu programa já entendi o problema.

byte[] bytes = id.getBytes();

e

new String(fo.toByteArray());

Aqui há um problema muito comum - achar que podemos guardar arrays de bytes em Strings. Isso dá muitos problemas porque Java tem a mania de trocar um byte pelo caracter ‘?’ se ele não encontrar no charset corrente. Então o que ocorre é que você nunca mais consegue recuperar o byte array original.

Isso dá montes de problemas com criptografia, mas deu problema também com você que só está tentando serializar um objeto.

Só para você ver o estrago, tente fazer o seguinte:

Crie um array de bytes com os bytes de -128 a +127. Converta para uma String com new String(). Agora pegue os bytes da String com .toByteArray(), e compare com o valor original. Você vai ver que cerca de 4 a 6 bytes do array original, dependendo da versão do JDK e do seu “regional settings”, foram trocados por ‘?’. Não importa qual o “charset” que você usar, sempre sempre sempre vai ter algum dos bytes que vai ser trocado por ‘?’.

Dica: Se for guardar um array de bytes em uma String, converta para hexadecimal ou Base-64, ou no seu caso em particular, talvez dê para deixar como byte[] mesmo.

martui

:scrambleup: Valeu pela dica, assim funcionou:

public EJBObject getService(String id) 
  		throws ServiceLocatorException {
		if (id == null) {
	  		throw new ServiceLocatorException("NULL");
		}
		try {
	  		byte[] bytes = Base64.decode(id.getBytes());
			ByteArrayInputStream io = new ByteArrayInputStream(bytes);
	  		ObjectInputStream os = new ObjectInputStream(io); 		
			Handle handle = (Handle) os.readObject();			
	  		return handle.getEJBObject();
		} catch(Exception ex) {
			ex.printStackTrace();
	  		throw new ServiceLocatorException("Location Fail");
		}
  }
    	
		
	public String getId(EJBObject session) 
	  throws ServiceLocatorException {
		try {
		  Handle handle = session.getHandle();	  
		  ByteArrayOutputStream fo = new ByteArrayOutputStream();		  
		  ObjectOutputStream so = new ObjectOutputStream(fo);		  
		  so.writeObject(handle);
		  so.flush();		  
		  so.close();
		  return new String(Base64.encode(fo.toByteArray()));
		  
		} catch(RemoteException ex) {
		  throw new ServiceLocatorException("Falha na Comunicação");
		} catch(IOException ex) {
		  throw new ServiceLocatorException("Falha na Leitura");
		}
	  }
Criado 14 de setembro de 2004
Ultima resposta 15 de set. de 2004
Respostas 2
Participantes 2