You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Joerg Schaible (JIRA)" <ji...@apache.org> on 2007/08/09 17:07:42 UTC
[jira] Created: (VFS-172) Cache of SFTP after move completely out
of sync.
Cache of SFTP after move completely out of sync.
------------------------------------------------
Key: VFS-172
URL: https://issues.apache.org/jira/browse/VFS-172
Project: Commons VFS
Issue Type: Bug
Affects Versions: 1.0
Reporter: Joerg Schaible
Priority: Critical
Simple test method. See all the bogus cases at the end:
{code:java}
public void testObjectsAfterMoveOfParentDoNotExistWithSFTP() throws IOException
{
final FileSystemOptions fsOptions = new FileSystemOptions();
final FileSystemManager fsManager = VFS.getManager();
final FileObject root = fsManager.resolveFile(SFTP_BASE_URL + "junit", fsOptions);
if (!root.exists()) {
root.createFolder();
}
assertTrue(root.exists());
final FileObject target = root.resolveFile("target");
if (!target.exists()) {
target.createFolder();
}
assertTrue(target.exists());
final FileObject work = root.resolveFile("work");
if (!work.exists()) {
work.createFolder();
}
assertTrue(work.exists());
FileObject inWork = work.resolveFile("inWork");
if (!inWork.exists()) {
inWork.createFolder();
}
assertTrue(inWork.exists());
final FileObject ready = target.resolveFile("ready-" + System.currentTimeMillis());
assertFalse(ready.exists());
work.moveTo(ready);
assertTrue(ready.exists());
assertFalse(work.exists());
try {
assertFalse(inWork.exists());
fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
} catch (final AssertionFailedError e) {
// <sigh>
}
try {
inWork.refresh();
assertFalse(inWork.exists());
fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
} catch (final AssertionFailedError e) {
// <sigh>
}
try {
assertFalse(work.resolveFile("inWork").exists());
fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
} catch (final AssertionFailedError e) {
// <sigh>
}
try {
work.refresh();
assertFalse(work.resolveFile("inWork").exists());
fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
} catch (final AssertionFailedError e) {
// <sigh>
}
// it even possible to write into a file of the non-existing folder ...
FileObject file = inWork.resolveFile("test.txt");
OutputStream out = file.getContent().getOutputStream();
out.write("Foo".getBytes());
try {
out.close();
} catch(IOException e) {
// ignore this
}
assertTrue(file.exists());
// force update of references
file = null;
out = null;
inWork = null;
System.gc();
System.gc();
// ... aaaaahhhh ... something changed
assertFalse(work.resolveFile("inWork").exists());
}
{code}
There's not a single possibility to tell VFS that the FileObject is bogus and even worse, you can write into non-existing files of a non-existing folder without getting an Exception ...
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
[jira] Updated: (VFS-172) Cache of SFTP after move completely out
of sync.
Posted by "Joerg Schaible (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/VFS-172?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Joerg Schaible updated VFS-172:
-------------------------------
Attachment: VFS-172.diff
After some debugging I realized that the SftFileObject will never refresh itself. Main cause is that - even if it is detached - it keeps it's attribs. Unfortunately the implementation assumes that it is a real file as long as the attribs are available. My patch resets now the attribs in doDispatch. This solves the problem in the following test case (the caching strategy forces a refresh calling resolveFile):
{code:java}
public void testObjectsAfterMoveOfParentDoNotExistWithSFTP() throws IOException
{
final FileSystemOptions fsOptions = new FileSystemOptions();
StandardFileSystemManager fsManager = new StandardFileSystemManager();
fsManager.init();
FileObject root = fsManager.resolveFile(SFTP_BASE_URL + "junit", fsOptions);
if (!root.exists()) {
root.createFolder();
}
assertTrue(root.exists());
final FileObject target = root.resolveFile("target");
if (!target.exists()) {
target.createFolder();
}
assertTrue(target.exists());
FileObject work = root.resolveFile("work");
if (!work.exists()) {
work.createFolder();
}
assertTrue(work.exists());
FileObject inWork = work.resolveFile("inWork");
if (!inWork.exists()) {
inWork.createFolder();
}
assertTrue(inWork.exists());
final FileObject ready = target.resolveFile("ready-" + System.currentTimeMillis());
assertFalse(ready.exists());
work.moveTo(ready);
assertTrue(ready.exists());
assertFalse(work.exists());
// resolve forces internal refresh
assertFalse(work.resolveFile("inWork").exists());
assertFalse(inWork.exists());
}
{code}
However, I was not able to run any of the unit tests, they are not found with M2. So I have no idea if the patch has side effects.
> Cache of SFTP after move completely out of sync.
> ------------------------------------------------
>
> Key: VFS-172
> URL: https://issues.apache.org/jira/browse/VFS-172
> Project: Commons VFS
> Issue Type: Bug
> Affects Versions: 1.0
> Reporter: Joerg Schaible
> Priority: Critical
> Attachments: VFS-172.diff
>
>
> Simple test method. See all the bogus cases at the end:
> {code:java}
> public void testObjectsAfterMoveOfParentDoNotExistWithSFTP() throws IOException
> {
> final FileSystemOptions fsOptions = new FileSystemOptions();
> final FileSystemManager fsManager = VFS.getManager();
> final FileObject root = fsManager.resolveFile(SFTP_BASE_URL + "junit", fsOptions);
> if (!root.exists()) {
> root.createFolder();
> }
> assertTrue(root.exists());
> final FileObject target = root.resolveFile("target");
> if (!target.exists()) {
> target.createFolder();
> }
> assertTrue(target.exists());
> final FileObject work = root.resolveFile("work");
> if (!work.exists()) {
> work.createFolder();
> }
> assertTrue(work.exists());
> FileObject inWork = work.resolveFile("inWork");
> if (!inWork.exists()) {
> inWork.createFolder();
> }
> assertTrue(inWork.exists());
> final FileObject ready = target.resolveFile("ready-" + System.currentTimeMillis());
> assertFalse(ready.exists());
> work.moveTo(ready);
> assertTrue(ready.exists());
> assertFalse(work.exists());
> try {
> assertFalse(inWork.exists());
> fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
> } catch (final AssertionFailedError e) {
> // <sigh>
> }
> try {
> inWork.refresh();
> assertFalse(inWork.exists());
> fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
> } catch (final AssertionFailedError e) {
> // <sigh>
> }
> try {
> assertFalse(work.resolveFile("inWork").exists());
> fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
> } catch (final AssertionFailedError e) {
> // <sigh>
> }
> try {
> work.refresh();
> assertFalse(work.resolveFile("inWork").exists());
> fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
> } catch (final AssertionFailedError e) {
> // <sigh>
> }
>
> // it even possible to write into a file of the non-existing folder ...
> FileObject file = inWork.resolveFile("test.txt");
> OutputStream out = file.getContent().getOutputStream();
> out.write("Foo".getBytes());
> try {
> out.close();
> } catch(IOException e) {
> // ignore this
> }
> assertTrue(file.exists());
> // force update of references
> file = null;
> out = null;
> inWork = null;
> System.gc();
> System.gc();
> // ... aaaaahhhh ... something changed
> assertFalse(work.resolveFile("inWork").exists());
> }
> {code}
> There's not a single possibility to tell VFS that the FileObject is bogus and even worse, you can write into non-existing files of a non-existing folder without getting an Exception ...
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
[jira] Resolved: (VFS-172) Cache of SFTP after move completely out
of sync.
Posted by "Mario Ivankovits (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/VFS-172?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Mario Ivankovits resolved VFS-172.
----------------------------------
Resolution: Fixed
Fix Version/s: 1.1
Assignee: Mario Ivankovits
Applied - Thanks for the patch!
Also implemented the refresh() method now to make the CachePolicy work with sftp too.
Test case still works, so it looks good to me.
> Cache of SFTP after move completely out of sync.
> ------------------------------------------------
>
> Key: VFS-172
> URL: https://issues.apache.org/jira/browse/VFS-172
> Project: Commons VFS
> Issue Type: Bug
> Affects Versions: 1.0
> Reporter: Joerg Schaible
> Assignee: Mario Ivankovits
> Priority: Critical
> Fix For: 1.1
>
> Attachments: VFS-172.diff
>
>
> Simple test method. See all the bogus cases at the end:
> {code:java}
> public void testObjectsAfterMoveOfParentDoNotExistWithSFTP() throws IOException
> {
> final FileSystemOptions fsOptions = new FileSystemOptions();
> final FileSystemManager fsManager = VFS.getManager();
> final FileObject root = fsManager.resolveFile(SFTP_BASE_URL + "junit", fsOptions);
> if (!root.exists()) {
> root.createFolder();
> }
> assertTrue(root.exists());
> final FileObject target = root.resolveFile("target");
> if (!target.exists()) {
> target.createFolder();
> }
> assertTrue(target.exists());
> final FileObject work = root.resolveFile("work");
> if (!work.exists()) {
> work.createFolder();
> }
> assertTrue(work.exists());
> FileObject inWork = work.resolveFile("inWork");
> if (!inWork.exists()) {
> inWork.createFolder();
> }
> assertTrue(inWork.exists());
> final FileObject ready = target.resolveFile("ready-" + System.currentTimeMillis());
> assertFalse(ready.exists());
> work.moveTo(ready);
> assertTrue(ready.exists());
> assertFalse(work.exists());
> try {
> assertFalse(inWork.exists());
> fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
> } catch (final AssertionFailedError e) {
> // <sigh>
> }
> try {
> inWork.refresh();
> assertFalse(inWork.exists());
> fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
> } catch (final AssertionFailedError e) {
> // <sigh>
> }
> try {
> assertFalse(work.resolveFile("inWork").exists());
> fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
> } catch (final AssertionFailedError e) {
> // <sigh>
> }
> try {
> work.refresh();
> assertFalse(work.resolveFile("inWork").exists());
> fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
> } catch (final AssertionFailedError e) {
> // <sigh>
> }
>
> // it even possible to write into a file of the non-existing folder ...
> FileObject file = inWork.resolveFile("test.txt");
> OutputStream out = file.getContent().getOutputStream();
> out.write("Foo".getBytes());
> try {
> out.close();
> } catch(IOException e) {
> // ignore this
> }
> assertTrue(file.exists());
> // force update of references
> file = null;
> out = null;
> inWork = null;
> System.gc();
> System.gc();
> // ... aaaaahhhh ... something changed
> assertFalse(work.resolveFile("inWork").exists());
> }
> {code}
> There's not a single possibility to tell VFS that the FileObject is bogus and even worse, you can write into non-existing files of a non-existing folder without getting an Exception ...
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
[jira] Commented: (VFS-172) Cache of SFTP after move completely out
of sync.
Posted by "Joerg Schaible (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/VFS-172?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12518921 ]
Joerg Schaible commented on VFS-172:
------------------------------------
It seems that the main problem is not the VFS code itself, but the usage of the jCraft library. Even after the following sequence the assert fails:
{code:java}
work.moveTo(ready);
assertTrue(ready.exists());
assertFalse(work.exists());
fsManager.close();
fsManager = new StandardFileSystemManager();
fsManager.init();
root = fsManager.resolveFile(SFTP_BASE_URL + "junit", fsOptions);
work = root.resolveFile("work");
assertFalse(work.resolveFile("inWork").exists());
{code}
I tried this with com.jcraft:jsch-0.1.23 and the current version com.jcraft:jsch-0.1.31. It seems that jsch keeps also a cache that is not reseted.
> Cache of SFTP after move completely out of sync.
> ------------------------------------------------
>
> Key: VFS-172
> URL: https://issues.apache.org/jira/browse/VFS-172
> Project: Commons VFS
> Issue Type: Bug
> Affects Versions: 1.0
> Reporter: Joerg Schaible
> Priority: Critical
>
> Simple test method. See all the bogus cases at the end:
> {code:java}
> public void testObjectsAfterMoveOfParentDoNotExistWithSFTP() throws IOException
> {
> final FileSystemOptions fsOptions = new FileSystemOptions();
> final FileSystemManager fsManager = VFS.getManager();
> final FileObject root = fsManager.resolveFile(SFTP_BASE_URL + "junit", fsOptions);
> if (!root.exists()) {
> root.createFolder();
> }
> assertTrue(root.exists());
> final FileObject target = root.resolveFile("target");
> if (!target.exists()) {
> target.createFolder();
> }
> assertTrue(target.exists());
> final FileObject work = root.resolveFile("work");
> if (!work.exists()) {
> work.createFolder();
> }
> assertTrue(work.exists());
> FileObject inWork = work.resolveFile("inWork");
> if (!inWork.exists()) {
> inWork.createFolder();
> }
> assertTrue(inWork.exists());
> final FileObject ready = target.resolveFile("ready-" + System.currentTimeMillis());
> assertFalse(ready.exists());
> work.moveTo(ready);
> assertTrue(ready.exists());
> assertFalse(work.exists());
> try {
> assertFalse(inWork.exists());
> fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
> } catch (final AssertionFailedError e) {
> // <sigh>
> }
> try {
> inWork.refresh();
> assertFalse(inWork.exists());
> fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
> } catch (final AssertionFailedError e) {
> // <sigh>
> }
> try {
> assertFalse(work.resolveFile("inWork").exists());
> fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
> } catch (final AssertionFailedError e) {
> // <sigh>
> }
> try {
> work.refresh();
> assertFalse(work.resolveFile("inWork").exists());
> fail("Thrown " + AssertionFailedError.class.getName() + " expected, because of buggy implementation");
> } catch (final AssertionFailedError e) {
> // <sigh>
> }
>
> // it even possible to write into a file of the non-existing folder ...
> FileObject file = inWork.resolveFile("test.txt");
> OutputStream out = file.getContent().getOutputStream();
> out.write("Foo".getBytes());
> try {
> out.close();
> } catch(IOException e) {
> // ignore this
> }
> assertTrue(file.exists());
> // force update of references
> file = null;
> out = null;
> inWork = null;
> System.gc();
> System.gc();
> // ... aaaaahhhh ... something changed
> assertFalse(work.resolveFile("inWork").exists());
> }
> {code}
> There's not a single possibility to tell VFS that the FileObject is bogus and even worse, you can write into non-existing files of a non-existing folder without getting an Exception ...
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.