Newsgroup: it.comp.java
Titolo: Servlet e path dell'applicazione

Ciao a tutti...
come sempre spero nel vostro aiuto per risolvere questa questione che
mi attanaglia da un po'...
Il problema è il seguente... ho una jsp che usa un bean per far
lavorare delle classi che, dati in input alcuni paramerti, accedono a
dei file xml presenti nella stessa applicazione e ne eseguono delle
query sul contenuto. Tutto funziona regolarmente testando le singole
classi, ma quando richiamo l'applicazione dal borwser web sfruttando
tomcat la classe che accede al file solleva una eccezione di file not
found.
Il problema sembra essere dovuto alla path usata per localizzare il
file nel senso che, richiamando l'app dal browser cambia il path della
root al quale fare riferimento.
La domanda è... esiste un modo per far capire alle classi
dell'applicazione quale è la root corretta dalla quale cercare il file
da leggere?
Aggiungo che:
  - i riferimenti al file da leggere sono scritti in modo relativo e
vorrei evitare di scriverli in modo assoluto per evitare di
riconfiguarae l'app ad ogni deploy...
  - vorrei evitare di passare in input alla classe che accede al file
il percorso dove cercare. Aggiungerebbe troppa ridondanza nelle
chiamate e poi sarebbe come passare ogni volta un parametro sempre
uguale... :S
Spero di non essere stato troppo contorto nell'illustrarvi il
problema.
Confido nel vostro prezioso supporto
Ciao
Sergio

 da leggere?
Mi hai preso "di sonno", spero di non sparare cantonate troppo grandi, 
ma con getServletContext().getRealPath("/") dovresti ricavare la root 
della tua applicazione web, quindi supponendo che il tuo XML si trovi in 
WEB-INF puoi ricavare il path come:
String file = getServletContext().getRealPath("/") +
        File.separator + "WEB-INF" +
        File.separator + "belfailxml.xml";
e poi fare come al solito.
Scusa se ho scritto qualche ovvieta', ma il cervello sta' gia' a nanna :D

 Scusa se ho scritto qualche ovvieta', ma il cervello sta' gia' a nanna :D
Grazie della risposta in "tarda serata" (o "prima mattina" come
preferisci :))!
Quello che hai indicato è esattamente uno degli n tentavivi che ho
provato.. il fatto è che getServletContext() (giustamente immagino)
non mi sembra che sia accessibile al di fuori di una servlet (o jsp)
mentre io dovrei utilizzarla a livello di classe.
Per chiarezza riporto a grandi linee la struttura dell'applicazione
  / root di Tomcat (c:/htdocs/web)
  +- miaApp
    +- index.jsp
    +- ...
    +- [resources]
      +- mioFile.xml
      +- ...
    +- [system]
      +- getInfo.jsp
      +- ...
    +- [WEB-INF]
      +- [classes]
        +- GetInfoBean.jsp
        +- MiaClasse.class
      +- ...
Il giro è il seguente. Da index.jsp viene richiamata la pagina system/
getInfo.jsp la quale utilizza il bean GetInfoBean per accedere alla
classe MiaClasse che punta al file mioFile.xml con la seguente stringa
"/resources/mioFile.xml".
MiaClasse solleva l'eccezione FileNotFound sul path %JAVA_HOME%/bin/
resources/miofile.xml :S
Putroppo ora non ho l'applicazione sotto mano e sono andato a memoria,
posso essere più preciso sul path utilizzato per l'accesso al file e
sul messaggio di errore stasera appena rientro a casa... spero in ogni
caso di aver dato una idea della questione.
Intanto grazie 1000 :)
Ciao
Sergio

 Sergio
Idea (sperimentale da niubbo JAVA pasticcione)
Creare una classe apposta (MioPath) contenente una stringa static,
creare i metodi statici setPath() e getPath().
Teoricamente da quanto ho capito non c'e' bisogno di istanziare MioPath.
Il path basta che sia settatto una volta da un servlet qualsiasi e
quindi dovrebbe essere accessibile a qualsiasi altra classe
semplicemente facendo:
il servlet qualsiasi fa:
..
MioPath.setPath(getServletContext().getRealPath("/"))
..
la classe generica fa:
..
String rootPath = MioPath.getPath();
Se ho sparato una castroneria correggetemi.
Comunque mi pare strano che non ci sia un modo pi� elegante di accedere
al contesto.
saluti

        +- ...
Solo un'ultima cosa sulla struttura: perche' hai messo resources li? Non 
ti conviene spostarla in WEB-INF, in modo che non sia accessibile via web?


potrei provare ma adesso non ho Netbeans sotto mano.

 potrei provare ma adesso non ho Netbeans sotto mano.
Cio� spiegandomi meglio, posso accedere alle variabili statiche anche se
non � presente nessuna istanza?
A pelle cos� mi sembrerebbe logico comunque aspetto il verdetto.

 A pelle così mi sembrerebbe logico comunque aspetto il verdetto.
Si è corretto. Una delle prorpietà delle variabili (e metodi) statici
è quella di essere disponibili senza necessariamente creare una
istanza della classe.
Per l'esempio in questione (che ovviamente proverò quanto prima ;) ) o
in altri simili, credo che la differenza tra usare un singleton o dei
metodi/variabili statiche sia solo al livello stilistico.
Più in generale, invece, il singleton ti permette di creare una sola
istanza della classe condivisa per tutta l'applicazione mantenendo i
vantaggi di una classe istanziata, tra i quali quello di poter
accedere senza problemi ai metodi di istanza di altre classi.
Personalmente è un pattern che mi è molto comodo e a volte lo
preferisco anche a soluzioni più rapide ma meno "eleganti", funzionali
e/o riutilizzabili.
Appena implementerò la suolizione proposta vi darò dei feedback!
Ciao
Sergio

 istanza della classe.
Ottimo.Grazie per il chiarimento.
Aspetto il feedback

 Aspetto il feedback
Sono (finalmente) riuscire ad implementare la soluzione proposta da
gb, che ringrazio ancora, per aver risolto perfettamente il problema.
Oltre alla chiarezza implementativa tale soluzione offre parecchi
spunti utili e mi ha portato a conoscenza dei listener (e per riflesso
dei filtri) che, venendo dal mondo di applicazioni desktop, ignoravo.
Grazie a tutti
Ciao
Sergio

 gb, che ringrazio ancora, per aver risolto perfettamente il problema.
Se la tua soluzione differisce molto da quella esposta in questa 
discussione, la posteresti? Mi piacerebbe darci un'occhiata


La soluzione che ho implementato è esattamente quella proposta da GB a
meno dei nomi delle classi, dei package e della chiamata
  sce.getServletContext().getRealPath("/resource/")
che ho modificato in
  sce.getServletContext().getRealPath("/")
per recuperare direttamente la root dell'applicazione in quanto tutto
il percorso del file è calcolato a runtime.
Se hai bisogno di ulteriori info non esitare a chiedere ;)
Ciao
Sergio