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

auto-extend session cause exception on sharding

    Details

    • Fix Priority:
      3

      Description

      I've a 6.2 installation with sharding enabled. When I'm logged into a company stored into a non-default shard the auto-extend feature cause the following exception

      18:26:39,817 ERROR [localhost-startStop-1][CompanyThreadLocal:62] com.liferay.portal.NoSuchUserException: No User exists with the key {companyId=21225, defaultUser=true}
      com.liferay.portal.NoSuchUserException: No User exists with the key {companyId=21225, defaultUser=true}
      	at com.liferay.portal.service.persistence.UserPersistenceImpl.findByC_DU(UserPersistenceImpl.java:4033)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:606)
      	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:320)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
      	at com.liferay.portal.dao.shard.advice.ShardPersistenceAdvice.invoke(ShardPersistenceAdvice.java:104)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
      	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
      	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
      	at com.sun.proxy.$Proxy54.findByC_DU(Unknown Source)
      	at com.liferay.portal.service.impl.UserLocalServiceImpl.loadGetDefaultUser(UserLocalServiceImpl.java:3040)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:606)
      	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115)
      	at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:62)
      	at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51)
      	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
      	at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175)
      	at com.sun.proxy.$Proxy182.loadGetDefaultUser(Unknown Source)
      	at com.liferay.portal.service.impl.UserLocalServiceImpl.getDefaultUser(UserLocalServiceImpl.java:2168)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:606)
      	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115)
      	at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175)
      	at com.sun.proxy.$Proxy182.getDefaultUser(Unknown Source)
      	at com.liferay.portal.service.UserLocalServiceUtil.getDefaultUser(UserLocalServiceUtil.java:1728)
      	at com.liferay.portal.model.impl.CompanyImpl.getDefaultUser(CompanyImpl.java:95)
      	at com.liferay.portal.model.impl.CompanyImpl.getLocale(CompanyImpl.java:142)
      	at com.liferay.portal.security.auth.CompanyThreadLocal.setCompanyId(CompanyThreadLocal.java:58)
      	at com.liferay.portal.util.PortalInstances._initCompany(PortalInstances.java:410)
      	at com.liferay.portal.util.PortalInstances.initCompany(PortalInstances.java:93)
      	at com.liferay.portal.servlet.MainServlet.initCompanies(MainServlet.java:765)
      	at com.liferay.portal.servlet.MainServlet.init(MainServlet.java:339)
      	at javax.servlet.GenericServlet.init(GenericServlet.java:160)
      	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1280)
      	at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1193)
      	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1088)
      	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5176)
      	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5460)
      	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
      	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
      	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
      	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
      	at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:656)
      	at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1635)
      	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
      	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
      	at java.lang.Thread.run(Thread.java:745)
      
      

      I suppose the problem is inside CompanyThreadLocal.setCompanyId()

      	public static void setCompanyId(Long companyId) {
      		if (_log.isDebugEnabled()) {
      			_log.debug("setCompanyId " + companyId);
      		}
      
      		if (companyId > 0) {
      			try {
      				Company company = CompanyLocalServiceUtil.getCompany(companyId);
      
      				LocaleThreadLocal.setDefaultLocale(company.getLocale());
      				TimeZoneThreadLocal.setDefaultTimeZone(company.getTimeZone());
      			}
      			catch (Exception e) {
      				_log.error(e, e);
      			}
      
      			_companyId.set(companyId);
      		}
      
      

      LocaleThreadLocal.setDefaultLocale() is ivoked before set the "active" companyId, so inside "ShardPersistenceAdvice.setShardNameByCompany()" the old value is used.
      In this case the old value is 0 and the Default User is searched inside default shard.

      To reproduce it in 6.2 CE GA4, or 6.2 EE sp13:

      • use the bundle
      • enable sharding in the standard way
        • default configuration has three Shard/DB (default, one, two)
      • enable "shard.selector=com.liferay.portal.dao.shard.ManualShardSelector"
      • enable session auto extend
        • session.timeout.auto.extend=true
        • session.timeout=10
      • create three company, one per shard
      • log into the one stored into shard two
      • wait for session auto extension

        Attachments

          Issue Links

            Activity

              People

              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Days since last comment:
                  4 years, 9 weeks, 6 days ago

                  Packages

                  Version Package