Uploaded image for project: 'Commons Lang'
  1. Commons Lang
  2. LANG-1144

Multiple calls of org.apache.commons.lang3.concurrent.LazyInitializer.initialize() are possible

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 3.4, 3.5
    • Fix Version/s: 3.6
    • Component/s: lang.concurrent.*
    • Labels:
      None
    • Environment:

      Java 1.8 on Windows 7 x64

      Description

      It is possible to create a construct, that allows multiple calls of LazyInitializer.initialize, when calculations (which can be very expensive) return null as result.
      In the Javadoc is described that the initialize method will be called only on the first access

          /**
           * Creates and initializes the object managed by this {@code
           * LazyInitializer}. This method is called by {@link #get()} when the object
           * is accessed for the first time. An implementation can focus on the
           * creation of the object. No synchronization is needed, as this is already
           * handled by {@code get()}.
           *
           * @return the managed data object
           * @throws ConcurrentException if an error occurs during object creation
           */
          protected abstract T initialize() throws ConcurrentException;
      

      The Junit Test can be something like this:
      (fix can be appplied from attached patch-file)

      package edu.test;
      
      import static org.junit.Assert.assertEquals;
      
      import org.apache.commons.lang3.concurrent.ConcurrentException;
      import org.apache.commons.lang3.concurrent.LazyInitializer;
      import org.junit.Test;
      
      public class LazyInitializerTest {
      
        private int lazyinitCounter = 0;
      
        private LazyInitializer<Object> lazyIinit = new LazyInitializer<Object>() {
      
          @Override
          protected Object initialize() throws ConcurrentException {
            lazyinitCounter++;
            return doSomeVeryExpensiveOperations();
          }
        };
        
        
        private Object doSomeVeryExpensiveOperations() {
          // do db calls
          // do some complex math calculations
          // the result of them all is null
          return null;
        }
        
        
        @Test
        public void testInitialization() throws Exception {
          lazyIinit.get();
          lazyIinit.get();
          assertEquals("Multiple call of LazyInitializer#initialize", 1, lazyinitCounter);
        }
      
      }
      
      
      

        Attachments

          Activity

            People

            • Assignee:
              garydgregory Gary Gregory
              Reporter:
              waldemar Waldemar Maier
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: