View Full Version : [IDL CORBA->Java](Elclipse-ORBStudio)Problemi nella compilazione delle interfacce idl
Ho creato queste tre semplici interfacce in IDLCorba e vorrei compilarle con OrbStudio in Eclipse.
Secondo la guida di OrbStudio dovrebbe essere sufficente cliccare col destro sul nome del file .idl nel package explorer poi andare su "ORB Menu"-->"Compile" e dovrebbe fare tutto automaticamente.Il fatto è che facendolo non succede nulla. La cosa che mi mette più in difficoltà è che non da alcun messaggio di errore, semplicemente non fa nulla.
Qualcuno che usa OrbStudio per Eclipse può darmi una mano?
Quoto qui le interfacce che ho scritto, molto probabilmente sono loro che contengono un errore, anche se mi sembra strano che OrbStudio non me lo dica.
module Subasta {
typedef sequence <coordinadorSubastas> listaCoordinadores;
interface coordinadorSubastas {
readonly attribute float valor;
readonly attribute string descripción;
readonly attribute string estado;
oneway void inscribirCliente (in string referencia);
oneway void abrirSubasta ();
boolean pujar (in float cantidad,in string referencia);
oneway void ultimaPuja (in string referencia);
oneway string ganador ();
float valor();
string descripción();
string estado();
};
interface gestorSubastas {
coordinadorSubastas crearSubasta (in float valorInicial,in string descripción, in long duración);
oneway void destruirSubasta (in coordinadorSubastas coordinador);
listaCoordinadores localizarSubasta (in string buscar);
};
interface clienteSubastas {
readonly attribute string identificación;
oneway void finSubasta (in gestorSubastas subasta);
oneway void nuevoValor (in float valor);
string identificación();
};
};
E' il mio primo programma distribuito che usa idl corba, non rabbrividite se vedere degli errori grossolani o delle oscenità nel codice!
Grazie.
due cose sicuramente da correggere :
usa solo caratteri nel range 0-127 (ovvero niente lettere accentate), e il primo typedef va dopo la dichiarazione sottostante.
Ok, grazie mille, l'ORBStudio ha ripreso a funzionare dopo le modifiche che mi hai consigliato di fare, probabilmente l'uso dei caratteri accentati lo impicciava un pò.
Ci sono ancora problemi nel mio file ma almeno adesso provando a compilare mi dice cosa c'è che non va bene.
Ora posso rimettermi al lavoro!Grazie, ciao! :)
Altra domanda, ho un piccolo dubbio sul funzionamento di corba e del linguaggio IDL.
Dopo aver compilato le interfacce IDL mediante ORBStudio (che non fa altro che usare IDLJ ) Saltano fuori tutti i file java di interfaccia.
Quelli stanno già bene così come li ha creati idlj o devono essere modificati ulteriormete durante la creazione dei file di implementazione?
no non toccarli.
Quei file contengono le classi che rappresentano l'interfaccia che hai dichiarato nell'idl.Ad esempio da una interfaccia coordinadorSubastas
viene generata una classe java coordinatorSubastas. Visto che contengono il codice per la gestione della comunicazione via rete (e non) che che a te non interessa, lasciale stare.
La scelta corretta e' quella di implementare una sottoclasse, chiamata ad esempio coordinatorSubastasImpl, in un file separato.
Ok grazie per le dritte, il lavoro procede abbastanza bene..ma ora ho un nuovo problema.
Si tratta della funzione del client nuevoValor(valore) che dovrebbe essere eseguita dal server su tutti i client che si sono prima registrati sul server stesso per avvertirli che il valore della variabile valor è cambiato.
Affinchè un client possa registrarsi deve chiamare la funzione del server InscribirCliente(String riferimentoAlClient). Inizialmente come riferimento al client facevo passare una striga ma a causa della funzione nuevoValor che deve essere eseguita dal server sul client deduco che una stringa non è più sufficente.. cosa devo passare come parametro della funzione InscribirCliente affinchè il server possa fare poi la chiamata sul client?
Grazie! :rolleyes:
La cosa piu' immediata e' un riferimento ad un oggetto che identifichi il client. Se il server deve compiere una operazione sul client sicuramente questa operazione fara' parte di una interfaccia, per cui il tipo da passare e' quello. Attenzione che probabilmente dovrai comunque passare una stringa identificativa del client: ad esempio non puoi confrontare i riferimenti di due chiamate successive per capire se sono lo stesso oggetto, devi usare un nome o, in alternativa, aggiungere all'interfaccia del client un metodo per chiedergli un ID.
Si ci avevo pensato anch'io ma il problema è il seguente, metto le definizioni idl per spiegarlo meglio.
module Subasta {
interface coordinadorSubastas {
readonly attribute float valor;
readonly attribute string descripcion;
readonly attribute string estado;
oneway void inscribirCliente (in string referencia);
oneway void abrirSubasta ();
boolean pujar (in float cantidad,in string referencia);
oneway void ultimaPuja (in string referencia);
string ganador ();
};
typedef sequence <coordinadorSubastas> listaCoordinadores;
interface gestorSubastas {
coordinadorSubastas crearSubasta (in float valorInicial,in string descripcion, in long duracion);
oneway void destruirSubasta (in coordinadorSubastas coordinador);
listaCoordinadores localizarSubasta (in string buscar);
};
interface clienteSubastas {
readonly attribute string identificacion;
oneway void finSubasta (in gestorSubastas subasta);
oneway void nuevoValor (in float valor);
};
};
Iniziando dalla terza interfaccia (clienteSubastas) questa deve OBBLIGATORIAMENTE essere definita dopo l'interfaccia "gestorSubastas" perchè "gestorSubastas" è un parametro di input della sua funzione "finSubasta".
L'interfaccia "gestorSubastas" a sua volta deve OBBLIGATORIAMENTE essere definita dopo l'interfaccia "coordinadorSubasta" perchè "coordinadorSubasta" è un parametro di input della sua funzione "destruirSubasta".
Quindi l'interfaccia "coordinadorSubasta" deve essere definita OBBLIGATORIAMENTE prima delle altre.
Ma in questo modo non posso passare un oggetto "clientesSubastas" come parametro di una sua funzione perchè "clientesSubastas" non è ancora stata definita.
E' un pò contorto spero che si capisca dove sta il mio problema.
Ti basta dichiarare la presenza dell'interfaccia prima di definirla:
module Subasta {
interface clienteSubastas;
interface coordinadorSubastas
{
readonly attribute float valor;
readonly attribute string descripcion;
readonly attribute string estado;
oneway void inscribirCliente (in clienteSubastas referencia);
oneway void abrirSubasta ();
boolean pujar (in float cantidad,in string referencia);
oneway void ultimaPuja (in string referencia);
string ganador ();
};
typedef sequence <coordinadorSubastas> listaCoordinadores;
interface gestorSubastas {
coordinadorSubastas crearSubasta (in float valorInicial,in string descripcion, in long duracion);
oneway void destruirSubasta (in coordinadorSubastas coordinador);
listaCoordinadores localizarSubasta (in clienteSubastas buscar);
};
interface clienteSubastas {
readonly attribute string identificacion;
oneway void finSubasta (in gestorSubastas subasta);
oneway void nuevoValor (in float valor);
};
};
Per inciso a meno che non ci siano altre motivazioni (consistenza con codice preesistente ad esempio) userei le maiuscole per le interfacce (clienteSubastas -> ClienteSubastas), soprattutto se poi programmi in Java.
Ok, grazie ai tuoi consigli sono riuscito ad andare avanti. Ho completato per ora il servente ma sono rimasto bloccato al server.
Ti posto il codice per semplicità
import org.omg.CORBA.SystemException;
import org.omg.PortableServer.POA;
import Subasta.CoordinadorSubastas;
/**
* This class is the implemetation object for your IDL interface.
*
* Let the Eclipse complete operations code by choosing 'Add unimplemented methods'.
*/
public class GestorSubastasServerImpl extends Subasta.GestorSubastasPOA {
POA currentPoa = null;
/**
* Constructor for GestorSubastasServerImpl
* @param currPoa
*/
public GestorSubastasServerImpl(POA currentPoa) {
this.currentPoa = currentPoa;
}
/**
* create method hides object creation
*
* @param currPoa
* @return GestorSubastasServerImpl
* @throws SystemException
*/
public static GestorSubastasServerImpl _create(POA currentPoa) throws SystemException {
return new GestorSubastasServerImpl(currentPoa);
}
/**
* _default_POA()
*
* Overrides the inherited _default_POA
* The inherited _default_POA returns the root POA, by overriding it the correct POA is returned.
*/
public POA _default_POA() {
return currentPoa;
}
@Override
public CoordinadorSubastas crearSubasta(float valorInicial,
String descripcion, int duracion) {
// TODO Auto-generated method stub
return null;
}
@Override
public void destruirSubasta(CoordinadorSubastas coordinador) {
// TODO Auto-generated method stub
}
@Override
public CoordinadorSubastas[] localizarSubasta(String buscar) {
// TODO Auto-generated method stub
return null;
}
}
:
1° dubbio: non so di preciso cosa sia il poa ne se con il codice generato automaticamente da orbstudio sia gestito autonomamente o debba essere io a passare qualche metodo per configurarlo.
2° dubbio: il metodo "creaSubasta" dovrebbe essere invocato per creare i vari servienti del tipo coordinadorSubasta. Non riesco a capire come perchè usare coordinadorSubasta cs = new coordinadorSubasta(...); per creare un serviente mi dice che è sbagliato.
3° dubbio: il metodo "destruirSubasta" dovrebbe essere invocato per distruggere un serviente.. in questo caso non ho proprio idea di come si faccia a distruggere un serviente... :rolleyes:
Se sei cosi' a digiuno di di Corba la vedo un po' dura... ti consiglio di indirizzarti su di un libro che possa guidarti meglio. Detto questo, e premesso che la mia esperienza riguardo CORBA copre soprattutto C++, cerco di chiarire un po' meglio.
Due premesse:
- come avrai capito in CORBA esistono sostanzialmente due tipi di oggetti, i Servant che contengono il codice eseguibile e i proxy che rappresentano oggetti. La separazione e' abbastanza netta per vari motivi (fault tolerance, persistenza etc.), e il POA (detto in termini _molto_ semplici) serve per mediare tra i due. Per inciso questo vuol dire che per ogni classe che dichiari in un idl vengono generate due classi distinte, una classe lato client (il proxy) e una lato server (quella da sottoclassare). Non ho idea pero' di come venga fatto nel tuo caso. Con idlj ad esempio vengono create due classi con nomi diversi, nel tuo caso ad esempio Subasta e SubastaPOA. La prima e' il proxy la seconda il servant.
- Non puoi creare nuovi oggetti da remoto, devi avere una qualche factory che li crei per te con gli opportuni metodi. Questi metodi (creaSubasta ad esempio) dovrebbero comportarsi nel modo seguente:
* crea una istanza di un oggetto di tipo SubastaPOA con gli opportuni argomenti, attivala e salvala da qualche struttura dati di modo che non venga reclamata dal GC
* ricavati una istanza di un oggetto Subasta. Non la puoi creare direttamente (e' per quello che ti da errore),ma la ottieni col methodo _this() di SubastaPOA.
* ritorni l'oggetto Subasta
noi nella nostra architettura facciamo qualcosa di simile al seguente (al netto della gestione degli errori e dei cast) :
public org.omg.CORBA.Object createObject( String name )
{
SubastaPOA s = new SubastaPOA();
servantMap.put(name,s);
org.omg.CORBA.Object obj = poa.servant_to_reference(p);
return obj;
}
p.s.: cerca di usare il tag [ code ] invece che [ quote ] per ilcodice, altrimenti l'indentazione va a gentil donzelle !
in questa situazione, distruggere il servente non vuol dire altro che toglierlo dalla mappa ed eventualmente forzarne la distruzione da parte del GC.
Ok ho preso un libro e sto cercando di capire un pò di più anche se non ho il tempo di leggere tutte le 700 pagine.
Non mi è chiara una cosa, il client invoca alcuni metodi remoti passando come parametro un riferimento a se stesso, come faccio a recuperare tale riferimento?
Sempre tramite una funzione del POA o il poa gestisce solo i serventi?
Se devi passare un riferimento a te stesso allora anche il client deve essere un oggetto corba attivato. A quel punto all'interno dell'oggetto attivato non occorre che chiamare il metodo _this() (con l'underscore davanti!) e passarlo alla chiamata.
Niente, anche con il libro c'è qualcosa che mi sfugge, non ho il tempo per leggerlo tutto e non riesco ad andare avanti con il mio progetto..
Cerchiamo di capire passo passo cosa c'è che non va:
Questo dovrebbe essere lo schema di un sistema distribuito CORBA da quanto ho capito, corregimi se sbaglio:
http://www.hwupgrade.it/forum/attachment.php?attachmentid=63238&stc=1&d=1213286295
Ok, iniziamo con il servitore, che, se non ho capito male, dovrebbe occuparsi di creare l'orb, il poa, e i vari serventi:
http://www.hwupgrade.it/forum/attachment.php?attachmentid=63240&stc=1&d=1213286850
E qui metto un frammento di codice che relativo al servitore:
public class GestorSubastasServerImpl extends Subasta.GestorSubastasPOA {
POA poa = null;
org.omg.CORBA.ORB orb;
GestorSubastasServerImpl(String[]args){
try{
orb = org.omg.CORBA.ORB.init(args,null);
poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
poa.the_POAManager().activate();
orb.run();
}
catch(InvalidName e){
System.err.println(e);
}
catch(UserException e){
System.err.println(e);
}
catch(SystemException e){
System.err.println(e);
}
}
Domanda: Che parametro devo passare alla funzione che inizializza l'orb? (intendo il parametro "args")
Credo si tratti dell'indirizzo ma in che formato? Come lo recupero?
A questo punto, dopo aver capito che arg devo passare dovremmo trovarci in qesta situazione:
http://www.hwupgrade.it/forum/attachment.php?attachmentid=63241&stc=1&d=1213287385
Fin qui tutto corretto?
PS: Come faccio ad inserire le immagini direttamente nella risposta e non farle apparire come link?
fin qui mi sembra che ci siamo. I parametri "args" sono quelli del metodo main: e' un modo per poter passare dei parametri all'orb (Ad esempio la porta su cui ascoltare se si lavora in TCP).
Si, scusa non mi sono spiegato bene.
So che "args" sono i parametri del metodo main ma nell'esempio di codice che ho trovato e precisamente a questa linea
orb = org.omg.CORBA.ORB.init(args,null);
i parametri del main vengono passati all'inizializzatore dell'orb.
La mia domanda era questa: che parametri devo passare al metodo main quando avvio il servente?
Ad esempio se utilizzo " java gestorSubasta " e non gli passo alcun parametro allora nessun parametro verrà passato a orb = org.omg.CORBA.ORB.init(args,null); quindi dovrebbe darmi un errore..
di solito che parametro si aspetta di ricevere in ingresso il metodo init() ?
PS: Grazie infinite per la tua disponibilità e pazienza
niente di particolare... dipende ovviamente da ORB a ORB ma in generale senza alcun parametro dovrebbe funzionare senza problemi.
I parametri li aggiungi quando vuoi ottenere qualche funzionalita' particolare. Un esempio e' quel che dicevo prima, far mettere l'ORB in ascolto su una porta particolare, (cosa che probabilmente ti tocchera' fare per inciso).
Quali parametri vengono accettati dipendono esclusivamente dal software che stai utilizzando. L'unica e' controllarne la documentazione.
Ok grazie ai tuoi preziosi consigli sono quasi riuscito a finire! :D
Mi manca solo l'implementazione di una cosa.
La funzione che dal server mi fa eliminare uno dei serventi:
Per farlo uso il metodo
poa.deactivate_object(id);
dove id è l'identificazione del servente che voglio eliminare.
Il problema è che vorrei che il servente compisse delle operazioni prima di essere eliminato ma non posso implementere un metodo pubblico che gli faccia fare queste operazioni perchè posso implementare solo i metodi che sono definiti nella sua interfaccia.
Esiste un metodo ereditato che io possa chiamare sul servante per dirgli che sta per essere eliminato?
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.