如何在配置到运行配置文件后解析并启动捆绑包

时间:2014-02-26 11:53:58

标签: osgi equinox p2

我的应用程序目前正在使用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(带有依赖项)已安装在磁盘上。

我现在需要将bundle安装到运行环境中而不重新启动。我在网上找到的所有例子都只是重新启动了不适合这种情况的平台。我之前使用过BundleContext.installBundle(),但它看起来太低了,我找不到如何从配置API获取网址。

我可以使用配置API的其他部分吗?我已经阅读了使用org.eclipse.equinox.internal.provisional.configurator.Configurator,但它是内部的,似乎无法解决问题。

我的问题是:在没有重新启动的情况下安装,解析和启动我刚配置的软件包的正确步骤是什么。

3 个答案:

答案 0 :(得分:1)

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

我们也使用BundleContext#installBundle(location)这样的情况。下面的代码示例说明了我们这样做的方式。我们获取要安装的软件包的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());
}

答案 1 :(得分:0)

我发现了一个额外的服务,将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触点在正确的阶段自动安装捆绑包。如果我找到更好的解决方案,我会尝试在此更新。

答案 2 :(得分:0)

我想分享一个完整的工作解决方案 - https://github.com/Nasdanika/server/blob/master/org.nasdanika.provisioning/src/org/nasdanika/provisioning/AutoUpdateComponent.java

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

使用方案:

有一个基于Equinox / OSGi的Web应用程序,为EPackage.Registry.INSTANCE(https://server-side-java-development-for-innovators.books.nasdanika.org/chapter-0-setup/documentation-system-overview.html,Packages部分)中注册的ECore模型提供文档。

模型包定期更新。如果没有AutoUpdateComponent手册,则需要重新部署Web应用程序才能使模型文档保持最新。

AutoUpdateComponent配置了存储库的位置,其中感兴趣的模型已发布。该组件将安装存储库中的新软件包并更新现有软件包。因此,模型文档会自动重新发布。