Uploaded image for project: 'PUBLIC - Liferay Portal Community Edition'
  1. PUBLIC - Liferay Portal Community Edition
  2. LPS-55260

When deserializing CacheResponseData, _byteBuffer may not be correctly restored

    Details

      Description

      If you configure cache to replicate full objects, CacheResponseData is incorrectly replicated.

      CacheResponseData has as a ByteBuffer member, that can not be serialized, and, as such, is declared transient. _byteBuffer member, if null, is initialized from byte[] _content member, using method ByteBuffer.wrap(). This method does not restore limit and mark _byteBuffer members, so strange behaviours can appear, like serving js files with zeros at the end.

      Steps to reproduce for ee-6.2.x:

      1. Execute the following script in the groovy console of the Server Administration in the Control Panel.
      import java.nio.ByteBuffer;
      import java.util.Arrays;
      import java.util.Random;
      
      import com.liferay.portal.kernel.servlet.BufferCacheServletResponse;
      import com.liferay.portal.kernel.test.AssertUtils;
      import com.liferay.portal.kernel.util.Validator;
      import com.liferay.portal.util.PortalUtil;
      import com.liferay.util.SerializableUtil;
      import com.liferay.util.servlet.filters.CacheResponseData;
      
      try {
      	BufferCacheServletResponse bufferCacheServletResponse =
      			new BufferCacheServletResponse(PortalUtil.getHttpServletResponse(actionResponse));
      
      	byte[] data = new byte[10];
      
      	Random random = new Random();
      
      	random.nextBytes(data);
      
      	ByteBuffer byteBuffer = ByteBuffer.wrap(data, 2, 5);
      
      	bufferCacheServletResponse.setByteBuffer(byteBuffer);
      
      	CacheResponseData cacheResponseData = new CacheResponseData(
      			bufferCacheServletResponse);
      
      	cacheResponseData.setAttribute("a1", "v1");
      	cacheResponseData.setAttribute("b1", "v2");
      
      	CacheResponseData deserializedCacheResponseData =
      			(CacheResponseData)SerializableUtil.deserialize(
      			SerializableUtil.serialize(cacheResponseData));
      
      	assertEquals(
      			"Content type not correctly recreated",
      			cacheResponseData.getContentType(),
      			deserializedCacheResponseData.getContentType());
      	assertEquals(
      			"Headers not correctly recreated", cacheResponseData.getHeaders(),
      			deserializedCacheResponseData.getHeaders());
      	assertEquals(
      			"Attribute a1 not correctly recreated",
      			cacheResponseData.getAttribute("a1"),
      			deserializedCacheResponseData.getAttribute("a1"));
      	assertEquals(
      			"Attribute a2 not correctly recreated",
      			cacheResponseData.getAttribute("a2"),
      			deserializedCacheResponseData.getAttribute("a2"));
      
      	ByteBuffer deserializedByteBuffer =
      			deserializedCacheResponseData.getByteBuffer();
      
      	assertArrayEquals(
      			"Byte buffer data not correctly recreated",
      			Arrays.copyOfRange(
      			byteBuffer.array(),
      			byteBuffer.arrayOffset() + byteBuffer.position(),
      			byteBuffer.arrayOffset() + byteBuffer.limit()),
      			Arrays.copyOfRange(
      			deserializedByteBuffer.array(),
      			deserializedByteBuffer.arrayOffset() +
      			deserializedByteBuffer.position(),
      			deserializedByteBuffer.arrayOffset() +
      			deserializedByteBuffer.limit()));
      } catch(Exception e) {
      	e.printStackTrace(out);
      }
      
      void assertEquals(String s, Object a, Object b) {
      	if (!a.equals(b)) {
      		throw new Exception(s);
      	}
      }
      
      void assertArrayEquals(String s, byte [] a, byte [] b) {
      	if (!Arrays.equals(a, b)) {
      		throw new Exception(s);
      	}
      }
      

      Actual result:

      • An exception is shown

      Expected result:

      • Nothing appears

      Steps to reproduce for ee-6.1.x:

      1. Set a cluster of two nodes.
      2. Make the following changes in ROOT/WEB-INF/classes/META-INF/liferay-multi-vm-clustered.xml replacing:

      ...
      <cache
      	eternal="false"
      	maxElementsInMemory="10000"
      	name="com.liferay.portal.servlet.filters.cache.CacheUtil"
      	overflowToDisk="false"
      	timeToIdleSeconds="600"
      >
      	<cacheEventListenerFactory
      		class="com.liferay.portal.cache.ehcache.LiferayCacheEventListenerFactory"
      		properties="replicatePuts=false,replicateUpdatesViaCopy=false"
      		propertySeparator=","
      	/>
      </cache>
      ...
      

      with:

      ...
      <cache
      	eternal="false"
      	maxElementsInMemory="10000"
      	name="com.liferay.portal.servlet.filters.cache.CacheUtil"
      	overflowToDisk="false"
      	timeToIdleSeconds="600"
      >
      	<cacheEventListenerFactory
      		class="com.liferay.portal.cache.ehcache.LiferayCacheEventListenerFactory"
      		properties="replicatePuts=true,replicateUpdatesViaCopy=true"
      		propertySeparator=","
      	/>
      </cache>
      ...
      

      3. Set the following property in portal-ext.properties:

      ehcache.multi.vm.config.location=/META-INF/liferay-multi-vm-clustered.xml
      

      4. Access to both nodes and check the Content-Length attribute of the javascript contents:

      Actual result:

      Content-Length values are not equal for every javascript content.

      Expected result:

      Content-Length values are equal for every javascript content.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              shitian.zhang Shitian "Shelton" Zhang (Inactive)
              Reporter:
              alberto.montero Alberto Montero
              Participants of an Issue:
              Recent user:
              Esther Sanz
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:
                Days since last comment:
                6 years, 8 weeks, 1 day ago

                  Packages

                  Version Package
                  6.2.4 CE GA5
                  6.2.X EE
                  7.0.0 M5