« 返回到 Upgrade Instructions

Upgrading ServiceBuilder generated classes to Liferay 5.1.x

Here's how ServiceBuilder used to work prior to Liferay 5.1.x:

  • The build-service Ant task generated the following startup file, which contained the spring.configs key:
    • docroot/WEB-INF/src/portlet-service.properties
  • The build-service Ant task generated the following Spring Bean XML config files:
    • docroot/WEB-INF/src/META-INF/data-source-spring.xml
    • docroot/WEB-INF/src/META-INF/ext-spring.xml
    • docroot/WEB-INF/src/META-INF/portlet-spring.xml
  • There were 3 Spring Bean factories at runtime:
    • Bean factory in the ROOT context that contains all the core ServiceBuilder-generated services (like UserLocalService)
    • Bean factory in the portlet's context that contains the portlet's ServiceBuilder-generated services (like BookLocalService)
      • Created in a non-standard manner: During hot deploy process, web.xml is massaged so that a Liferay servlet context listener would get fired upon startup. The listener scanned the portlet's classpath for a file named portlet-service.properties which contained a spring.configs key whose value was a list of Spring Bean XML files.
    • Bean factory in the portlet's context
      • Created in the standard manner, by registering the Spring ContextLoaderListener in web.xml, and specifying the Spring contextConfigLocation context-param key with applicationConext.xml specified as the Spring Bean XML files to load. Used by PortletFaces to keep some singleton Spring Bean instances for objects like PortletFacesUtil

Here's how it worked in Liferay 5.1.1:

  • The build-service Ant task generates the following startup file, which NO LONGER contains the spring.configs key:
    • docroot/WEB-INF/src/service.properties
  • The build-service Ant task generates the following Spring Bean XML config files:
    • docroot/WEB-INF/src/META-INF/data-source-spring.xml
    • docroot/WEB-INF/src/META-INF/misc-spring.xml
    • docroot/WEB-INF/src/META-INF/portlet-spring.xml
  • There is only 1 Spring Bean factory (the one in the ROOT context), created in a standard Spring manner, with some Liferay adjustments:
    • It is "standard" in that Spring Bean XML config files are listed in the contextConfigLocation context-param key. The spring.configs entry is no longer used.
    • The Liferay-specific PortletContextLoaderListener is specified, rather than the Spring ContextLoaderListener. Actually, the Liferay one is simply a subclass of the Spring one that adds functionality.
    • Again, all Spring Beans are loaded into the factory in the ROOT context, which means that its easy to inject core liferay services like CounterLocalService into a Spring Bean in a portlet
    • Developer is responsible for manually adding the following markup to web.xml:
	<!-- Spring XmlWebApplicationContext bean definition files -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/classes/META-INF/data-source-spring.xml,/WEB-INF/classes/META-INF/misc-spring.xml,/WEB-INF/classes/META-INF/portlet-spring.xml,/WEB-INF/classes/META-INF/ext-spring.xml,/WEB-INF/applicationContext*.xml
		</param-value>
	</context-param>
	<!-- Spring XmlWebApplicationContext class -->
	<context-param>
		<param-name>contextClass</param-name>
		<param-value>com.liferay.portal.spring.context.PortletApplicationContext</param-value>
	</context-param>
	<!-- Listener that starts up the XmlWebApplicationContext IOC container (bean factory) -->
	<listener>
		<listener-class>com.liferay.portal.kernel.spring.context.PortletContextLoaderListener</listener-class>
	</listener>

Here's how it works in Liferay 5.1.2 (and moving forward):

  • The build-service Ant task generates the docroot/WEB-INF/src/service.properties startup file, which ONCE AGAIN INCLUDES the spring.configs key:
    #
    # Input a list of comma delimited Spring configurations. These will be
    # loaded after the bean definitions specified in the contextConfigLocation
    # parameter in web.xml.
    #
    spring.configs=\
        WEB-INF/classes/META-INF/base-spring.xml,\
        WEB-INF/classes/META-INF/hibernate-spring.xml,\
        WEB-INF/classes/META-INF/infrastructure-spring.xml,\
        WEB-INF/classes/META-INF/portlet-spring.xml,\
        WEB-INF/classes/META-INF/ext-spring.xml
 }}}

* The build-service Ant task generates the following Spring Bean XML config files:
** docroot/WEB-INF/src/META-INF/base-spring.xml
** docroot/WEB-INF/src/META-INF/hibernate-spring.xml
** docroot/WEB-INF/src/META-INF/infrastructure-spring.xml
** docroot/WEB-INF/src/META-INF/portlet-spring.xml

* There is only 1 Spring Bean factory (the one in the ROOT context), created in a standard Spring manner, with some Liferay adjustments:
** It is "standard" in that Spring Bean XML config files are listed in the contextConfigLocation context-param key. The XML files listed in the spring.configs entry are loaded after the bean definitions specified in the contextConfigLocation parameter in web.xml.
** The Liferay-specific PortletContextLoaderListener is specified, rather than the Spring ContextLoaderListener. This is simply a subclass of the Spring one that adds functionality.
** Again, all Spring Beans are loaded into the factory in the ROOT context, which means that its easy to inject core liferay services like CounterLocalService into a Spring Bean in a portlet
** Developer may add the following markup to web.xml, but is only necessary when there are other bean definitions (unlrelated to ServiceBuilder) that the developer wants Spring to manage:
{{{
	<!-- Spring XmlWebApplicationContext bean definition files -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/applicationContext.xml</param-value>
	</context-param>

Developer is responsible for manually adding the following markup to web.xml:

<!-- Spring XmlWebApplicationContext class --><context-param><param-name>contextClass</param-name><param-value>com.liferay.portal.spring.context.PortletApplicationContext</param-value></context-param><!-- Listener that starts up the XmlWebApplicationContext IOC container (bean factory) --><listener><listener-class>com.liferay.portal.kernel.spring.context.PortletContextLoaderListener</listener-class></listener> }}} 

0 附件
37899 查看
平均 (1 投票)
满分为 5,平均得分为 5.0。
评论
讨论主题回复 作者 日期
Glad to see this documentation. Is it also... Helmi Mahara 2008年11月20日 上午7:37
My problem solved after put this in... Helmi Mahara 2008年11月21日 上午4:56
I followed this documentation and did it in... Erika Piffero 2009年2月26日 上午12:53
Hi Helmi, Even I am facing the same problem.... Rajkumar Balasubramanian 2009年7月7日 下午10:48
I have got the same problem of not able to... Mahipalsinh Rana 2009年11月4日 上午1:31

Glad to see this documentation.
Is it also working in EXT environment? Or only in portlet?

I followed this documentation and did in EXT environment. After deployment and starting Tomcat I got this exception:
java.lang.ExceptionInInitializerError
at com.liferay.portal.events.StartupAction.run(StartupAction.java:51)
at com.liferay.portal.servlet.MainServlet.init(MainServlet.java:153)
at javax.servlet.GenericServlet.init(GenericServlet.java:212)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1139)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:966)
...
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433)
Caused by: java.lang.RuntimeException: CompanyLocalService is not set
at com.liferay.portal.service.CompanyLocalServiceUtil.getService(CompanyLocalServic­eUtil.java:230)
at com.liferay.portal.service.CompanyLocalServiceUtil.getCompanies(CompanyLocalServ­iceUtil.java:133)
at com.liferay.portal.search.lucene.IndexWriterFactory.<init>(IndexWriterFactory.ja­va:82)
at com.liferay.portal.search.lucene.LuceneUtil.<init>(LuceneUtil.java:766)
at com.liferay.portal.search.lucene.LuceneUtil.<clinit>(LuceneUtil.java:764)

In the EXT environment what configuration should be in:
- portal-ext.properties, escpecially for spring.configs
- web.xml

I really appreciate the answer.
Thank you.
在 08-11-20 上午7:37 发帖。
My problem solved after put this in portal-ext.properties
custom.sql.configs=custom-sql/default.xml,custom-sql/defaul­t-ext.xml
在 08-11-21 上午4:56 发帖以回复 Helmi Mahara
I followed this documentation and did it in portlet war development (with sdk plugin). During hot deploy I have this error: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.ext.portlet.newsletter.service.NewsletterDeliveryLocalService.impl': Injection of resource fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.ext.portlet.newsletter.service.NewsletterDeliveryService.impl': Injection of resource fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.ext.portlet.newsletter.service.NewsletterEntryLocalService.impl': Injection of resource fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.ext.portlet.newsletter.service.NewsletterEntryService.impl': Injection of resource fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.ext.portlet.newsletter.service.NewsletterFlagLocalService.impl': Injection of resource fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.ext.portlet.newsletter.service.NewsletterFlagService.impl': Injection of resource fields failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'com.liferay.counter.service.CounterLocalService.impl' is defined

it seems that my portlet can't inject core liferay services...

any suggestion?
在 09-2-26 上午12:53 发帖以回复 Helmi Mahara
Hi Helmi,

Even I am facing the same problem. Please let me know whether you have resolved the problem? Please give suggestions on it. Its very urgent.
在 09-7-7 下午10:48 发帖以回复 Erika Piffero
I have got the same problem of not able to create new bean reference while developing portlet in Plugins enviroment. It looks like circular reference issue where A class refer to B , B refer to C , and C wants A . My guess and due to that it is not able to initialize any of it.

Same error what rajkumar posted I have got .

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.cignex.portlet.survey.service.SurveyLocalService.impl': Injection of BeanReference fields failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'com.cignex.portlet.survey.service.SurveyService.impl' is defined
at com.liferay.portal.spring.annotation.BeanReferenceAnnotationBeanPostProcessor.po­stProcessAfterInstantiation(BeanReferenceAnnotationBeanPostProcessor.java:67)

Any­ help
在 09-11-4 上午1:31 发帖。