AndrDevEK AndrDevEK - 1 month ago 10
Java Question

How to prevent Java Web Start application caching additional download resources

My JWS application uses a library (also my code) that under the hood retrieves various XML documents from server:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(xmlFileUrl);


The contents at the URLs change from time to time, and application needs to re-fetch the content at start up and later while running.

The problem is that JWS caches the content and returns cached content for subsequent requests.

Telling JWS to remove cached content for the URL does work:

DownloadService ds = (DownloadService)ServiceManager.lookup("javax.jnlp.DownloadService");
ds.removeResource(xmlFileUrl, null);


But the library is used by other front ends, and I want to avoid making the library dependent on javaws.jar. My current solution defines an interface in the library that allows library to request cache clearing. JWS launcher passes an implementation of the interface to the library. There are multiple components that fetch various resources and while I can make it work, the whole thing is clumsy.

Another workaround is to append a unique query for every request, e.g.

url += "?ignored="+System.currentTimeMillis()+Math.random();


but that will pollute JWS cache and I see it as source of confusion, wtf and bloat.

The XML documents are generated on the server. Setting header:

Cache-Control: no-cache'


does not help.

I am interested if there is a cleaner solution to this problem. If I could set some HTTP headers on server that would be ideal. Listing resources not to be cached in .jnlp would be acceptable but not ideal as URLs are constructed in the library and I'd have to significantly change the init code. Other methods and ideas are welcome.

Answer

I'm surprised I did not see void java.net.URLConnection.setUseCaches(boolean usecaches) method before.

This solution works including in JWS. It does not make dependency on javaws.jar which is clean and simple.

URL url = new URL(xmlFileLocation);
URLConnection connection = url.openConnection();
// Prevent JavaWebStart from returning cached copy.
connection.setUseCaches(false);

// Now fetch the content, e.g.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder(); 
Document doc = db.parse(connection.getInputStream());

This is still backward in that the application that consumes the server response decides to not use the cache, rather than the framework(JWS) honoring server side cache control HTTP headers.

Comments