我真的很擅长这个(OSGI),尝试做一些简单的例子 . 我不能做懒惰的行动 . 我知道有一些蓝图可以解决这些问题,但在继续之前,我认为学习一些基础知识会很好 .
Bundle DataService:
Manifest-Version: 1.0
Bundle-Version: 1.0.0
Bundle-Name: DataService
Bundle-ManifestVersion: 2
Bundle-Activator: DataService.Activator
Import-Package: org.osgi.framework
Bundle-SymbolicName: DataService
Export-Package: DataService;version="1.0.0"
Bundle-ActivationPolicy: lazy
Bundle DataServiceClient:
Manifest-Version: 1.0
Bundle-Version: 1.0.0
Bundle-Name: DataServiceClient
Bundle-ManifestVersion: 2
Bundle-Activator: DataServiceClient.Activator
Import-Package: org.osgi.framework, DataService;version="[1.0.0,1.0.0]"
Bundle-SymbolicName: DataServiceClient
好的,我已经改变了我的代码,但仍然没有运气 .
外部应用程序,安装捆绑包,启动框架,然后只启动DataServiceClient捆绑包 . 无法访问任何捆绑类 .
File bundleDir = new File("./bundles/");
String[] bundleResources = bundleDir.list();
for(String bundleResourcePath : bundleResources) {
File bundleResource = new File(bundleDir, bundleResourcePath);
InputStream bs =new FileInputStream(bundleResource);
mFramework.getBundleContext().installBundle(bundleResource.getName(), bs);
}
mFramework.start();
bl = mFramework.getBundleContext().getBundles();
for(Bundle b : bl) {
if (b.getBundleId() != 0 && b.getSymbolicName().contains("DataServiceClient")) {
b.start();
}
}
这是DataServiceClient的开始:
System.out.println("DataServiceClient Start");
IDataService service = new DummyService();
System.out.println(service.getData());
这是“DataService”包中的DummyService类 .
public class DummyService implements IDataService {
@Override
public String getData() {
return "DummyService Data";
}
}
这是“DataService”包的开头:
System.out.println("DataService Start");
我得到的输出:
DataServiceClient Start
DummyService Data
不过我希望看到:
DataServiceClient Start
DataService Start
DummyService Data
来自http://www.osgi.org/Design/LazyStart的一点点
Lazy Activation
Lazy activation is a life cycle policy that mandates a bundle MUST be activated upon the first successful request to load a class from that bundle.
然而,因为它不起作用,我想我完全误解了懒惰激活的概念或我做错了什么 .
除非我明确地为DataService bundle调用start,否则它似乎不会为DataService bundle调用Activator.start . 这就是我没有得到的 .
感谢你的时间
3 回答
您确定,您的Activator确实没有被调用 . 我经常遇到这样的情况,即激活器被调用但经验丰富且异常,OSGi吞下了它 . 你可以在Activator.start的第一行尝试println来检查这个 . 在这种情况下,尝试捕获日志记录也很有用 .
顺便说一句 . 使用大写字母命名包非常不寻常 . 不确定是否有问题,但我会避免这种情况 .
当你调用DummyClient.GetData()时,不清楚是什么 . 你说它调用DataService包中的一个类,但是如何? DataService是一个普通的bundle,你的代码是主要的Java启动器应用程序,OSGi中没有办法让“外部”应用程序静态依赖普通的bundle .
无论如何,即使您可以执行此操作,也可以在启动捆绑包之前执行此行代码 . 在捆绑启动之前肯定不会调用捆绑激活器!!我希望在第36行调用你的激活器,即你在每个捆绑包上调用
bundle.start()
.但是真的......你究竟想做什么?
Bundle-ActivationPolicy: lazy
标志几乎完全没用 . 我有8年的OSGi经验,并且由于遗留原因,它们只在Eclipse RCP应用程序中使用过此设置 . 除非您正在编写Eclipse插件或Eclipse RCP应用程序,否则 you should not use Bundle-ActivationPolicy: lazy in OSGi .在OSGi中实现懒惰(或“及时”)实例化的正确方法是使用声明性服务(DS) . 当客户端首次尝试调用它们而不是在注册时,DS会发布的所有服务对象都会按需实例化 . 您无需执行任何特殊操作即可启用此功能 .
关于更改后的代码......你永远不会真正启动捆绑包
DataServiceClient
,因此无法调用其激活器 . 您已经从启动捆绑包的循环中明确地将其排除在外 . OSGi只会在bundle.start()
启动的bundle上调用BundleActivator
.这是一个非常广泛的误解点... OSGi never automatically starts bundles ,即使启用了
Bundle-ActivationPolicy: lazy
标志 .可能你打算做的是按如下方式启动软件包:
事实上,您为所有捆绑包执行此操作,而不是随意启动捆绑包的子集 .
但同样,我必须重申我在其他答案中提出的观点 . 使用
Bundle-ActivationPolicy: lazy
是没有意义的,除非您正在开发Eclipse RCP应用程序,在这种情况下,您有时必须将其用于愚蠢的遗留原因 .