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

Service Builder generated code (within Portlet/Hook plugin) causes "Unresolved compilation problems" while referencing Liferay services.

    Details

    • Type: Bug Bug
    • Status: Closed
    • Resolution: Duplicate
    • Affects Version/s: 6.1.0 CE GA1
    • Fix Version/s: 6.1.1 CE GA2
    • Labels:
      None
    • Environment:
      Liferay 6.1 GA1 bundled with Tomcat, PostgreSQL 9.1, Windows 7, Liferay IDE for Eclipse
    • Similar Issues:
      Show 5 results 

      Description

      Steps to reproduce error:
      1. Create portlet/hook plugin with SDK
      2. Create service.xml with entity that references any Liferay service:

      <service-builder>
      <entity name="Foo" local-service="true">
      ...
      <column name="memberEntry" type="Collection" entity="com.liferay.portal.User"
      mapping-key="userId" />
      ...
      <reference entity="User" package-path="com.liferay.portal" />
      ...
      </entity>
      </service-builder>
      

      3. Build service with ant build-service
      4. Deploy service with ant deploy

      Liferay fails to deploy plugin and prints out the following stacktrace:

      18:59:17,540 ERROR [ContextLoader:227] Context initialization failed
      org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pl.kgolebiowski.recipientsList.service.RecipientsListLocalService' defined in ServletContext resource [/WEB-INF/c
      lasses/META-INF/portlet-spring.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pl.kgolebiowski.recipient
      sList.service.persistence.RecipientsListPersistence' defined in ServletContext resource [/WEB-INF/classes/META-INF/portlet-spring.xml]: Instantiation of bean failed; nested exception is org.springfram
      ework.beans.BeanInstantiationException: Could not instantiate bean class [pl.kgolebiowski.recipientsList.service.persistence.RecipientsListPersistenceImpl]: Constructor threw exception; nested exceptio
      n is java.lang.Error: Unresolved compilation problems:
      com.liferay.portal.model.impl.UserModelImpl cannot be resolved to a variable
      com.liferay.portal.model.impl.UserModelImpl cannot be resolved to a variable
      com.liferay.portal.model.impl.UserImpl cannot be resolved to a type
      com.liferay.portal.service.persistence.UserPersistenceImpl cannot be resolved to a variable
      com.liferay.portal.model.impl.UserImpl cannot be resolved to a type
      com.liferay.portal.model.impl.UserModelImpl cannot be resolved to a variable
      com.liferay.portal.model.impl.UserModelImpl cannot be resolved to a variable
      com.liferay.portal.model.impl.UserImpl cannot be resolved to a type
      com.liferay.portal.service.persistence.UserPersistenceImpl cannot be resolved to a variable
      com.liferay.portal.model.impl.UserModelImpl cannot be resolved to a variable
      com.liferay.portal.model.impl.UserModelImpl cannot be resolved to a variable
      com.liferay.portal.model.impl.UserImpl cannot be resolved to a type
      com.liferay.portal.service.persistence.UserPersistenceImpl cannot be resolved to a variable
      
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
      at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
      at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
      at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:282)
      at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:204)
      at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
      at com.liferay.portal.spring.context.PortletContextLoaderListener.contextInitialized(PortletContextLoaderListener.java:99)
      at com.liferay.portal.kernel.servlet.PortalClassLoaderServletContextListener.doPortalInit(PortalClassLoaderServletContextListener.java:91)
      at com.liferay.portal.kernel.util.BasePortalLifecycle.portalInit(BasePortalLifecycle.java:42)
      at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:61)
      at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:53)
      at com.liferay.portal.kernel.util.BasePortalLifecycle.registerPortalLifecycle(BasePortalLifecycle.java:52)
      at com.liferay.portal.kernel.servlet.PortalClassLoaderServletContextListener.contextInitialized(PortalClassLoaderServletContextListener.java:50)
      at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4765)
      at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5260)
      at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
      at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:866)
      at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:842)
      at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:615)
      at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1095)
      at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1617)
      at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
      at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
      at java.util.concurrent.FutureTask.run(FutureTask.java:138)
      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
      at java.lang.Thread.run(Thread.java:619)
      

      Service builder generates code that depends on portal-impl.jar (in above example it is class com.liferay.portal.model.impl.UserModelImpl) which is not accessible within Hook/Portlet plugin scope.

      Examples of faulty code generated by SB (class MyServicePersistenceImpl):

      public static final FinderPath FINDER_PATH_GET_USERS = new FinderPath(com.liferay.portal.model.impl.UserModelImpl.ENTITY_CACHE_ENABLED,
      com.liferay.portal.model.impl.UserModelImpl.FINDER_CACHE_ENABLED,
      com.liferay.portal.model.impl.UserImpl.class,
      com.liferay.portal.service.persistence.UserPersistenceImpl.FINDER_CLASS_NAME_LIST_WITHOUT_PAGINATION,
      "getUsers",
      new String[] {
      Long.class.getName(), "java.lang.Integer", "java.lang.Integer",
      "com.liferay.portal.kernel.util.OrderByComparator"
      });
      
      public List<com.liferay.portal.model.User> getUsers(long pk, int start,
      int end, OrderByComparator orderByComparator) throws SystemException {
      ...
      SQLQuery q = session.createSQLQuery(sql);
      
      q.addEntity("Portal_User",
      com.liferay.portal.model.impl.UserImpl.class);
      
      QueryPos qPos = QueryPos.getInstance(q);
      
      qPos.add(pk);
      ...
      }
      

      Discussion about the bug: http://www.liferay.com/community/forums/-/message_boards/message/13557544

        Issue Links

          Activity

          Hide
          Tomas Polesovsky added a comment - - edited

          Hi Krzysztof, I found the same problem earlier. It's more architectural limitation than a bug. You can see the same problem in different colors here: http://issues.liferay.com/browse/LPS-8292

          If you want to reference User entity then you have to provide concrete class (not just an interface) to Hibernate so as it is able to map that class to the User_ table. But you need to keep in mind that portal has own hibernate session and your plugin will have also, together with all the hibernate caches and entities cached in there.

          One solution (more simple) is to omit the user reference in your service.xml and just use Long userId. Then in your service layer introduce custom method where you merge results from your persistence (using custom finder or dynamic query) with users you load using portal API.

          Another solution is to turn off concrete caches in hibernate, portal and your plugin hibernate, provide your own implementation of User interface for your hibernate session. But this is very complex.

          Third solution is to omit hibernate and use native SQL to get what you want. But again, you need to turn of caches or can't modify the User.

          Show
          Tomas Polesovsky added a comment - - edited Hi Krzysztof, I found the same problem earlier. It's more architectural limitation than a bug. You can see the same problem in different colors here: http://issues.liferay.com/browse/LPS-8292 If you want to reference User entity then you have to provide concrete class (not just an interface) to Hibernate so as it is able to map that class to the User_ table. But you need to keep in mind that portal has own hibernate session and your plugin will have also, together with all the hibernate caches and entities cached in there. One solution (more simple) is to omit the user reference in your service.xml and just use Long userId. Then in your service layer introduce custom method where you merge results from your persistence (using custom finder or dynamic query) with users you load using portal API. Another solution is to turn off concrete caches in hibernate, portal and your plugin hibernate, provide your own implementation of User interface for your hibernate session. But this is very complex. Third solution is to omit hibernate and use native SQL to get what you want. But again, you need to turn of caches or can't modify the User.
          Hide
          Krzysztof Gołębiowski added a comment -

          Tomas, thanks for your answer. It was some time ago but as I remember, I used first option - referencing by userId. Hope they will fix it or rather find some different solution - but issues are still in backlog so far.

          Show
          Krzysztof Gołębiowski added a comment - Tomas, thanks for your answer. It was some time ago but as I remember, I used first option - referencing by userId. Hope they will fix it or rather find some different solution - but issues are still in backlog so far.
          Hide
          Tomas Polesovsky added a comment -

          Hi Krzysztof, good to read from you again I close this bug as a duplicate, please watch the original issue

          Show
          Tomas Polesovsky added a comment - Hi Krzysztof, good to read from you again I close this bug as a duplicate, please watch the original issue
          Hide
          Krzysztof Gołębiowski added a comment -

          Ok

          Show
          Krzysztof Gołębiowski added a comment - Ok

            People

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

              Dates

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

                Development

                  Structure Helper Panel