Ho un dubbio che mi attanaglia da stamattina, quando, controllando i log di Tomcat, ho notato una cosa alquanto strana. Illustro prima la situazione, poi il problema che si è verificato.

C'è una WebApplicazione che gira su Tomcat 6 in una macchina Win 2003 Server (presto, spero, verrà spostata).
In particolare c'è una sezione che attua una procedura che permette all'utente di effettuare alcune scelte. La procedura si svolge in 3 passi:

1) Carico una lista di oggetti (in un ArrayList) e visualizzo una pagina JSP in cui faccio scegliere all'utente uno degli oggetti caricati

2) Quando l'utente effettua la scelta e conferma la form, carico una seconda lista di oggetti (dipendenti dalla prima) e visualizzo una seconda pagina JSP in cui faccio scegliere all'utente uno degli oggetti appena caricati

3) Quando l'utente effettua la seconda scelta e conferma la form, carico una terza lista di oggetti e li visualizzo per l'utente in una nuova pagina JSP

Lo scenario è classico: l'utente vede un elenco di marche; ne sceglie una; viene visualizzato un elenco di modelli per la marca scelta; l'utente ne sceglie uno e vengono visualizzati tutti i prodotti relativi al modello scelto.

Tutto questo processo è gestito da un solo dispatcher che, in base al passo in cui ci si trova, effettua le operazioni richieste e visualizza la JSP corretta. Le JSP operano utilizzando gli oggetti in sessione.

Ecco il dispatcher:

codice:
public void dispatch(HttpServletRequest request, HttpServletResponse response) throws ... {
   ...
   switch( step ) {

      case 0:   // Primo step. Carico le marche e le visualizzo
         caricaMarche( ... );
         view = ... // La JSP che si occupa del rendering per la scelta della marca
         break;

      case 1:   // Secondo step. L'utente ha scelto la marca: carico e visualizzo i relativi modelli
         caricaModelli( ... );
         view = ... // La JSP che si occupa del rendering per la scelta del modello
         break;

      case 2:   // Terzo step. L'utente ha scelto il modello: carico i prodotti e li visualizzo
         caricaProdotti( ... );
         view = ... // La JSP che visualizzerà i prodotti per la scelta dell'utente
   }
   ...
}
E questi sono i metodi caricaMarche() e caricaModelli(), ovvero i due incriminati nel problema:

codice:
private void caricaMarche( ... ) {
   Session s = ... ;

   ...

   ArrayList marche = new ArrayList()

   ...   // Carico le marche dal sistema e popolo l'ArrayList

   s.setAttribute("marche", marche);
}

private void caricaModelli( ... ) {
   Session s = ...;
   ...
   // Prelevo il codice della marca selezionata dall'utente
   String codiceMarca = request.getParameter("codiceMarca");

   // Carico i modelli per la marca selezionata
   ...

   // Prelevo dalla sessione l'ArrayList delle marche, caricato nello step precedente
   ArrayList listaMarche = (ArrayList) s.getAttribute("marche");
   if (listaMarche != null) {
      ...   // Effettuo altre considerazioni e operazioni
   } else {
      // Scrivo nel log di Tomcat le informazioni relative alla situazione anomala
      System.err.println("ArrayList marche nullo nel Dispatcher.");
      System.err.println("Codice marca: " + codiceMarca);
      System.err.println("Utente: " + utente.getUserID());
      System.err.println("Cliente: " + utente.getCodiceCliente());
      System.err.println("Situazione della sessione:");
      System.err.println("Creation-Time: " + s.getCreationTime());
      System.err.println("Last-Accessed-Time: " + s.getLastAccessedTime());
   }
}
Ed ecco cosa ho trovato nel log stamattina:

codice:
ArrayList marche nullo nel Dispatcher.
Codice marca: 260
Utente: 1242
Cliente: 004489
Situazione della sessione:
Creation-Time: 1284645496234
Last-Accessed-Time: 1284645511359
Aggiungo una informazione utile: ho imposto un timeout di sessione di 3 ore per ciascun utente loggato. Ciò significa che la sessione scade dopo 3 ore di inattività.

Da quello che c'è nel log si può evincere quanto segue:

1) E' stato eseguito il codice del ramo "else" del metodo "caricaModelli()" postato sopra

2) Dal punto 1) si desume che l'utente ha correttamente visualizzato la pagina delle marche ed ha effettuato una scelta (ha selezionato la marca classificata con codice 260)

3) Dal punto 2) si desume che la JSP che visualizza l'elenco delle marche ha trovato in sessione l'ArrayList delle marche

4) Dal punto 3) si desume che il metodo "caricaMarche()" ha effettuato correttamente il suo lavoro.

5) Il punto 4) è in netta contraddizione con il log presente in Tomcat per i seguenti motivi:

a) La sessione era stata creata solo 15 secondi prima che venisse a galla l'errore (quindi non poteva ancora essere scaduta)

b) L'utente è riuscito ad effettuare una scelta (codice marca 260!), quindi l'ArrayList era in sessione al momento del rendering della JSP.

Qualcuno ha qualche idea del motivo per cui possono accadere queste cose? Finché questo genere di cose capitano 1 volta ogni 7-8 mesi non è un grosso problema, ma tutto questo mi dà da pensare sull'affidabilità di Tomcat.


Ciao.