Announcement Announcement Module
Collapse
No announcement yet.
Behavior of static member when using factory-method Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Behavior of static member when using factory-method

    I have a factory that has a non static getObject that returns a static member of the factory.

    That static member updates its data when a file is updated on disk. I know this is working as I can see the value change when the file is reloaded via a low priority thread.

    What I expected to see is that the reference would change but is instead behaving like the static member is never updated within the bean context.

    I realize that the FooConfigurationFactory is a singleton but I would expect that any call to that singleton's factory-method which returns a static FooConfiguration would see the FooConfiguration update between calls to getBean("fooConfiguration"), if the static FooConfiguration changed but I am not seeing that. What is the reason for that and how would I gain the behavior that I am expecting?

    Example from a single JUnit test with no request scoping, etc:

    Code:
    FooConfiguration config = (FooConfiguration)context.getBean("fooConfiguration");
     assertTrue(config.isEnabled("someProp"));
    
    System.out.println("Hey go modify your file!");
    Thread.sleep(30000);
    
    // I modify the file and see the file reload and the static reference update by getting the value of someProp and seeing it is now changed
    
    assertFalse(config.isEnabled("someProp"));
    So the assertFalse fails because someProp is still evaluating to true even though I can see that the static ref within the factory has changed for that property after the load. I expected the assertFalse to pass but the unit test still thinks the value is true.

    Code:
    public class FooConfigurationFactory {
    
        private static FooConfiguration fooConfiguration;
        private URL fileLocation;
        private long pollingDelay;
        private FileWatcherThread thread;
    
        public FooConfigurationFactory() {
        }
    
        public void init() {
            if (FooConfigurationFactory.fooConfiguration == null) {
                loadProperties();
                try {
                    thread = new FileWatcherThread(getFileLocation(), getPollingDelay());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        public FooConfiguration getObject() {
            return FooConfigurationFactory.fooConfiguration;
        }
    
        public void loadProperties() {
            FooConfiguration tmpFooConfiguration = new FooConfiguration(getFileLocation());
            FooConfigurationFactory.fooConfiguration = tmpFooConfiguration;
            System.out.println("\n\n>>>>>>>>>>>>>>>>> loadProperties called. someProp = " + fooConfiguration.isEnabled("someProp") + "\n\n");
        }
    ......

    Code:
        <bean id="fooConfigurationFactory"
              class="FooConfigurationFactory"
              init-method="init">
            <property name="fileLocation" ref="fooUrl"/>
            <property name="pollingDelay" value="1000"/>
        </bean>
    
        <bean id="fooConfiguration"
              factory-bean="FooConfigurationFactory"
              factory-method="getObject"/>
    Last edited by chuck99; Oct 1st, 2012, 09:55 AM.

  • #2
    Make following change in your code and try again:
    Code:
    private static volatile FooConfiguration fooConfiguration;
    In addition, what is the WowoConfiguration? Was it a typo of FooConfiguration?

    Comment


    • #3
      I will try the volatile marker. Yes that was a type in FooConfiguration which I have edited. Thank you for pointing that out.

      Comment


      • #4
        The volatile marker did not allow future getBean calls to see a changed static FooConfiguration after a thread modified the FooConfiguration.

        Is this a bug in Spring 3.0.5? It appears as though the Bean container is creating a singleton copy of the static member returned by the original getObject call? Maybe this is an aberation of my Junit test implementation?

        From a unit test perspective I have one runBeforeClass which loads the context file and creates the container. I have 2 completely different tests which make assertions after FooConfiguration fooConfig = (FooConfiguration)context.getBean("fooConfiguratio n");

        Both tests see the value as unchanged for FooConfiguration even though the Factory itself shows that the static FooConfiguration has in fact changed state by calling FooConfigurationFactory.fooConfiguration.isEnabled ("someProperty"); I realize that this static ref is not the same as the getBean call but they should both be pointing to the static class member I should think?

        Another point - I did modify the second unit test by making the FooConfiguration public just to grab it from the class to ensure that the value had changed and it did even the .getBean("fooConfiguration") factory-method call is still seeing an unchanged copy of FooConfiguration.

        Comment

        Working...
        X