| Summary: | [api tooling] Bundle version computer and re-export of a superclass breaking API | ||
|---|---|---|---|
| Product: | [Eclipse Project] PDE | Reporter: | Martin Oberhuber <mober.at+eclipse> |
| Component: | API Tools | Assignee: | PDE API Tools Inbox <pde-apitools-inbox> |
| Status: | RESOLVED INVALID | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | darin.eclipse, john.arthorne, Olivier_Thomann |
| Version: | 3.4 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows XP | ||
| Whiteboard: | |||
|
Description
Martin Oberhuber
Does org.eclipse.rse.subsystems.files.dstore explicit re-export org.eclipse.rse.core? No. As long as org.eclipse.rse.subsystems.files.dstore doesn't re-export explicitly org.eclipse.rse.core, the clients that are using org.eclipse.rse.subsystems.files.dstore are not broken. You should change the version of org.eclipse.rse.subsystems.files.dstore only if you re-export org.eclipse.rse.core or if you introduce a breaking API based on the new one from org.eclipse.rse.core. So I would say that in your case, you should not change anything except the micro or the qualifier of org.eclipse.rse.subsystems.files.dstore. Ok to close ? Hm... I'm not so sure.
Actually, the only change in my bundle is that it now does
Require-Bundle: org.eclipse.rse.core;bundle-version="[3.0.0,4.0.0)",
whereas before it did
Require-Bundle: org.eclipse.rse.core;bundle-version="[2.0.0,3.0.0)"
I was under the impression that the mere fact of requiring a downstream bundle which introduces an API breakage would be an API breakage already. But perhaps I'm wrong... if all the clients explicitly require-bundle only those bundles that they use API from, then an old-style client who only links against my bundle (but not any downstream one) should still be fine...
Just for the fun of it, I tried putting this in my Manifest:
Require-Bundle:
org.eclipse.rse.core;bundle-version="[3.0.0,4.0.0)";visibility:=reexport
and thought that now it would be a breaking API change; but it looks like API Tooling doesn't think so, and probably it is right because the old version of the bundle did not reexport the downstream API while the new one does, so it's only API addition but no breaking API change.
Sorry if this bug is the wrong place to discuss this, but I'm simply confused.
I wonder if there is any testcase where the old version would already have done a reexport, and the new version either gets rid of the reexport or keeps the reexport but reexports a new major version of the downstream bundle... I cannot test it easily because I'd have to change my API baseline, but I thought I'd ask..
My understanding is that as long as the clients of org.eclipse.rse.subsystems.files.dstore cannot be broken by the breaking change in org.eclipse.rse.core it should be fine. For the re-export case, I think you would need both sides to re-export in order to see a breakage. I don't know who could clarify this rule about using a plugin that has breaking changes without reexporting it. I think I found out myself -- thanks for bearing with me. By writing an artificial client of subsystems.files.dstore that ONLY imported that bundle and NOT the not-reexported org.eclipse.rse.core bundle, I saw that PDE would forbid writing any Java code that requires access to any of the rse.core stuff. This means, that when the downstream bundle is not reexported, and a client doesn't require it (because it doesn't directly use any of its API), then this client can happily run against the newer version, it is binary compatible. So I agree that I don't need to rev up the major version in this case. In fact, for a client that ONLY uses the small subsystems.files.dstore API, any (breaking or non-breaking) change in the downstream bundles could be seen as an implementation change only, so a micro version rev up seems to be in order. On the other hand, the change is of course not source compatible: because when the downstream bundle extends my superclass by adding some new private method(s), and the client extends my exported subclass and happens to add a method with the same name but public, the code will no longer compile although I have only made a micro version rev up. But fortunately, we're only talking about binary compatibility here, and not source compatibility. Looks like I'll need to downrev my bundles... thanks again. But I'd still like to know whether you guys have a testcase that does a reexport in the baseline, a reexport in the new code, and has a major version change in the downstream bundle... would API Tooling suggest a major version change in the bundle under test as well? The cool thing here is, that when my client only requires plugin but not plugin.downstream, it can see, use and instantiate the classes declared in plugin; but any class that's declared in plugin which extends a class from plugin.downstream cannot be extended in the client. That way, binary breaking changes are avoided. The only odd thing in this case is JDT's error message when I try to extend a class that I can see, but where a superclass is invisible because I don't import its bundle: "The type plugin.VisibleClass cannot be resolved. It is indirectly referenced from required .class files." I think this is indirect, because VisibleClass is visible and can be resolved. The problem is really, that a superclass of VisibleClass can not be resolved. I filed bug 228927 for this issue. Marking INVALID since API Tooling and the version computer are doing the right thing. See bug 230178 for a different but probably related issue. |