Hi Tanvir,

I would strongly recommend that you do not use solution A. Static variables are 
a very bad thing for many reasons, not least (as you have discovered) because 
they completely bypass the lifecycle management of your component. In answer to 
the question:

"Question: If we set LogService and RefManager as immediate components 
(RefManager  is immediate  by default for  being a Component), is it guaranteed 
that  they will be activated before EmpService?"

No - this will not help you. You are stepping totally outside the design of 
Declarative Services and the result will be an inconsistent mess.

"Another solution for the above problem is to view LogService as OPTIONAL"

This is actually something different, as it’s saying that you want your code to 
work both with and without a log service, in this case you do need to be able 
to handle there being no log service to log to.


To go back to your original question:

"Is there a way to solve this proliferation of DS Components and References?"

Having lots of DS components is a good thing! They are lightweight and they 
manage your service dependencies. 

You could use field injection to avoid some boilerplate:

@Component
public class Emp implements EmpService {
  @Reference
  LogService log;
}

If you really are allergic to using DS for injecting the Log service then an 
alternative is to use something like SLF4J instead. This can be configured to 
log to the Log Service (by installing the correct SLF4J back end) and then you 
can configure the Log service to log somewhere else if you desire.

Regards,

Tim

> On 22 Jan 2018, at 06:06, Tanvir via osgi-dev <osgi-dev@mail.osgi.org> wrote:
> 
> 
> In DS, for accessing a service reference, the class has to be a Component. 
> That means to access common  services, such as log service, all classes 
> becomes Components. In the following example, to access log service all 
> classes in Emp bundle became Components.
>  
> @Component
> public class Emp implements EmpService {
>   LogService log
>   @Reference (cardinality = ReferenceCardinality.MANDATORY)
>   void setLogService(LogService log) { this.log = log; } 
>   
> }
> @Component
> public class EmpAddress  {
>   LogService log
>   @Reference (cardinality = ReferenceCardinality.MANDATORY)
>   void setLogService(LogService log) { this.log = log; } 
> }
> @Component
> public class EmpPayroll  {
>   LogService log
>   @Reference (cardinality = ReferenceCardinality.MANDATORY)
>   void setLogService(LogService log) { this.log = log; } 
> }
>  ....
> 
> Question: Is there a way to solve this proliferation of DS Components and 
> References? 
> 
> Solution A: We can factor out reference code and move them to a RefManager 
> Component. Also maintain a shared static variable to LogService for all other 
> classes.
> 
> @Component 
> public class RefManager {
>   static LogService log
>   @Reference (cardinality = ReferenceCardinality.MANDATORY)
>   void setLogService(LogService log) { this.log = log; } 
>  static LogService  getLogger() { return log;}}
> 
> @Component
> public class Emp implements EmpService {
>    ..
>    RefManager. getLogger.log();
> }
> 
> public class EmpAddress  {
>      .. 
>    RefManager. getLogger.log();
> }
> public class EmpPayroll  { 
>    ..
>    RefManager. getLogger.log();
> }
>  
> 
> Problem: Now we can end up with null LogService reference even though 
> LogService ref  is MANDATORY . E.g. if EmpService  is activated before 
> RefManager  or LogService, it gets null LogService ref.
>  
> Question: If we set LogService and RefManager as immediate components 
> (RefManager  is immediate  by default for  being a Component), is it 
> guaranteed that  they will be activated before EmpService? 
> 
> Solution B: 
> Another solution for the above problem is to view LogService as OPTIONAL. 
> However, an optional reference can be null requiring a null check. That means 
> each use of Log Service  api require the following null check.
> 
> If (log!=null) log.log(..);
> 
> 
> Problem:  Considering that log apis are heavily used, this seems tedious and 
> error-prone. Is there a better way of using OPTIONAL reference?
> 
>  
> 
> -- 
> Best,
> Tanvir
> _______________________________________________
> OSGi Developer Mail List
> osgi-dev@mail.osgi.org
> https://mail.osgi.org/mailman/listinfo/osgi-dev

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to