API de mise en cache Java Webstart et URLConnection

La description de l’ API de mise en cache d’URLConnection indique la dernière phrase:

Il n’y a pas d’implémentation par défaut de la mise en cache URLConnection dans Java 2 Standard Edition. Cependant, Java Plugin et Java WebStart en fournissent un immédiatement.

Où puis-je trouver plus d’informations sur Webstart ResponseCache?

  • Quelles versions de Webstart sur quelles plateformes activent la mise en cache?
  • Dans quels cas est-il actif? Seulement HTTP Get?
  • Peut-il être configuré?
  • Le code source est-il disponible?

Contexte:

Cas 1

Avec le code suivant (groovy)

def url = new URL('http://repo1.maven.org/maven2/') def connection = url.openConnection() def result = connection.inputStream.text 

Je m’attendrais à ce que chaque fois que le code est exécuté, le serveur est contacté. Mais quand exécuté en

 Java Web Start 10.9.2.05 JRE-Version verwenden 1.7.0_09-b05 Java HotSpot(TM) Client VM 

le comportement est différent. La première fois que le code est exécuté, le serveur est contacté. Toutes les exécutions ultérieures du code n’impliquent aucune communication avec le serveur (tracé à l’aide de Wireshark).

Mais cela devient encore plus étrange. Après le redémarrage de l’application Webstart, lors de la première exécution du code, l’URL http://repo1.maven.org/maven2/.pack.gz est demandé, ce qui donne un 404 . Seulement que l’URL d’origine est demandée, résultant en un 304 NOT MODIFIED . Toutes les exécutions ultérieures n’impliquent aucune communication avec le serveur.

Je pense que l’approche consistant à améliorer de manière transparente la connexion d’URL avec des capacités de mise en cache est agréable et aide à améliorer les performances des applications clientes. Mais comme le serveur dans ce cas n’a pas défini d’en-tête Expires ni d’en-tête de contrôle du cache, je pense que le code ci-dessus devrait toujours demander au serveur et ne pas ignorer ma demande en silence.

Cas 2

Le code suivant ne fonctionne pas lorsqu’il est exécuté avec Webstart 10.1.1.255 (il a été installé par une version bêta antérieure de java 7, mais je ne sais pas de quelle version il s’agissait)

 URL url = new URL("http://repo1.maven.org/maven2/"); URLConnection connection = url.openConnection(); connection.setRequestProperty("Accept-Encoding", "gzip"); connection.connect(); InputStream is = connection.getInputStream(); if ("gzip".equalsIgnoreCase(connection.getContentEncoding())) { is = new GZIPInputStream(is); } is.close(); 

Avec Java Web Start 10.1.1.255 à partir de la deuxième exécution, j’ai reçu un

 java.io.IOException: Not in GZIP format at java.util.zip.GZIPInputStream.readHeader(Unknown Source) at java.util.zip.GZIPInputStream.(Unknown Source) at java.util.zip.GZIPInputStream.(Unknown Source) 

Avec Java Web Start 1.6.0_24 et maintenant Java Web Start 10.2.1.255 je ne Java Web Start 10.2.1.255 pas à reproduire le problème.

Avec Wireshark, j’ai constaté que dans le cas où j’avais l’erreur, l’en-tête http contenait une entrée If-Modified-Since et le code de retour était donc 304. Dans les autres cas, il n’y avait pas d’If-Modified-Since. Par conséquent, je pense que la mise en cache n’est pas active dans les versions stables de webstart – malgré la dernière phrase du lien ci-dessus.

Il semble que le cache de la version bêta effectue un réglage agressif des requêtes get http: il utilise If-Modified-Since et essaie automatiquement d’utiliser le codage gzip, même si le code client ne définit pas cet en-tête. Mais lorsque le cache est atteint, le stream renvoyé n’est pas gzippé, bien que getContentEncoding renvoie “gzip”.

Comme la mise en cache ne semble pas être active dans la version stable de Webstart sur ma machine, je ne peux plus vérifier si le bogue est dans le code et j’hésite donc à déposer un rapport de bogue.

La seule information que j’ai trouvée jusqu’à présent concerne Java Rich Internet Applications Enhancements de JDK 7.

Mise en cache activée par défaut: La mise en cache du contenu du réseau pour le code d’application exécuté en mode de démarrage Web est maintenant activée par défaut. Cela permet aux applications d’améliorer les performances et la cohérence avec le mode d’exécution des applets. Pour garantir l’utilisation de la dernière copie du contenu, l’application peut utiliser URLConnection.setUseCaches (false) ou l’en-tête de la demande, valeurs Cache-Control no-cache / no-store.

[…]

Améliorations apscopes à la gestion du contenu avec l’encodage gzip: le cache de déploiement conserve le contenu de l’application sous forme compressée et le renvoie tel quel à l’application avec l’encodage du contenu gzip dans l’en-tête HTTP. Cela rend le comportement plus cohérent dans les différents modes d’exécution (premier lancement par rapport au lancement suivant, cache activé par rapport à cache désactivé). Voir 6575586 pour plus de détails.

J’ai modifié votre code. J’espère que ça marche pour toi.

 URL url = new URL("http://repo1.maven.org/maven2/"); URLConnection connection = url.openConnection(); connection.setRequestProperty("Accept-Encoding", "ISO-8859-1"); connection.connect(); InputStream is = connection.getInputStream(); if ("gzip".equalsIgnoreCase(connection.getContentEncoding())) { is = new GZIPInputStream(is); } is.close(); 

Le cache semble être implémenté par com.sun.deploy.cache.DeployCacheHandler , qui réside dans deploy.jar. Je ne trouve la source dans aucun repository officiel; ce lien est une sorte de copie du marché gris.

En un coup d’œil, je ne trouve aucune indication indiquant qu’il est désactivé (ou activé!) Sur une plate-forme particulière. Ce gestionnaire de cache est présent depuis au moins Java 6.

Il ne cache que les demandes GET. Un commentaire dans la méthode isResourceCacheable explique:

  // do not cache resource if: // 1. cache disabled // 2. useCaches is set to false and resource is non jar/zip file // 3. connection is not a GET request // 4. cache-control header is set to no-store // 5. lastModified and expiration not set // 6. resource is a partial body resource 

Je ne vois aucun moyen de configurer directement le cache.