*ServiceUtil classes in OSGi modules

Jan Tošovský, modified 6 Years ago. Liferay Master Posts: 576 Join Date: 7/22/10 Recent Posts

In the post https://community.liferay.com/forums/-/message_boards/message/83433590 there is stated:

 

The *LocalServiceUtil classes are purely for legacy portlets as they hide the dependency and only provide an indirection to call the service. With OSGi components, you should never call the *LocalServiceUtil classes any more.

 

Can somebody elaborate why they should never be used?

 

In my module I use base portlet, which is subclassed. Only subclasses have @Component annotation which means no @Reference annotation is processed. This behaviour is described here https://community.liferay.com/blogs/-/blogs/liferay-osgi-annotations-what-they-are-and-when-to-use-them

 

However, if I replace injected services (marked by @Reference annotations) with *ServiceUtil method calls, it seems to be working.

 

Now I am not sure if this just coincidence. I really do not want to duplicate my code in all subclasses.

thumbnail
Minhchau Dang, modified 6 Years ago. Liferay Master Posts: 598 Join Date: 10/22/07 Recent Posts
Jan Tošovský:

Can somebody elaborate why they should never be used?

When you use a LocalServiceUtil, you are claiming that your component needs no implementation of that service before it is considered ready for activation. In other words, as long as the API bundle is there, even if there is no service bundle deployed, even if none of its Spring components were registered, you're saying that your component will work perfectly and it is perfectly safe for other components to start calling methods on your component.

If you're building code in a vacuum, and you're not calling the LocalServiceUtil from a component activation, it's probably safe. However, if you're working with a team, this is a debugging nightmare waiting to happen.

Jan Tošovský:

In my module I use base portlet, which is subclassed. Only subclasses have @Component annotation which means no @Reference annotation is processed. This behaviour is described here https://community.liferay.com/blogs/-/blogs/liferay-osgi-annotations-what-they-are-and-when-to-use-them

You can put the @Reference on a method in the child, have that method exist on both the parent and the child, and have the child delegate its call to the parent. I believe this is what David refers to as "@Reference annotation copying" in a subsequent blog on this topic, BND Instruction to Avoid, where the BND instruction that you should avoid is one that transparently provides that reference copying (if you put the annotation on methods rather than member variables).