liferay multi tenancy configuration

Liferay multi-tenancy configuration with shards

Steps to configure a Liferay multi-tenancy environment

If you’ve read my previous article Liferay Saas solution – handling multi-tenancy where I describe the principles used to handle a multi-tenancy installation for Liferay, you are probably wondering about the technical details of how to actually configure a Liferay multi-tenancy environment. Well, here is a description of what we did. Hope you find it useful. If you have any questions please leave a comment an I will try to help.


In short these are the modifications made to allow Liferay to lazy connect to the shards and allow a fast start-up no matter the number of shards involved:

  1. Explicitly set the Hibernate dialect – this is done in the portal-ext.properties file;
  2. Database connection information and data source settings – dynamically create data sources and make necessary adjustments such that actual connection is delayed as much as possible
  3. Handling the Hibernate session factory – initialize Hibernate configuration only once, not for each shard
  4. Prevent start up initializations
  5. Initializations not made on start up should be made on first access of each shard / instance
  6. Initializations needed for Control Panel functions

1. Explicitly set the Hibernate dialect

[LIFERAY-HOMEDIR]/portal-ext.properties

This file is actually overwrites the default settings of the Portal. The default Portal settings are stored in the [LIFERAY-HOMEDIR]/tomcat/webapps/ROOT/portal-imp.jar. After following the documentation of Liferay this file looked somthing like

spring.configs=\
        META-INF/base-spring.xml,\
        \
        META-INF/hibernate-spring.xml,\
        META-INF/infrastructure-spring.xml,\
        META-INF/management-spring.xml,\
        \
        META-INF/util-spring.xml,\
        \
        META-INF/jpa-spring.xml,\
        \
        META-INF/audit-spring.xml,\
        META-INF/cluster-spring.xml,\
        META-INF/editor-spring.xml,\
        #META-INF/jcr-spring.xml,\
        portal-shards-jcr.xml,\
        META-INF/ldap-spring.xml,\
        META-INF/messaging-core-spring.xml,\
        META-INF/messaging-misc-spring.xml,\
        META-INF/poller-spring.xml,\
        META-INF/rules-spring.xml,\
        META-INF/scheduler-spring.xml,\
        META-INF/scripting-spring.xml,\
        META-INF/search-spring.xml,\
        META-INF/workflow-spring.xml,\
        \
        META-INF/counter-spring.xml,\
        META-INF/document-library-spring.xml,\
        META-INF/mail-spring.xml,\
        META-INF/portal-spring.xml,\
        META-INF/portlet-container-spring.xml,\
        \
        META-INF/ext-spring.xml,\
        \
        portal-shards.xml

shard.selector=com.liferay.portal.dao.shard.ManualShardSelector
shard.available.names=default,c1,c2,........,c15000

hibernate.dialect=org.hibernate.dialect.MySQLDialect

In this file we have placed the sharding settings according to the Liferay documentation. We have also added the hibernate.dialect explicitly as this was one of the reasons for which the portal tried to connect to each and every shard in order to detect the Hibernate dialect to use.

Also, notice that we have added a reference to portal-shards.xml which is actually a copy of the  [LIFERAY-HOMEDIR]/tomcat/webapps/ROOT/WEB-INF/lib/portal-impl.jar/META-INF/shard-data-source-spring.xml. We did this so that we can modify the shards configuration without having to change the content of the jar everytime. Instead now, the portal looks for the file in [LIFERAY-HOMEDIR]/tomcat/webapps/ROOT/WEB-INF/classes/.

To keep things clearer can add this to the file

include-and-override=portal-ext-extra-shards.properties

What this does is indicate to Liferay that it should load the file portal-ext-extra-shards.properties along side the portal-ext.properties. This allows us to separately store settings related to the sharding.

2. Database connection information and data source settings

One important thing to note is that for sharding one needs to add connection information in the portal-ext.properties file in the form of

jdbc.[shard-name].driverClassName=com.mysql.jdbc.Driver
jdbc.[shard-name].url=[Connection string]
...

This information is used to create the DataSource objects that the application uses. The DataSource objects are defined in the Spring context, namely in the portal-shards.xml file created as indicated above. This instantiates a few singletons org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy with a target data source set as com.liferay.portal.dao.jdbc.util.DataSourceFactoryBean which in turn has as a parameter named parameterPrefix indicating the prefix used to retrieve the connection information from the portal-ext.properties file. LazyConnectionDataSourceProxy is actually a very useful choice in our situation as this type of data source will actually connect to the database only upon the first creation of a statement. So far we did not change anything from the default configuration, but to support the 15000 clients / portal instances we need to add 15000 connection information groups in the portal-ext.properties file and 15000 Spring beans in the portal-shards.xml file. This can be done by generating these entries with some script, but one thing we chose to do is to aviod overfilling the portal-ext.properties file which is more often used for changing portal configurations and what we did, we chose to replace the default com.liferay.portal.dao.jdbc.util.DataSourceFactoryBean from portal-shards.xml with our own implementation which does not look at the 15000 groups of connection information lines, but dynamically generates connections based on some rules for schema names, database user names and passwords.

In short we created a org.springframework.beans.factory.config.AbstractFactoryBean and put it in place of the com.liferay.portal.dao.jdbc.util.DataSourceFactoryBean. Our class  createInstance creates one com.mchange.v2.c3p0.ComboPooledDataSource object for each entry in the Spring context and uses the propertyPrefix value to create the connection information. As we can see we used C3P0 as our connection pool provider as this is the default provider used by the Portal.

IMPORTANT NOTE: Through testing we noted that even though the portal uses LazyConnectionDataSourceProxy which only initializes the connection pool upon first creating a statement, when we started the Portal it was creating connections thus slowing down the start up time. This was because LazyConnectionDataSourceProxy will try to connect on initialization if the defaultAutoCommit and defaultTransactionIsolation properties are not set. So we have set them such.

<bean id="shardDataSource0" lazy-init="true">
   <property name="defaultAutoCommit" value="true"/>
   <property name="defaultTransactionIsolation" value="4"/>
   <property name="targetDataSource">
     <bean lazy-init="true">
     <property name="propertyPrefix" value="jdbc.default."/>
     </bean>
   </property>
</bean>

3. Handling the Hibernate session factory

In the Portal shard configuration we notice that the Hibernate SessionFactory used is com.liferay.portal.dao.shard.ShardSessionFactoryTargetSource which in turn uses a key/value map with one com.liferay.portal.spring.hibernate.PortalHibernateConfiguration object for each shard. The latter is a LocalSessionFactoryBean responsible for the Hibernate configurations and mappings. This is all fine as is, but again, for 15000 it’s not ideal as for every shard the system will load the Hibernate configuration files 15000 times which means a long start up time.

What we did to avoid this is extend the com.liferay.portal.spring.hibernate.PortalHibernateConfiguration and override the newConfiguration method to only create the Configuration object once. This means that the Portal Hibernate mappings files are only loaded once. Through testing we also noted that the Portal still wanted to connect to each shard upon start up and found that it was due to Hibernate that needed to access the database metadata. There is a hibernate property that determines this and that is hibernate.temp.use_jdbc_metadata_defaults which defaults to true. So, we set this property to false in our version of the PortalHibernateConfiguration class.

Also in this PortalHibernateConfiguration we noticed that the buildSessionFactory method was called for each shard so we also made an override of that as the SessionFactory objects created were the same excepting the data source. We therefore created a method that creates a SessionFactory and sets a data source. Please see 6. Initializations needed for Control Panel functions where we used this method.

Here’s how our PortalHibernateConfiguration version looks like

..... extends com.liferay.portal.spring.hibernate.PortalHibernateConfiguration {

  private static Configuration _config = null;
  private static SessionFactory _sessionFactory = null;

  @Override
  protected Configuration newConfiguration() {
   if (_config == null) {
    _config = super.newConfiguration();
    _config.getProperties().setProperty("hibernate.temp.use_jdbc_metadata_defaults", "false");
   }
   return _config;
  } 

  @Override
  protected SessionFactory buildSessionFactory() throws Exception {
    if (_sessionFactory == null) {
    _sessionFactory = super.buildSessionFactory();
    }
    return _sessionFactory;
  }

  public SessionFactory buildSessionFactory(DataSource dataSource) throws Exception {
   this.setDataSource(dataSource);
   return super.buildSessionFactory();
  }

Don’t forget replace all occurrences of com.liferay.portal.spring.hibernate.PortalHibernateConfiguration with your implementation in the portal-shards.xml. Also, place your implementation in a .jar file and drop it in the [LIFERAY-HOMEDIR]/tomcat/webapps/ROOT/WEB-INF/lib folder.

 4. Prevent start up initializations

Up to this point we have configured the Liferay Spring context to delay and avoid connecting to all the shards on context initialization with the though in mind that only when a user actually accesses their shard / instance the connection will actually be made.

Also through testing we realized that this was not enough, because the Portal does some initializations upon start up which involve accessing data form all shards. So, we had to find a way to prevent those initializations to take place before the Portal actually finished starting. Step by step, we were able to identify the initialization tasks  that were performed on start up and tried to disable them. The idea was actually to disable them on start up, but perform them at a later time – on user access to the shard.

We identified that the initialization of each shard / instance was made inside the com.liferay.portal.servlet.MainServlet servlet on the initCompanies method, so we decided to override this method to only init the main shard. Here’s how our implementation looks like

 

... extends MainServlet {

 @Override
 protected void initCompanies() throws Exception {
	ServletContext servletContext = getServletContext();
	String[] webIds = PortalInstances.getWebIds();
	PortalInstances.initCompany(servletContext, webIds[0]);

 }
}

In order for the new servlet to be used you have to replace com.liferay.portal.servlet.MainServlet with your implementation in the [LIFERAY-HOMEDIR]/tomcat/webapps/ROOT/WEB-INF/web.xml file.

If everything was set up right then the Portal should start with this configuration in a reasonable amount of time (for me it takes around 80 seconds).

IMPORTANT NOTE: Though the Portal now starts quickly only the default shard will function properly. Remember that we have deactivated the start up initialization. We still have to initialize each shard upon access.

5. Initializations not made on start up should be made on first access of each shard / instance

In the previous step we have replaced the initialization of all the shards with the initialization of the default shard only. We would now like to have this initialization taking place upon first access of a shard. In order to do that we have decided to put the initialization code inside one of the filters of the Portal ROOT webapp. Namely, we have overridden the processFilter method of the com.liferay.portal.servlet.filters.virtualhost.VirtualHostFilter class. This filter is used to provide virtual host functionality, that is when a user accesses a certain virtual host pointing to the Liferay portal server it will route the user to the correct shard / instance corresponding to the virtual host name. This filter was appropriate for our goals and also it is the first filter in the list of filters giving it priority over the others.

In our implementation of the filter we identify the shard / instance accessed by the name of the virtual host, we call the initialization code for a shard / instance (just like in the original com.liferay.portal.servlet.MainServlet.initCompanies() method). We also store the hosts for which the initialization has been made such that we only initialize one shard upon first access and not every time.

The resulting code for the filter looks something like this

... extends VirtualHostFilter {

	private static List lstInitializedHosts = new ArrayList();

	@Override
	protected void processFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws Exception {
		String host = PortalUtil.getHost(request);
		if (!lstInitializedHosts.contains(host)) {
			lstInitializedHosts.add(host);
			Company company = CompanyLocalServiceUtil.getCompanyByVirtualHost(host);
			PortalInstances.initCompany(request.getSession().getServletContext(), company.getWebId());
		}
		super.processFilter(request, response, filterChain);
	}
}

Again, in order for the new filter to be used you have to replace com.liferay.portal.servlet.filters.virtualhost.VirtualHostFilter with your implementation in the [LIFERAY-HOMEDIR]/tomcat/webapps/ROOT/WEB-INF/web.xml file.

Place your implementation in a .jar file (can be the same as for the servlet) and drop it in the [LIFERAY-HOMEDIR]/tomcat/webapps/ROOT/WEB-INF/lib folder.

With these settings the Portal will start just as quick as with only one shard / instance and upon each access of an existing shard it will create a database connection and then initialize the shard correctly such that everything will work as expected.

6. Initializations needed for Control Panel functions

Even though the Portal shards / instances work correctly, if you go to the Control Panel and try to define a new instance, the Portal will start to give errors. This is because as you remember each instance is only initialized when directly accessed by a user through a virtual host name. So why does it give an error, because in the default shard’s Control Panel things don’t stay local only on the current shard, but the Portal accesses all sorts of other information from other shards. Those shards might not be yet initialized and therefore the error. Actually the error had to do with the fact that the SessionFactory was not correctly built.

To fix this problem we have turned to the Aspect Oriented configuration used by the portal. What this does is wrap around Portal API calls such that it detects to which shard / instance the call refers to and sets creates the conditions for the call to get executed on the correct shard. We decided that this might be a good place to detect if calls to other instances than the default instance are made such that we initialize them before making the call so that the errors do not appear anymore.

We have extended the ShardAdvice class of the portal in this way

... extends ShardAdvice {

	private static List lstInitializedShards = new ArrayList();
	private static ShardSelector _shardSelector;
	static {
		try {
			_shardSelector = (ShardSelector) Class.forName(PropsValues.SHARD_SELECTOR).newInstance();
		} catch (Exception e) {
		}
	}

	/**
	 * @param shardName
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private void buildSessionFactory(String shardName, String methodCall) throws Exception {

		if (PropsValues.SHARD_DEFAULT_NAME.equals(shardName) || lstInitializedShards.contains(shardName)) {
			return;
		}

		lstInitializedShards.add(shardName);
		ShardSessionFactoryTargetSource shardSessionFactoryTargetSource =

		(ShardSessionFactoryTargetSource) PortalBeanLocatorUtil.locate("shardSessionFactoryTargetSource");

		Class cls = ShardSessionFactoryTargetSource.class;
		Field fld = cls.getDeclaredField("_sessionFactories");
		fld.setAccessible(true);

		Map _sessionFactories = (Map) fld
				.get(shardSessionFactoryTargetSource);

		int dataSourceIndex = 0;
		if (!"default".equals(shardName)) {
			dataSourceIndex =

			Integer.parseInt(StringUtils.replace(StringUtils.replace(shardName, "c", ""), ".", ""));
		}
		DataSource dataSource = (DataSource) PortalBeanLocatorUtil.locate("shardDataSource" + dataSourceIndex);

		PortalHibernateConfiguration sessionFactory = new PortalHibernateConfiguration();

		_sessionFactories.put(shardName, sessionFactory.buildSessionFactory(dataSource));
	}

	@Override
	public Object invokeByParameter(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

		String methodSignature = _getSignature(proceedingJoinPoint);
		if (!"ResourceCodeLocalServiceImpl.checkResourceCodes()".equals(methodSignature)) {

			Object[] arguments = proceedingJoinPoint.getArgs();

			long companyId = (Long) arguments[0];

			Shard shard = ShardLocalServiceUtil.getShard(Company.class.getName(), companyId);

			String shardName = shard.getName();

			buildSessionFactory(shardName, "invokeByParameter: " + methodSignature);
		}
		return super.invokeByParameter(proceedingJoinPoint);
	}

	@Override
	public Object invokeCompanyService(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		String methodName = proceedingJoinPoint.getSignature().getName();
		Object[] arguments = proceedingJoinPoint.getArgs();

		String shardName = PropsValues.SHARD_DEFAULT_NAME;

		if (methodName.equals("addCompany")) {
			String webId = (String) arguments[0];
			String virtualHost = (String) arguments[1];
			String mx = (String) arguments[2];
			shardName = (String) arguments[3];

			shardName = _getCompanyShardName(webId, virtualHost, mx, shardName);

		} else if (methodName.equals("checkCompany")) {
			String webId = (String) arguments[0];

			if (!webId.equals(PropsValues.COMPANY_DEFAULT_WEB_ID)) {
				if (arguments.length == 3) {
					String mx = (String) arguments[1];
					shardName = (String) arguments[2];

					shardName = _getCompanyShardName(webId, null, mx, shardName);

				}

				try {
					Company company = CompanyLocalServiceUtil.getCompanyByWebId(webId);

					shardName = company.getShardName();
				} catch (NoSuchCompanyException nsce) {
				}
			}
		} else if (methodName.startsWith("update")) {
			long companyId = (Long) arguments[0];

			Shard shard = ShardLocalServiceUtil.getShard(Company.class.getName(), companyId);

			shardName = shard.getName();
		}

		buildSessionFactory(shardName, "invokeCompanyService: " + _getSignature(proceedingJoinPoint));
		return super.invokeCompanyService(proceedingJoinPoint);
	}

	private String _getCompanyShardName(String webId, String virtualHost, String mx, String shardName) {

		Map shardParams = new HashMap();

		shardParams.put("webId", webId);
		shardParams.put("mx", mx);

		if (virtualHost != null) {
			shardParams.put("virtualHost", virtualHost);
		}

		shardName = _shardSelector.getShardName(ShardSelector.COMPANY_SCOPE, shardName, shardParams);

		return shardName;
	}

	private String _getSignature(ProceedingJoinPoint proceedingJoinPoint) {
		String methodName = StringUtil.extractLast(proceedingJoinPoint.getTarget().getClass().getName(),
				StringPool.PERIOD);

		methodName += StringPool.PERIOD + proceedingJoinPoint.getSignature().getName() + "()";

		return methodName;
	}
}

What the code does is build SessionFactory objects with the right data source and set them in the right place. Please note that the code relies on the presumption that the shards are identified as default, c1, c2, c3, …

Place your implementation in a .jar file (can be the same as for the servlet and filter) and drop it in the [LIFERAY-HOMEDIR]/tomcat/webapps/ROOT/WEB-INF/lib folder.

In order for your implementation to be used by the Portal you have to replace the entry in the portal-shards.xml

replace this

<bean id="com.liferay.portal.dao.shard.ShardAdvice">

with this

<bean id="your.implementation.of.ShardAdvice">

 

 

John Negoita

View posts by John Negoita
I'm a Java programmer, been into programming since 1999 and having tons of fun with it.

34 Comments

  1. […] See technical details on how to configure Liferay for multi-tenancy. […]

    Reply
  2. MuraliAugust 3, 2013

    Nice Article

    Reply
  3. Bhuwan GautamSeptember 22, 2013

    Hi John,

    I have customs portlets and I am using service builder to generate persistence layer. Table are only only created for default jdbc connection in case of custom portlets and other two shard databases are unaffected. What I am missing here?

    Reply
    1. John NegoitaSeptember 22, 2013

      Hi,

      Is your question related to the setup I’m describing in the post? Please note that this setup makes use of lazy connections, so only the connection
      to the default database is created at first, so probably Hibernate’s hbm2ddl=auto will not work. Anyway, this setting is highly unadvised for production environment.

      I don’t know if you use the service builder for the persistence layer if that’s setup for working with shards. I think you should test your custom portlets on an instance other than the default, and if it gives errors that it cannot find the tables try to create the tables manually in that shard.

      For my production environment I’m using liquibase for database source control.

      Reply
  4. Bhuwan GautamSeptember 22, 2013

    Here is my portal-ext.properties file

    ###############################
    #Liferay Portal-ext.properties
    ###############################
    # MySQL Default Shard Database Connector
    jdbc.default.driverClassName=com.mysql.jdbc.Driver
    jdbc.default.url=jdbc:mysql://localhost/lportal?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
    jdbc.default.username=
    jdbc.default.password=

    # MySQL Shard SpotPay Database Connector
    jdbc.one.driverClassName=com.mysql.jdbc.Driver
    jdbc.one.url=jdbc:mysql://localhost/lportal1?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
    jdbc.one.username=
    jdbc.one.password=

    # MySQL Shard WellsFargo Database Connector
    jdbc.two.driverClassName=com.mysql.jdbc.Driver
    jdbc.two.url=jdbc:mysql://localhost/lportal2?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
    jdbc.two.username=
    jdbc.two.password=

    # For multitenancy purpose
    #Spring configuration files to be loadded. By adding shard-data-source-spring.xml in the list database sharding feature
    #can be enabled
    spring.configs=\
    META-INF/base-spring.xml,\
    \
    META-INF/hibernate-spring.xml,\
    META-INF/infrastructure-spring.xml,\
    META-INF/management-spring.xml,\
    \
    META-INF/util-spring.xml,\
    \
    META-INF/jpa-spring.xml,\
    \
    META-INF/executor-spring.xml,\
    \
    META-INF/audit-spring.xml,\
    META-INF/cluster-spring.xml,\
    META-INF/editor-spring.xml,\
    META-INF/jcr-spring.xml,\
    META-INF/ldap-spring.xml,\
    META-INF/messaging-core-spring.xml,\
    META-INF/messaging-misc-spring.xml,\
    META-INF/mobile-device-spring.xml,\
    META-INF/notifications-spring.xml,\
    META-INF/poller-spring.xml,\
    META-INF/rules-spring.xml,\
    META-INF/scheduler-spring.xml,\
    META-INF/scripting-spring.xml,\
    META-INF/search-spring.xml,\
    META-INF/workflow-spring.xml,\
    \
    META-INF/counter-spring.xml,\
    META-INF/mail-spring.xml,\
    META-INF/portal-spring.xml,\
    META-INF/portlet-container-spring.xml,\
    META-INF/staging-spring.xml,\
    META-INF/virtual-layouts-spring.xml,\
    META-INF/shard-data-source-spring.xml,\
    META-INF/ext-spring.xml

    shard.selector=com.liferay.portal.dao.shard.ManualShardSelector
    shard.available.names=default,one,two
    hibernate.dialect=org.hibernate.dialect.MySQLDialect
    shard.default.name=default

    After I run the server, default table(liferay’s table) are populated to all the shards perfectly. But when i deployed my custom portlets, it only reflects to default shard and other two shards are remains as it is. I am wondering if I missed any step.

    Appreciate your suggestion.

    Thanks
    Bhuwan

    Reply
    1. John NegoitaSeptember 24, 2013

      Hi,

      Custom portlets make use of the same connections as the portal. Did you deploy your custom portlets on all the shards?
      What errors do they give when accessing them? It might be that you have to manually create the tables for the custom portlets
      on the secondary shards.

      Reply
  5. Bhuwan GautamSeptember 22, 2013

    It would be very helpful if you can provide some standard suggestion on the multi-tenancy part.

    Reply
  6. Bhuwan GautamSeptember 28, 2013

    Yeah it worked !! Thanks for your time.

    Reply
    1. John NegoitaOctober 2, 2013

      Glad I could help

      Reply
  7. ahamed sakirOctober 11, 2013

    I followed https://www.liferay.com/community/wiki/-/wiki/Main/Database+Sharding article and implemented 6 DB and working fine. But after some time it is showing suddenly

    com.liferay.portal.kernel.events.ActionException: com.liferay.portal.NoSuchLayoutSetException: No LayoutSet exists with the key {groupId=10422, privateLayout=false}
    com.liferay.portal.events.ServicePreAction.run(ServicePreAction.java:145)

    Really i cud not move to production.

    I used Liferay605/tomcat/mysql/Ubuntu

    Reply
    1. John NegoitaOctober 11, 2013

      Hi Ahmed,

      I think that the error is that after a while the portal’s cache expires and when the service layer tries to retrieve some data, it looks for the data in the cache, doesn’t find it because the cache expired and then tries to query the database, only it queries the wrong database due to a bug in the cache implementation (I really hate the cache implementation myself).

      Can you try the following:
      1. login on one shard (not the default)
      2. leave the window open until the session expires (this usually triggers a clearing of the cache)
      3. try to access the shard again (this should trigger the exception)

      I have run into this scenario in my code doing some shard operation and managed to get around by specifically selecting which shard to use.

      Reply
      1. ahamed sakirOctober 12, 2013

        same exatly i am facing this issue what you are telling. what to do?any solution for this… Please help

        Reply
      2. ahamed sakirOctober 12, 2013

        Hi Negotia,
        I am facing same above problem only . Kindly please help how to solve this issue. Waiting for your reply please.

        Reply
  8. ahamed sakirOctober 12, 2013

    it is happening in without login(guest) scenario only not in logged-in scenario.
    if i leave a page idle some mins then if i refresh that page getting above exception on page and console.Pls help

    Reply
    1. John NegoitaOctober 12, 2013

      can you send me the full stack trace?
      did you configure any custom PreAction or install any plugin/hook/extension?

      Reply
      1. ahamed sakirOctober 12, 2013

        Caused by: com.liferay.portal.NoSuchLayoutSetException: No LayoutSet exists with the key {groupId=10563, privateLayout=false}
        at com.liferay.portal.service.persistence.LayoutSetPersistenceImpl.findByG_P(LayoutSetPersistenceImpl.java:969)
        at sun.reflect.GeneratedMethodAccessor341.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
        at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)
        at com.liferay.portal.dao.shard.ShardAdvice.invokePersistence(ShardAdvice.java:245)
        at sun.reflect.GeneratedMethodAccessor100.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
        at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
        at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        at com.sun.proxy.$Proxy28.findByG_P(Unknown Source)
        at com.liferay.portal.service.impl.LayoutSetLocalServiceImpl.getLayoutSet(LayoutSetLocalServiceImpl.java:114)
        at sun.reflect.GeneratedMethodAccessor340.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
        at com.liferay.portal.dao.jdbc.aop.DynamicDataSourceTransactionInterceptor.invoke(DynamicDataSourceTransactionInterceptor.java:44)
        at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:58)
        at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:58)
        at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:58)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        at com.sun.proxy.$Proxy165.getLayoutSet(Unknown Source)
        at com.liferay.portal.service.LayoutSetLocalServiceUtil.getLayoutSet(LayoutSetLocalServiceUtil.java:245)
        at com.liferay.portal.model.impl.LayoutImpl.getLayoutSet(LayoutImpl.java:283)
        at com.liferay.portal.events.ServicePreAction.servicePre(ServicePreAction.java:1245)
        at com.liferay.portal.events.ServicePreAction.run(ServicePreAction.java:142)
        … 141 more

        Reply
  9. ahamed sakirOctober 18, 2013

    04:40:26,249 ERROR [jsp:684] User ID null
    04:40:26,250 ERROR [jsp:685] Current URL /web/guest
    04:40:26,251 ERROR [jsp:686] Referer null
    04:40:26,252 ERROR [jsp:687] Remote address 127.0.0.1
    04:40:26,252 ERROR [jsp:689] com.liferay.portal.kernel.events.ActionException: com.liferay.portal.NoSuchLayoutSetException: No LayoutSet exists with the key {groupId=10563, privateLayout=false}
    com.liferay.portal.kernel.events.ActionException: com.liferay.portal.NoSuchLayoutSetException: No LayoutSet exists with the key {groupId=10563, privateLayout=false}
    at com.liferay.portal.events.ServicePreAction.run(ServicePreAction.java:145)
    at com.liferay.portal.events.EventsProcessorImpl.processEvent(EventsProcessorImpl.java:81)
    at com.liferay.portal.events.EventsProcessorImpl.process(EventsProcessorImpl.java:58)
    at com.liferay.portal.events.EventsProcessorUtil.process(EventsProcessorUtil.java:53)
    at com.liferay.portal.servlet.MainServlet.processServicePre(MainServlet.java:1064)
    at com.liferay.portal.servlet.MainServlet.service(MainServlet.java:449)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.strip.StripFilter.processFilter(StripFilter.java:309)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.gzip.GZipFilter.processFilter(GZipFilter.java:137)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.secure.SecureFilter.processFilter(SecureFilter.java:182)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.autologin.AutoLoginFilter.processFilter(AutoLoginFilter.java:254)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
    at com.liferay.portal.servlet.FriendlyURLServlet.service(FriendlyURLServlet.java:133)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.strip.StripFilter.processFilter(StripFilter.java:261)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.gzip.GZipFilter.processFilter(GZipFilter.java:126)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.secure.SecureFilter.processFilter(SecureFilter.java:182)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.i18n.I18nFilter.processFilter(I18nFilter.java:221)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.cache.CacheFilter.processFilter(CacheFilter.java:385)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.etag.ETagFilter.processFilter(ETagFilter.java:45)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.autologin.AutoLoginFilter.processFilter(AutoLoginFilter.java:254)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.sso.ntlm.NtlmPostFilter.processFilter(NtlmPostFilter.java:81)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.sharepoint.SharepointFilter.processFilter(SharepointFilter.java:179)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.virtualhost.VirtualHostFilter.processFilter(VirtualHostFilter.java:239)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:738)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:196)
    at com.liferay.portal.servlet.filters.threadlocal.ThreadLocalFilter.processFilter(ThreadLocalFilter.java:35)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:465)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Unknown Source)
    Caused by: com.liferay.portal.NoSuchLayoutSetException: No LayoutSet exists with the key {groupId=10563, privateLayout=false}
    at com.liferay.portal.service.persistence.LayoutSetPersistenceImpl.findByG_P(LayoutSetPersistenceImpl.java:969)
    at sun.reflect.GeneratedMethodAccessor338.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)
    at com.liferay.portal.dao.shard.ShardAdvice.invokePersistence(ShardAdvice.java:245)
    at sun.reflect.GeneratedMethodAccessor96.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
    at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at com.sun.proxy.$Proxy28.findByG_P(Unknown Source)
    at com.liferay.portal.service.impl.LayoutSetLocalServiceImpl.getLayoutSet(LayoutSetLocalServiceImpl.java:114)
    at sun.reflect.GeneratedMethodAccessor337.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at com.liferay.portal.dao.jdbc.aop.DynamicDataSourceTransactionInterceptor.invoke(DynamicDataSourceTransactionInterceptor.java:44)
    at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:58)
    at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:58)
    at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:58)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at com.sun.proxy.$Proxy165.getLayoutSet(Unknown Source)
    at com.liferay.portal.service.LayoutSetLocalServiceUtil.getLayoutSet(LayoutSetLocalServiceUtil.java:245)
    at com.liferay.portal.model.impl.LayoutImpl.getLayoutSet(LayoutImpl.java:283)
    at com.liferay.portal.events.ServicePreAction.servicePre(ServicePreAction.java:1245)
    at com.liferay.portal.events.ServicePreAction.run(ServicePreAction.java:142)
    … 141 more

    Reply
  10. Bhuwan GautamNovember 11, 2013

    Hi John,

    I found performance degradation after the multi-tenant implementation. I didn’t have a multi-tenant environment previously in my application. At that time the application was taking around 8 sec to complete one of the major job in the application.

    Currently I have 3 instances one.com, two.com, and three.com. Once I browse two.com and try to run the same major job, it is now taking 50 sec.

    I read that the application takes time to initialize the instance at first and after that the performance will be same as with only one shards(ie. without multi-tenant scenerio) configuration.

    I would like to know your thought on causes to the performance in a multi-tenant configuration.

    Thanks in advance
    Bhuwan

    Reply
    1. John NegoitaNovember 11, 2013

      Hi Bhuwan,

      the multi-tenant implementation has indeed the disadvantage that upon first access of an instance the database connections pool needs to be initialized because it is no longer initialized at start-up. So, one thing would be to give me some more details about what you mean by major job: do you access a certain instance and then you start some process, or do you run a script from the main instance?

      Also, I think that the 50 seconds are too much, so my guess is that the configuration for the connection pool is not ideal. You should check the settings for the initial pool size and set it lower, otherwise upon first accessing an instance the system will wait for the connections in the pool to initialize.

      hope this helps,
      john

      Reply
      1. Bhuwan GautamNovember 11, 2013

        Hi John,

        Here is the scenerio:

        Case 1: Running with only one database configuration(ie. without multi-tenant environment)
        I have a service method which hits around 10 tables and it is taking around 10 sec.

        Case 2: Multi-tenant env(just change in the portal-ext file) and the same service of #1 is taking 50 sec after accessing the instance.

        Any Idea?

        Thanks
        Bhuwan

        Reply
        1. John NegoitaNovember 13, 2013

          Do you mean that the service is using data only from one instance (shard)? or multiple shards. Please give me more details about what the service is doing

          Reply
          1. Bhuwan GautamNovember 14, 2013

            Hi John,

            Yes, it is using only once instance. I have a one service which calls other 5 services and which hits 5 different database. Also there is a loop to populate the 3 years of data. This all is happening on the same instance. It was taking 8 sec earlier and now it is taking 50 sec. Any clue?

            Thanks
            Bhuwan

          2. John NegoitaNovember 16, 2013

            Hi,

            in your spring configuration, where you define the shardDataSourceX bean, try and set the following properties for the connection pool

            minPoolSize = 0
            acquireIncrement = 0
            initialPoolSize = 0
            maxPoolSize = 20

            this will ensure that upon first usage of a shard will only initialize 1 connection, therefore taking less time.

            let me know how it turns out

          3. Bhuwan GautamNovember 14, 2013

            Hi John,

            The other problem after multi-tenant configuration is that the transaction management is not working. It was working earlier with the non multi-tenant configuration.

            Need your help.

            Thanks
            Bhuwan

  11. Bhuwan GautamNovember 21, 2013

    Hi Jon,

    The performance issue after multi-tenant was due to the transaction management. Since the transaction management is not working, while saving 1095 times it will try to execute the commit statement everytime I think and it is taking time.

    So I really need to know what is the case in the multi-tenanat configuration that transaction management is not working.

    Thanks
    Bhuwan

    Reply
  12. Bhuwan GautamDecember 4, 2013

    Hi John,

    Thanks for your support. I have resolved both the performance issue and the transaction management issue in multi-tenant setup. Actually after the implementation of transaction management(JTA) performance issue is automatically gets resolved.
    The reason was if you do not have TM in application then your db will try to execute the commit stmt everytime you hit to the database. But in case of TM it will hit commit at the end only.

    Thanks
    Bhuwan

    Reply
    1. John NegoitaDecember 5, 2013

      Hi Gautam,

      glad to hear that everything works. Can you tell me what you did to implement transaction management?

      thanks,
      John

      Reply
  13. gabiDecember 5, 2013

    Hi John,

    I’ve noticed you’re really experienced with Liferay and I’m currently building an environment using Liferay and I never used it before so I wonder if you can help me 🙂

    Currently we try to configure 2 test tenants but we plan to configure more than 100 so we’ll need to optimize it , however we experience some issues when creating a new portal instance.

    We are using a Jboss with Liferay 6.1.2GA3 on a RH machine that connects to a database server(pgsql 9.2).

    We created a custom portal-shards.xml and placed it under WEB-INF/classes, a portal-ext.properties file where we include a second file where the define the spring.configs list and some shard configs. The last two are placed on a separate config folder.

    The server starts ok we can access the control panel via the default shard but when we try to add a new portal instance the following error occur(similar with the one described here):

    com.liferay.portal.NoSuchResourcePermissionException: No ResourcePermission exists with the key {companyId=1, name=com.liferay.portal.model.Layout, scope=4, primKey=26, roleId=10154}

    The odd part is that we configured same Jboss/Liferay using exactly the same config files and locations on a WIN 8 machine that connects remotely to the db server and it works just fine. Do you have any idea why this is happening and what we should try? I would really appreciate the help

    Thanks,
    Gabi

    Reply
    1. John NegoitaDecember 5, 2013

      Hi Gabi,

      The error indicates that it cannot find a record in the resourcepermission table in the database.
      It might be that it’s looking for it in the wrong database. You can manually check the database for the record and see if you can find it.
      It looks a bit strange that the companyId = 1, because in Liferay 6.0 companyIds started at 10801 or something, maybe this changed in 6.1

      Reply
  14. AbhayMarch 19, 2014

    Hi John
    In my case, I too had to manually run script to generate custom tables in each of the additional shards as it did not automatically create the custom portlet tables. Not sure why.
    But I am running into a Hibernate error :

    com.liferay.portal.kernel.dao.orm.ORMException: org.hibernate.MappingException: Unknown entity: com.xxxxxx.xxx.xxx.MyEntityImpl

    The same setup works just fine if I turn off sharding in the portlet-ext.properties.

    any guesses ?

    Reply
  15. Bhuwan GautamOctober 21, 2014

    Hi John,

    Sorry for the late reply. Following are the steps to implement JTA on Liferay+JBoss environment.

    Java Transaction api(JTA)
    The Java Transaction API(JTA), one of the java Enterprise Edition (java EE) APIs, enables distributed transactions to be done across mutliple X/OpenXA resources in a java environment. JTA is a specification developed under the java community process as JSR 907.
    The JTA API consists of classes in two Java packages:
    javax.transaction
    javax.transaction.xa

    Configuration steps:
    Download jta-1_1-classes.zip from link below and rename it to jta.jar. Add jta.jar in $JBOSS_HOME/jboss-eap-.1/modules/system/layers/base/com/liferay/portal/main/ inside module base directory and change module.xml http://download.oracle.com/otndocs/jcp/jta-1.1-classes-oth-JSpec/?submit=Download
    module.xml

    Use xa-datasource which is recommended for clustered servers and jta environment
    file: standalone.xml or standalone-ha.xml
    xa-datasource

    database_url
    database_user
    database_password
    mysql
    TRANSACTION_READ_COMMITTED

    Note : for sharded configuration make additional xa-datasource as required.

    change mysql driver to use MysqlXADatasource class
    file: standalone.xml or standalone-ha.xml
    mysql_driver

    com.mysql.jdbc.jdbc2.optional.MysqlXADataSource

    enable jta transaction manager
    liferay by default uses hibernate transaction manager
    default tx manager
    transaction.manager.impl=com.liferay.portal.spring.hibernate.LastSessionRecorderHibernateTransactionManager
    transaction.manager.property.globalRollbackOnParticipationFailure=false
    liferay provides following properties to switch from hibernate transaction manager to jta transaction manager
    liferay provided jta properties
    transaction.manager.impl=org.springframework.transaction.jta.JtaTransactionManager
    transaction.manager.property.allowCustomIsolationLevels=true
    transaction.manager.property.globalRollbackOnParticipationFailure=true
    but above configuration is not sufficient so we need to make change on spring configuration file and above properties can be skipped. Transaction manager can be changed directly on spring bean configuration inside hibernate-spring.xml.
    file : hibernate-spring.xml
    default config :
    default tx manager

    modified config:
    modified

    Note: Only xml changes is sufficient here and no need to add properties in portal-ext.properties

    Disable autocommit true
    Liferay by default sets autocommit true which is not allowed on JTA environment. We need to change a set of spring configuration file to disable autocommit property for datasource which is metioned below;
    change counter-spring.xml
    default config:
    default

    modified config:
    modified

    change dynamic-data-source-spring.xml
    default config:
    default

    modified config:
    modified

    change infrastructure-spring.xml
    default config:
    default

    modified config:
    modified

    change shard-data-source-spring.xml
    default config:
    default

    modified config:
    modified

    Note: Above liferay-spring configuration files can be retrieved from liferay-source
    Now above spring files will be placed inside folder ROOT.war/WEB-INF/classes/META-INF and will configured in portal-ext.properties to override default configuration which will already be done together with Sharded configuration.
    spring config in portal-ext.properties
    spring.configs=\
    META-INF/base-spring.xml,\
    META-INF/hibernate-spring.xml,\
    META-INF/infrastructure-spring.xml,\
    META-INF/management-spring.xml,\
    META-INF/util-spring.xml,\
    META-INF/jpa-spring.xml,\
    META-INF/executor-spring.xml,\
    META-INF/audit-spring.xml,\
    META-INF/cluster-spring.xml,\
    META-INF/editor-spring.xml,\
    META-INF/jcr-spring.xml,\
    META-INF/ldap-spring.xml,\
    META-INF/messaging-core-spring.xml,\
    META-INF/messaging-misc-spring.xml,\
    META-INF/mobile-device-spring.xml,\
    META-INF/notifications-spring.xml,\
    META-INF/poller-spring.xml,\
    META-INF/rules-spring.xml,\
    META-INF/scheduler-spring.xml,\
    META-INF/scripting-spring.xml,\
    META-INF/search-spring.xml,\
    META-INF/workflow-spring.xml,\
    META-INF/counter-spring.xml,\
    META-INF/mail-spring.xml,\
    META-INF/portal-spring.xml,\
    META-INF/portlet-container-spring.xml,\
    META-INF/staging-spring.xml,\
    META-INF/virtual-layouts-spring.xml,\
    #META-INF/dynamic-data-source-spring.xml,\
    META-INF/shard-data-source-spring.xml,\
    #META-INF/memcached-spring.xml,\
    #META-INF/monitoring-spring.xml,\
    META-INF/ext-spring.xml

    Reply
  16. Bhuwan GautamOctober 21, 2014

    Hi John,

    I have Successfully implemented JTA on Liferay+JBoss but still I am having one problem regarding the database changes. When there is a change in the database( new table or other changes) then I have to disable JTA to reflect those changes to the database. Once the changes are reflect then I need to turn on JTA again.

    Do you know any workaround?

    Reply
  17. srikanthSeptember 24, 2015

    HI john ,
    i want to enable add document feature in one of the shard instances how to do ?

    Reply
  18. […] in the Spring configuration of Liferay – if you are interested you can read more about configuring Liferay with shards. Depending on how the server is configured, shards can be assigned to portal instances manually or […]

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top