Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 337016

Summary: [operations] Simplify operation API to cater for self case
Product: [Eclipse Project] Equinox Reporter: Pascal Rapicault <pascal>
Component: p2Assignee: Pascal Rapicault <pascal>
Status: RESOLVED FIXED QA Contact:
Severity: enhancement    
Priority: P3 CC: dj.houghton, djo, irbull, jeffmcaffer, mbaudier, reiswich, slewis, susan, Thomas.M.Crockett, tjwatson
Version: 3.7Flags: tjwatson: pmc_approved+
dj.houghton: review+
Target Milestone: 3.7 RC1   
Hardware: PC   
OS: Mac OS X - Carbon (unsup.)   
Whiteboard:
Attachments:
Description Flags
simplified API
none
Pascal's AbsoluteInstallOperation from the mailing list
none
new patch
none
new patch
none
Changes to address potential issue in removal
none
Patch correcting issues and completing the work none

Description Pascal Rapicault CLA 2011-02-11 19:47:42 EST
Created attachment 188826 [details]
simplified API

This bug is created to continue the discussion http://dev.eclipse.org/mhonarc/lists/p2-dev/msg03812.html that talks about simplifying the operations API for the 90% case of installing / uninstalling and updating the self profile.

Attached is an attempt at a simplification for the install operation.

Questions: 
- What should the update do?
- Do we really need soemthing like getInstalledRoots(), can't ppl just query? This one annoys me because this seems like a never ending source of expension for things like all the IUs that are blue, all the features, all the bundles. In this case I'm tempted to expose IQuery and point the user at the helpers in QueryHelper.
Comment 1 Pascal Rapicault CLA 2011-02-11 19:52:22 EST
As an example with the attached API added, the code to update would become:

InstallOperation operation = new SimpleCaseFactory().createOperation(versionedIdList, repoURIList, monitor);
result = operation.resolveModal(monitor);

if (result.isOK()) {
	final ProvisioningJob installJob = operation.getProvisioningJob(monitor);
	result = installJob.runModal(monitor);
}
Comment 2 Pascal Rapicault CLA 2011-02-11 19:54:17 EST
In fact I believe that there is an even simpler code since the getProvisioningJob takes care of the resolution if not already done.

 InstallOperation operation = new SimpleCaseFactory().createOperation(versionedIdList, repoURIList, monitor);
 ProvisioningJob installJob = operation.getProvisioningJob(monitor);
 result = installJob.runModal(monitor);
Comment 3 Eugen Reiswich CLA 2011-02-15 03:32:48 EST
> Questions: 
> - Do we really need soemthing like getInstalledRoots(), can't ppl just query?

Well of course they could, but I remember that it took us weeks to figure out how the Queries API works: 

	IQuery<IInstallableUnit> installableUnits = QueryUtil.createIUQuery(versionedId.getId(), version);
	IQueryResult<IInstallableUnit> ius = context.getMetadata(monitor).query(installableUnits, monitor);

> This one annoys me because this seems like a never ending source of expension
> for things like all the IUs that are blue, all the features, all the bundles.
> In this case I'm tempted to expose IQuery and point the user at the helpers in
> QueryHelper.

(In reply to comment #2)
> In fact I believe that there is an even simpler code since the
> getProvisioningJob takes care of the resolution if not already done.
> 
>  InstallOperation operation = new
> SimpleCaseFactory().createOperation(versionedIdList, repoURIList, monitor);
>  ProvisioningJob installJob = operation.getProvisioningJob(monitor);
>  result = installJob.runModal(monitor);

In my opinion this should do the work for the install operation. We've been also discussing update and uninstall operations.
Comment 4 Pascal Rapicault CLA 2011-02-16 23:12:09 EST
> In my opinion this should do the work for the install operation. We've been
> also discussing update and uninstall operations.
  I agree. I just posted this to get some initial feedback before continuing implementing the other operations since they are more or less the same things.
Comment 5 Dave Orme CLA 2011-02-28 15:41:53 EST
Hi Pascal,

I've looked at the code in your first attachment, and it looks exactly like what we need, but with one addition: all IUs not in the list need to be removed from the running profile. i.e.: It would have to be implemented using the AbsoluteInstallOperation you posted on the mailing list (which I'll add here).

Regarding the second thought: that the simpler API can be derived from this one, I think it can be, if we're careful.  This is because the error conditions are different.

In this API, we have a list of the IUs to install, so as long as all IUs in the list are available on some P2 repo, we can continue.

But in the other case, we are deriving the list of IUs to install from what's in the set of repos.  If some repo isn't available, we have to fail because we can no longer be sure that we have the correct set of IUs to install.

But I think maybe this step can be handled before calling the API you defined here?
Comment 6 Dave Orme CLA 2011-02-28 15:42:36 EST
Created attachment 189995 [details]
Pascal's AbsoluteInstallOperation from the mailing list
Comment 7 Pascal Rapicault CLA 2011-03-02 21:00:05 EST
> But in the other case, we are deriving the list of IUs to install from what's
> in the set of repos.  If some repo isn't available, we have to fail because we
> can no longer be sure that we have the correct set of IUs to install.
> 
> But I think maybe this step can be handled before calling the API you defined
> here?
   Another possibility would be for the operation to return the IUs not found (maybe exception) and let the user call the operation again. What do you think?
Comment 8 Susan McCourt CLA 2011-03-03 18:12:46 EST
Pascal asked me to look these over.
I'm wondering rather than "SimpleCaseFactory" as a name, we introduce

OperationHelper  (kind of like QueryHelper).

Various methods in OperationHelper return commonly used operations.  So we'd have

OperationHelper.createFeatureInstallOperation(List<URI> repos, List<IVersionedId> toInstall, IProgressMonitor monitor)

and 

OperationHelper.createAbsoluteInstallOperation(Collection<IInstallableUnit> toInstall)

Then the AbsoluteInstallOperation class (and any other classes we build to deal with these cases) doesn't have to be public, the signature for that helper could return InstallOperation.

This keeps the public API quite clean (just a new helper) and we can implement all kinds of operations internally for the common cases.

Otherwise, i like this approach to solving the problem.  If this is needed for M6 (API freeze) then we need someone to commit the code, or at least commit the helper and method signatures even if not implemented yet.
Comment 9 Dave Orme CLA 2011-04-06 12:05:16 EDT
(In reply to comment #8)
> Pascal asked me to look these over.
> I'm wondering rather than "SimpleCaseFactory" as a name, we introduce
> 
> OperationHelper  (kind of like QueryHelper).
> 
> Various methods in OperationHelper return commonly used operations.  So we'd
> have
> 
> OperationHelper.createFeatureInstallOperation(List<URI> repos,
> List<IVersionedId> toInstall, IProgressMonitor monitor)
> 
> and 
> 
> OperationHelper.createAbsoluteInstallOperation(Collection<IInstallableUnit>
> toInstall)

<snip/>

Yes, that looks good.

(Funny; I seem to not be getting--or maybe missing--Bugzilla mail somehow.  Good thing I checked before I yelled about your not getting back on this. ;) )
Comment 10 Pascal Rapicault CLA 2011-04-19 13:26:38 EDT
Created attachment 193604 [details]
new patch

This is a new patch. For consistency with the rest of API, I have kept the AbsoluteInstallOperation, maybe we could add a setAbsolute method on the InstallOperation. 
The code is not complete but the API is good.
Comment 11 Susan McCourt CLA 2011-04-19 14:01:36 EDT
I'm not particularly fond of the name "AbsoluteInstallOperation," because there could be uninstalls and updates also happening.  It's really a complete "zapping" of the profile to synch with an external specification.  Almost as if we're trying to clone a profile.

Hmmm...
RepopulateProfileOperation???

Although that doesn't sound very "simple."

Dave, any better ideas?

My main complaint is that I think "install" could be misleading.  It's possible that nothing new gets added, just things tossed and/or upgraded.
Comment 12 DJ Houghton CLA 2011-04-19 14:05:19 EDT
I think Susan is subtly suggesting "become:". :-)
Comment 13 Dave Orme CLA 2011-04-19 18:19:41 EDT
(In reply to comment #11)
> I'm not particularly fond of the name "AbsoluteInstallOperation," because there
> could be uninstalls and updates also happening.  

Yes.  I don't think any of the other operations do both install and update and here we also have uninstall happening too.

> It's really a complete
> "zapping" of the profile to synch with an external specification.  Almost as if
> we're trying to clone a profile.
> ....
> Dave, any "better" ideas? <redacted:)/>

How about SynchronizeProfileOperation?

I suggest that we have just one version of this API:  One that takes the list of IUs to provision as a parameter, probably as a Set<IInstallableUnit> (that one would normally get as a result of running an IQuery<IInstallabelUnit>).

If that exact set of IUs is available from the set of set of configured metadata/artifact repos, we provision exactly that set and remove all others.  Otherwise, we give up.

This handles the hardest case: when you know (from a web service based on login credentials, etc) exactly what IUs you need to provision.

Handling the "synch with some set of repos already on a server" case will be up to clients.  In this case, clients will have to query the canonical set of repositories and derive the Set<IInstallableUnit> themselves or give up if they can't.
Comment 14 Dave Orme CLA 2011-04-19 18:24:01 EDT
(In reply to comment #13)
> If that exact set of IUs is available from the set of set of configured
> metadata/artifact repos

s/configured/specified;
Comment 15 Jeff McAffer CLA 2011-04-20 10:26:01 EDT
Naming is hard. "Synchronize" has a better feel IMHO.  Note that all of the operations may result in installs, updates and/or uninstalls happening under the covers.  The point AFAICT of the Operations is to make it easy to just "[install|update|uninstall] this IU", whatever else may happen.  The difference with sync is that it is exclusive so you had better get the complete set of roots.

Note also that it is not a priori an install.  The new set being passed to the operation may have fewer things (e.g., an uninstall) or newer/older versions (i.e., an update).  

SynchronizeOperation sounds good to me.  (note "profile" is implicit as these various operation apply to the SELF profile)

As for "OperationHelper", sure if that better matches up with other similar classes.  Otherwise "OperationFactory" would fit better.
Comment 16 Dave Orme CLA 2011-04-20 16:19:42 EDT
(In reply to comment #15)
> SynchronizeOperation sounds good to me.  (note "profile" is implicit as these
> various operation apply to the SELF profile)

+1

> As for "OperationHelper", sure if that better matches up with other similar
> classes.  Otherwise "OperationFactory" would fit better.

+1
Comment 17 Susan McCourt CLA 2011-04-20 17:32:32 EDT
+1 for SynchronizeOperation and OperationFactory

We use XxxHelper elsewhere but since this thing spits out instances, it's a true factory.
Comment 18 Pascal Rapicault CLA 2011-04-20 22:26:35 EDT
Created attachment 193772 [details]
new patch

Here is a patch taking into account all the feedback provided wrt naming.
Comment 19 Pascal Rapicault CLA 2011-04-20 22:34:13 EDT
Note that in this new patch most methods now throw a ProvisionException. This is done in order to handle the case where the IUs (in the form of IVersionedId) that are passed in as a parameter can't be found.
Comment 20 Jeff McAffer CLA 2011-04-21 09:52:17 EDT
Thanks for the updated patch.  The new names look good and the exception is a good idea.  I'm ok with this going in now.

Note that Tom loaded the patch in his workspace and got  compile error on the new protected field on InstallOperation.  It is complaining that there is no Javadoc for the field.  While it is not an API field (we have @noextend on the class), the javadoc builder does not appear to be smart enough.  Please add some Javadoc to the field to keep it happy.

As a side note, I'm not sure how Tom is seeing a problem and you are not (I was not in a position to load the patch right now).

Note also that the copyright date on InstallOperation should be updated as well.
Comment 21 Pascal Rapicault CLA 2011-04-21 21:03:44 EDT
I have released this patch. Thx for the feedback. I'll keep it open for now for the rest of the work:
- test
- implementation
Comment 22 Dave Orme CLA 2011-04-26 11:31:33 EDT
I took a look at the patch.  Overall it looks good.  One nit:

The JavaDoc for SynchronizeOperation still has the old name (AbsoluteXXXOperation) in the code example.
Comment 23 Dave Orme CLA 2011-04-26 12:29:54 EDT
If I want to have SynchronizeOperation-style functionality now, what's the best option: back-port starting from a nightly or M build?

I tried reimplementing this myself by copying ProfileChangeOperation InstallOperation, and SynchronizeOperation, etc. into my workspace.  However, there seem to be many references to P2 internals from these classes.  For example PCO references PlannerResolutionJob, ProfileChangeRequest which in turn reference things like IFailedStatusEvaluator and PlanAnalyzer...

Thoughts, suggestions, and opinions are welcome.  Thanks in advance.
Comment 24 Pascal Rapicault CLA 2011-04-27 08:19:19 EDT
How far back are you trying to port this?
Comment 25 Dave Orme CLA 2011-04-27 10:06:43 EDT
(In reply to comment #24)
> How far back are you trying to port this?

3.6.2
Comment 26 Dave Orme CLA 2011-04-27 10:09:42 EDT
Alternatively, if I could find an atomic way to execute multiple operations such that if any of them fail, they all get rolled back, I could use an UninstallOperation followed by an UpdateOperation followed by an InstallOperation...?  But having SynchronizeOperation would be much nicer. :)

Additional thoughts appreciated.
Comment 27 Thomas Watson CLA 2011-04-27 13:49:41 EDT
Jeff and I discussed this last week and agreed it would be good to get into 3.7.  I thought it was already marked as approved.
Comment 28 Dave Orme CLA 2011-04-28 12:48:17 EDT
Is this patch in a nightly yet?  If not is there anything I can do to accelerate that process so I can test against it?  Thanks.
Comment 29 Dave Orme CLA 2011-04-29 15:44:22 EDT
(In reply to comment #28)
> Is this patch in a nightly yet?  If not is there anything I can do to
> accelerate that process so I can test against it?  Thanks.

Please forgive the line noise; found it in the latest I-build.  :)  Thanks.
Comment 30 Dave Orme CLA 2011-05-02 11:03:35 EDT
I tested this patch using last week's I build and was unable to get the code to uninstall Features that had been previously installed.  I'm working on a test case to upload.
Comment 31 Pascal Rapicault CLA 2011-05-03 09:30:30 EDT
Without a test case, could you quickly describe the scenario where you are running into a problem?
Comment 32 Dave Orme CLA 2011-05-03 11:18:08 EDT
(In reply to comment #31)
> Without a test case, could you quickly describe the scenario where you are
> running into a problem?

Install v4.0.0.  Upgrade to 4.0.1.  Upgrade to 5.0.0.  Rollback to 4.0.0.

The rollback fails to uninstall the others.
Comment 33 Dave Orme CLA 2011-05-03 12:55:35 EDT
(In reply to comment #32)
> (In reply to comment #31)
> Install v4.0.0.  Upgrade to 4.0.1.  Upgrade to 5.0.0.  Rollback to 4.0.0.
> 
> The rollback fails to uninstall the others.

This was in our internal test suite.  I'm now trying to replicate this result in a small example, which will either validate what we've found or tell me that I'm the one with the bug. ;-)

But, schedule being what it is, I wanted you to know sooner than later.
Comment 34 Pascal Rapicault CLA 2011-05-03 19:36:12 EDT
Created attachment 194659 [details]
Changes to address potential issue in removal

Dave, I was working on this code today and saw something suspicious for the removal. Please try with the patch attached.
Comment 35 Pascal Rapicault CLA 2011-05-03 22:37:09 EDT
Created attachment 194662 [details]
Patch correcting issues and completing the work

Here is the patch completing the implementation of these factory and a few test cases.
Comment 36 Pascal Rapicault CLA 2011-05-03 22:37:39 EDT
DJ could you please review.
Comment 37 DJ Houghton CLA 2011-05-04 11:16:58 EDT
Patch released with updated copyright.
Comment 38 Dave Orme CLA 2011-05-04 11:42:45 EDT
Thanks Pascal.  This looks better.  I'll grab/test the latest.
Comment 39 Pascal Rapicault CLA 2011-05-05 17:46:05 EDT
Dave, if you were to run in any issue, please reach out to me directly on the p2 ml. Thx.
Comment 40 Dave Orme CLA 2011-05-05 19:06:52 EDT
K, thanks Pascal.
Comment 41 Tom Crockett CLA 2011-06-07 00:24:39 EDT
David, any luck backporting this to 3.6.2? We are also badly in need of an update mechanism that simply synchronizes with an update site, and can't wait for 3.7.
Comment 42 Pascal Rapicault CLA 2011-06-07 00:34:03 EDT
Tom as far as I know you should be able to copy the code of org.eclipse.equinox.p2.operations.SynchronizeOperation class straight into 3.6. 
Alternatively you can also just take the operations bundle from 3.7 and run it in 3.6.
Please keep us posted.
Comment 43 Dave Orme CLA 2011-06-07 07:42:21 EDT
(In reply to comment #42)
> Tom as far as I know you should be able to copy the code of
> org.eclipse.equinox.p2.operations.SynchronizeOperation class straight into 3.6. 

I tried this--and SynchronizeOperation depends on things that are internal API in P2, so one would have to use nasty tricks like creating a fragment bundle in the org.eclipse.equinox.p2.operations namespace (which you don't own) in order to make this work.

> Alternatively you can also just take the operations bundle from 3.7 and run it
> in 3.6.
> Please keep us posted.

This should work.
Comment 44 Pascal Rapicault CLA 2011-06-07 08:37:51 EDT
The following class compiles on 3.6. The only change I made is to make keep a copy of the "toInstall" argument in the operation itself rather than relying on it being available from the super class like it is the case in 3.7. Note that I have not run that code.


/*******************************************************************************
 *  Copyright (c) 2011 Sonatype, Inc. and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 * 
 *  Contributors:
 *     Sonatype, Inc. - initial API and implementation
 *     IBM Corporation - Ongoing development
 *******************************************************************************/
package org.eclipse.equinox.p2.operations;

import java.util.Collection;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.operations.Messages;
import org.eclipse.equinox.internal.provisional.p2.director.ProfileChangeRequest;
import org.eclipse.equinox.p2.engine.IProfile;
import org.eclipse.equinox.p2.engine.query.UserVisibleRootQuery;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.planner.ProfileInclusionRules;
import org.eclipse.equinox.p2.query.QueryUtil;

/**
 * A {@link SynchronizeOperation} describes an operation that will modify the installation to 
 * exclusively include the InstallableUnit mentioned. Note that all the Installable Units necessary
 * to satisfy the dependencies of the Installable Units installed will also be installed.  
 * 
 * The following snippet shows how one might use an SynchronizeOperation to perform a synchronous resolution and
 * then kick off an install in the background:
 * 
 * <pre>
 * SynchronizeOperation op = new SynchronizeOperation(session, new IInstallableUnit [] { myIU });
 * IStatus result = op.resolveModal(monitor);
 * if (result.isOK()) {
 *   op.getProvisioningJob(monitor).schedule();
 * }
 * </pre>
 * 
 * @since 2.1
 * @see ProfileChangeOperation
 * @noextend This class is not intended to be subclassed by clients.
 */
public class SynchronizeOperation extends InstallOperation {
	Collection<IInstallableUnit> localToInstall;

	public SynchronizeOperation(ProvisioningSession session, Collection<IInstallableUnit> toInstall) {
		super(session, toInstall);
		this.localToInstall = toInstall;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.equinox.p2.operations.ProfileChangeOperation#computeProfileChangeRequest(org.eclipse.core.runtime.MultiStatus, org.eclipse.core.runtime.IProgressMonitor)
	 */
	protected void computeProfileChangeRequest(MultiStatus status, IProgressMonitor monitor) {
		request = ProfileChangeRequest.createByProfileId(session.getProvisioningAgent(), profileId);
		IProfile profile;
		SubMonitor sub = SubMonitor.convert(monitor, Messages.InstallOperation_ComputeProfileChangeProgress, localToInstall.size());
		profile = session.getProfileRegistry().getProfile(profileId);
		request.removeAll(profile.query(new UserVisibleRootQuery(), sub).toUnmodifiableSet());
		request.addAll(localToInstall);
		for (IInstallableUnit entryToInstall : localToInstall) {
			// If the user is installing a patch, we mark it optional.  This allows the patched IU to be updated later by removing the patch.
			if (QueryUtil.isPatch(entryToInstall))
				request.setInstallableUnitInclusionRules(entryToInstall, ProfileInclusionRules.createOptionalInclusionRule(entryToInstall));
			else
				request.setInstallableUnitProfileProperty(entryToInstall, IProfile.PROP_PROFILE_ROOT_IU, Boolean.toString(true));

			sub.worked(1);
		}
		sub.done();
	}
}
Comment 45 Eugen Reiswich CLA 2011-07-02 07:56:39 EDT
Hi folks, 

I just checked out Eclipse Indigo and was pleased to see that the provisioning helper classes discussed here are already part of Eclipse 3.7. I immediately wanted to check out how they work. First of all I am a bit confused what's the right helper class to use: OperationFactory or SynchronizeOperation?

I first tried org.eclipse.equinox.p2.operations.OperationFactory as constructing the InstallOperation using this class seems to be easier for me.  Unfortunately I always end up with a NPE trying to create an InstallOperation:

OperationFactory operationFactory = new OperationFactory();
Collection<org.eclipse.equinox.p2.metadata.IVersionedId> p2VersionIds = convertToP2VersionIds(featureIds);
Collection<URI> p2Repos = Arrays.asList(repoLocations);

InstallOperation installOperation = operationFactory.createInstallOperation(p2VersionIds, p2Repos, monitor);

--> Causes: 

java.lang.NullPointerException
	at org.eclipse.equinox.internal.p2.repository.helpers.AbstractRepositoryManager.loadIndexFile(AbstractRepositoryManager.java:721)
	at org.eclipse.equinox.internal.p2.repository.helpers.AbstractRepositoryManager.loadRepository(AbstractRepositoryManager.java:640)
	at org.eclipse.equinox.internal.p2.metadata.repository.MetadataRepositoryManager.loadRepository(MetadataRepositoryManager.java:96)
	at org.eclipse.equinox.internal.p2.metadata.repository.MetadataRepositoryManager.loadRepository(MetadataRepositoryManager.java:92)
	at org.eclipse.equinox.p2.engine.ProvisioningContext.loadMetadataRepository(ProvisioningContext.java:211)
	at org.eclipse.equinox.p2.engine.ProvisioningContext.getLoadedMetadataRepositories(ProvisioningContext.java:194)
	at org.eclipse.equinox.p2.engine.ProvisioningContext.getMetadata(ProvisioningContext.java:275)
	at org.eclipse.equinox.p2.operations.OperationFactory.createInstallOperation(OperationFactory.java:98)
	at org.remotercp.service.provisioning.install.InstallFeaturesServiceImpl.installFeature(InstallFeaturesServiceImpl.java:262)
	at org.remotercp.provisioning.local.ui.views.LocalFeaturesView$3.run(LocalFeaturesView.java:206)
	at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
	at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
	at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
	at org.eclipse.jface.action.ActionContributionItem$6.handleEvent(ActionContributionItem.java:452)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4125)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1457)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1480)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1465)
	at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1270)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3971)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3610)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2696)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2660)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
	at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.remotercp.mail.example.Application.start(Application.java:31)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1386)

The second attempt using the org.eclipse.equinox.p2.operations.SynchronizeOpertion I got stuck as I don't know how to properly convert org.eclipse.equinox.p2.metadata.IVersionedId to Collection<IInstallableUnit>.

Any hint which helper class to use and how to proceed would be very appreciated.
Comment 46 Pascal Rapicault CLA 2011-07-02 09:29:05 EDT
Please open a new bug for the NPE.
For the other issue, it is possible to go from a Collection of IIU to a Collection of IVersionedId but not the reverse. Note that in 3.7.1 and in 3.8 the API got slightly tweaked since the API did not make proper use of generics.
Comment 47 Dave Orme CLA 2011-07-02 10:03:45 EDT
(In reply to comment #45)
> Hi folks, 
> 
> I just checked out Eclipse Indigo and was pleased to see that the provisioning
> helper classes discussed here are already part of Eclipse 3.7. I immediately
> wanted to check out how they work. First of all I am a bit confused what's the
> right helper class to use: OperationFactory or SynchronizeOperation?

Here's how I tried to do it:

https://github.com/pieceoftheloaf/SynchronizeOperation

Unfortunately, this isn't working for me right now either.

The code there is an RCP application that launches, tries to update itself, then prints out the installed IUs, and restarts.

The driver is a JUnit test that fires off the update and checks to see if the expected IUs are there after the update.

The problem I'm running into is specifying the correct root set of IUs.  If I include the launcher IU, then the P2 resolver complains.  If I don't, then the update completes, but it deletes the launcher .exe, resulting in a non-runnable product.

So this is my current state trying to get this to work.

Hopefully the code is still useful to look at.
Comment 48 Pascal Rapicault CLA 2011-07-02 12:07:14 EDT
The NPE is likely caused by the absence of the org.eclipse.equinox.p2.transport.ecf in your configuration. I recommend you to consume p2 through the org.eclipse.equinox.p2.core.feature.
Comment 49 Eugen Reiswich CLA 2011-07-04 12:53:41 EDT
(In reply to comment #48)
> The NPE is likely caused by the absence of the
> org.eclipse.equinox.p2.transport.ecf in your configuration. I recommend you to
> consume p2 through the org.eclipse.equinox.p2.core.feature.

Hi Pascal, 

adding *p2.transport.ecf has helped to get rid of the NPE, thanks! BTW my Eclipse Indigo has no *.p2.core.feature plug-in. Is this an additional plug-in I need to install? 

Anyways, I tried to install the EclEmma Plug-in in my application using these parameters: 

private static final String UPDATE_SITE_LOCATION = "http://update.eclemma.org/";
private IVersionedId featureId = new VersionedId("com.mountainminds.eclemma.feature.feature.group",
			"1.5.3");

Passing on this information to the OperationFactory I get the following exception:

org.eclipse.equinox.p2.core.ProvisionException: No IU could be found for com.mountainminds.eclemma.feature.feature.group/1.5.3.
	at org.eclipse.equinox.p2.operations.OperationFactory.gatherIUs(OperationFactory.java:65)
	at org.eclipse.equinox.p2.operations.OperationFactory.createInstallOperation(OperationFactory.java:98)
	at org.remotercp.service.provisioning.install.InstallFeaturesServiceImpl.installFeature(InstallFeaturesServiceImpl.java:262)
	at org.remotercp.provisioning.local.ui.views.LocalFeaturesView$3.run(LocalFeaturesView.java:206)
	at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
	at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
	at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
	at org.eclipse.jface.action.ActionContributionItem$6.handleEvent(ActionContributionItem.java:452)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4125)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1457)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1480)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1465)
	at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1270)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3971)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3610)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2696)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2660)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
	at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.remotercp.mail.example.Application.start(Application.java:31)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1386)

However when I try to install this feature within Eclipse the update site works fine. Any ideas what might be wrong here?

Regards, 
Eugen
Comment 50 Pascal Rapicault CLA 2011-07-04 13:35:22 EDT
> Eclipse Indigo has no *.p2.core.feature plug-in. Is this an additional plug-in I need to install? 
  This is a feature not a plugin.

IIRC, eclemma has a legacy update site. Make sure you have the org.eclipse.equinox.p2.updatesite bundle.
Did you try to install from a local site that contains a simple IU?
Comment 51 Eugen Reiswich CLA 2011-07-05 02:56:05 EDT
(In reply to comment #50)
> > Eclipse Indigo has no *.p2.core.feature plug-in. Is this an additional plug-in I need to install? 
>   This is a feature not a plugin.
> 
> IIRC, eclemma has a legacy update site. Make sure you have the
> org.eclipse.equinox.p2.updatesite bundle.
> Did you try to install from a local site that contains a simple IU?

Thank's Pascal, it works now fine for me with Eclipse Indigo. I would also like to use the OperationFactory in Eclipse 3.6 as we are still testing Indigo. Is this generally possible?

I checked out the *p2.core.feature but in Eclipse 3.6 I am missing the *.p2.transport.ecf plug-in. In addition to that: which plug-ins do I need in order to use the OperationFactory? I ended up here in a dependency resolving jungle.

Thanks, 
Eugen
Comment 52 Pascal Rapicault CLA 2011-07-05 05:01:08 EDT
> Thank's Pascal, it works now fine for me with Eclipse Indigo. I would also like
> to use the OperationFactory in Eclipse 3.6 as we are still testing Indigo. Is
> this generally possible?
   OperationFactory should work just fine in 3.6. You should be able to use the p2.operations bundle from 3.7 in 3.6


> I checked out the *p2.core.feature but in Eclipse 3.6 I am missing the *.p2.transport.ecf plug-in. 
  the p2.core.feature and the p2.transport.ecf are new in 3.7

>In addition to that: which plug-ins do I need in order to use the OperationFactory? I ended up here in a 
> dependency resolving
  Take all the bundles that are listed in the p2.core.feature.
Comment 53 Eugen Reiswich CLA 2011-07-06 10:51:28 EDT
Hi folks, 

one more question: why does the uninstall operation requires a collection of repos?

public UninstallOperation createUninstallOperation(Collection<IVersionedId> toUninstall, Collection<URI> repos, IProgressMonitor monitor);
Comment 54 Tom Crockett CLA 2011-11-02 04:07:51 EDT
(In reply to comment #47)
> Unfortunately, this isn't working for me right now either.
> 
...
> The problem I'm running into is specifying the correct root set of IUs.  If I
> include the launcher IU, then the P2 resolver complains.  If I don't, then the
> update completes, but it deletes the launcher .exe, resulting in a non-runnable
> product.
> 
> So this is my current state trying to get this to work.
> 
> Hopefully the code is still useful to look at.

Any further news on how this is supposed to work? I've tried using the SynchronizeOperation and I think I'm running into the same problem as David reports with the resolver complaining. How do I choose the correct set of IUs to update so that there won't be a bunch of conflicts? Clearly "all the IUs in that are in the update repository" is not the right answer...
Comment 55 Dave Orme CLA 2011-11-02 09:27:57 EDT
(In reply to comment #54)
> Any further news on how this is supposed to work? I've tried using the
> SynchronizeOperation and I think I'm running into the same problem as David
> reports with the resolver complaining. How do I choose the correct set of IUs
> to update so that there won't be a bunch of conflicts? Clearly "all the IUs in
> that are in the update repository" is not the right answer...

It's fixed in the repo, but there are bugs in the current release.

So you have to be using the Director from the 3.8 stream (or 3.7.2 when it ships).

I've backported it to 3.7.1 and an example that works with 3.7.1 is here:

https://github.com/pieceoftheloaf/SynchronizeOperation