[jira] [Created] (CONFIGURATION-497) PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

[jira] [Created] (CONFIGURATION-497) PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed

David Mollitor (Jira)
Kate Butler created CONFIGURATION-497:
-----------------------------------------

             Summary: PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed
                 Key: CONFIGURATION-497
                 URL: https://issues.apache.org/jira/browse/CONFIGURATION-497
             Project: Commons Configuration
          Issue Type: Bug
          Components: File reloading
    Affects Versions: 1.8, 1.6
            Reporter: Kate Butler
            Priority: Minor


I have an application which stores some counters in a PropertiesConfiguration with auto-save enabled. These counters are incremented regularly - during peak load the PropertiesConfiguration object will be updated every 5 milliseconds on average, and there will also be threads reading from it at the same time. All access to the PropertiesConfiguration is made through a wrapper class which enforces synchronization.
About one in every 8,000 calls to setProperty() will fail, seemingly because the file handle is still open from the previous call. I have a single-threaded test case which can reproduce this by writing continuously to a PropertiesConfiguration object - it usually fails within 10,000 iterations and has never successfully completed 500,000 iterations.

{code:title=Test Case|borderStyle=solid}
  public void testHeavyLoadWritingToConf() throws ConfigurationException {
    PropertiesConfiguration conf = new PropertiesConfiguration(new java.io.File(FILE_PATH));
    conf.setAutoSave(true);
   
    for (int i = 0; i < NUM_WRITES; i++) {
      if (i % 100 == 0 && i > 0) {
        System.out.println("Test has completed " + i + " iterations");
      }
      conf.setProperty("my.counter", i);
    }
    System.out.println("All writes successful");
  }
{code}

{code:title=Stack trace|borderStyle=solid}
org.apache.commons.configuration.ConfigurationRuntimeException: Failed to auto-save
        at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:753)
        at org.apache.commons.configuration.AbstractFileConfiguration.clearProperty(AbstractFileConfiguration.java:799)
        at org.apache.commons.configuration.AbstractConfiguration.setProperty(AbstractConfiguration.java:485)
        at org.apache.commons.configuration.AbstractFileConfiguration.setProperty(AbstractFileConfiguration.java:788)
        at com.magicmemories.spike.PersistenceLockingTest.testHeavyLoadWritingToConf(PersistenceLockingTest.java:27)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at junit.framework.TestCase.runTest(TestCase.java:168)
        at junit.framework.TestCase.runBare(TestCase.java:134)
        at junit.framework.TestResult$1.protect(TestResult.java:110)
        at junit.framework.TestResult.runProtected(TestResult.java:128)
        at junit.framework.TestResult.run(TestResult.java:113)
        at junit.framework.TestCase.run(TestCase.java:124)
        at junit.framework.TestSuite.runTest(TestSuite.java:232)
        at junit.framework.TestSuite.run(TestSuite.java:227)
        at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.apache.commons.configuration.ConfigurationException: Unable to save to file C:\testarea\test.properties
        at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:139)
        at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:95)
        at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:473)
        at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:414)
        at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:749)
        ... 23 more
Caused by: java.io.FileNotFoundException: C:\testarea\test.properties (The process cannot access the file because it is being used by another process)
        at java.io.FileOutputStream.open(Native Method)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:194)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:145)
        at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:135)
        ... 27 more
{code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

       
Reply | Threaded
Open this post in threaded view
|

[jira] [Commented] (CONFIGURATION-497) PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed

David Mollitor (Jira)

    [ https://issues.apache.org/jira/browse/CONFIGURATION-497?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13276179#comment-13276179 ]

Oliver Heger commented on CONFIGURATION-497:
--------------------------------------------

Many thanks for this detailed report.

I had a look at the code, and this issue is indeed interesting: From your stacktrace, it is obvious that the {{AbstractFileConfiguration.save(URL)}} method is called. This method opens an output stream and closes it at the end in a finally block. So this seems to be alright.

However, {{save(URL)}} delegates to {{save(OutputStream)}}, and here something suspicious happens. A {{FileWriter}} is created on top of the output stream and used to write the content of the configuration. This writer is never closed - only its underlying output stream.

I have no clue whether this can cause the problem; will have to do some tests. OTOH, this is the only strange thing related to resource handling I found. On which platform did you see this exception? Did you test on other platforms, too?
               

> PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed
> -----------------------------------------------------------------------------------------
>
>                 Key: CONFIGURATION-497
>                 URL: https://issues.apache.org/jira/browse/CONFIGURATION-497
>             Project: Commons Configuration
>          Issue Type: Bug
>          Components: File reloading
>    Affects Versions: 1.6, 1.8
>            Reporter: Kate Butler
>            Priority: Minor
>
> I have an application which stores some counters in a PropertiesConfiguration with auto-save enabled. These counters are incremented regularly - during peak load the PropertiesConfiguration object will be updated every 5 milliseconds on average, and there will also be threads reading from it at the same time. All access to the PropertiesConfiguration is made through a wrapper class which enforces synchronization.
> About one in every 8,000 calls to setProperty() will fail, seemingly because the file handle is still open from the previous call. I have a single-threaded test case which can reproduce this by writing continuously to a PropertiesConfiguration object - it usually fails within 10,000 iterations and has never successfully completed 500,000 iterations.
> {code:title=Test Case|borderStyle=solid}
>   public void testHeavyLoadWritingToConf() throws ConfigurationException {
>     PropertiesConfiguration conf = new PropertiesConfiguration(new java.io.File(FILE_PATH));
>     conf.setAutoSave(true);
>    
>     for (int i = 0; i < NUM_WRITES; i++) {
>       if (i % 100 == 0 && i > 0) {
>         System.out.println("Test has completed " + i + " iterations");
>       }
>       conf.setProperty("my.counter", i);
>     }
>     System.out.println("All writes successful");
>   }
> {code}
> {code:title=Stack trace|borderStyle=solid}
> org.apache.commons.configuration.ConfigurationRuntimeException: Failed to auto-save
> at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:753)
> at org.apache.commons.configuration.AbstractFileConfiguration.clearProperty(AbstractFileConfiguration.java:799)
> at org.apache.commons.configuration.AbstractConfiguration.setProperty(AbstractConfiguration.java:485)
> at org.apache.commons.configuration.AbstractFileConfiguration.setProperty(AbstractFileConfiguration.java:788)
> at com.magicmemories.spike.PersistenceLockingTest.testHeavyLoadWritingToConf(PersistenceLockingTest.java:27)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at junit.framework.TestCase.runTest(TestCase.java:168)
> at junit.framework.TestCase.runBare(TestCase.java:134)
> at junit.framework.TestResult$1.protect(TestResult.java:110)
> at junit.framework.TestResult.runProtected(TestResult.java:128)
> at junit.framework.TestResult.run(TestResult.java:113)
> at junit.framework.TestCase.run(TestCase.java:124)
> at junit.framework.TestSuite.runTest(TestSuite.java:232)
> at junit.framework.TestSuite.run(TestSuite.java:227)
> at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
> at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
> at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
> Caused by: org.apache.commons.configuration.ConfigurationException: Unable to save to file C:\testarea\test.properties
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:139)
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:95)
> at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:473)
> at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:414)
> at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:749)
> ... 23 more
> Caused by: java.io.FileNotFoundException: C:\testarea\test.properties (The process cannot access the file because it is being used by another process)
> at java.io.FileOutputStream.open(Native Method)
> at java.io.FileOutputStream.<init>(FileOutputStream.java:194)
> at java.io.FileOutputStream.<init>(FileOutputStream.java:145)
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:135)
> ... 27 more
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

       
Reply | Threaded
Open this post in threaded view
|

[jira] [Commented] (CONFIGURATION-497) PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed

David Mollitor (Jira)
In reply to this post by David Mollitor (Jira)

    [ https://issues.apache.org/jira/browse/CONFIGURATION-497?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13277274#comment-13277274 ]

Kate Butler commented on CONFIGURATION-497:
-------------------------------------------

I've seen this on 4 different PCs so far (3x Win7 and 1x WinXP) with various updates of Java 1.6 from 23 through to 30. Our nightly build runs on a Linux box and so far it doesn't seem to have happened there.
               

> PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed
> -----------------------------------------------------------------------------------------
>
>                 Key: CONFIGURATION-497
>                 URL: https://issues.apache.org/jira/browse/CONFIGURATION-497
>             Project: Commons Configuration
>          Issue Type: Bug
>          Components: File reloading
>    Affects Versions: 1.6, 1.8
>            Reporter: Kate Butler
>            Priority: Minor
>
> I have an application which stores some counters in a PropertiesConfiguration with auto-save enabled. These counters are incremented regularly - during peak load the PropertiesConfiguration object will be updated every 5 milliseconds on average, and there will also be threads reading from it at the same time. All access to the PropertiesConfiguration is made through a wrapper class which enforces synchronization.
> About one in every 8,000 calls to setProperty() will fail, seemingly because the file handle is still open from the previous call. I have a single-threaded test case which can reproduce this by writing continuously to a PropertiesConfiguration object - it usually fails within 10,000 iterations and has never successfully completed 500,000 iterations.
> {code:title=Test Case|borderStyle=solid}
>   public void testHeavyLoadWritingToConf() throws ConfigurationException {
>     PropertiesConfiguration conf = new PropertiesConfiguration(new java.io.File(FILE_PATH));
>     conf.setAutoSave(true);
>    
>     for (int i = 0; i < NUM_WRITES; i++) {
>       if (i % 100 == 0 && i > 0) {
>         System.out.println("Test has completed " + i + " iterations");
>       }
>       conf.setProperty("my.counter", i);
>     }
>     System.out.println("All writes successful");
>   }
> {code}
> {code:title=Stack trace|borderStyle=solid}
> org.apache.commons.configuration.ConfigurationRuntimeException: Failed to auto-save
> at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:753)
> at org.apache.commons.configuration.AbstractFileConfiguration.clearProperty(AbstractFileConfiguration.java:799)
> at org.apache.commons.configuration.AbstractConfiguration.setProperty(AbstractConfiguration.java:485)
> at org.apache.commons.configuration.AbstractFileConfiguration.setProperty(AbstractFileConfiguration.java:788)
> at com.magicmemories.spike.PersistenceLockingTest.testHeavyLoadWritingToConf(PersistenceLockingTest.java:27)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at junit.framework.TestCase.runTest(TestCase.java:168)
> at junit.framework.TestCase.runBare(TestCase.java:134)
> at junit.framework.TestResult$1.protect(TestResult.java:110)
> at junit.framework.TestResult.runProtected(TestResult.java:128)
> at junit.framework.TestResult.run(TestResult.java:113)
> at junit.framework.TestCase.run(TestCase.java:124)
> at junit.framework.TestSuite.runTest(TestSuite.java:232)
> at junit.framework.TestSuite.run(TestSuite.java:227)
> at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
> at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
> at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
> Caused by: org.apache.commons.configuration.ConfigurationException: Unable to save to file C:\testarea\test.properties
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:139)
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:95)
> at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:473)
> at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:414)
> at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:749)
> ... 23 more
> Caused by: java.io.FileNotFoundException: C:\testarea\test.properties (The process cannot access the file because it is being used by another process)
> at java.io.FileOutputStream.open(Native Method)
> at java.io.FileOutputStream.<init>(FileOutputStream.java:194)
> at java.io.FileOutputStream.<init>(FileOutputStream.java:145)
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:135)
> ... 27 more
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

       
Reply | Threaded
Open this post in threaded view
|

[jira] [Commented] (CONFIGURATION-497) PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed

David Mollitor (Jira)
In reply to this post by David Mollitor (Jira)

    [ https://issues.apache.org/jira/browse/CONFIGURATION-497?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13279823#comment-13279823 ]

Oliver Heger commented on CONFIGURATION-497:
--------------------------------------------

Unfortunately, I cannot reproduce the problem on my machine (Win 7). The test runs successfully. Maybe my old laptop is too slow? This makes it hard to fix.

I can try to create a patch which uses a different approach for creating the writer and ensures that it gets closed. IMO this is the only strange thing in the code which could cause this behavior. Would you be able to test this? If this actually solves the problem, we can add it to the code base.
               

> PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed
> -----------------------------------------------------------------------------------------
>
>                 Key: CONFIGURATION-497
>                 URL: https://issues.apache.org/jira/browse/CONFIGURATION-497
>             Project: Commons Configuration
>          Issue Type: Bug
>          Components: File reloading
>    Affects Versions: 1.6, 1.8
>            Reporter: Kate Butler
>            Priority: Minor
>
> I have an application which stores some counters in a PropertiesConfiguration with auto-save enabled. These counters are incremented regularly - during peak load the PropertiesConfiguration object will be updated every 5 milliseconds on average, and there will also be threads reading from it at the same time. All access to the PropertiesConfiguration is made through a wrapper class which enforces synchronization.
> About one in every 8,000 calls to setProperty() will fail, seemingly because the file handle is still open from the previous call. I have a single-threaded test case which can reproduce this by writing continuously to a PropertiesConfiguration object - it usually fails within 10,000 iterations and has never successfully completed 500,000 iterations.
> {code:title=Test Case|borderStyle=solid}
>   public void testHeavyLoadWritingToConf() throws ConfigurationException {
>     PropertiesConfiguration conf = new PropertiesConfiguration(new java.io.File(FILE_PATH));
>     conf.setAutoSave(true);
>    
>     for (int i = 0; i < NUM_WRITES; i++) {
>       if (i % 100 == 0 && i > 0) {
>         System.out.println("Test has completed " + i + " iterations");
>       }
>       conf.setProperty("my.counter", i);
>     }
>     System.out.println("All writes successful");
>   }
> {code}
> {code:title=Stack trace|borderStyle=solid}
> org.apache.commons.configuration.ConfigurationRuntimeException: Failed to auto-save
> at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:753)
> at org.apache.commons.configuration.AbstractFileConfiguration.clearProperty(AbstractFileConfiguration.java:799)
> at org.apache.commons.configuration.AbstractConfiguration.setProperty(AbstractConfiguration.java:485)
> at org.apache.commons.configuration.AbstractFileConfiguration.setProperty(AbstractFileConfiguration.java:788)
> at com.magicmemories.spike.PersistenceLockingTest.testHeavyLoadWritingToConf(PersistenceLockingTest.java:27)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at junit.framework.TestCase.runTest(TestCase.java:168)
> at junit.framework.TestCase.runBare(TestCase.java:134)
> at junit.framework.TestResult$1.protect(TestResult.java:110)
> at junit.framework.TestResult.runProtected(TestResult.java:128)
> at junit.framework.TestResult.run(TestResult.java:113)
> at junit.framework.TestCase.run(TestCase.java:124)
> at junit.framework.TestSuite.runTest(TestSuite.java:232)
> at junit.framework.TestSuite.run(TestSuite.java:227)
> at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
> at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
> at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
> Caused by: org.apache.commons.configuration.ConfigurationException: Unable to save to file C:\testarea\test.properties
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:139)
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:95)
> at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:473)
> at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:414)
> at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:749)
> ... 23 more
> Caused by: java.io.FileNotFoundException: C:\testarea\test.properties (The process cannot access the file because it is being used by another process)
> at java.io.FileOutputStream.open(Native Method)
> at java.io.FileOutputStream.<init>(FileOutputStream.java:194)
> at java.io.FileOutputStream.<init>(FileOutputStream.java:145)
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:135)
> ... 27 more
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

       
Reply | Threaded
Open this post in threaded view
|

[jira] [Updated] (CONFIGURATION-497) PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed

David Mollitor (Jira)
In reply to this post by David Mollitor (Jira)

     [ https://issues.apache.org/jira/browse/CONFIGURATION-497?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Oliver Heger updated CONFIGURATION-497:
---------------------------------------

    Attachment: commons-configuration-497.patch

Patch to ensure that the Writer is always closed.
               

> PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed
> -----------------------------------------------------------------------------------------
>
>                 Key: CONFIGURATION-497
>                 URL: https://issues.apache.org/jira/browse/CONFIGURATION-497
>             Project: Commons Configuration
>          Issue Type: Bug
>          Components: File reloading
>    Affects Versions: 1.6, 1.8
>            Reporter: Kate Butler
>            Priority: Minor
>         Attachments: commons-configuration-497.patch
>
>
> I have an application which stores some counters in a PropertiesConfiguration with auto-save enabled. These counters are incremented regularly - during peak load the PropertiesConfiguration object will be updated every 5 milliseconds on average, and there will also be threads reading from it at the same time. All access to the PropertiesConfiguration is made through a wrapper class which enforces synchronization.
> About one in every 8,000 calls to setProperty() will fail, seemingly because the file handle is still open from the previous call. I have a single-threaded test case which can reproduce this by writing continuously to a PropertiesConfiguration object - it usually fails within 10,000 iterations and has never successfully completed 500,000 iterations.
> {code:title=Test Case|borderStyle=solid}
>   public void testHeavyLoadWritingToConf() throws ConfigurationException {
>     PropertiesConfiguration conf = new PropertiesConfiguration(new java.io.File(FILE_PATH));
>     conf.setAutoSave(true);
>    
>     for (int i = 0; i < NUM_WRITES; i++) {
>       if (i % 100 == 0 && i > 0) {
>         System.out.println("Test has completed " + i + " iterations");
>       }
>       conf.setProperty("my.counter", i);
>     }
>     System.out.println("All writes successful");
>   }
> {code}
> {code:title=Stack trace|borderStyle=solid}
> org.apache.commons.configuration.ConfigurationRuntimeException: Failed to auto-save
> at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:753)
> at org.apache.commons.configuration.AbstractFileConfiguration.clearProperty(AbstractFileConfiguration.java:799)
> at org.apache.commons.configuration.AbstractConfiguration.setProperty(AbstractConfiguration.java:485)
> at org.apache.commons.configuration.AbstractFileConfiguration.setProperty(AbstractFileConfiguration.java:788)
> at com.magicmemories.spike.PersistenceLockingTest.testHeavyLoadWritingToConf(PersistenceLockingTest.java:27)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at junit.framework.TestCase.runTest(TestCase.java:168)
> at junit.framework.TestCase.runBare(TestCase.java:134)
> at junit.framework.TestResult$1.protect(TestResult.java:110)
> at junit.framework.TestResult.runProtected(TestResult.java:128)
> at junit.framework.TestResult.run(TestResult.java:113)
> at junit.framework.TestCase.run(TestCase.java:124)
> at junit.framework.TestSuite.runTest(TestSuite.java:232)
> at junit.framework.TestSuite.run(TestSuite.java:227)
> at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
> at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
> at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
> Caused by: org.apache.commons.configuration.ConfigurationException: Unable to save to file C:\testarea\test.properties
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:139)
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:95)
> at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:473)
> at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:414)
> at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:749)
> ... 23 more
> Caused by: java.io.FileNotFoundException: C:\testarea\test.properties (The process cannot access the file because it is being used by another process)
> at java.io.FileOutputStream.open(Native Method)
> at java.io.FileOutputStream.<init>(FileOutputStream.java:194)
> at java.io.FileOutputStream.<init>(FileOutputStream.java:145)
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:135)
> ... 27 more
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

       
Reply | Threaded
Open this post in threaded view
|

[jira] [Commented] (CONFIGURATION-497) PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed

David Mollitor (Jira)
In reply to this post by David Mollitor (Jira)

    [ https://issues.apache.org/jira/browse/CONFIGURATION-497?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13282227#comment-13282227 ]

Kate Butler commented on CONFIGURATION-497:
-------------------------------------------

Nope, that patch did not fix it.
And that was when I noticed that my real-time virus scanning had somehow magicly turned itself back on even though I always keep it turned off in my development environment. The test case is passing now, so the real problem is more likely to be a bug in my synchronized wrapper.

Thanks for your time Oliver, sorry to have led you up the garden path!
               

> PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed
> -----------------------------------------------------------------------------------------
>
>                 Key: CONFIGURATION-497
>                 URL: https://issues.apache.org/jira/browse/CONFIGURATION-497
>             Project: Commons Configuration
>          Issue Type: Bug
>          Components: File reloading
>    Affects Versions: 1.6, 1.8
>            Reporter: Kate Butler
>            Priority: Minor
>         Attachments: commons-configuration-497.patch
>
>
> I have an application which stores some counters in a PropertiesConfiguration with auto-save enabled. These counters are incremented regularly - during peak load the PropertiesConfiguration object will be updated every 5 milliseconds on average, and there will also be threads reading from it at the same time. All access to the PropertiesConfiguration is made through a wrapper class which enforces synchronization.
> About one in every 8,000 calls to setProperty() will fail, seemingly because the file handle is still open from the previous call. I have a single-threaded test case which can reproduce this by writing continuously to a PropertiesConfiguration object - it usually fails within 10,000 iterations and has never successfully completed 500,000 iterations.
> {code:title=Test Case|borderStyle=solid}
>   public void testHeavyLoadWritingToConf() throws ConfigurationException {
>     PropertiesConfiguration conf = new PropertiesConfiguration(new java.io.File(FILE_PATH));
>     conf.setAutoSave(true);
>    
>     for (int i = 0; i < NUM_WRITES; i++) {
>       if (i % 100 == 0 && i > 0) {
>         System.out.println("Test has completed " + i + " iterations");
>       }
>       conf.setProperty("my.counter", i);
>     }
>     System.out.println("All writes successful");
>   }
> {code}
> {code:title=Stack trace|borderStyle=solid}
> org.apache.commons.configuration.ConfigurationRuntimeException: Failed to auto-save
> at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:753)
> at org.apache.commons.configuration.AbstractFileConfiguration.clearProperty(AbstractFileConfiguration.java:799)
> at org.apache.commons.configuration.AbstractConfiguration.setProperty(AbstractConfiguration.java:485)
> at org.apache.commons.configuration.AbstractFileConfiguration.setProperty(AbstractFileConfiguration.java:788)
> at com.magicmemories.spike.PersistenceLockingTest.testHeavyLoadWritingToConf(PersistenceLockingTest.java:27)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at junit.framework.TestCase.runTest(TestCase.java:168)
> at junit.framework.TestCase.runBare(TestCase.java:134)
> at junit.framework.TestResult$1.protect(TestResult.java:110)
> at junit.framework.TestResult.runProtected(TestResult.java:128)
> at junit.framework.TestResult.run(TestResult.java:113)
> at junit.framework.TestCase.run(TestCase.java:124)
> at junit.framework.TestSuite.runTest(TestSuite.java:232)
> at junit.framework.TestSuite.run(TestSuite.java:227)
> at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
> at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
> at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
> Caused by: org.apache.commons.configuration.ConfigurationException: Unable to save to file C:\testarea\test.properties
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:139)
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:95)
> at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:473)
> at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:414)
> at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:749)
> ... 23 more
> Caused by: java.io.FileNotFoundException: C:\testarea\test.properties (The process cannot access the file because it is being used by another process)
> at java.io.FileOutputStream.open(Native Method)
> at java.io.FileOutputStream.<init>(FileOutputStream.java:194)
> at java.io.FileOutputStream.<init>(FileOutputStream.java:145)
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:135)
> ... 27 more
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

       
Reply | Threaded
Open this post in threaded view
|

[jira] [Closed] (CONFIGURATION-497) PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed

David Mollitor (Jira)
In reply to this post by David Mollitor (Jira)

     [ https://issues.apache.org/jira/browse/CONFIGURATION-497?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Kate Butler closed CONFIGURATION-497.
-------------------------------------

    Resolution: Not A Problem
   

> PropertiesConfiguration.setProperty() with auto-save returns before file handle is closed
> -----------------------------------------------------------------------------------------
>
>                 Key: CONFIGURATION-497
>                 URL: https://issues.apache.org/jira/browse/CONFIGURATION-497
>             Project: Commons Configuration
>          Issue Type: Bug
>          Components: File reloading
>    Affects Versions: 1.6, 1.8
>            Reporter: Kate Butler
>            Priority: Minor
>         Attachments: commons-configuration-497.patch
>
>
> I have an application which stores some counters in a PropertiesConfiguration with auto-save enabled. These counters are incremented regularly - during peak load the PropertiesConfiguration object will be updated every 5 milliseconds on average, and there will also be threads reading from it at the same time. All access to the PropertiesConfiguration is made through a wrapper class which enforces synchronization.
> About one in every 8,000 calls to setProperty() will fail, seemingly because the file handle is still open from the previous call. I have a single-threaded test case which can reproduce this by writing continuously to a PropertiesConfiguration object - it usually fails within 10,000 iterations and has never successfully completed 500,000 iterations.
> {code:title=Test Case|borderStyle=solid}
>   public void testHeavyLoadWritingToConf() throws ConfigurationException {
>     PropertiesConfiguration conf = new PropertiesConfiguration(new java.io.File(FILE_PATH));
>     conf.setAutoSave(true);
>    
>     for (int i = 0; i < NUM_WRITES; i++) {
>       if (i % 100 == 0 && i > 0) {
>         System.out.println("Test has completed " + i + " iterations");
>       }
>       conf.setProperty("my.counter", i);
>     }
>     System.out.println("All writes successful");
>   }
> {code}
> {code:title=Stack trace|borderStyle=solid}
> org.apache.commons.configuration.ConfigurationRuntimeException: Failed to auto-save
> at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:753)
> at org.apache.commons.configuration.AbstractFileConfiguration.clearProperty(AbstractFileConfiguration.java:799)
> at org.apache.commons.configuration.AbstractConfiguration.setProperty(AbstractConfiguration.java:485)
> at org.apache.commons.configuration.AbstractFileConfiguration.setProperty(AbstractFileConfiguration.java:788)
> at com.magicmemories.spike.PersistenceLockingTest.testHeavyLoadWritingToConf(PersistenceLockingTest.java:27)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at junit.framework.TestCase.runTest(TestCase.java:168)
> at junit.framework.TestCase.runBare(TestCase.java:134)
> at junit.framework.TestResult$1.protect(TestResult.java:110)
> at junit.framework.TestResult.runProtected(TestResult.java:128)
> at junit.framework.TestResult.run(TestResult.java:113)
> at junit.framework.TestCase.run(TestCase.java:124)
> at junit.framework.TestSuite.runTest(TestSuite.java:232)
> at junit.framework.TestSuite.run(TestSuite.java:227)
> at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
> at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
> at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
> at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
> Caused by: org.apache.commons.configuration.ConfigurationException: Unable to save to file C:\testarea\test.properties
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:139)
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:95)
> at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:473)
> at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:414)
> at org.apache.commons.configuration.AbstractFileConfiguration.possiblySave(AbstractFileConfiguration.java:749)
> ... 23 more
> Caused by: java.io.FileNotFoundException: C:\testarea\test.properties (The process cannot access the file because it is being used by another process)
> at java.io.FileOutputStream.open(Native Method)
> at java.io.FileOutputStream.<init>(FileOutputStream.java:194)
> at java.io.FileOutputStream.<init>(FileOutputStream.java:145)
> at org.apache.commons.configuration.DefaultFileSystem.getOutputStream(DefaultFileSystem.java:135)
> ... 27 more
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira