ONOS升级替换SCR注解后跨Bundle无法获取服务引用问题
排查ONOS升级中@Reference注入EventDeliveryService为null的问题
以下是针对你遇到的问题的具体排查方向和验证方法:
1. 检查DS注解元数据生成是否正常
切换到OSGi原生org.osgi.service.component.annotations注解后,必须确保编译时生成了正确的组件描述元数据(XML文件),否则OSGi DS容器无法识别依赖注入规则。
- 验证方式:解压
onos-app-tunnel的bundle包,查看是否存在OSGI-INF目录,且目录下有对应LabelResourceManager.xml和TunnelManager.xml文件;或者检查META-INF/services/org.osgi.service.component.annotations.Component文件是否包含这两个组件的类名。 - 修复方法:在
onos-app-tunnel的pom.xml中添加OSGi注解处理器依赖和插件配置,确保编译时生成元数据:<build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-scr-plugin</artifactId> <version>2.1.20</version> <executions> <execution> <id>generate-scr-scrdescriptor</id> <goals> <goal>scr</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.osgi</groupId> <artifactId>osgi.annotation</artifactId> <version>8.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>osgi.core</artifactId> <version>7.0.0</version> <scope>provided</scope> </dependency> </dependencies>
2. 确认父类@Reference的继承性
OSGi原生@Reference注解默认不支持继承,如果父类AbstractListenerProviderRegistry中的@Reference没有添加@Inherited注解,子类不会自动继承该依赖注入配置。
- 验证方式:检查父类的
EventDeliveryService字段上的注解:// 错误示例:无@Inherited,子类无法继承引用 @Reference protected EventDeliveryService eventDeliveryService; // 正确示例:添加@Inherited让子类继承引用配置 @Inherited @Reference protected EventDeliveryService eventDeliveryService; - 临时测试:在子类
LabelResourceManager或TunnelManager中显式添加相同的@Reference字段,看是否能正常注入。
3. 检查@Reference的基数与策略配置
如果父类中@Reference的配置导致组件激活时强制依赖未就绪,会出现注入null的情况(虽然你手动能获取服务,但可能组件激活时机早于服务完全注册)。
- 验证方式:调整父类的
@Reference属性:@Reference( cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY ) protected EventDeliveryService eventDeliveryService;policy = DYNAMIC:允许服务动态注册/注销时重新注入policyOption = GREEDY:确保服务可用时立即注入,无需等待组件激活
4. 验证Bundle依赖声明
onos-app-tunnel可能未正确声明对EventDeliveryService所在bundle的依赖,导致DS容器激活顺序错误。
- 验证方式:查看
onos-app-tunnel的MANIFEST.MF,确认:Import-Package包含org.onosproject.event(假设EventDeliveryService在这个包下),且版本范围匹配3.0.0.SNAPSHOT- 或者添加
Require-Bundle: org.onosproject.core.net;resolution:=mandatory(假设服务在onos-core-net中)
- 额外配置:在组件类上显式指定依赖顺序:
@Component( service = TunnelManager.class, dependsOn = "org.onosproject.core.net.EventDeliveryService" ) public class TunnelManager extends AbstractListenerProviderRegistry { // ... }
5. 检查字段可见性与注入方式
OSGi DS对注入字段的可见性有要求,private字段无法被注入,而Felix SCR可能允许这种情况。
- 验证方式:确保父类中
EventDeliveryService字段为protected或public,而非private:// 正确:protected字段允许子类继承并被DS注入 @Reference protected EventDeliveryService eventDeliveryService;
6. 确认DS容器版本兼容性
旧版本的OSGi DS容器可能对R6+的原生注解支持不完善,需要确保Karaf中使用的DS实现版本符合要求。
- 验证方式:在Karaf中执行
bundle:list | grep SCR,查看org.apache.felix.scr的版本,建议使用2.1.x及以上版本,确保支持OSGi原生注解。
内容的提问来源于stack exchange,提问作者emalovecode
相关产品推荐
相关产品推荐

