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

Custom Model Listener: value.object.listener on plugin portlet sdk project throw java.langClassNotFoundException

    Details

    • Type: Bug
    • Status: Closed
    • Resolution: Fixed
    • Affects Version/s: 6.0.3 GA, 6.0.6 GA, 6.0.12 EE, 6.1.0 CE RC1, 6.1.1 CE GA2, 6.1.20 EE GA2
    • Labels:
    • Environment:
    • Branch Version/s:
      6.1.x, 6.0.x
    • Backported to Branch:
      Committed
    • Epic/Theme:
    • Story Points:
      2
    • Fix Priority:
      3
    • Similar Issues:
      Show 5 results 

      Description

      When follow the recipe desribed in http://www.liferay.com/community/forums/-/message_boards/message/3229889 (How to Create Model Listener Class in Plugin?) I get an error message like this:

      Loading file:/share/dev/mesalc-web/sdk/portlets/mesalc-data/docroot/WEB-INF/classes/service.properties
      15:53:26,043 ERROR [InstitutionPersistenceImpl:1420]
      java.lang.ClassNotFoundException: org.mesalc.hook.listeners.InstitutionListener
      at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1516)
      at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1361)
      at com.liferay.portal.kernel.util.InstanceFactory.newInstance(InstanceFactory.java:37)
      at com.liferay.portal.kernel.util.InstanceFactory.newInstance(InstanceFactory.java:25)
      at org.mesalc.service.persistence.InstitutionPersistenceImpl.afterPropertiesSet(InstitutionPersistenceImpl.java:1413)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

      Looking at the code in XXXPersistenceImpl.afterPropertiesSet method, I could see that the invocation to create the new listerner instance:

      ...InstanceFactory.newInstance(listenerClassName));

      was made whitout specifying a ClassLoader. Testing to change this line to:

      ...InstanceFactory.newInstance(PortletClassLoaderUtil.getClassLoader (), listenerClassName));

      solve the problem, but as this class is autogenerated, I lose the changes every time I run "ant build-service".

        Issue Links

          Activity

          Hide
          mansay Reinaldo Silva added a comment -

          As a workaround it's possible to expand the build-service task mentioned in the recipe to include a replace like:

          <replace
          dir="$

          {basedir}

          /docroot/WEB-INF/src/<your service package>/service/persistence"
          includes="*PersistenceImpl.java"
          summary="yes">
          <replacefilter>
          <replacetoken>import com.liferay.portal.kernel.log.LogFactoryUtil;</replacetoken>
          <replacevalue>import com.liferay.portal.kernel.log.LogFactoryUtil;
          import com.liferay.portal.kernel.portlet.PortletClassLoaderUtil;</replacevalue>
          </replacefilter>
          <replacefilter
          token="InstanceFactory.newInstance("
          value="InstanceFactory.newInstance(PortletClassLoaderUtil.getClassLoader (),"/>
          </replace>

          Show
          mansay Reinaldo Silva added a comment - As a workaround it's possible to expand the build-service task mentioned in the recipe to include a replace like: <replace dir="$ {basedir} /docroot/WEB-INF/src/<your service package>/service/persistence" includes="*PersistenceImpl.java" summary="yes"> <replacefilter> <replacetoken>import com.liferay.portal.kernel.log.LogFactoryUtil;</replacetoken> <replacevalue>import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.portlet.PortletClassLoaderUtil;</replacevalue> </replacefilter> <replacefilter token="InstanceFactory.newInstance(" value="InstanceFactory.newInstance(PortletClassLoaderUtil.getClassLoader (),"/> </replace>
          Hide
          icarrara Ivano Carrara added a comment -

          The workaround is not working ...

          After I included the suggested code to the build-service task, when I opened Eclipse IDE I got the below error about the new build-common-plugin.xml:

          The value of attribute "dir" associated with an element type "replace" must not contain the '<' character.

          Do you tried the modified file in Eclipse?

          Show
          icarrara Ivano Carrara added a comment - The workaround is not working ... After I included the suggested code to the build-service task, when I opened Eclipse IDE I got the below error about the new build-common-plugin.xml: The value of attribute "dir" associated with an element type "replace" must not contain the '<' character. Do you tried the modified file in Eclipse?
          Hide
          icarrara Ivano Carrara added a comment -

          Excuse me for the previous comment, was my fault!

          But... I installed in Liferay SDK the new buil-common-plugin.xml from this LPS-10988 workaround, then I replaced the name of my service package as below:

          <replace dir="$

          {basedir}

          /docroot/WEB-INF/src/o2/base/service/persistence" includes="*PersistenceImpl.java" summary="yes">

          ... and rebuilt the services but the error is still the same:

          Caused by: com.liferay.portal.kernel.bean.BeanLocatorException: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'o2.base.service.persistence.OMUserDittaPersistence' is defined

          Anyone used the modified build-common-plugin.xml as this workaround stated ?

          Show
          icarrara Ivano Carrara added a comment - Excuse me for the previous comment, was my fault! But... I installed in Liferay SDK the new buil-common-plugin.xml from this LPS-10988 workaround, then I replaced the name of my service package as below: <replace dir="$ {basedir} /docroot/WEB-INF/src/o2/base/service/persistence" includes="*PersistenceImpl.java" summary="yes"> ... and rebuilt the services but the error is still the same: Caused by: com.liferay.portal.kernel.bean.BeanLocatorException: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'o2.base.service.persistence.OMUserDittaPersistence' is defined Anyone used the modified build-common-plugin.xml as this workaround stated ?
          Hide
          mansay Reinaldo Silva added a comment -

          Just in case, make sure to make a full clean before rebuild/deploy, ie undeploy your portlet, ant clean build-service deploy

          Show
          mansay Reinaldo Silva added a comment - Just in case, make sure to make a full clean before rebuild/deploy, ie undeploy your portlet, ant clean build-service deploy
          Hide
          mansay Reinaldo Silva added a comment -

          Also, you can look to the approach taken in LPS-15144. I recently used against the sources for 6.0.6 and works perfectly.

          Again, full clean is an anti-headache sanity measure when services sources are involved, especially when existing methods signatures changes.

          Show
          mansay Reinaldo Silva added a comment - Also, you can look to the approach taken in LPS-15144 . I recently used against the sources for 6.0.6 and works perfectly. Again, full clean is an anti-headache sanity measure when services sources are involved, especially when existing methods signatures changes.
          Hide
          mukul.liferay Mukul Kumar added a comment -

          The easiest solution of this issue is to just modify your bean's persistenceImpl class's method name afterPropertiesSet: -

          /**

          • Initializes the MyBean persistence.
            */
            public void afterPropertiesSet() {
            String[] listenerClassNames = StringUtil.split(GetterUtil.getString(
            com.liferay.portal.kernel.util.PropsUtil.get(
            "value.object.listener.com.test.model.MyBean")));

          if (listenerClassNames.length > 0) {
          try {
          List<ModelListener<MyBean>> listenersList = new ArrayList<ModelListener<MyBean>>();
          for (String listenerClassName : listenerClassNames)

          { listenersList.add((ModelListener<MyBean>)InstanceFactory.newInstance(PortletClassLoaderUtil.getClassLoader(), listenerClassName, (Class<?>[])null, (Object[])null)); }

          listeners = listenersList.toArray(new ModelListener[listenersList.size()]);
          }
          catch (Exception e)

          { _log.error(e); }
          }
          }

          I have passed PortletContext to InstanceFactory and it will find my Listener bean. For completely fixed this issue just change the lifera.src\portal-impl\src\com\liferay\portal\tools\servicebuilder\dependencies\persistence_impl.ftl: -

          /**
          * Initializes the ${entity.humanName} persistence.
          */
          public void afterPropertiesSet() {
          String[] listenerClassNames = StringUtil.split(GetterUtil.getString(${propsUtil}.get("value.object.listener.${packagePath}.model.${entity.name}")));

          if (listenerClassNames.length > 0) {
          try {
          List<ModelListener<${entity.name}>> listenersList = new ArrayList<ModelListener<${entity.name}>>();

          for (String listenerClassName : listenerClassNames) {
          listenersList.add((ModelListener<${entity.name}>)InstanceFactory.newInstance(PortletClassLoaderUtil.getClassLoader(), listenerClassName, (Class<?>[])null, (Object[])null));
          }

          listeners = listenersList.toArray(new ModelListener[listenersList.size()]);
          }
          catch (Exception e) { _log.error(e); }

          }

          Cheers and happy coding............

          Show
          mukul.liferay Mukul Kumar added a comment - The easiest solution of this issue is to just modify your bean's persistenceImpl class's method name afterPropertiesSet: - /** Initializes the MyBean persistence. */ public void afterPropertiesSet() { String[] listenerClassNames = StringUtil.split(GetterUtil.getString( com.liferay.portal.kernel.util.PropsUtil.get( "value.object.listener.com.test.model.MyBean"))); if (listenerClassNames.length > 0) { try { List<ModelListener<MyBean>> listenersList = new ArrayList<ModelListener<MyBean>>(); for (String listenerClassName : listenerClassNames) { listenersList.add((ModelListener<MyBean>)InstanceFactory.newInstance(PortletClassLoaderUtil.getClassLoader(), listenerClassName, (Class<?>[])null, (Object[])null)); } listeners = listenersList.toArray(new ModelListener [listenersList.size()] ); } catch (Exception e) { _log.error(e); } } } I have passed PortletContext to InstanceFactory and it will find my Listener bean. For completely fixed this issue just change the lifera.src\portal-impl\src\com\liferay\portal\tools\servicebuilder\dependencies\persistence_impl.ftl: - /** * Initializes the ${entity.humanName} persistence. */ public void afterPropertiesSet() { String[] listenerClassNames = StringUtil.split(GetterUtil.getString(${propsUtil}.get("value.object.listener.${packagePath}.model.${entity.name}"))); if (listenerClassNames.length > 0) { try { List<ModelListener<${entity.name}>> listenersList = new ArrayList<ModelListener<${entity.name}>>(); for (String listenerClassName : listenerClassNames) { listenersList.add((ModelListener<${entity.name}>)InstanceFactory.newInstance(PortletClassLoaderUtil.getClassLoader(), listenerClassName, (Class<?>[])null, (Object[])null)); } listeners = listenersList.toArray(new ModelListener [listenersList.size()] ); } catch (Exception e) { _log.error(e); } } Cheers and happy coding............
          Hide
          edward.gonzales Edward Gonzales (Inactive) added a comment -

          Thanks for providing a fix Mukul! Please vote for this issue. We will keep you updated with any news regarding the implementation of this fix. Thanks again for your effort!

          Show
          edward.gonzales Edward Gonzales (Inactive) added a comment - Thanks for providing a fix Mukul! Please vote for this issue. We will keep you updated with any news regarding the implementation of this fix. Thanks again for your effort!
          Hide
          sophia.zhang Sophia Zhang added a comment -

          Can't tested by QA. Closing as "Fixed".

          Show
          sophia.zhang Sophia Zhang added a comment - Can't tested by QA. Closing as "Fixed".

            People

            • Votes:
              6 Vote for this issue
              Watchers:
              9 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                2 years, 46 weeks ago

                Development

                  Subcomponents

                    Structure Helper Panel