7

It seems like java is holding some kind of a cache to URL (& files). e.g. I have a file "resourcs.txt" in a jar file in my classpath. The content of this file is: "Version 1"

new java.io.BufferedReader (new java.io.InputStreamReader( new URL("jar", "", "file:test.jar!/resourcs.txt").openConnection().getInputStream())).readLine()

returns "Version 1" (as expected)

I change the file content to be "Version 2" and call again to this code. And I still get "Version 1"

How can I clear this "cache".

Notice: I found out it only happens on Linux.

Guy Korland
  • 9,139
  • 14
  • 59
  • 106

5 Answers5

8

Because of the jar protocol used in your URL, the connection is an instance of sun.net.www.protocol.jar.JarURLConnection which takes benefit from a cache implemented in sun.net.www.protocol.jar.JarFileFactory

Source code confirms a setUseCache(false) on URLConnection implementation will prevent the use of that cache.

My hypothesis about the Linux/Windows behavior difference: the close event notification from URLJarFileCloseController interface is triggered faster on Windows because it does not appreciate to keep file handles opened for a too long period...

Yves Martin
  • 10,217
  • 2
  • 38
  • 77
5

Actually, the simple answer is really close to the answer given by sbridges, but you can't instantiate URLConnection using "new URLConnection(...)", because it's a abstract class.

You can just do this way:

    URL url = new URL(urlSrt);
    URLConnection con = url.openConnection();
    con.setUseCaches(false);
Isaac Leal
  • 121
  • 2
  • 2
  • Great, thank you. I think the resource caching in java is a dangerous feature not everyone knows about. I tried to refresh webcam images from a url but always got the same image. – Stephan Jul 09 '15 at 06:59
  • I'm trying this, thought it would work but without success. I'm baffled. In my case, it's not a JAR url and it is also using `BufferedReader`. – tresf Oct 30 '18 at 03:21
3

You can turn off caching for a url connection using,

  URLConnection con = new URLConnection(new URL("jar", "", "file:test.jar!/resourcs.txt"));
  con.setUseCaches(false);
  new BufferedReader (new InputStreamReader(con.getInputStream())).readLine();
sbridges
  • 24,960
  • 4
  • 64
  • 71
1

I think this is some kind of class-loading problem, because it is the jar-protocoll.

Try to open your jar as a zip-file instead.

ZipFile zf = new ZipFile(file);
try {
  InputStream in = zf.getInputStream("resourcs.txt");
  // ... read from 'in' as normal
} finally {
  zf.close();
}
Christian Kuetbach
  • 15,850
  • 5
  • 43
  • 79
0

If you are using some third party code this should work:

url.openConnection().setDefaultUseCaches(false);
Mateusz Kaflowski
  • 2,221
  • 1
  • 29
  • 35