Newsgroup: it.comp.java
Titolo: problema filosofi a cena

Salve a tutti,
sono alle prime armi di Java, e ho trovato su internet un esempio di
soluzione al problema dei cinque filosofi, con Java RMI.
Il problema è che al momento dell'esecuzione del Server mi viene
generato l'errore
Exception in HelloServer: java.rmi.StubNotFoundException: Stub class
not found: Prove_Java.FilosofiRMI.server.TavolaImpl_Stub; nested
exception is:
        java.lang.ClassNotFoundException:
Prove_Java.FilosofiRMI.server.TavolaImpl_Stub
E il Server non va. Come posso fare? Posto il codice per intero.
-Classe Server
package Prove_Java.FilosofiRMI.server;
import java.rmi.Naming;
public class Server {
	/**
	 * Istanzia un oggetto TavolaImpl e lo iscrive nel registro locale
	 *
	 * @param args
	 *            Se presente, il numero dei posti della tavola. Valore di
	 *            dafult: 5.
	 */
	public static void main(String[] args) {
		//Controlla se c'e' come input il numero dei posti della tavola
		int posti = 5;
		if (args.length == 1)
			posti = Integer.parseInt(args[0]);
		try {
			System.out.println("Ristorante aperto");
			//Iscrive nel registro l'istanza della classe TavolaImpl
			Naming.rebind("Tavola", new TavolaImpl(posti));
			System.out.println("Tavola apparecchiata per " + posti + "
persone.");
			System.out.println("In attesa di clienti...");
		} catch (Exception e) {
			System.out.println("Exception in HelloServer: " + e);
		}
	}
}
-Classe TavolaImpl
package Prove_Java.FilosofiRMI.server;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class TavolaImpl extends UnicastRemoteObject implements Tavola {
	/**
	 * Stato iniziale del filosofo seduto: non ha bisogno delle bacchette.
	 */
	public static final int PENSANDO = 0;
	/**
	 * Stato del filosofo: sta mangiando e ha le bacchette.
	 */
	public static final int MANGIANDO = 1;
	/**
	 * Stato del filosofo in attesa: vuole mangiare ma le bacchette sono
	 * occupate.
	 */
	public static final int AFFAMATO = 2;
	/**
	 * Stato iniziale del filosofo: non e' ancora seduto o e' gia' andato
via.
	 */
	public static final int ASSENTE = 3;
	/**
	 * Array degli stati dei filosofi
	 */
	private int[] stato;
	/**
	 * Posti totali della tavola
	 */
	private int size;
	/**
	 * Costruisce una nuova tavola:
	 *
	 * @param size
	 *            Numero dei posti totali della tavola
	 * @throws RemoteException
	 */
	public TavolaImpl(int size) throws RemoteException {
		this.size = size;
		stato = new int[size];
		//Inizializza lo stato dei filosofi
		for (int i = 0; i < size; i++)
			stato[i] = ASSENTE;
	}
	/**
	 * Esclusivo. Controlla se ci sono posti liberi a cui sedersi e ne
assegna
	 * uno al filosofo cambiando lo stato da ASSENTE a PENSANDO
	 *
	 * @return l'indice del posto disponibile se c'e', -1 altrimenti
	 * @throws RemoteException
	 */
	public synchronized int occupaPosto() throws RemoteException {
		int i = 0;
		//Scorre la lista degli stati fnché non trova un posto libero
		while ((i < stato.length) && (stato[i] != ASSENTE))
			i++;
		//Non ha trovato posti liberi, il filosof rimane in piedi e se ne va
		if (i >= stato.length) {
			i = -1;
		} else {
			//Ha trovato un posto libero, il filosofo si siede e comincia la
			// cena
			stato[i] = PENSANDO;
		}
		return i;
	}
	/**
	 * Esclusivo. Libera il posto precedentemente occupato dal filosofo
	 * cambiando lo stato in ASSENTE
	 *
	 * @param index
	 *            Indice della sedia occupata dal filosofo
	 * @throws RemoteException
	 */
	public synchronized void liberaPosto(int index) throws RemoteException
{
		stato[index] = ASSENTE;
	}
	/**
	 * @return Numero di posti totali della tavola
	 * @throws RemoteException
	 */
	public int getPosti() throws RemoteException {
		return size;
	}
	/**
	 * Traduce lo stato del filosofo da numero a stringa
	 *
	 * @param index
	 *            Identificativo del filosofo
	 * @return Frase che riassume lo stato del filosofo
	 * @throws RemoteException
	 */
	public String getStato(int index) throws RemoteException {
		String statoFilosofo;
		int i = stato[index];
		switch (i) {
			case PENSANDO :
				statoFilosofo = "pensando";
				break;
			case MANGIANDO :
				statoFilosofo = "mangiando";
				break;
			case AFFAMATO :
				statoFilosofo = "aspettando le bacchette per mangiare";
				break;
			case ASSENTE :
				statoFilosofo = "in piedi o se ne è andato";
				break;
			default :
				statoFilosofo = "in uno stato indefinito";
				break;
		}
		return statoFilosofo;
	}
	/**
	 * Esclusivo. Prende le bacchette se sono libere, altrimenti si mette
in
	 * attesa. Cambia lo stato ad AFFAMATO ed infine a MANGIANDO una volta
	 * prese le bacchette.
	 *
	 * @param index
	 *            indice del filosofo
	 * @throws RemoteException
	 */
	public synchronized void getBacchette(int index) throws
RemoteException {
		stato[index] = AFFAMATO;
		//Controlla se entrambe le bacchette sono libere
		while ((stato[(index + stato.length - 1) % stato.length] ==
MANGIANDO)
			|| (stato[(index + 1) % stato.length] == MANGIANDO)) {
			try {
				wait();
			} catch (InterruptedException e) {
			}
		}
		stato[index] = MANGIANDO;
	}
	/**
	 * Esclusivo. Rilascia le bacchette modificando lo stato del filosofo.
	 * Notifica a tutti i filosofi in attesa che si sono liberate delle
	 * bacchette.
	 *
	 * @param index
	 *            indice del filosofo
	 * @throws RemoteException
	 */
	public synchronized void releaseBacchette(int index)
		throws RemoteException {
		stato[index] = PENSANDO;
		notifyAll();
	}
}
-Classe Tavola (per il server)
package Prove_Java.FilosofiRMI.server;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Tavola extends Remote {
	/**
	 * Controlla se ci sono posti liberi a cui sedersi e ne assegna uno al
	 * richiedente
	 *
	 * @return l'indice del posto disponibile se c'e', -1 altrimenti
	 * @throws RemoteException
	 */
	public int occupaPosto() throws RemoteException;
	/**
	 * Libera il posto precedentemente
	 *
	 * @param index
	 *            Indice della sedia occupata
	 * @throws RemoteException
	 */
	public void liberaPosto(int index) throws RemoteException;
	/**
	 * @return Numero di posti totali della tavola
	 * @throws RemoteException
	 */
	public int getPosti() throws RemoteException;
	/**
	 * @param index
	 *            Identificativo del filosofo
	 * @return Frase che riassume lo stato del filosofo
	 * @throws RemoteException
	 */
	public String getStato(int index) throws RemoteException;
	/**
	 * Prende le bacchette se sono libere, altrimenti si mette in attesa.
	 *
	 * @param index
	 *            indice del filosofo
	 * @throws RemoteException
	 */
	public void getBacchette(int index) throws RemoteException;
	/**
	 * Rilascia le bacchette.
	 *
	 * @param index
	 *            indice del filosofo
	 * @throws RemoteException
	 */
	public void releaseBacchette(int index) throws RemoteException;
}
-------------------------------------Passiamo al
Client-------------------------------------------------------------
-Classe Client
package Prove_Java.FilosofiRMI.client;
import java.rmi.Naming;
public class Client {
	/**
	 * Ritrova l'oggetto remoto sulla rete, lo passa ai filosofi e dopo un
	 * tempo prestabilito fa finire la cena.
	 *
	 * @param args
	 *            Se presenti: l'host in cui risiede l'oggetto remoto
(default:
	 *            localhost) e la durata della cena in secondi (default:
10)
	 */
	public static void main(String[] args) {
		//Gestione della sicurezza
		System.setSecurityManager(new SecurityManager());
		//Prende come input l'indirizzo dell'host
		String host = "localhost";
		if (args.length > 0)
			host = args[0];
		//Prende come input la durata della cena
		int time = 10000;
		if (args.length > 1)
			time = Integer.parseInt(args[1]) * 1000;
		int posti;
		Tavola tavola;
		try {
			//Referenzia l'oggetto remoto
			tavola = (Tavola) Naming.lookup("//" + host + "/Tavola");
			posti = tavola.getPosti();
			System.out.println("Posti disponibili: " + posti);
			//Crea tanti filosofi quanti sono i posti della tavola
			Filosofo[] filosofi = new Filosofo[posti];
			for (int i = 0; i < posti; i++)
				filosofi[i] = new Filosofo(tavola);
			System.out.println("Filosofi a cena: " + filosofi.length);
			//Fa partire i thread dei filosofi
			for (int i = 0; i < posti; i++)
				filosofi[i].start();
			//Aspetta che passi il tempo "time"
			try {
				Thread.sleep(time);
			} catch (InterruptedException e) {
				System.err.print("Interrupted Exception in Client.main(): ");
				e.printStackTrace();
			}
			//Comunica ai filosofi che la cena è terminata
			System.out.println("Arriva il cameriere con il conto da pagare");
			for (int i = 0; i < filosofi.length; i++)
				filosofi[i].terminate();
			//Manda un interrupt per far smettere ai filosofi di mangiare o
			// pensare
			//NB: i filosofi in attesa delle bacchette, mangeranno prima di
			// andarsene
			for (int i = 0; i < filosofi.length; i++)
				filosofi[i].interrupt();
		} catch (Exception e) {
			System.out.println("Exception in Client:" + e);
		}
	}
}
-Classe Tavola(per il client)
package Prove_Java.FilosofiRMI.client;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Tavola extends Remote {
	/**
	 * Controlla se ci sono posti liberi a cui sedersi e ne assegna
	 * uno al richiedente
	 *
	 * @return l'indice del posto disponibile se c'e', -1 altrimenti
	 * @throws RemoteException
	 */
	public int occupaPosto() throws RemoteException;
	/**
	 * Libera il posto precedentemente
	 *
	 * @param index
	 *            Indice della sedia occupata
	 * @throws RemoteException
	 */
	public void liberaPosto(int index) throws RemoteException;
	/**
	 * @return Numero di posti totali della tavola
	 * @throws RemoteException
	 */
	public int getPosti() throws RemoteException;
	/**
	 * @param index
	 *            Identificativo del filosofo
	 * @return Frase che riassume lo stato del filosofo
	 * @throws RemoteException
	 */
	public String getStato(int index) throws RemoteException;
	/**
	 * Prende le bacchette se sono libere, altrimenti si mette in attesa.
	 *
	 * @param index
	 *            indice del filosofo
	 * @throws RemoteException
	 */
	public void getBacchette(int index) throws RemoteException;
	/**
	 * Rilascia le bacchette.
	 *
	 * @param index
	 *            indice del filosofo
	 * @throws RemoteException
	 */
	public void releaseBacchette(int index) throws RemoteException;
}
-Classe Filosofo
package Prove_Java.FilosofiRMI.client;
import java.rmi.RemoteException;
public class Filosofo extends Thread {
	/**
	 * Rappresenta l'indice del posto della tavola a cui siede il
filosofo.
	 * -1 rappresenta un filosofo in piedi
	 */
	private int index = -1;
	/**
	 * Indica se il tempo della cena e' scaduto
	 */
	private boolean terminated = false;
	Tavola tavola;
	/**
	 * Conta il numero dei filosofi attualmente nel ristorante
	 */
	private static int filSeduti = 0;
	/**
	 * Costruisce un nuovo filosofo e incrementa la varabile statica
filSeduti;
	 *
	 * @param tavola
	 *            tavola alla quale il filosofo intende sedersi
	 */
	public Filosofo(Tavola tavola) {
		this.tavola = tavola;
		filSeduti++;
	}
	/**
	 * Indica al thread di terminare settando a true la variabile
terminated
	 *
	 */
	public void terminate() {
		terminated = true;
	}
	/**
	 * Determina qual e' l'ultimo filosofo ad abbandonare la tavola
	 *
	 * @throws RemoteException
	 */
	private void abbandona() throws RemoteException {
		//Controlla se il filosofo e' seduto
		if (index != -1) {
			tavola.liberaPosto(index);
			if (--filSeduti > 0) {
				//Ci sono altri filosofi seduti
				System.out.println(
					"Il filosofo " + index + " abbandona la tavola");
			} else {
				//E' l'ultimo filosofo seduto
				System.out.println(
					"Il filosofo "
						+ index
						+ " e' costretto a pagare e poi"
						+ " abbandona la tavola");
			}
		}
	}
	/**
	 * Crea una versione stringa dell'oggetto
	 *
	 * @return Indice e stato del filosofo
	 */
	public String toString() {
		String stringa;
		try {
			stringa =
				"Il filosofo " + index + " sta " + tavola.getStato(index) + ".";
			return stringa;
		} catch (RemoteException e) {
			stringa = "Il filosofo " + index + "e' in uno stato indefinito.";
			System.err.println("Errore nel metodo tavola.getStato(): " + e);
			e.printStackTrace();
		}
		return stringa;
	}
	/**
	 * Implementa il thread filosofo. Se trova un posto libero, pensa e
mangia
	 * fino a quando non viene invocato il metodo terminate()
	 */
	public void run() {
		try {
			// Il filosofo controlla se ci sono posti liberi
			System.out.println("Un filosofo prova a sedersi");
			if ((index = tavola.occupaPosto()) == -1) {
				this.terminate();
				System.out.println("Il filosofo non trova posto e se ne va");
			} else {
				System.out.println("Filosofo " + index + ": si siede");
			}
			while (!terminated) {
				// Il filosofo pensa
				System.out.println("Filosofo " + index + ": inizia a pensare");
				try {
					sleep(1000 + (int) (Math.random() * 3000));
				} catch (InterruptedException e) {
				}
				System.out.println(
					"Filosofo " + index + ": finisce di pensare");
				if (!terminated) {
					// Il filoso mangia
					System.out.println(
						"Filosofo "
							+ index
							+ ": prova a prendere le bacchette");
					tavola.getBacchette(index);
					System.out.println(
						"Filosofo "
							+ index
							+ ": bacchette prese, comincia a mangiare");
					try {
						sleep(1000 + (int) (Math.random() * 3000));
					} catch (InterruptedException e) {
					}
					System.out.println(
						"Filosofo " + index + ": pasto completato");
					System.out.println("Filosofo " + index + ": rilascia le
bacchette");
					tavola.releaseBacchette(index);
				}
			}
			this.abbandona();
		} catch (RemoteException e) {
			System.err.println(
				"Connessione con la tavola persa. Remote Exception in
Filosofo.run(): "
					+ e);
			e.printStackTrace();
			//Evita che in caso di malfunzionamenti di rete
			//la variabile statica assuma dei valori fasulli
			filSeduti--;
		}
	}
}
-------------------------------------------------------------------------------------------------------------------------------
La cartella Prove_Java è situata sul desktop.
Grazie in anticipo per tutti i consigli che mi darete.

Ciao,
il protocollo RMI per funzionare si basa su due classi STUB:
lo stub del client si occupa di passare i parametri sulla rete; quello
del server li decodifica e invoca l'oggetto remoto; quindi spedisce il
risultato allo stub del client, che decodifica  quindi il risultato e
lo restituisce al chiamante.
Queste classi sono generate in automatico con il comando RMIC (mi pare
che si scriva cosi!)
quindi prima di far partire tutto devi lanciare questo comando!
per quanto riguarda i filosofi...li lascerei morire di fame! :LOL
bal...@hotmail.com
 ha scritto:
