留言板
Register service
Hi!
I am currently developing an MVC Portlet with the Liferay IDE for Liferay 7 CE GA5. Everything's been great so far, except for one thing. I created an interface that describes the methods that I need to invoke in my MVCPortlet class that correspond to my business logic. Then, I created an implementation of said interface,; however, my implementation requires that I have a reference to the AssetEntryLocalService class to use in my code. So I tried what I've seen on documentation, a great blog post by David, and what I see on my MVCPortlet class and it is not working...
This is what I currently have. When I print _assetEntryLocalService, it returns null.
Am I missing something? I read that in order for us to have a reference to any OSGI component, the class that makes the reference should also be an OSGI component, hence the component annotation.
Thanks for any help!
I am currently developing an MVC Portlet with the Liferay IDE for Liferay 7 CE GA5. Everything's been great so far, except for one thing. I created an interface that describes the methods that I need to invoke in my MVCPortlet class that correspond to my business logic. Then, I created an implementation of said interface,; however, my implementation requires that I have a reference to the AssetEntryLocalService class to use in my code. So I tried what I've seen on documentation, a great blog post by David, and what I see on my MVCPortlet class and it is not working...
This is what I currently have. When I print _assetEntryLocalService, it returns null.
package xx.yy.zz.mymodule.service.impl;
import com.liferay.asset.kernel.service.AssetEntryLocalService;
@Component(
immediate = true
)
public class MyLocalServiceImpl implements MyLocalService {
...
...
...
@Reference(unbind ="-")
private void setAssetEntryLocalService (AssetEntryLocalService assetEntryLocalService) {
_assetEntryLocalService = assetEntryLocalService;
}
private AssetEntryLocalService _assetEntryLocalService;
}
Am I missing something? I read that in order for us to have a reference to any OSGI component, the class that makes the reference should also be an OSGI component, hence the component annotation.
Thanks for any help!
That is proper for your MyLocalServiceImpl.
Are you doing an @Reference injection of MyLocalService into your MVC portlet class too?
Are you doing an @Reference injection of MyLocalService into your MVC portlet class too?
David, I am so glad that you are the one participating on my thread. No, in my Portlet, instead of assigning a reference to MyLocalService using OSGI, I am importing the class and creating a new instance on any method were it is necessary. I understand that it might be wrong, but I am even creating a new instance of this service on my view.jsp.
In any case, when I try to invoke any method from _assetEntryLocalService inside a method on MyLocalServiceImpl, I get a NullPointerException. Besides the OSGI annotations, is there any other kind of setup that I'm missing?
In any case, when I try to invoke any method from _assetEntryLocalService inside a method on MyLocalServiceImpl, I get a NullPointerException. Besides the OSGI annotations, is there any other kind of setup that I'm missing?
Edward A:
David, I am so glad that you are the one participating on my thread. No, in my Portlet, instead of assigning a reference to MyLocalService using OSGI, I am importing the class and creating a new instance on any method were it is necessary. I understand that it might be wrong, but I am even creating a new instance of this service on my view.jsp.
This indeed is your problem: When you instantiate your service yourself, you're responsible for initializing it. When you leave this to the OSGi framework, it will do the initialization for you. You're using a service, not an instantiated class. The service won't be available when undeployed and you must not keep references in other places than the @Reference location (for longer than temporary use).
You can (for the short processing time) store a reference to the service in the request attributes, so that you can use it from your view.jsp, but never should you instantiate your Impl class yourself.
+1 for Olaf's response.
It works like Spring containers - if you let Spring auto-wire your dependency in, Spring will make sure the dependency is fully wired.
But if you just do a "new MyLocalServiceImpl();" sort of approach, you're taking Spring out of the picture and it would not be able to handle the wiring.
If you do want to do the "new MyLocalServiceImpl();" approach, well you're taking over responsibility for the construction so you are also incurring the responsibility for the dependency injection.
It works like Spring containers - if you let Spring auto-wire your dependency in, Spring will make sure the dependency is fully wired.
But if you just do a "new MyLocalServiceImpl();" sort of approach, you're taking Spring out of the picture and it would not be able to handle the wiring.
If you do want to do the "new MyLocalServiceImpl();" approach, well you're taking over responsibility for the construction so you are also incurring the responsibility for the dependency injection.