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

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

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 3.4, 3.5
    • 3.6
    • lang.concurrent.*
    • None
    • 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

        1. 0001-LANG-1144-allow-nulls-as-return-value.patch
          2 kB
          Waldemar Maier
        2. commons-lang.patch
          1 kB
          Gary D. Gregory

        Activity

          People

            ggregory Gary D. Gregory
            waldemar Waldemar Maier
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: