PUBLIC - Liferay Portal Community Edition
  1. PUBLIC - Liferay Portal Community Edition
  2. LPS-32878

When a portlet is deployed, there are no check about name length. If it is over PortletItem.portletId column width (75 characters), the portlet is incorrectly deployed, generating later errors.

    Details

    • Branch Version/s:
      6.1.x
    • Backported to Branch:
      Committed
    • Technical Documentation Required:
      Needs Documentation
    • Fix Priority:
      4
    • Similar Issues:
      Show 5 results 

      Description

      Depending on the application server, the error may be more or less obvious. If using tomcat, a clear error is shown, and the portlet is incorrectly deployed.

      17:12:26,699 ERROR [pool-2-thread-2][JDBCExceptionReporter:76] Data truncation: Data too long for column 'portletId' at row 1
      17:12:26,704 ERROR [pool-2-thread-2][TransactionInterceptor:143] Application exception overridden by commit exception
      org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL [insert into Portlet (companyId, portletId, roles, active_, id_) values (?, ?, ?, ?, ?)]; nested exception is org.hibernate.exception.DataException: Could not execute JDBC batch update
      at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:642)
      at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)
      at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664)
      at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
      at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
      at com.liferay.portal.spring.transaction.TransactionInterceptor.processCommit(TransactionInterceptor.java:132)
      at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:87)
      at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
      at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55)
      at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
      at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55)
      at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
      at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55)
      at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
      at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55)
      at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
      at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:55)
      at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
      at com.liferay.portal.security.pacl.PACLAdvice.invoke(PACLAdvice.java:51)
      at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
      at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:162)
      at $Proxy64.checkPortlet(Unknown Source)
      at com.liferay.portal.service.PortletLocalServiceUtil.checkPortlet(PortletLocalServiceUtil.java:259)

      If using WebSphere, no errors are shown, but the portlet is incorrectly deployed, breaking porlets list.

        Issue Links

          Activity

          Hide
          Alberto Montero added a comment - - edited

          This issues arises mainly with customer developed plugins, where PortletItem.name holds a string that contains both the plugin file name and the portlet name, so it is easier to be over 75 characters.

          Using some DB engines (tested on DB2 9.7), when creating a prepared statement, if a parameter is substituted by a value larger than the column width and exception is thrown

          [1/30/13 17:08:07:093 GMT] 00000020 SystemOut O 17:08:07,092 ERROR [WebContainer : 1][org.hibernate.util.JDBCExceptionReporter:76] The value of a host variable in the EXECUTE or OPEN statement is out of range for its corresponding use.. SQLCODE=-302, SQLSTATE=22001, DRIVER=3.62.57

          Show
          Alberto Montero added a comment - - edited This issues arises mainly with customer developed plugins, where PortletItem.name holds a string that contains both the plugin file name and the portlet name, so it is easier to be over 75 characters. Using some DB engines (tested on DB2 9.7), when creating a prepared statement, if a parameter is substituted by a value larger than the column width and exception is thrown [1/30/13 17:08:07:093 GMT] 00000020 SystemOut O 17:08:07,092 ERROR [WebContainer : 1] [org.hibernate.util.JDBCExceptionReporter:76] The value of a host variable in the EXECUTE or OPEN statement is out of range for its corresponding use.. SQLCODE=-302, SQLSTATE=22001, DRIVER=3.62.57
          Hide
          Raymond Auge added a comment - - edited

          There may be some other issue at work here since the portal-model-hints.xml file declares that the Portlet.portletId table column is 200 wide. Meanwhile, the PortletPreferences is also 200 wide.

          It's possible that there is a "DB Upgrade" issue if we ever had a column width of 75 and expected it later to be widened to 200 and never was altered.

          Secondly, there is another way that portletIds might mistakenly reach max length:

          It's when we have an instanceable portlet. The instance separator (_INSTANCE_) is already 10 characters wide.

          Furthermore, the instance id has been increased, in version 6.1+, to 8 characters.

          This means that instanced portletId can be extended by 18 characters which reduces the total possible length a plugin's portletId should be to 182 chars.

          A plugin already includes a separator (_WAR_) which further reduces the length of portlet ids a developer should create to 177 chars.

          This has to be slit between the web context path and portlet id (after normalization by PortalUtil.getJsSafePortletId(portletId)).

          One final addition to the portlet id might come when using portlets on "customizable pages". This feature allows users to make personalized changes to shared pages. The portlets added in this manner are name-spaced to the user in order to not collide with other users' portlets. This name-spacing adds a further separator (_USER_) plus the userId to the portletId. Due to the portal's counter strategy, it's unlikely that a userId is less than 5 digits wide. This places the minimum length of the user separator and id at 11 chars. It would be safer to allow for user ids of around 20 digits in width, further reducing the max portlet id length at 152 chars.

          In summary, it should be recommendation to limit the width of portlet ids assigned by developers to no more than 152 chars when combining the servlet context name plus portlet id.

          Show
          Raymond Auge added a comment - - edited There may be some other issue at work here since the portal-model-hints.xml file declares that the Portlet.portletId table column is 200 wide. Meanwhile, the PortletPreferences is also 200 wide. It's possible that there is a "DB Upgrade" issue if we ever had a column width of 75 and expected it later to be widened to 200 and never was altered. Secondly, there is another way that portletIds might mistakenly reach max length: It's when we have an instanceable portlet. The instance separator ( _INSTANCE_ ) is already 10 characters wide. Furthermore, the instance id has been increased, in version 6.1+, to 8 characters. This means that instanced portletId can be extended by 18 characters which reduces the total possible length a plugin's portletId should be to 182 chars. A plugin already includes a separator ( _WAR_ ) which further reduces the length of portlet ids a developer should create to 177 chars. This has to be slit between the web context path and portlet id (after normalization by PortalUtil.getJsSafePortletId(portletId) ). One final addition to the portlet id might come when using portlets on "customizable pages". This feature allows users to make personalized changes to shared pages. The portlets added in this manner are name-spaced to the user in order to not collide with other users' portlets. This name-spacing adds a further separator ( _USER_ ) plus the userId to the portletId. Due to the portal's counter strategy, it's unlikely that a userId is less than 5 digits wide. This places the minimum length of the user separator and id at 11 chars. It would be safer to allow for user ids of around 20 digits in width, further reducing the max portlet id length at 152 chars. In summary, it should be recommendation to limit the width of portlet ids assigned by developers to no more than 152 chars when combining the servlet context name plus portlet id.
          Hide
          Alberto Montero added a comment -

          Hi Ray,

          I have checked the DB creation scripts and I have found that in tables PortletItem and Repository, the column portletId has width 75 chars. I guess these were not updated when model hints were expanded.

          I have also found that table JournalFeed has a column named targetPortletId, that should probably be expanded to 200 chars. What do you think?

          Alberto

          Show
          Alberto Montero added a comment - Hi Ray, I have checked the DB creation scripts and I have found that in tables PortletItem and Repository, the column portletId has width 75 chars. I guess these were not updated when model hints were expanded. I have also found that table JournalFeed has a column named targetPortletId, that should probably be expanded to 200 chars. What do you think? Alberto
          Show
          Raymond Auge added a comment - Final pr was https://github.com/brianchandotcom/liferay-portal/pull/11371
          Hide
          Raymond Auge added a comment -

          Alberto, I think that change would require a different ticket. Can you go ahead and create that?

          Show
          Raymond Auge added a comment - Alberto, I think that change would require a different ticket. Can you go ahead and create that?
          Hide
          Brian Chan added a comment -

          private static final int _PORTLET_ID_MAX_LENGTH =
          ModelHintsUtil.getMaxLength(Portlet.class.getName(), "portletId") -
          (PortletConstants.INSTANCE_SEPARATOR.length() +
          PortletConstants.USER_SEPARATOR.length() + 39);

          39 is the longest possible value for a long.

          Show
          Brian Chan added a comment - private static final int _PORTLET_ID_MAX_LENGTH = ModelHintsUtil.getMaxLength(Portlet.class.getName(), "portletId") - (PortletConstants.INSTANCE_SEPARATOR.length() + PortletConstants.USER_SEPARATOR.length() + 39); 39 is the longest possible value for a long.
          Hide
          Alberto Montero added a comment -

          Created LPS-35711 to expand columns.

          Show
          Alberto Montero added a comment - Created LPS-35711 to expand columns.
          Hide
          Michael Saechang added a comment -

          Committed on:
          Portal 6.2.x GIT ID: 703b9bcdd7ff824f4239e136dda9c31754ab62bf.

          Show
          Michael Saechang added a comment - Committed on: Portal 6.2.x GIT ID: 703b9bcdd7ff824f4239e136dda9c31754ab62bf.

            People

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

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                1 year, 40 weeks, 5 days ago

                Development

                  Structure Helper Panel