Bug 330534 - Discussion on how to solve OT/J issues about joining the Indigo release train
Summary: Discussion on how to solve OT/J issues about joining the Indigo release train
Status: RESOLVED FIXED
Alias: None
Product: Community
Classification: Eclipse Foundation
Component: Architecture Council (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: eclipse.org-architecture-council CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 329784 330338
Blocks:
  Show dependency tree
 
Reported: 2010-11-17 20:57 EST by Olivier Thomann CLA
Modified: 2011-05-01 14:17 EDT (History)
9 users (show)

See Also:


Attachments
Sample p2 repository (4.21 KB, application/octet-stream)
2010-11-22 12:57 EST, John Arthorne CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Olivier Thomann CLA 2010-11-17 20:57:23 EST
This is a follow-up of the bug 330312 comment 33.
Comment 1 John Arthorne CLA 2010-11-18 10:39:18 EST
The current candidate seems to be load-time weaving. Adding a blocking bug needed to make that work well.
Comment 2 Stephan Herrmann CLA 2010-11-18 13:19:07 EST
I have drafted an initial "essay" at 
   http://wiki.eclipse.org/OTJdtCore

That page is intended to put all our cards on the table and to enable
a discussion about possible technical solutions.

The page gives background why I believe that no patch-less solution is 
possible in the near future. Here are some consequences in a nutshell:

From my current understanding the following are currently not possible:
* install two independent patch features affecting the same original feature
* install an original JDT/Core patch on top of the OT patch feature
For the second item I see, however, two options:
* user can uninstall OTDT and install JDT/Core patch instead (always possible)
* user can wait until the same bugfix occurs in a new version of the OT patch
  (I will make sure this happens in a very timely fashion)

An issue that I missed in previous discussions: indirect bundle dependencies
could indeed unintentionally pull in the OT variant of jdt.core.

Would it be possible to mark this plugin (the OT variant) as "exact version
match only"? I.e., allow the solver to use this plugin version only if 
explicitly requested, preferring an older version otherwise?
Any p2 expert to tell if this is possible already today or could be easily
added?
Comment 3 Stephan Herrmann CLA 2010-11-18 13:35:03 EST
From some comments (sorry no reference - just rumors :) ) I understood
that people would be fine with a fake where the OT patch would be
distributed under a separate OSGi bundle name, yet its classes would
be used instead of those from the original JDT/Core.

Did I get that suggestion right?

I understand this as a solution to the issue of unintentionally picking
the OT variant where the original should be picked.

With my limited knowledge about p2 I feel that my proposal in the previous
comment ("exact-version-match-only") could be much easier. And I think
it would be much cleaner.

However, if this fake should be the way to go we could perhaps even use
our existing adaptor hook to tweak the class loader in the necessary way.
Yucks.
Comment 4 Stephan Herrmann CLA 2010-11-20 10:18:26 EST
I've made initial experiments with an alternative strategy:

By a different scheme of our version qualifiers we could ensure that
the version of the OT variant is always *less* than the original.
Given also that we never publish into a new major.minor.micro stream
before JDT does, this would effectively prevent that the OT variant
be selected when the original was intended.

Only the explicit request from the OT feature would ever pick the 
OT variant.

Initial experiments indicate this *might* work. Before working out the
details I'd like to hear advice whether the tool chain PDE/Build -
p2 - Equinox could possibly cope with a patch feature that literally
*downgrades* a plugin (from original JDT to OT variant with lesser version).
Currently, I couldn't convince PDE/Build to correctly resolve a required 
fragment when using the proposed versioning scheme.

At this point it seems we have three variants:
(a) provision plugin by a different OSGi name (from the object teams namespace)
    but let runtime use it in the jdt namespace.
(b) set a flag in p2 metadata that the variant plugin should never match
    to any version range, only to an explicit version request.
(c) make variant appear under lesser version.

IMHO, (b) would be cleanest, if possible without too much efforts needed.
Comment 5 Stephan Herrmann CLA 2010-11-21 19:08:28 EST
(In reply to comment #4)
> (c) make variant appear under lesser version.

I made progress towards this solution. Most parts of the tooling seem to
play well with this strategy. Only PDE/Build has a problem when also 
fragments of jdt.core are involved.

I have filed bug 330763 as a request to enhance PDE/Build with support for
ResolverHooks (which have recently been added to the equinox framework).
Comment 6 John Arthorne CLA 2010-11-22 12:57:30 EST
Created attachment 183587 [details]
Sample p2 repository
Comment 7 John Arthorne CLA 2010-11-22 13:13:37 EST
(In reply to comment #4)
> (a) provision plugin by a different OSGi name (from the object teams namespace)
>     but let runtime use it in the jdt namespace.

This one seems the easiest and cleanest to me. Essentially the p2 metadata would have a name like org.eclipse.objectteams.jdt.core, but the artifact would be org.eclipse.jdt.core. The p2 metadata is used exclusively during dependency resolution, which means the metadata will only match a consumer that wants the objectteams bundle. This means there is no chance that at install-time to get the wrong thing. Once installed, the actual bundle would be in the org.eclipse.jdt.core namespace which suits your runtime requirements. Even better the OT/J would no longer need to be installed as a patch, so all the patch-related limitations go away.

I have attached a sample p2 repository where I did this as a test. The p2 metadata says aaa.some.plugin, but the artifact name is aaa.another.plugin. Once the feature is installed, aaa.another.plugin is resolved at runtime. The great news is that this works out of the box with no change in p2 today! I knew we conceptually allowed for this decoupling but as far as I know it hadn't been tried yet.

> (b) set a flag in p2 metadata that the variant plugin should never match
>     to any version range, only to an explicit version request.

There is no such concept in our p2 metadata or dependency resolution (SAT4J) today. I don't even know if this is possible, but if so it would minimally require a new concept in our metadata and a change to how to interact with SAT4J to encode that new form of constraint. So, this option might be feasible but I think it would be a big change.

> (c) make variant appear under lesser version.

This doesn't seem to solve our core problems. A consumer bundle requiring org.eclipse.jdt.core still has no way of saying "only allow OT/J versions", or "only allow original versions". Without having a clear way for the consumer to specify this means the solution is very brittle. The more common failure case would now be that someone expects the OT/J version but gets the original by accident, which is still not great. Also it requires continued use of patch features with their associated limitations.
Comment 8 Andrew Niefer CLA 2010-11-22 17:21:11 EST
One way to avoid the OT/J bundle being installed accidentally would be for its IU to have a non-greedy dependency on the OT feature that contains it.

This would be accomplished by adding a p2.inf file to the OT/J bundle, containing something like this:

requires.1.namespace=org.eclipse.equinox.p2.iu
requires.1.name=org.eclipse.ot.feature.group
requires.1.range=[1.0.0,2.0.0)
requires.1.greedy=false
requires.1.optional=false

This means that the OT jdt bundle can only be installed if the OT feature is also installed.  The greedy=false means that p2 will not automatically pull in the OT feature to satisfy this dependency.  The feature must be explicitly selected by the user.
Comment 9 John Arthorne CLA 2010-11-22 17:31:23 EST
(In reply to comment #7)

> (a) provision plugin by a different OSGi name (from the object teams namespace)
>     but let runtime use it in the jdt namespace.

We discussed this issue at length in the Equinox meeting today. The problem with this solution is that we still have a determinism problem at runtime. I.e., if the user has both variants of jdt.core installed, it will be uncertain which version is selected by the OSGi resolver. I assume you want users to be able to install OT/J on top of an existing JDT or Eclipse SDK, so this solution does not work.

That led us to the solution described by Andrew, which uses an extra dependency to ensure the OT/J variant is installed IFF the ObjectTeams feature is installed.
Comment 10 Stephan Herrmann CLA 2010-11-22 17:53:56 EST
Thanks for your suggestions! 
The one in comment 8 looks cool, expressing exactly the constraint
we need. I'm currently preparing a build with this strategy so we'll
soon have something to test in real life.
Comment 11 Stephan Herrmann CLA 2010-11-23 06:49:42 EST
From all I can see the strategy from comment 8 indeed solves the issue
of accidentally installing the OT variant of jdt.core.
Thus this bug no longer depends on bug 330763.

For transparency here's what I tried:
1. Install the eclipse-cpp-indigo-M3 package, which has no JDT
2. Add the newly built OT site, make sure it is loaded
3. Select "All Available Sites" 
   (I assume this comes close to having everything in one repo).
4. Install "Collaboration" > "Subversive JDT Ignore Extensions"
   (this pulls in the jdt.core plugin)
5. Check Installation details for jdt.core

For the first run of the experiment I had an OT site which contained
the newest build on top of our M3 build.
As a result the patch from the M3 build got accidentally installed.
This shows that the experiment actually tests the right thing

Then I rebuilt our site to contain only the latest build with the p2.inf
from comment 8. This time step 5 correctly showed the original
org.eclipse.jdt.core.v_B22.

Also explicitly installing the JDT and explicitly installing the OTDT
on top of the JDT worked. So my conclusion is that this particular issue
is resolved, but I'm leaving the OT site from the experiment online at
   http://download.eclipse.org/objectteams/updates/bug330534
should anybody else want to perform some more tests against it.

Many thanks to the equinox team.

I'll still leave this bug open for now to document the dependencies on
bug 329784 (touchpoint instruction) and also bug 330338 (ui).
Comment 12 David Williams CLA 2010-11-23 23:47:44 EST
(In reply to comment #8)
> One way to avoid the OT/J bundle being installed accidentally ...

> ... The feature must be explicitly
> selected by the user.

Keep in mind, even though we say it is a bad idea, many users "select everything" to be installed. So I think we'd count that as "sort of by accident"?

In that case, is it clear (to others, it is not to me) what subsequently happens if someone tries to update, or install another product that depends on jdt into an existing eclipse installation, etc.? My intuition (given previous experience with p2) is there would still be lots of opportunities for clashes and inconsistent installations.
Comment 13 John Arthorne CLA 2010-11-24 09:11:14 EST
(In reply to comment #12)
> Keep in mind, even though we say it is a bad idea, many users "select
> everything" to be installed. So I think we'd count that as "sort of by
> accident"?

Is this really something many users do?? I have often tried this during a test pass as a load test, but I don't recall ever getting it to work. There would always be things like target platform components that would not install, or other conflicts preventing it from completing. I haven't tried it lately so maybe it does in fact work, but it doesn't seem like a common workflow to me.

Second, if a user blindly installs everything, there are plenty of other ways the behaviour of JDT could be altered. Plug-ins could be reaching into JDT internals, or using weaving technology to alter JDT behavior. Although we would like all of those kinds of things to be avoided, the most important thing is that the consumer is able to control what they install and they have a recourse if something goes wrong (find the faulty component and uninstall it). For example someone crafting a commercial product will select the release train components they want, and then heavily test that lineup to make sure it suits their needs. If they find problems they can make changes to that chosen lineup to avoid them.

> In that case, is it clear (to others, it is not to me) what subsequently
> happens if someone tries to update, or install another product that depends on
> jdt into an existing eclipse installation, etc.? My intuition (given previous
> experience with p2) is there would still be lots of opportunities for clashes
> and inconsistent installations.

In this situation, if someone attempts to install software that requires JDT, it will install fine, but run on OT/J variant of JDT. If JDT is upgraded, the OT/J patch feature will get uninstalled.
Comment 14 Martin Oberhuber CLA 2010-11-25 02:23:13 EST
As far as I know, in the RT project (RAP for instance), components that should only go into the target platform but not into the IDE simply have a dependency that cannot be satisfied in the IDE.

If you refer to the recent discussion about OT/J, the solution is outlined in
bug 330534 comment 8.
Comment 15 David Williams CLA 2010-11-30 00:39:09 EST
(In reply to comment #13)
> (In reply to comment #12)
> > Keep in mind, even though we say it is a bad idea, many users "select
> > everything" to be installed. So I think we'd count that as "sort of by
> > accident"?
> 
> Is this really something many users do?? 

I don't know frequency ... just that it seems to come up every release. 
The point I was trying to make was that users are not as deliberate about installing things as "we" often think they are ... they often just install things either "sort of by accident" or just to experiment, or select a whole category of things, or whatever ... so I was trying to say we need to consider those use cases too ... and not just rely on "if they selected it, they must have intentionally really wanted it". 

> ... the most important thing is
> that the consumer is able to control what they install and they have a recourse
> if something goes wrong (find the faulty component and uninstall it). 

Yes. But, I hate to admit, I still don't see how to uninstall something by using the IDE UI (just director). That's probably not really relevant to this issue ... just wanted to document that people will end up with it installed, and wanted to make sure that didn't hose up future upgrades or installs. Sounds like it won't. 

Thanks for the additional info.
Comment 16 Stephan Herrmann CLA 2011-05-01 14:17:42 EDT
The core issue has been resolved as of comment 11 (based on comment 8).

Additionally, Object Teams happily consumes the solutions from bug 329784
and bug 330338. 

From my POV this closes this issue. Thanks to all for your help!