RMI e JNI - Crash na máquina Virtual

Olá a tados,

Estou fazendo um servidor RMI com algumas funcionalidades deste implementadas em uma lib.so (shared object) em C/C++/linux.
Acesso as funcionalidades da SO através de uma classe e metodos static usando JNI (java native interface). No momento em que conecto os clientes (fiz uma simulação de 17 clientes conectando simultaneamente o servidor através de threads) a máquina virtual do servidor dá crash e cai o servidor. Alguém tem alguma idéia de o que pode ser , ou de resolver este problema?
Imagino que a threads do Servidor RMI que atendem os clientes estão tendo problema na hora de concorrer com o recurso implementado na SO. Algem sabe se é alguma configuração?

Desde já agradeço a todos,

Fala cara!!!

Quando múltiplas threads tentam acessar o mesmo método ao mesmo tempo, é bom que você coloque nele o modificador synchronized, desta forma as threads irão ter direito a usar o método uma de cada vez.

No Java 5 já existem melhores maneiras de lidar com a concorrência, porém aí tem que dar uma estuada ou lida em tutoriais pra saber legal.

Porém, quando vc diz que o servidor da crash, quer dizer o que? tudo congela, ele lança alguma exceção??

Abs!

Beleza,

Pelo que sei a cada conexão que o client RMI faz no servidor RMI a máquina virtual cria automaticamente uma thead para atendê-lo. Eu não tenho tenho dominio sobre essas theads…
Quando eu falo em crash da JVM, falo de que ela não consegui se resolver com o problema e pau. Manda enviar log de erros para a SUN. Pode-se fazer uma analogia com a tela azul do windows.
O que vc sugere? implementar threads com synchronized para o resurso?

Abaixo segue a implementação do Servidor RMI:
Ps.: uso o conceito de Fabrica de objetos (tutorial em http://www.dca.fee.unicamp.br/courses/PooJava/objdist/javarmi.html )

Na classe HBServerFabricaObjImp eu disponibilizo os objetos da Fabrica
e na classe HBServerImp no método rv = FenrirBICWrapper.identify(objtemplate,threshold,objresult,objid); é o recurso compartilhado.

A classe FenrirBICWrapper carrega a SO:

public class FenrirBICWrapper {

static {
   	try {
      System.load("/work/FBIC.so");
    }
    catch(UnsatisfiedLinkError ule) {
      System.out.println(ule);
    }
}
public static native int initialize(String fileName, int opt);

public static native int finalizeComponent();

public static native int identify(FnrTTemplate objTemplate, int threshold, FnrTResult result, FnrInt id);

public static native int identifySafe(FnrTTemplate objTemplate, int threshold, FnrTResult result, FnrInt id);

}


public class HBServerFabricaObjImp extends HBServerImp implements HBServerFabricaObjInter {
//private FenrirBICWrapper Fbic_so;
private ConectaBancoDados connBd;
private Connection conexao;

// static Logger logger = Logger.getLogger(HBServerFabricaObjImp.class);
/**
* @throws RemoteException
*/
private Hashtable container = new Hashtable();
private Hashtable cartaoCliente = new Hashtable();

public HBServerFabricaObjImp(Properties	confServidor) throws RemoteException {
   super(null);

 //  Fbic_so = new FenrirBICWrapper() ;
 // System.out.println(confServidor.getProperty("xmlFbic"));	   
   
   int rv = FenrirBICWrapper.initialize(confServidor.getProperty("pathXmlFbic") , 1);
	//		if (rv!=0) logger.info("Erro inicializaçao do componente: " + rv);
//	else logger.info("Componente inicializado com sucesso");
   try {

    if (rv!=0) 
    	throw new  Exception("Erro inicializaçao do componente FenrirBICWrapper: " + rv);
    else 	System.err.println("Componente FenrirBICWrapper inicializado com sucesso");
    }
    	catch(Exception error) {
	    error.printStackTrace();
	    System.exit( 1 );
    }
    	
 /*
	
}

public HBServerInter getObjetoFabricado(String nomeObjeto) throws RemoteException {

	HBServerInter objHBServer = null;

if (container.containsKey(nomeObjeto))
	objHBServer = (HBServerInter) container.get(nomeObjeto);
else {
	objHBServer = new HBServerImp(cartaoCliente);
	container.put(nomeObjeto,objHBServer);
 //   logger.info("Novo objeto Fabricado: " + nomeObjeto);
  	System.err.println("Novo objeto Fabricado: " + nomeObjeto);
}

return objHBServer;

}

public void descarteObjeto(String nomeObjeto) throws RemoteException{
try {
container.remove(nomeObjeto);
System.err.println("Objeto descartado: " + nomeObjeto);
//logger.info("Objeto descartado: " + nomeObjeto);
}
catch (Exception e) {
System.err.println(“Erro na remocao do Objeto”+nomeObjeto+ “do Container”);
//logger.error(e+“Erro na remocao do Objeto”+nomeObjeto+ “do Container”);
}
}

public void finalizeFabrica (String senha)throws RemoteException {

try {
	if  (! senha.equalsIgnoreCase("fechefabrica")) 
  		throw new Exception("Senha errada!");  
 else
   	 	System.exit( 0 ); 
	
}		
 catch (Exception e) {
	// TODO: handle exception
 	e.printStackTrace();
}

}

public static void main(String[] args) {
    try {
  	  //BasicConfigurator.configure();
      //logger.setLevel(Level.DEBUG);  
    	Properties	confServidor = new Properties();	
	      //carrega o arquivo de propriedades do Servidor 
	  	try {
		  	 confServidor.load(new FileInputStream("/work/confservidor.properties"));	
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} 	

      String servicoServidor = "HBFabricaObjetos";//confServidor.getProperty("nomeServico"); 
      System.setSecurityManager(new RMISecurityManager());
      
      
      HBServerFabricaObjImp fabricaObjetos = new HBServerFabricaObjImp(confServidor);
    //  HBServerFabricaObjInter stub = (HBServerFabricaObjInter) UnicastRemoteObject.exportObject(fabricaObjetos);

      Registry registro = LocateRegistry.getRegistry();
      registro.rebind(servicoServidor, fabricaObjetos);
      System.err.println("Iniciando servidor... Fabrica de objetos pronta!.");
      //logger.info("Iniciando servidor. HBServerFactory pronto!.");
    } 
    catch (Exception e) {
    //  logger.error(e);
    	e.printStackTrace();
    	System.exit(1);
    }
  }
 
protected void finalize(){
	FenrirBICWrapper.finalizeComponent();
}

}


public class HBServerImp extends UnicastRemoteObject implements
HBServerInter {

private Hashtable cartaoCliente;
private int rv;
private FnrTResult objResult= new FnrTResult();
private FnrInt objId = new FnrInt(0);
private String objTemp;
private Cliente objCliente;

public HBServerImp(Hashtable cartaoCliente  ) throws RemoteException {
	this.cartaoCliente = cartaoCliente;
}

	
	public Cliente identifiqueCliente(FnrTTemplate objTemplate, int threshold) throws RemoteException{
		objCliente = new Cliente();	
		
		long startTime = 0;     	 	
     	startTime = System.currentTimeMillis();
   
   	RV = FENRIRBICWRAPPER.IDENTIFY(OBJTEMPLATE,THRESHOLD,OBJRESULT,OBJID);
 
         long endTime = System.currentTimeMillis();
       System.err.println("Execution time indentify Fenrir: " + (endTime - startTime) + " ms.");

     

        if (rv==0) {

	      objCliente.setIdTempale(objId.getValue());
	   	  objTemp = (String) (cartaoCliente.get(new Integer(objId.getValue())));
  
	   	  objCliente.setNumeroCartao(objTemp.substring(0,12));
	  	  objCliente.setNome(objTemp.substring(13,objTemp.length()));

		} 
	   else objCliente.setIdTempale(rv);
	   return objCliente;
	}
	
	public int atualizeTemplate(Cliente objCliente) throws RemoteException{
		return 0;
	}

	public int deleteTemplate(Cliente objCliente) throws RemoteException{
		return 0;
	}

	public int verifiqueTemplate(Cliente objCliente, FnrTResult result) throws RemoteException{
		return 0;
	}

	public void RestaureBaseFenrir() throws RemoteException{
	}
	
	public int cadastreTemplate(Cliente objCliente) throws RemoteException{
	}

}

Obrigado

Kra… muito código!!

Uma dica, quando for postar código, encapsule-o em marcadores Code. Tem uma série de marcadores que podem ser usados bem em cima de onde se digita o texto do post.

Vamos lá, tem dois métodos que eu achei críticos kra, não deu pra entender mta coisa do código, pq é bem específico, mas vamos lá:

public Cliente identifiqueCliente(FnrTTemplate objTemplate, int threshold) 

Esse método pelo que parece é que faz uso do JNI… Vc poderia setar ele como synchronized:

public synchronized Cliente identifiqueCliente(FnrTTemplate objTemplate, int threshold) 

O q vc disse é bem acertado, cada requisição RMI ao servidor gera uma nova thread que tenta processar o método. Vc também poderia desabilitar a chamada JNI e colocar qqer enganação no lugar, pra ver se ainda assim o servidor trava, quem sabe não é uma limitação do RMI mesmo?

Qqer coisa, posta ae…

Abraços![/code]