Cache problem with Image

Hi,

I have an applet that load an image from our server. The loading is fine, the user can see the image and navigate away from this page. After this, another user modify the image. If the first user re-open the applet (without closing the browser / JRE) the image is still the first one.

The user need to close the browser to be able to see the new image. The first image is in the Java cache. I could disable it, but I could do this for all users. So my question is, how can I force the applet to fetch the imag each time instead of taking it from the JRE cache?

I tried to load the image with Toolkit getImage and I read somwhere that I should use Toolkit createImage to avoid the cache. That didn't work, so I read somwhere else that I should use ImageIO. What I did without any success. I even tried to make the read process by myself with an InputStream reading it byte by byte... Nothing to do!!

I'm not able to find any informations... if somebody could give me a hint!!!?

Thx a lot

[1030 byte] By [bumperta] at [2007-11-27 4:20:13]
# 1
Have you looked into the possibility that the SERVER is caching the image?
xiarcela at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 2

No matter what, the client will have to get it from the server. Depending on the purpose of the application, the method would differ. A few ideas:

- Have the page auto-refresh after a specific time interval (not the best solution)

- If the server knows when an image is modified, and you know which users have access, have accessed, still accessing that same image, the next time they refresh the page, you can post a little hint on the page signaling the image has been updated and they should refresh. Your server would simply check the timestamp on the file vs. the timestamp the other users who have accessed it.

- If it's a java applet, you can have it check with the server if it has been modified, and if it has, refresh the page. You would just have to issue a call to the servlet to do this check for you.

Not caching the image with java is a good idea.

Sometimes you will have no control over this. If a user hits the back button, then forward, and they have caching enabled in their browser, it is unavoidable unless they request it again.

kdajania at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 3
> Have you looked into the possibility that the SERVER is caching the image?Then why would closing and restarting the browser fix the problem? I'm confused.
Hippolytea at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 4
> > Have you looked into the possibility that the> SERVER is caching the image?> > Then why would closing and restarting the browser fix> the problem? I'm confused.point. probably should have read a little closer.
xiarcela at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 5
I would check to make sure that you aren't caching an older version of the applet!Suggestion: get your code running correctly as a stand-alone application, then appletize it.
Hippolytea at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 6

xiarcel: If a take the link of the image that the applet has loaded and past it in the browser, the image is up to date.

kdajani:

>Have the page auto-refresh after a specific time interval (not the best solution)

Even if I refresh the webpage, the image is still the cached one in the applet. I really need to close the JRE (browser) and I suppose that this only work because I put only the minimum cache size (1m) so something else overwrite it and the applet need to fetch it. I'll test it with the default cache size.

>If the server knows when an image is modified, and you know which users have access, have accessed, still accessing that same image, the next time they refresh the page, you can post a little hint on the page signaling the image has been updated and they should refresh. Your server would simply check the timestamp on the file vs. the timestamp the other users who have accessed it.

Like I said for your first suggestion, only refreshing the webpage didn't work. The image displayed in the applet is still the same and I really need to display it in an applet not on the webpage in html.

>If it's a java applet, you can have it check with the server if it has been modified, and if it has, refresh the page. You would just have to issue a call to the servlet to do this check for you.

It defenetly an applet, but like you already read, refreshing the page isn't working :)

Hippolyte:

>I would check to make sure that you aren't caching an older version of the applet!

Not so bad, maybe my applet was in the cache and that should work with one of the method I tried. I'll tried it by delete the cache each time and give you feedback.

thx a lot to all

bumperta at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 7

I made this test that didn't work:

ByteArrayOutputStream baos = new ByteArrayOutputStream();

URLConnection conn = url.openConnection();

InputStream inputStream = conn.getInputStream();

byte[] nextByte = new byte[1];

while((inputStream.read(nextByte, 0, 1)) != (-1)) {

baos.write(nextByte[0]);

}

inputStream.close();

Image ball = Toolkit.getDefaultToolkit().createImage(baos.toByteArray(), 0, baos.size());

bumperta at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 8

> >If it's a java applet, you can have it check with

> the server if it has been modified, and if it has,

> refresh the page. You would just have to issue a call

> to the servlet to do this check for you.

>

> It defenetly an applet, but like you already read,

> refreshing the page isn't working :)

Well, why can't the applet retrieve it again from the server? This is a shared resource problem. If you have multiple users accessing and modifying the same resource, your right, a page refresh won't work because the applet doesn't have the new data. You have to get the new data from the server.

kdajania at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 9

I'm not sure I understand. Each time the applet is loading, a function fetch the image.

It's not many users that share the image in the same time. Example:

I open the applet and see the image with letter A print on it. After this, I go read some news on google. In the time i'm reading news, another person, download the image, modify it in Photoshop and upload it but with the letter B on it. After this, I type again the URL for the applet to see the image again, but instead of seeing B, i'm seeing A... Sorry for my english, is it more clear?

By the way, I tried another time with

Image ball = ImageIO.read(url);

without any succes.

Thx for your help

bumperta at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 10
if you go to another link, does your applet time out and terminate?I think that would work. If your applet terminates upon viewing another site, if you go back to it again, it would have to come back with all the new information. Unless the image is being cached on your machine.
kdajania at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 11

Try aiming this at your image:

import java.awt.event.*;

import java.io.*;

import java.net.*;

import javax.imageio.*;

import javax.swing.*;

public class ImagePanel extends JPanel {

private static final long serialVersionUID = 0;

private URL url;

private JLabel label;

private ActionListener al = new ActionListener() {

public void actionPerformed(ActionEvent evt) {

reloadImage();

}

};

public ImagePanel(URL url) {

this.url = url;

label = new JLabel();

add(label);

setBorder(BorderFactory.createTitledBorder(""));

reloadImage();

new Timer(1000, al).start();

}

public void reloadImage() {

try {

label.setIcon(new ImageIcon(ImageIO.read(url)));

setBorder(BorderFactory.createTitledBorder(new java.util.Date().toString()));

} catch (IOException e) {

e.printStackTrace();

}

}

//testing main

public static void main(String[] args) throws MalformedURLException {

URL url = new URL("http://blogs.sun.com/jag/resource/JagHeadshot-small.jpg");

ImagePanel panel = new ImagePanel(url);

JFrame f = new JFrame();

f.getContentPane().add(panel);

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.pack();

f.setLocationRelativeTo(null);

f.setVisible(true);

}

}

If you run it as a standalone app, do you see the image refreshing?

If you add an instance of ImagePanel to your applet, what then?

The timer driving image reloading was just for convenience. You could

comment out the timer and explicitly reload by calling reloadImage when needed.

Hippolytea at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 12

If I open a new webpage after loading the applet, the stop and destroy function is called, so the applet terminate. When I open the link, the aplet start again (init and start) and the function that load the image is called again.

But I think that the image is cached into the JRE cache, so it look here before fetchihg it from the web and it's all my problem :0

Thx a lot

bumperta at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 13

hippolyte:

The test isn't good for me, thet test would be good if the image

http://blogs.sun.com/jag/resource/JagHeadshot-small.jpg

was changing each time i refresh it, but it's always the same image.

A simple solution, I guess, would be to name the image differently each time, so Java should be obligate to load it each time... but the problem is because sometimes I need to keep the same image name even after modificiation.

bumperta at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 14

> hippolyte:

>

> The test isn't good for me, thet test would be good

> if the image

> http://blogs.sun.com/jag/resource/JagHeadshot-small.jpg

> was changing each time i refresh it, but it's always

> the same image.

I admit that image doesn't change, but I can't think of the URL for a changing

image. Can you ? ;-) I invite you to change the URL to *your* image.

> A simple solution, I guess, would be to name the

> image differently each time, so Java should be

> obligate to load it each time... but the problem is

> because sometimes I need to keep the same image name

> even after modificiation.

Another problem with that approach is figuring out the current name!

Hippolytea at 2007-7-12 9:27:12 > top of Java-index,Java Essentials,Java Programming...
# 15

> But I think that the image is cached into the JRE cache

You THINK. But it will be easier to solve the problem if you know what it is. So when you change the image in the server, try to load the new version of the image into your browser directly, not into the applet. Put its URL into the browser's address bar. If the applet and the browser behave differently then you know it is the JRE cache.

DrClapa at 2007-7-21 21:04:52 > top of Java-index,Java Essentials,Java Programming...
# 16
I already made the test, you can see it in this thread. It's a JRE cache problem... the image is ok into the browser!
bumperta at 2007-7-21 21:04:52 > top of Java-index,Java Essentials,Java Programming...
# 17

Hippolyte: I tested your application with my image and it didn't work with an applet. But i tested it in Eclipse in application and it work.

I dont know what to think... is the code acting differently with an applet?

Humm, I'm trying to investigate a bit more. If you have any new idea, please let me know.

Thx a lot for your help

bumperta at 2007-7-21 21:04:52 > top of Java-index,Java Essentials,Java Programming...
# 18

This may be worth a try, just to see if it works.

I assume you are running Windows: go to Control Panel, and open Java.

On the General tab, the area at the bottom is labeled "Temporary Internet Files".

If you view... resources, do you see the URL of your image in the listing?

If you press the settings... button instead, you can uncheck "keep temporary files

on my computer", and also press "delete files...:" Then give your applet another

chance.

I don't touch applets, so I don't know if this will fix things.

Hippolytea at 2007-7-21 21:04:52 > top of Java-index,Java Essentials,Java Programming...
# 19
Yes it's exactly the problem. The image is in the cache viewer and it's good if I clear it. My problem is that I can do it by myself, but I can't ask all our users to do the sames things... I really need to find a solution to force the image loading instead of taking it from the cache.
bumperta at 2007-7-21 21:04:52 > top of Java-index,Java Essentials,Java Programming...
# 20

What doesn't make sense to me is that you said that you tried converting the image to a byte array and sending it to the applet and THAT still gave you the old image?

Sending a byte array would have NOTHING to do with the JRE cache so I am still convinced that your problem lies with your server image, or your server side code sending you the older image.

maple_shafta at 2007-7-21 21:04:52 > top of Java-index,Java Essentials,Java Programming...
# 21

No matter the way I read the image from the server, it's still try to acces img.jpg so the JRE know that you want to access this image and check in his cache. It's the normal process no?

My image and our Apache server send it well, cause if I past the link of the image directly in the browser, the image is the new one.

bumperta at 2007-7-21 21:04:52 > top of Java-index,Java Essentials,Java Programming...
# 22
Why check for this img.jpg file?If you can break the image down to a byte array, send it to the client (applet) and then build the Image within the applet.You don't even need the file to view the image in the applet. This is the only way I can imagine to avoid caching.
maple_shafta at 2007-7-21 21:04:52 > top of Java-index,Java Essentials,Java Programming...
# 23

> I already made the test, you can see it in this

> thread. It's a JRE cache problem... the image is ok

> into the browser!

Well, I couldn't see it in this thread. I still can't, after reading it again. But okay, you did the test. The way to make URLs avoid caching is to attach a parameter to them with a random value. Like this:http://yourhost/image.jpg?param=104378888000

And the usual strategy is to use System.currentTimeMillis(), after looking up the correct spelling of that method which I didn't do, as the value of the parameter.

DrClapa at 2007-7-21 21:04:52 > top of Java-index,Java Essentials,Java Programming...
# 24
> http://yourhost/image.jpg?param=104378888000How cheeky! Another option is not to use an applet ;-)
Hippolytea at 2007-7-21 21:04:52 > top of Java-index,Java Essentials,Java Programming...
# 25

Even with the parameter after the image name, the JRE still get it as the same image and I still continue to have this problem.

So what I did, I generate the image with a random name each time. I needed to keep the same image name for a design restriction (that I cannot change cause isn't not me that requiert this), but I don't have time anymore to put on this problem. So I rename it after loading it... very bad I know, but it solve my problem now!!!!

Thx a lot to all people that helped me. Could be good when I have some spare time to tried to solve this problem in another way :)

bumperta at 2007-7-21 21:04:52 > top of Java-index,Java Essentials,Java Programming...