Newsgroup: it.comp.java
Titolo: Tomcat, cache e strano comportamento...

Tutti sappiamo che  il caching delle pagine da parte  di browser e proxy
e`  una gran  rottura in  molte applicazioni  web, per  cui si  cerca di
eliminarlo con "http-equiv:" e/o con response.setHeader(...), ecc.
Con le  JSP il metodo "piu`  giusto" sarebbe il secondo,  che pero` fun-
ziona solo se nel frattempo non  sono stati inviati dati al browser, per
cui  nella nostra  webapp avevamo  incluso (<%@  include  file=....  %>)
all'inizio  di ogni  pagina  un frammento  di  codice con  una serie  di
response.setHeader().
Orbene, non funziona... A quanto pare, per ogni direttiva JSP, tipo "<%@
page  import ...%>",  la corrispondente  pagina HTML  generata  mette un
carattere di "a capo". Dopo un  po' di meditazioni mi e` venuto in mente
che la cosa potrebbe dipendere dal fatto che chi programma usa un editor
sotto Windows (la  webapp gira sia sotto Windows  che Linux, ovviamente,
sia sotto Tomcat 3.2.1 che 4.x;  J2SE/JDK 1.3.1 e 1.4.1) e quindi i file
*.jsp hanno  come carattere di fine  riga la coppia  "CR-LF" anziche' il
solo  "LF"  di UNIX,  e  che il  compilatore  Java,  poi, interpreta  il
carattere in piu` come "template text"  e quindi lo invia in output, col
risultato che response.setHeader() viene ignorato e response.sendError()
va  addirittura in  IllegalStateException... la  cosa  spiegherebbe pure
perche' anche in certe pagine  di "sola elaborazione", con un successivo
<%jsp:forward ... />, questo non funzionasse.
Ho suggerito di  passare tutti i file con il  solito "dos2unix" e vedere
se il  problema si ripresenta,  e al momento  sto aspettando che  mi ri-
chiamino  per  dirmi  se   cambia  qualcosa,  ma  volevo  sentire  anche
l'opinione del newsgroup: ho scoperto l'acqua calda (tipo: "c'e` scritto
nelle specifiche  di Java/JSP & Co.,  capitolo 0, riga 1;  impara a leg-
gere!"), o si tratta di un "bug" di Tomcat e/o di Java ?
Saluti,
Luca Polo.
-- 
 /Luca Polo : 
Luca...@gest.unipd.it
 || Dipartimento di Tecnica e       \
| System & network administrator      || Gestione dei Sistemi Industriali |
 \
http://www.gest.unipd.it/~jake
      || Universita` di Padova -- Italy  /

Ma sei sicuro che il problema sia quello?
IllegalStateException è la tipica eccezione che viene lanciata quando è
possibile che la pagina vada a chiamare più di una response.sendRedirect,
per esempio se c'è una struttura di condizioni if sbagliata, tipo:
if a{
 response.sendRedirect("pagina a")
}
if b{
 response.sendRedirect("pagina b")
}
--------------------------------
Inviato via 
http://usenet.libero.it

 Luca Polo.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 writes:
P> Ma sei sicuro che il problema sia quello?
Non al 100%: l'idea  mi e` venuta ieri sera e poi  non ho piu` sentito i
due che dovevano  verificarla; comunque non siamo nel  caso del forward/
redirect seguito da ulteriore  output: *quel* particolare tipo di errore
ce lo siamo gia` lasciati alle spalle da tempo :-).
Piu` che altro, pero`, mi piacerebbe capire se l'avere dei fine riga con
CR/LF, anziche' solo LF, puo` essere  la causa della presenza di N righe
vuote all'inizio della pagina HTML  generata (e si tratta proprio di una
riga vuota per ogni direttiva JSP: abbiamo fatto una prova aggiungendo e
togliendo  direttive  "inutili" --  tipo  una  "import"  di package  non
usati), che a loro volta, magari, causano le eccezioni o rendono inutile
impostare gli header anti-cache.


 impostare gli header anti-cache.
Gli header "anti-cache" stanno nell'intestazione della risposta HTTP,
ben
prima della pagina HTML, insieme ai vari Content-Type, User-Agent, ecc.
Dubito fortemente che il problema sia un CRLF. Temo molto di piu' che il
problema sia IE che se ne frega altamente...
--
Mattia


 writes:
MD> hai provato a settare un buffer abbastanza grosso in modo che i 
MD> dati vengano effettivamente spediti al client solo ad elaborazione 
MD> terminata?
Non ancora, anche perche'  questo "effetto speciale" causato dalle righe
vuote ci e`  venuto in mente ieri sera... non e`  mai successo a nessuno
di  avere problemi  con  la cache  e/o  di trovarsi  con  N righe  vuote
all'inizio della  pagina HTML generata,  tante quante sono  le direttive
JSP originali ?
Oltretutto non  serve impostare  un buffer piu`  grande, perche'  a quel
punto avremmo comunque gia` avuto dei caratteri mandati in output...
MD> Ho sempre visto l'IllegalStateException proprio in casi in cui veniva 
MD> fatto un forward/redirect quando lo stream verso il client era gia' 
MD> cominciato
Infatti sono state un paio di  eccezioni del genere, dove secondo la lo-
gica  del codice  NON  potevano esserci  (response.setXYZ() subito  all'
inizio; niente  righe vuote  in mezzo al  codice; return subito  dopo un
forward/redirect; ecc.) a farci notare 'sta faccenda delle righe in piu`
uscite dall'iperspazio e poi a collegarla anche alla "questione cache".
			 *** AGGIORNAMENTO ***
Ho sentito i colleghi: a quanto pare  non e` colpa di CR/LF vs LF, ma e`
proprio  il generatore  del  codice  che inserisce  un  certo numero  di
"out.write("\r\n");" prima ancora di cominciare a mandar fuori il codice
HTML  della pagina  JSP, ad  es.  (guardando il  codice nella  directory
"work"):
,--- >8 ----
|  pageContext = _jspxFactory.getPageContext(this, request, 
|      response, "", true, 8192, true);
|  .....
| 
|  out = pageContext.getOut();
| 
|  // HTML // begin [file="/index.jsp";from=(0,27);to=(2,0)]
|  out.write("\r\n\r\n");
|  // end
|  // HTML // begin [file="/index.jsp";from=(2,56);to=(3,0)]
|  out.write("\r\n");
|  // end
|  // HTML // begin [file="/index.jsp";from=(3,31);to=(11,12)]
|  out.write("\r\n\r\n<HTML>\r\n<HEAD>\r\n .......");
`--- 8< ----
Ora, quei "from=(X,Y);to=(A,B)" corrispondono proprio alla posizione dei
caratteri di fine  riga sia di eventuali righe vuote  o commenti, sia di
righe con direttive JSP (ad es. la prima, che altro non e` che la solita
"<%@ page language="java" %>", di esattamente 27 lettere, seguita da una
riga vuota: risultato, "\r\n\r\n" e buonanotte al secchio...).
Workaround per la cache:  l'include con le response.setHeader() e` stato
messo  come *prima*  riga, e  ora la  cache viene  gestita correttamente
(pero`  cosi`  non e`  proprio  sintatticamente  corretto...); resta  il
problema con i <%jsp:forward ... /> & Co., che ovviamente non si possono
mettere in testa, senno` la pagina servirebbe a poco...
Mi dicevano  che in qualche forum  su Java/JSP ne hanno  parlato, e pare
che  il suggerimento  fosse del  tipo "usate  le servlet,  non  le JSP":
grazie mille... torniamo indietro invece di andare avanti ?
Insomma, a me pare proprio un  bug di Tomcat: IMHO qualcuno si e` dimen-
ticato qualche "chop()"  (Perl docet :-)) per strada...  che faccio, ri-
scrivo Tomcat ? Mi faccio dare indietro i soldi ? :-)


 JSP originali ?
si, ma dovrebbe bastare metter tutto sulla stessa riga per evitarlo
es1:
<%@ page import=".."/><%@ page import=".."/><%@ page import=".."/><%
out.print("blabla");
%>
es2:
<%@ page import="pkg1.*,pkg2.*"/><%out.print("blabla");%>
Come ti dicevo nel'altro post comunque gli header non fanno parte della
pagina HTML ma dell'intestazione HTTP, header e content sono separati da
una
riga vuota.
http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-rev-06.txt
es:
Content-Type: text/html; charset=utf-8
Date: Wed, 06 Nov 2002 15:25:55 GMT
Server: Apache Tomcat/4.1.12-LE-jdk14 (HTTP/1.1 Connector)
Connection: close
<HTML>
....
</HTML>
quindi gli spazi di troppo hanno ben poco a che fare con il 
controllo della cache.
Ora se c'e' un Apache davanti al vostro Tomcat, ci sono direttive
che impostano automaticamente gli header Cache-control e Expires,
con Tomcat da solo non so quali impostazioni facciano lo stesso.


 (pero`  cosi`  non e`  proprio  sintatticamente  corretto...);
Non so se puo' servirti, ma qualsiasi cosa sull'header (ad esempio i 
cookie) dovrebbe essere messa all'inizio, da specifica. Se funziona "per 
merito" del buffering, sei comunque a rischio quando passi da un server 
all'altro. Insomma non e' detto che funzioni, piu' che un workaround 
direi che e' un must.
ciao, HTH
uL

 writes:
MD> si, ma dovrebbe bastare metter tutto sulla stessa riga per evitarlo
Eh,  ma non  sara` mica  bello cosi`,  dai... :-)  IMHO  Tomcat dovrebbe
ignorare i newline  se questi sono gli unici  caratteri compresi tra due
tag JSP: non e` tanto difficile da implementare.
MD> Come ti dicevo nel'altro post comunque gli header non fanno parte
MD> della pagina HTML ma dell'intestazione HTTP, header e content sono
MD> separati da una riga vuota.
Si`, questo  lo so  (anche perche'  e` lo stesso  sistema usato  da anni
anche per  SMTP & Co.). Il problema  e` che quando Tomcat  inizia con le
out.write(), a  quel punto  considera terminati gli  header e non  ci si
puo` piu`  far nulla (o poco:  i tag META con  Http-Equiv funzionano una
volta  si`  e  tre  no...).  Vabbe', adesso  sappiamo  che  c'e`  questa
idiosincrasia (la Terza  Via tra "bug" e "feature"  :-)) e ci regoleremo
di conseguenza, anche se cio` ferisce il mio animo estetico :-).
