My application is currently using equinox's IProvisioningAgent to find and provision a bundle into my running profile. The code is along the lines of the following;
// 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);
This works fine and I can see that the IU (with dependencies) has been installed on disk.
I now need to install the bundle(s) into the running environment without restarting. All examples that I can find online just restart the platform which isn't suitable in this case. I have used BundleContext.installBundle()
previously, but it seems too low level and I can't find how to get the URL from the provisioning API.
Is there another part of the provisioning API that I can use? I have read up on using org.eclipse.equinox.internal.provisional.configurator.Configurator
, but it's internal and doesn't seem to solve the problem anyway.
My question is: What is the correct step to install, resolve and start the bundles that I have just provisioned without restarting.
I found an additional service that exposed the IU's artifacts as a java.io.File
so can replace Ilya's especially stinky part.
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());
}
For the most part, this works. The code here has been stripped of error handling and probably won't compile without tweaks. It should work for different profiles and different agents.
I believe there is a better solution that involves using eclipse touchpoints to auto install the bundle in the correct phase. If I find a better solution, I will try to update here.