Osgi 在设置到运行配置文件后,如何解析和启动捆绑包

Osgi 在设置到运行配置文件后,如何解析和启动捆绑包,osgi,equinox,p2,Osgi,Equinox,P2,我的应用程序目前正在使用equinox的IProvisioningAgent查找捆绑包并将其配置到我的运行配置文件中。代码大致如下所示: // Look up agent provider using OSGI service IProvisioningAgentProvider provider = ...; IProvisioningAgent = provider.createAgent(null); // Use currently running agent // Define IU

我的应用程序目前正在使用equinox的IProvisioningAgent查找捆绑包并将其配置到我的运行配置文件中。代码大致如下所示:

// Look up agent provider using OSGI service
IProvisioningAgentProvider provider = ...;
IProvisioningAgent = provider.createAgent(null); // Use currently running agent

// Define IU
IInstallableUnit iu = ...; // found using remote repository queries

// Find profile
IProfileRegistry registry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME);
IProfile profile = registry.getProfile(IProfileRegistry.SELF);

// Create change request
IPlanner planner = (IPlanner) agent.getService(IPlanner.SERVICE_NAME);
IProfileChangeRequest request = planner.createChangeRequest(profile);
request.add(iu);

// Create plan and perform
IProvisioningPlan plan = planner.getProvisioningPlan(request, ctx, monitor);
IEngine engine = (IEngine) agent.getService(IEngine.SERVICE_NAME);
IStatus status = engine.perform(plan,  PhaseSetFactory.createDefaultPhaseSet(), monitor);
这很好,我可以看到IU(带有依赖项)已经安装在磁盘上

我现在需要在不重新启动的情况下将捆绑包安装到正在运行的环境中。我可以在网上找到的所有示例都只是重新启动平台,这在本例中不适用。我以前使用过
BundleContext.installBundle()
,但它的级别似乎太低,我找不到如何从配置API获取URL

我是否可以使用资源调配API的其他部分?我已经读过关于使用
org.eclipse.equinox.internal.temporative.configurator.configurator
,但它是内部的,似乎并不能解决问题


我的问题是:在不重新启动的情况下,安装、解析和启动我刚刚配置的捆绑包的正确步骤是什么。

P2中没有用于将捆绑包安装/更新到运行平台的API

对于这种情况,我们也使用
BundleContext#installBundle(位置)
。下面的代码示例说明了我们的操作方式。我们获取要安装的捆绑包的URL的方式不符合犹太教义,如果您有更好的解决方案,请提出建议

IPath bundlePoolPath=...;
String iuFullName=...; //this you get from P2

Bundle bundle = null;

//XXX especially stinky part
IPath bundleAsJar = bundlePoolPath.append("plugins/" + iuFullName + ".jar"); 

URL bundleURL = bundleAsJar.toFile().toURI().toURL();

try {
    bundle = ctx.installBundle(bundleLocationURL.toExternalForm());
}
catch (BundleException e) {
    // may fail if the bundle is extracted to dir (hello, P2)
    IPath bundleAsDir = bundlePoolPath.append("plugins/" + iuFullName);
    bundleURL = bundleAsDir.toFile().toURI().toURL();
    bundle = ctx.installBundle(bundleURL.toExternalForm());
}

我发现了一个额外的服务,它将IU的工件公开为
java.io.File
,因此可以取代Ilya特别讨厌的部分

IAgentLocation location = (IAgentLocation) agent.getService(IAgentLocation.SERVICE_NAME);
URI bundlePool = location.getDataArea(ECLIPSE_TOUCHPOINT_ID);
IArtifactRepositoryManager manager = (IArtifactRepositoryManager) agent.getService(IArtifactRepositoryManager.SERVICE_NAME);
// XXX Bit of a smell to cast here, but I know they are files now.
IFileArtifactRepository repository = (IFileArtifactRepository) manager.loadRepository(
                bundlePool, monitor);


// I can get the artifact and then query the repository
for (IArtifactKey artifact : iu.getArtifacts()) {
  File file = repository.getArtifactFile(artifact);
  URI uri = file.toURI();

  // Install the bundle
  ctx.installBundle(uri.toString());
}
在大多数情况下,这是可行的。这里的代码已经去掉了错误处理,如果没有调整,可能无法编译。它应该适用于不同的配置文件和不同的代理


我相信有一个更好的解决方案,使用eclipse接触点在正确的阶段自动安装包。如果我找到了更好的解决方案,我会尝试在这里更新。

我想分享一个完整的工作解决方案-

此实现通过迭代所有可用配置文件(以下场景中的一个)和系统存储库(以下场景中的两个),避免使用硬编码配置文件和捆绑位置名称。我不知道它是否在所有情况下都有效,但它在下面解释的场景中确实有效

使用场景:

有一个基于Equinox/OSGi的web应用程序,为EPackage.Registry.INSTANCE(,Packages部分)中注册的ECore模型提供文档

模型包定期更新。如果没有AutoUpdateComponent,则需要手动重新部署web应用程序,以使模型文档更新


AutoUpdateComponent配置了相关模型发布的存储库位置。该组件安装存储库中的新捆绑包,并更新现有捆绑包。因此,模型文档将自动重新发布。

谢谢您的帮助;我添加了我自己的答案,因为我相信它改进了symbolicName to URI问题。我不能评价你的答案,因为我没有足够的声誉。ECLIPSE\u TOUCHPOINT\u ID的价值是什么?