Vaadin Resource objects lock files

Hi everybody,

It has been almost 4 days I am stuck with this issue.
I am adding an image file to my CssLayout this way :

addComponent(new Embedded(null, new FileResource(imageFile, app)));

and it works very well.
The problem is that after that, I cannot delete this
imageFile
file because it is used by this Resource object.

imageFile.delete();
// => returns false

I tried to use a StreamResource object, but I got stuck as well.

Any idea ?

For now, I have found a little workaround, which is to copy the image File to a
class
directory, in order to get it using the ClassResource object.
The ClassResource object seems not to lock the file.

Anyway, isn’t that a
bug
?

I mean, if the Resource object goes to the Garbage Collector, the File should be unlocked, right ?

Bug or a feature, that is always the question. In this case I’d guess the file locking is not intentional. Also I would guess the locking happens only on windows. I checked the code and it appears that the API has directed the code to create the (File)InputStream eagerly. In some cases the stream might not be used and left open.

You could try this kind of class instead of the default FileResource:


package com.example.lazyfileresource;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import com.vaadin.Application;
import com.vaadin.terminal.DownloadStream;
import com.vaadin.terminal.FileResource;

public class LazyFileResource extends FileResource {

	public LazyFileResource(File sourceFile, Application application) {
		super(sourceFile, application);
	}

	@Override
	public DownloadStream getStream() {
		new DownloadStream(null, getMIMEType(), getFilename()) {
			@Override
			public InputStream getStream() {
				try {
					return new FileInputStream(getSourceFile());
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					throw new RuntimeException(e);
				}
			}
		};
		return super.getStream();
	}

}

Report me if it works well. I you also provide a test case I can consider making that the default in the Vaadin core.

cheers,
matti

Hi Matti,

Thank you for your answer.
I’ve just tried out your code, but my file still gets locked.

Here is a very simple test :


Embedded embedded = new Embedded(null, new FileResource(imageFile, app));
addComponent(embedded);
removeComponent(embedded);
imageFile.delete(); // returns false

The weird part of this thing is that even if I try to close the stream, the file remains locked.

Hi,

Where are your files located? Maybe your app server locks those files.

cheers,
matti

Hi,

Thank you for your interest.
My files are located inside my portlet repository. They aren’t locked until I add them as components in my application. Then if I want to unlock them I have two solutions :

  • either I re-deploy my portlet
  • either I restart my Tomcat server

Did you get some more informations about that behaviour ?

I found out where this issue come from.
Actually I was using the
renameTo
method from my
File
object which locked my image File.

To conclude, the Vaadin FileResource object does not lock files, despite my first thoughts.

EDIT : This morning I found out that the FileResource is actually locking my file. I don’t know why but the FileUtil.copyFile(File source, File destination) method from the Liferay framework does work. But still I cannot remove those. :frowning: