Ora che abbiamo effettuato il deploy del nostro primo componente, non ci resta che creare un client per testarne le sue funzionalità.
Come già scritto nei precedenti capitoli, client di questo strato di logica può essere una web application (una servlet o jsp), un altro bean, un oggetto CORBA ed anche una semplice classe Java.
Come test di unità, quindi, creeremo una classe java, che ci mostrerà:
- come accedere ai servizi dell'application server;
- come creare un bean;
- come richiamare le funzioni del bean.
La nostra classe sarà un semplice main statico standalone da avviare da console. Per poter accedere all'application server utilizzeremo il servizio di naming JNDI che ci consentirà di recuperare i servizi dell'application server utilizzando i nomi simbolici. Ogni application server utilizza delle classi specifiche (che quindi dovremo importare nel nostro progetto client), definite in una struttura dati apposita.
Listato 1. Struttura che definisce le classi utilizzate dall'application server
Properties props = new Properties();
// Bisogna valorizzare alcuni parametri, che rappresentano il
// modo con cui accediamo al JNDI dell'application server
// La classe concreta (importare il package jnpserver.jar)
props.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
// La url dell'application server e la porta a cui risponde JNDI (default)
props.put(Context.PROVIDER_URL, "jnp://localhost:1099");
// Il context rappresenta la virtualizzazione dell'application server
Context ctx=new InitialContext(props);
In base all'application server scelto setteremo la proprietà Context.INITIAL_CONTEXT_FACTORY
dichiarando la classe concreta da utilizzare. Inoltre, in base al protocollo con il quale accederemo, cambierà il relativo url (la proprietà CONTEXT.PROVIDER_URL
).
Negli esempi proposti ho utilizzato Eclipse come IDE di sviluppo e JBOSS come application server. Utilizzando JBOSS ho dovuto importare sotto il progetto client il package jnpserver.jar
, in cui sono definite le classi concrete appena citate (nel caso utilizziate altri application server dovrete riferirvi alla documentazione per conoscere quali package importare). Altro package che dovrete sempre importare sarà il package jboss-j2ee.jar
(per altri application server AS_NAME-j2ee.jar
) in cui sono definite interfacce ed eccezioni utilizzate dalla tecnologia enterprise.
Attraverso l'oggetto ctx, ora, potremo accedere a tutti i servizi esposti dall'application server che si trova in locale. Per il nostro esempio dovremo recuperare il bean precedentemente installato.
Listato 2. Recupera il bean precedentemente installato
/**
* Chiediamo all'application server (mediante JNDI) la Home del bean
* chiamata ServerTimeHome.JNDI_NAME (variabile statica che rappresenta
* il nome con cui quel bean è registrato).
* Bisogna effettuare un'operazione di cast, in quanto il tipo di ritorno è un Object
*/
ServerTimeHome sth = (ServerTimeHome) PortableRemoteObject.narrow(ctx.lookup(ServerTimeHome.JNDI_NAME), ServerTimeHome.class);
Per poter fare ciò è necessario importare le interfacce ServerTimeHome
e ServerTime
. Sicuramente il modo più semplice per fare questa operazione sarà quello di creare un package ed importarlo nel nuovo progetto, ma attenzione perché ogni modifica alle interfacce coinvolgerà tutti i progetti che ne fanno uso. Al context viene richiesto (metodo lookup()
) l'oggetto chiamato ServerTime (il nome è cablato nella variabile statica per comodità) e poi viene effettuata un'operazione di casting particolare, attraverso l'oggetto PortableRemoteObject
.
Ora abbiamo la Home dello stateless session bean, dalla quale potremo creare una o più istanze del bean ServerTime.
Listato 3. Crea il bean e usa un metodo di business
// Creazione del bean vero e proprio
ServerTime st=sth.create();
// Uso del metodo di business
System.out.println("Data e ora del server: "+st.getTime());
Richiamare i metodi del bean risulta semplice come se l'oggetto si trovasse nello stesso spazio degli oggetti locali. Le eccezioni, vista la semplicità del test, sono state tutte raccolte e gestite dal class loader. Di seguito un esempio dell'esecuzione del test.
Nella parte alta vediamo la finestra di esecuzione dell'application server (JBoss). Notiamo che il bean è stato installato correttamente e risponde (bound) al nome di ServerTime. Più in basso notiamo l'esecuzione dei metodi: il metodo di creazione, eseguito all'avvio del bean e le chiamate al metodo getTime
. Nella finestra in basso, invece, vediamo l'esecuzione del client con il risultato del metodo getTime
, richiamato sul server.