This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
Hi! This is a very strange bug and IMHO with a very big spread all over the NetBeans platform configurations. If you read an attribute twice you get first a changed attribute. With the second read you get the standard attribute value from the layer file. This issue kills many scenarios to use the SystemFileSystem with MultifileSystem as a changeable registry. More, the problem appears only randomly (if the developer needs to read the attribute twice and the user have changed the attribute). Here an example. A sample entry in the layer.xml: <filesystem> <folder name ="org-sepix"> <folder name= "Panes"> <file name="Demo.txt"> <attr name="position" intvalue="100"/> </file> </folder> </folder> </filesystem> and a minimized example class: public class Demo { public static void demo () { FileObject folder = FileUtil.getConfigFile("org-sepix/Panes/"); for (FileObject fileObject : folder.getChildren()) { try { System.out.println(fileObject.getNameExt()); System.out.println("position = " + fileObject.getAttribute("position") + " should 100"); fileObject.setAttribute("position", new Integer (200)); System.out.println("position = " + fileObject.getAttribute("position") + " should 200"); // Here the problem: System.out.println("position = " + fileObject.getAttribute("position") + " should 200"); } catch (IOException ex) { Exceptions.printStackTrace(ex); } } } } And this is the output: Demo.txt position = 100 should 100 position = 200 should 200 position = 100 should 200 The last line is the wrong output. This is reproducible with all attributes. It's hard to debug, the debugger also changes the value. IMHO it's a special coded block to optimize reads for attributes in the MultiFileObject class: private final Object getAttribute(String attrName, String path) { // Look for attribute in any file system starting at the front. // Additionally, look for attribute in root folder, where // the relative path from the folder to the target file is // prepended to the attribute name, all separated with slashes. // This search scheme permits writable front systems to set file // attributes on deeply buried files in back systems without // actually creating copies of the files or even their parent folders. // [PENDING] consider the effects of mask files String prefixattr = ((path.length() == 0) ? null : (path.replace('/', '\\') + '\\' + attrName)); { /*There was proved that this block enhances performance*/ Object oPerf; FileObject localFo = getAttributeCache().getDelegate(); String cachedAttrName = getAttributeCache().getAttributeName(); if ((localFo != null) && !localFo.equals(this) && cachedAttrName.equals(attrName)) { if (localFo.isRoot() && (prefixattr != null)) { try { FileSystem foFs = localFo.getFileSystem(); if (!foFs.isReadOnly() || getMultiFileSystem().canHaveRootAttributeOnReadOnlyFS(prefixattr)) { localFo = foFs.getRoot(); oPerf = getAttribute(localFo, prefixattr, ""); // NOI18N if (oPerf != null) { return devoidify(oPerf); } } } catch (FileStateInvalidException fiex) { //then continue } } /** There is no chance to cache localFo.getPath(), because every * rename up to it in hierarchy makes this cache invalid. */ oPerf = getAttribute(localFo, attrName, localFo.getPath()); if (oPerf != null) { return devoidify(oPerf); } } } The line (792) String cachedAttrName = getAttributeCache().getAttributeName(); returns a valid (pre-read) name ("position") and the first if-statement is true. The line (814): oPerf = getAttribute(localFo, attrName, localFo.getPath()); returns the wrong value (the default from the layer.xml, not the changed attribute value) From my feeling it's an P1 in case of the unexpected runtime results. As developer I've found two workarounds: Read a different attribute before or cast the FileObject to FileChangeListener and call fileRenamed (null) to delete the internal cache via updateAll/mfo.freeAttribCache(); but this is only a well known implementation hack and doesn't have an effect to the existing code in the platform. best regards, josh.
Same source code in NB 7.0rc1. Is it possible to fix it before 7 goes final?
Unit test is better than demo application.
(In reply to comment #2) > Unit test is better than demo application. Sorry, I will make this the next time.
Created attachment 107480 [details] Tests that try, but fail to simulate the problem
Hi! Cool, in the Dev-Builds the test works. But with 6.9.1 (I've downloaded the release691_fixes_base) the test fails with an assertion error. Testcase: testMultiFileSystemWithOverridenAttributes(org.openide.filesystems.XMLFileSystemTestHid): FAILED should be 200 still expected:<200> but was:<100> junit.framework.AssertionFailedError: should be 200 still expected:<200> but was:<100> at org.openide.filesystems.XMLFileSystemTestHid.testMultiFileSystemWithOverridenAttributes(XMLFileSystemTestHid.java:357) at org.netbeans.junit.NbTestCase.access$200(NbTestCase.java:95) at org.netbeans.junit.NbTestCase$2.doSomething(NbTestCase.java:365) at org.netbeans.junit.NbTestCase$1Guard.run(NbTestCase.java:294) at org.netbeans.junit.NbTestCase.runBare(NbTestCase.java:384) at org.netbeans.junit.NbTestCase.run(NbTestCase.java:228) at org.openide.filesystems.MultiThreadedTestCaseHid.run(MultiThreadedTestCaseHid.java:85) at junit.extensions.TestDecorator.basicRun(TestDecorator.java:24) at org.netbeans.junit.NbTestSetup$1.protect(NbTestSetup.java:64) at org.netbeans.junit.NbTestSetup$1.protect(NbTestSetup.java:64) at org.netbeans.junit.NbTestSetup.run(NbTestSetup.java:68) (your patch can be imported into release691_fixes_base, only fix imports for List/ArrayList is needed) However, I have no idea what was done in Dev, so it will work again. For a back-port it would be important to find it out. br, josh.
OK, I integrated the test then: ergonomics#617757c16f7e can you verify the issue is fixed in trunk?
Integrated into 'main-golden', will be available in build *201104070400* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress) Changeset: http://hg.netbeans.org/main/rev/617757c16f7e User: Jaroslav Tulach <jtulach@netbeans.org> Log: #197308: Test that seem to work in 7.0 but were broken in 6.9