Mi sono scontrato con un problema: far scrivere (o leggere) un file presente su di un'unità di rete ad una WebApplication che gira su Tomcat sotto Windows. Per due giorni ho fatto prove su prove, ho provato a modificare le policy di catalina per cercare di dare dei permessi alla mia WebApp sull'unità di rete interessata, ho cercato una soluzione nel web, trovando decine e decine di casi identici mai risolti.

Uno di questi è stato presentato in passato anche su questo forum e l'autore della discussione si è rassegnato a cambiare strategia:
http://forum.html.it/forum/showthrea...readid=1228190

Il problema che si propone
Supponiamo di avere una unità di rete mappata X:
Supponiamo anche che non ci siano restrizioni su tale unità: esistono tutti i permessi di lettura/scrittura per tutti gli utenti.
Abbiamo bisogno di scrivere o leggere un file su/da questa unità. Utilizzando una applicazione desktop, la cosa è semplice. Il codice seguente, ad esempio, funziona senza alcun problema (tralascio la gestione delle eccezioni):

codice:
PrintStream ps = new PrintStream( new FileOutputStream("X:/pippo.txt") );
ps.println("Scrivo una riga di testo.");
ps.close();
Riportando lo stesso identico codice all'interno di una WebApplication (ad esempio, una Servlet) che gira all'interno di Tomcat, questo codice provocherà una FileNotFoundException. Navigando tra le varie discussioni di diversi forum scopro che lo stesso problema viene sollevato in lettura (non ho fatto prove, ma posso tranquillamente crederci).

La causa
Trovare la causa di questo "malfunzionamento" è stato il problema più difficile e, una volta capito il perchè di questa cosa, trovare la soluzione è stato banale.
Questa eccezione viene sollevata per un motivo molto semplice: Tomcat non vede le unità di rete. Ed il motivo è altrettanto semplice: Tomcat viene avviato come servizio; essendo avviato come servizio, non vi è necessariamente un utente loggato, quando il servizio parte. E le unità di rete vengono sempre mappate da utenti "loggati" (o, comunque, utilizzando le credenziali dell'utente che le ha mappate). Di conseguenza, un servizio non può essere a conoscenza di un'unità di rete che verrà, eventualmente, mappata da un utente in seguito.

Come si risolve
Una volta capito qual è il problema, la soluzione è ovvia. L'unità di rete "X:" viene mappata usando una UNC: "\\nomeserver\risorsa". Bene, invece di usare "X:" useremo la UNC ed il nostro codice diventerà:

codice:
PrintStream ps = new PrintStream( new FileOutputStream("//nomeserver/risorsa/pippo.txt") );
ps.println("Scrivo una riga di testo.");
ps.close();
Sperando che questa cosa possa essere utile anche ad altri.


Ciao.