Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OSGI @Component annotation does not include references required by the base class while extending an existing OSGI service

I'm trying to extend an OSGI service. The OSGI service that is being extended includes some references and properties. I'm using the new org.osgi.service.component.annotations package. The meta XML generated by the annotations processor of OSGi R6 implementation does not account for the reference and property declarations made in the OSGI service I'm extending.

Apache Felix Maven SCR plugin handles this use case well and the class annotated with Felix annotations includes references and properties of the base class as well.

Is there a way to get this working with the official OSGI annotation implementation. I don't want to fallback to Felix SCR plugin unless I have to as their official website says to move on to the OSGI implementation and this is a new project where SCR plugin is not already in use.

like image 990
Sharath Madappa Avatar asked Jan 03 '23 20:01

Sharath Madappa


2 Answers

The meta XML generated by the annotations processor of OSGi R6 implementation does not account for the reference and property declarations made in the OSGI service I'm extending.

The behaviour you are expecting is down to the build tool you are using to generate the XML, not the annotations themselves. In general it is not a good idea to generate the XML based on annotations found in the parent class. This is because the parent class located at build time may not be the same as the parent class located at runtime. In this situation it is possible that generated injection sites might not actually be present at runtime, causing lots of problems. In fact even if the type is the same, you are referencing private details of the parent class from the subclass.

That warning aside, you are probably using a bnd-based tool, such as the maven-bundle-plugin or bnd-maven-plugin to generate the XML file. To avoid the issues I have mentioned bnd does not search the parent class of a component for annotations, but this behaviour can be overridden in configuration using the following instruction:

-dsannotations-options: inherit

If you add that configuration option then you should see the behaviour that you want, but it is strongly recommended that you do not do this when the parent class and child class are in different bundles.

like image 188
Tim Ward Avatar answered May 06 '23 00:05

Tim Ward


Another option that doesn't require inheriting annotations from the base class is to redeclare the needed references in the component itself:

@Component(
     service = SomeService.class,
     reference = {
         @Reference(
             name = "baseClassField",
             field = "baseClassField",
             service = SomeOtherService.class
         ),
         @Reference(
             name = "otherBaseClassField",
             field = "otherBaseClassField",
             service = YetAnotherService.class,
             cardinality=ReferenceCardinality.MULTIPLE,
             policy=ReferencePolicy.DYNAMIC
         )
     }
)
public class MyServiceImplementation
    extends AbstractSomeServiceBaseImpl
    implements SomeService
{...}

The obvious disadvantage is that you explicitly hardcode the implementation details of the superclass, which may be even more wrong than implicitly inheriting them at build time. This way not only can the runtime class have different fields than the compile time dependency, but even at compile time when the base class changes you have to make sure to update your class to reflect the added, removed, or renamed fields.

like image 25
Sergiu Dumitriu Avatar answered May 06 '23 00:05

Sergiu Dumitriu