论坛

主页 » Liferay Portal » English » 3. Development

组合视图 统一视图 树状图
讨论主题 [ 上一个 | 下一个 ]
toggle
Ay Kay
Deploying Service Builder output to other portlets. How?
2013年1月31日 上午7:55
答复

Ay Kay

等级: Junior Member

帖子: 52

加入日期: 2011年11月17日

最近的帖子

Hi there.

Simple case. I have numerous portlets. Some of them need access to the same data in the database. This is handled via classes (DTOs, etc.) created by Service Builder. These Service Builder classes reside in an extra hook project. (Because I don't want them to be attached to a particular portlet, right?!)

How can I make the Service Builder classes now available to the other portlets?

Thanks for your hints.
Cheers

PS: I tried a couple of things that failed so far.
I placed the automatically generated JAR file holding the interfaces into the docroot/WEB-INF/lib folder of a particular porlet.
I generated an additional JAR file holding all implementing classes and also put that into that docroot/WEB-INF/lib.
All I get is either:
com.liferay.portal.kernel.bean.BeanLocatorException: BeanLocator has not been set for servlet context MY-HOOK-PROJECT
or when I add the hook project to Tomcat:
[render_portlet_jsp:154] java.lang.ClassCastException: $Proxy398 cannot be cast to my.package.datamodel.service.persistence.MyEntityPersistence
David H Nebinger
RE: Deploying Service Builder output to other portlets. How?
2013年1月31日 上午8:10
答复

David H Nebinger

等级: Liferay Legend

帖子: 7892

加入日期: 2006年9月1日

最近的帖子

Well, putting them in a hook was your first mistake.

You should create a vanilla Liferay MVC portlet, one that you feel comfortable deploying that has no other dependencies. This portlet gets deployed, but never actually placed on a page in Liferay.

Create your service layer there, and deploy that guy.

For other portlets, use liferay-plugin-package.properties file in the Liferay IDE and use a 'required deployment context' entry for the service portlet. The IDE will pull in the service jar, and the portlets will have access to the service layer. You won't have to worry about bean locator exceptions, because Liferay knows the portlets have a requirement for the service portlet, and they won't start until the service portlet has started.

Currently, you have everything in a hook. A hook doesn't have it's own context, it is deployed into the portal's context (ROOT). So the generated SB code is going to fail because it thinks there is a real context for the hook (which there isn't) and will never be able to handle the bean locator correctly.
Daniel Wilmes
RE: Deploying Service Builder output to other portlets. How?
2013年1月31日 上午8:23
答复

Daniel Wilmes

等级: Regular Member

帖子: 164

加入日期: 2011年5月23日

最近的帖子

We have done something similiar to what you are describing. We put the jar file generated by our hook in the tomcat global class path.

$root\liferay-portal-6.1.1-ce-ga2\tomcat-7.0.27\lib\ext
Ay Kay
RE: Deploying Service Builder output to other portlets. How?
2013年2月3日 上午6:27
答复

Ay Kay

等级: Junior Member

帖子: 52

加入日期: 2011年11月17日

最近的帖子

Thank you! That brought a lot of enlightement into my dark corner of ignorance.

By debugging I too discovered that while getting hold of a persistence object a context is used to distinguish things. Though I don't know why something like a front end concept like a web context is used to distinguish back end means like persistence classes, I now understand why Service Builder can only be used from within a Portlet realm.
So thanks David Nebinger for your quick and thorough explanation of background processes here!!

Daniel, I don't know how the hack you managed to do that, but this was exactly my inital approach. An approach that was a little too natural or naiv, given the background info we now have from David. I too would expect something like back end means such as a persistence layer to just be jar-ed and put into a globally accessable folder such as TOMCAT/lib/ext. If you could scetch out how you achieved that ..., well: hands down!

Thank you guys and have a nice weekend.
Cheers


PS: Just a sidenote and a spoiler to my progress in this case. I got rid of the sole hook project environment of my SB classes and re-did it within a dummy portlet I deployed, but never use on a page. Just as David proposed. Additionally I mentioned that "SB portlet" in all portlets that need to use the SB back end classes in their liferay-plugin-package.properties. Eclipse makes this easy enough. Still all it achieved was again just
[render_portlet_jsp:154] java.lang.ClassCastException: $Proxy398 cannot be cast to my.package.datamodel.service.persistence.MyEntityPersistence
I did a lot of F5 (project refreshes), project rebuilds, than copying generated jar to the portlets, again tons of F5, rebuilds,... but nothing.
Since I lost so many hours on this, I decided to swallow my pride and generate the SB classes in need in each and every portlet that requires it. I spare any comment on that.
David H Nebinger
RE: Deploying Service Builder output to other portlets. How?
2013年2月3日 上午7:38
答复

David H Nebinger

等级: Liferay Legend

帖子: 7892

加入日期: 2006年9月1日

最近的帖子

Ay Kay:
[render_portlet_jsp:154] java.lang.ClassCastException: $Proxy398 cannot be cast to my.package.datamodel.service.persistence.MyEntityPersistence


The front end should never be trying to use the persistence classes. All access should be via the XxxLocalServiceUtil classes.

By getting a class cast exception on the persistence object leads me to believe that you're trying to use the persistence layer for something, but you're not resolving the class loader issues as part of the process.

Any time you find yourself trying to access the persistence layer in the front end code, you need to adjust your thinking. The methods should be put into the XxxLocalServiceImpl class within the plugin that has the service code. Add the methods there, then re-run service builder to expose them in the XxxLocalServiceUtil class for the front end to get access to them.