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

Bug 354888

Summary: Cache extensions from parent lost in shared install
Product: [Eclipse Project] Equinox Reporter: DJ Houghton <dj.houghton>
Component: p2Assignee: DJ Houghton <dj.houghton>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: niels, pascal, rderwin, tmhouser
Version: 3.7   
Target Milestone: Juno M2   
Hardware: PC   
OS: Mac OS X - Carbon (unsup.)   
Whiteboard:
Bug Depends on:    
Bug Blocks: 357132    

Description DJ Houghton CLA 2011-08-16 16:41:20 EDT
In the shared install scenario if we have some cache extensions set in the profile properties, we do not copy them over to the child profile when we create it. 

Since profiles are not cascaded, should we be copying these values? Perhaps to a new property? (org.eclipse.equinox.p2.cache.extensions.parent?) 

Otherwise as soon as anything is installed into the child profile, the cache extensions are lost.
Comment 1 DJ Houghton CLA 2011-08-16 16:50:58 EDT
To elaborate further, we have a product scenario where we have a shared install and the bundles are in a separate location from the install area. e.g.

  C:/Program Files/MyCompany/MyProduct  <- exe and config are here
  C:/Program Files/MyCompany/MyProductShared <- bundles are here

We don't want to use -bundlepool (or -shared) when installing via the director because we want to control the contents of the shared location. Currently we use the cache extensions profile property but when a non-admin user starts and a new profile is created in their local work area, this property is lost.
Comment 2 DJ Houghton CLA 2011-08-17 15:11:56 EDT
Pascal, I added you to the CC list as I think you may have some ideas about this from previous conversations. :-)
Comment 3 Tom Houser CLA 2011-08-17 18:10:00 EDT
Pascal, there are actually two symptoms we are seeing and we have determined that both are caused by the same bug.  Here are the two symptoms:

1) In a shared install scenario, the cache extensions are not being copied to the child profile.

2) In a normal non-shared install scenario, if we run "eclipse -clean" all the features are removed from "platform.xml".

The bug that causes both these problems is that the p2 engine incorrectly writes out the "platform.xml" file.  The "platform.xml" file that it writes out has two sites:

   file:../MyProduct
   platform://base

Notice that the MyProductShared site (which has all the features) has been incorrectly identified as the "platform://base".  The "platform://base" URL will resolve to the eclipse install directory so those URLs are essentially both the same (and thus MyProductShared is missing).

Thus, in symptom 1, in a shared install scenario, the cache extensions are not being copied to the child profile because there is no site in the "platform.xml" that references the MyProductShared location.

Similarly, in symptom 2, when "eclipse -clean" is executed, no features are found in the install location and thus all the <feature> elements are deleted from the "platform://base" <site> in the "platform.xml".

For some reason, when saving the "platform.xml" file, the p2 engine assumes that whatever site contains the "org.eclipse.equinox.launcher" plugin is the "platform://base" site, which is incorrect.

When the p2 engine writes the "eclipse.ini" file, it does correctly identify the install folder with the "-install" option.

We had this same problem with the old reconciler based installs.  To work around it we had to unzip a copy of the "org.eclipse.equinox.launcher*" plugins in the install folder's plugins folder (e.g. the MyProduct/plugins folder).  We are not doing this workaround in the new p2 engine based installs.

Here is where the p2 engine determines the install location when writing out the "platform.xml" file:

Thread [main] (Suspended (breakpoint at line 47 in PlatformConfigurationWrapper))	
	PlatformConfigurationWrapper.getOSGiInstallArea(Manipulator) line: 47	
	PlatformConfigurationWrapper.save() line: 236	
	EclipseTouchpoint.savePlatformConfigurationWrapper(IProfile) line: 78	
	EclipseTouchpoint.commit(IProfile) line: 144	
	EngineSession.commit(IProgressMonitor) line: 123	
	Engine.perform(IProfile, IPhaseSet, Operand[], ProvisioningContext, IProgressMonitor) line: 91	
	Engine.perform(IProvisioningPlan, IPhaseSet, IProgressMonitor) line: 44	

Notice that it just uses the location of the "org.eclipse.equinox.launcher" bundle:

	private static URL getOSGiInstallArea(Manipulator manipulator) {
		final String OSGI = "org.eclipse.osgi"; //$NON-NLS-1$
		BundleInfo[] bis = manipulator.getConfigData().getBundles();
		String searchFor = "org.eclipse.equinox.launcher"; //$NON-NLS-1$
		for (int i = 0; i < bis.length; i++) {
			if (bis[i].getSymbolicName().equals(searchFor)) {
				if (bis[i].getLocation() != null) {
					try {
						if (bis[i].getLocation().getScheme().equals("file")) //$NON-NLS-1$
							return fromOSGiJarToOSGiInstallArea(bis[i].getLocation().getPath()).toURL();
					} catch (MalformedURLException e) {
						//do nothing
					}
				}
				if (searchFor.equals(OSGI))
					return null;
				searchFor = OSGI;
				i = -1;
			}
		}
		return null;
	}

We have determined that both symptom 1 and symptom 2 above are caused by the "platform:/base" issue in the "platform.xml".

That is, if the "platform.xml" is correctly written out by fixing PlatformConfigurationWrapper.getOSGiInstallArea() to correctly identify the install area, then, in a shared install scenario, the cache extension profile property is not lost in the child profile (i.e. symptom 1).

Similarly, if the "platform.xml" is correctly written out by fixing PlatformConfigurationWrapper.getOSGiInstallArea() to correctly identify the install area, then "eclipse -clean" does not remove all the <feature> elements from the "platform.xml" file (i.e. symptom 2).

Note that the PlatformConfigurationWrapper.getOSGiInstallArea() method must be fixed in both the installer (e.g. IM) and in the installed product.  Otherwise, the first time any p2 operation is run from the installed product (e.g. reconciliation during product startup, operations via p2 UI, etc), the "platform.xml" is corrupted again (i.e. with incorrectly identified "platform:/base" site).

When writing the "platform.xml" file, why doesn't PlatformConfigurationWrapper use the same method to determine the install area that EclipseLauncherParser uses when it writes the "-install" option in the "eclipse.ini" file?  That is, why doesn't it just use:

    manipulator.getLauncherData().getLauncher().getParentFile()
Comment 4 DJ Houghton CLA 2011-08-31 11:55:06 EDT
Pascal and I talked about this and you are correct that the code in Framework admin has better logic. Looking at the code, it seems to calculate the osgi install area 5 different ways. In order:
- look for -install on the command-line
- look for -startup on the command-line and calculate based on the OSGi JAR
- get the "home" value on the launcher data object
- get the OSGi JAR from the launcher data object and calculate
- perform the File.getParentFile logic like you mention

Since the Equinox extensions to Framework Admin aren't visible (and we don't want to rely on the Equinox runtime as our implementation), we can look at migrating some code over to the Eclipse touchpoint. I don't think the first 2 are applicable but we have the launcher data object and can calculate based on the values it contains.
Comment 5 DJ Houghton CLA 2011-08-31 16:18:49 EDT
Pascal, what do you think about this change? I pushed it to the bug354888 branch.

http://git.eclipse.org/c/equinox/rt.equinox.p2.git/commit/?h=bug354888&id=a4651532eecc5072259063cdf1937c53a7038c36
Comment 6 DJ Houghton CLA 2011-09-01 10:42:49 EDT
I pushed another change in [1]. Basically I just added the old behaviour back in the case that we can't calculate the location from the launcher data.

http://git.eclipse.org/c/equinox/rt.equinox.p2.git/commit/?h=bug354888&id=32903bb64374f0635d64ef909b67c47e5fa3892e
Comment 7 DJ Houghton CLA 2011-09-07 13:08:23 EDT
I'm happy with the changed and merged the branch into master.