Newsgroup: it.comp.java
Titolo: consiglio su servlets

Ciao a tutti.
Vorrei un consiglio sulla seguente implementazione del mio servlet.
public class myServlet extends HttpServlet{
....
static Hashtable myHt;
public void init(ServletConfig config) throws ServletException{
    // creazione di un connection pool myPool
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
    if(myHt == null)
        myHt= loadHt(); // utilizza il connection pool
    usaHt(myHt); // fa quello che vuole con la hashtable
}
}
in questo modo faccio carico la hashtable una sola volta (la primissima
request) e poi, visto che e' static, sara' comune a tutti i thread e quindi
a tutte le istanze del servlet.
C'e' qualcosa di sbagliato in questo ragionamento?
Ci sono alternative migliori?
Grazie
Marcello

 
Sarebbe più opportuno caricare la hashtable nel metodo init, 
in questo modo sei sicuro che viene caricata una sola e poi se 
vogliamo esagerare potresti usare una hashMap al posto di una hashtable.
:-)

 
E' sconsigliato usare variabili static, e dalla specifica 2.3 c'e' il 
ContextListener che ti permette una soluzione molto piu' elegante e 
gestibile di init() (e corretta come assegnamento delle responsabilita': 
perche' dovrebbe una servlet istanziare degli oggetti per altre servlet 
se c'e' un modo di farlo a livello web-app?)
ciao
uL

 gestibile di init() 
Non ho ancora dato un'occhiata  alla specifica 2.3 (mia culpa se sono 
rimasto indietro :-) ).


Questa sostituzione non e' trasparente, la hashMap non e' sincronizzata e quindi potrebbe
essere necessario gestirla.
Ciao,
    Bruno.
---
| Bruno Bossola
| A Java Software Engineer :-)
| 
http://members.xoom.it/bbruno
| 
http://digilander.iol.it/bbossola


Visto che hai iniziato tu, allora a questo punto esagero :-D: perche' la servlet dovrebbe
contenere alcuna logica oltre alla sua? Gia' fa un po' troppe cose, non facciamogli fare
niente altro.



Infatti :) Comunque, sia la soluzione init e che l'inizializzazione 
static che hai consigliato sono sconsigliate.
ciao!
uL
 

 essere necessario gestirla.
  Cosě andrebbe bene?
  Map m = Collections.synchronizedMap(new HashMap(...));
G.M.

   Map m = Collections.synchronizedMap(new HashMap(...));
Beh ma allora buttati direttamente su una HashTable, no? (Devo anche dire che non ho
approfondito la differenza tra una HashMap sincronizzata e una HashTable...)
potrebbe anche essere
synchronized loadHT() {
  if (ht == null) {
    ht = new HashMap();
    ...
  }
}
Insomma dipende un po' da quali metodi usino la tua hash (se siano tra loro sincronizzati o
meno ecc ecc)
Ciao,
 Stefano
----------
"X WindowSSS, teSSSoro mio... lo odieremo per SSSempre"
Bill Gollum
----------

 
Il metodo init e' analogo al costruttore, anche se e' una callback. Una 
volta costruita, la servlet rimane in piedi piu' o meno per sempre. (a 
meno che il container non decida di distruggerla, per esempio per 
risparmiare memoria, e poi ricostruirla quando serve, oppure 
l'applicazione non venga "chiusa"). E visto che per ogni servlet 
esistera' una sola istanza, sei a posto, viene invocato una sola volta. 
Pero' ogni servlet ha il suo, di init() e questo potrebbe crearti 
problemi se hai piu' servlet nella tua webapp, mentre l'applicazione web 
nel suo *complesso* ha il ContextListener per notificarti che e' stata 
creata (il Context e' comune a tutte le servlet e jsp e rappresenta 
praticamente l'applicazione).
E' li' che devi mettere risorse che vanno condivise da tutte le 
servlet/jsp, tipo un pool di connessioni jdbc.
Nell'init ci si mettono delle risorse che servono solo a quella 
particolare servlet (o istanza, tanto il mapping e' 1:1).
Altrimenti puo' anche funzionare, ma non e' detto che funzionera' sempre 
con le future specifiche. Il ContextListener e' invece fatto apposta per 
evitare di andare ad infognarsi in variabili static, falsi Singleton ed 
altro.
HTH
uL

 
Grazie Ugo sei stato esauriente come al solito. :-)
G.M.


I know, ma secondo me bisogna arrivarci, e non e' corretto assumere che tutto il mondo
stia usando la versione 2.3, non credi? 
http://www.servlets.com/polls/results.tea?name=servletversion
Mica lavoriamo tutti in Sun, qui :-D
Inoltre, al di la del discorso servlet, l'inizializzazione static che ho consigliato e'
una delle due uniche possibilità che ti permettano di costruire correttamente un oggetto
di quel tipo: consiglio vivamente a tutti di dare un'occhiata a questo link:
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
(che avevo gia' inserito nel post precedente). 
Ah, prima che tu me lo chieda: io uso variabili statiche? No :-D. 



Penso proprio di si :-D, ma comunque dipende da come viene usata nel sistema: e' possibile
che semplicemente l'hashmap sia funzionale gia' cosi com'e' o magari sia sufficiente
introdurre le sincronizzazioni dove necessario. Io volevo solo dire che non e' cosi'
immediata la sostituzione, bisogna farci attenzione :-D


 Vorrei un consiglio sulla seguente implementazione del mio servlet.
[cut]
grazie a tutti
(che mi compro a fare i libri ;-D )
marcello

 
http://www.servlets.com/polls/results.tea?name=servletversion
certo! Intendevo per la 2.3, immaginando che chi cominci ora lo faccia 
direttamente con l'ultima spec... anche se non lavora in Sun :)
Carino il poll!
uL

 la loro creazione a thread diversi.
Aspetta, qui non mi torna qualcosa... stai parlando del 
SingleThreadModel? Se cosi' non fosse, da specifica, il container deve 
istanziare un solo oggetto servlet, a meno che non si usi proprio il 
famigerato SingleThreadModel: e fra l'altro in questo caso il Container 
*non* puo' usare il pool se lo sviluppatore sincronizza il service, ma 
deve in effetti sincronizzare veramente il service (un bel gioco di parole)
Quindi il Container puo' utilizzare un pool solo nel caso si implementi 
il SingleThreadModel e in piu' senza sincronizzare nulla (potrebbe 
comunque scegliere di utilizzare una servlet sincronizzata, fra l'altro, 
anche se non sarebbe il massimo)
Visto che l'ho spiegato malissimo, faccio una tabellina riassuntiva (da 
leggere con font non proporzionale):
Synch. 
SingleThreadM. 
N. di Istanze
-------------------------------------
no 
no 
	1
si 
no 
	1
no 
si 
	n (pool) o 1 synch
si 
si 
	1 synch
Sperando si capisca un po' di piu'!
Poi volevo aggiungere una nota sulle inizializzazioni statiche: non e' 
garantito che la servlet sia ben costruita fino all'invocazione di init, 
quindi e' ad esempio improprio cercare di connettersi a DB o ad EJB 
poiche' il Container non garantisce che tutto sia a posto.
ciao
uL


Di nuovo, non tutti usano EJB :-) (mah, 'sti tipi strani :-D) e quindi potrebbe non
impippargliene nulla: c'e' chi usa, ad esempio, Turbine e si trova benissimo cosi, o chi
si sviluppa in casa il proprio application server. 
Ah, ci tengo a rimarcarlo, io le variabili statiche non le uso :-), e neppure metto logica
nelle servlet. Ma non posso supporre ne' richiedere che il resto del mondo faccia
altrettanto (e neanche me ne impippa un granche' :-D). Io rispondo, se ho tempo consiglio.


Salve,
scusate l'intromissione..... ma leggiucchiando qua e la per il newsgroup
sono incappato in questa interessante discussione sull'init() delle
servlet....
Attualmente io uso Tomcat 3.2.4 (prima usavo la 3.2.2 con eguali risultati)
ed ho alcune servlet che all'interno del metodo init() fanno alcune cosette,
tra le quali ad esempio ce ne è una che addirittura istanzia un nuovo thread
generando una sorta di miniapplicazioncina sempre attiva e residente che
elabora alcuni file sull'harddisk del server (ps: il server è mio....)...
logicamente (forse a causa di una mia infinita ignoranza su Tomcat e
simili...ed anche su Java....) ad ogni lancio di Tomcat devo almeno una
volta richiedere da un browser la servlet che ho fatto altrimenti non verrà
mai istanziata neppure una volta......
( sarebbe bello sapere se si può costruire un'estensione server di Tomcat e
farla partire automaticamente al lancio dello stesso.....)
Domanda: ... premettendo che comunque tutto funziona da più mesi sul mio
sistema senza aver mai generato nemmeno un intoppo, che a quali casini posso
andare in contro in questa mia programmazione poco elegante e penso fuori da
ogni standard???
Saulti,
Luca Landi

 
lo so, lo so :)
uL

 
A parte anatemi da parte di Sun :-), fino a che la configurazione
del tuo sistema e' stabile, non c'e' nessun problema. Ti consiglio 
comunque di verificare se ad esempio il tutto continua a funzionare
con Tomcat 4, ad esempio.
Certo pero' che sei proprio fuori standard :-)
Ciao,
    Bruno. (da casa)
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 
anatemi da parte mia... :)
Comunque ci dovrebbero essere modi proprietari per fare la stessa cosa 
pre servlet 2.3.
ciao
uL