Closed guw closed 1 year ago
Why do you think it is an equinox issue? You bundles most likely do not use correct use constrains (according to your debug output none at all) or wrong import ranges so nothing to blame to Equinox.
Because of the use of Require-Bundle
with visibility:=reexport
between the two Equinox should never resolve to different import versions. The mandate to have uses directive is not really needed.
The mandate to have uses directive is not really needed.
Can you please reference the relevant part of the spec about this? reexport only means to rexport the package, so if you don't have any usage constraints they are exported as is (without any constraints) so user of that package are exposed to classpath inconsistencies see
This is why I whine endlessly (and to little avail) on cross-projects about duplicates and especially about duplicate guava versions because that in particular so often leads to wiring problems due to the fact that it so often percolates up into the APIs. Of course guava's approach of creating a new major version on a regular basis is a compounding factor. Interestingly, this is not even a wiring problem, but some other nasty flavor of the too many guavas problem long with nasty re-rexports.
Firstly, perhaps we (you) need to explain/understand why guava 31.1.0.jre even present in the installation? Something must require it to the exclusion of 32.1.2.jre. What might that be? Is that thing perhaps in the transitive dependencies of either of these two things? Unfortunately we can't even guess from the information provided here.
Of course as highly technical people, we all realize that we can't concretely investigate this problem without being able to reproduce it...
It might be faster to change com.google.common.collect;version="31.1.0" to 32.1.2 and see if the build even works. That might point the finger at the source of the problem...
@merks with proper use-constrains the resolver would give a detailed technical answer already :-)
This is not a wiring problem because (as explained) the wire are all correct according to the given constraints (!), the problem now occurs exactly as described in the second article, a service (or even more likely static singleton) is accessed but the provider is using another classloader as the consumer.
So this is likely a result of using different bad style patterns in combination in descending order:
Can you please reference the relevant part of the spec about this.
I don't think this needs a spec. Lots of things in Equinox exist for backward compatibility to the old Eclipse days. This feels like one of those things which should just work.
Of course as highly technical people, we all realize that we can't concretely investigate this problem without being able to reproduce it...
@merks Agreed. That's why I keep my Eclipse instance open and use the host OSGi console to debug. I am not even sure this would reproduce cleanly.
I am trying several things to work around it. Calculating uses in PDE does not work. It's always stuck at this package. Seems to be caught in an endless loop.
why guava 31.1.0.jre even present in the installation?
🤷 It's not in the target platform of the project/plug-in. The plug-in is using the one from Orbit. It's likely some other extension which brought it into the installation. I don't really think you can avoid this at scale out there. Thus, having some logic in Equinox to be smarter here would help.
It might be faster to change com.google.common.collect;version="31.1.0" to 32.1.2 and see if the build even works. That might point the finger at the source of the problem...
Yepp, I'm also investigating this as a workaround as long as uses constraints cannot be computed by PDE.
I don't think this needs a spec.
Please see the Mission Statement:
From a code point of view, Equinox is an implementation of the OSGi core framework specification, a set of bundles that implement various optional OSGi services and other infrastructure for running OSGi-based systems. The Equinox OSGi core framework implementation is used as the reference implementation and as such it implements all the required features of the latest OSGi core framework specification.
Lots of things in Equinox exist for backward compatibility to the old Eclipse days.
You can always use "good old Eclipse 2.0" for sure, but current Equinox mission is not that... so there is neither a test nor a TCK for this one obviously so whatever you expect is at least undefined behavior.
@guw
Would you be able to share the installation profile? I.e., the latest .profile.gz in `
@merks Thanks Ed! I'd rather avoid you spending time on this analysis. I do believe Uses info would be best here but I'm having trouble calculating it.
I'm really rather curious ; goodness knows when the next time a problem like this shows up. I just tested that it's really easy to use the CBI Aggregation Analyzer Editor to analyze profile. I understand if there are reasons you can't share the profile though; that's up to you...
So the caffine thing strictly requires 31.x.
These bundles can resolve to the 32.x because there is no constraint to the contrary:
This bundle shows the possible resolutions from the other end:
I expect that OSGi keeps the wiring consistent here.
And then finally this bundle is importing guava packages as well as receiving/seeing them from its bundle requirement via the exports of that required bundle:
So it does indeed seem as if it's the case that if "something" was smart enough to wire this SDK bundle to guava 31.x instead of guava 32.x there would be no class loader constraint violation. But nothing knows that the SDK bundle sees the guava version of the sourceimports bundle...
Thanks @merks. Meanwhile, I added some Uses constraints and updated to the latest versions. Let's see if this mitigates the problem.
sorry for the pains. The versions were generated and appended by the bnd plugin, which inspected the maven dependency version. I believe the fix would be for me to specify it explicitly with a minimum version constraint, e.g. ;version=20.0
, and bnd won't override that. I am not super familiar with osgi and use bnd + paxExam tests to try to be a good citizen. I'm not sure if bnd is being too rigid in its defaults or if it's mostly guava predating semver.
The caffeine-guava adapter provides an adapter for users who leaked Guava's cache externally or have a significant amount of code to migrate but don't want to bother yet. In the bazel-eclipse project, it has one usage which is internal and could trivially drop the adapter for shorter code. In this case I think that would be the right fix, and I'll review osgi metadata to be more forgiving.
This is why I whine endlessly (and to little avail) on cross-projects about duplicates and especially about duplicate guava versions because that in particular so often leads to wiring problems due to the fact that it so often percolates up into the APIs. Of course guava's approach of creating a new major version on a regular basis is a compounding factor. Interestingly, this is not even a wiring problem, but some other nasty flavor of the too many guavas problem long with nasty re-rexports.
Yes Guava can be really it problem. Xtext's re-exports of Guava prevented us updating our product to recent Eclipse versions since Eclipse 2022-12, with 2023-09 we can finally update because Xtext thankfully updated to the latest guice and guava. What also makes this problem very hard besides the re-exports is that even with 2023-09 we have a mixture of guava 32 from Maven-Central and Guava from 27 and 31 from Orbit (little sarcastic remark: good old Orbit ensures all use the same version). The problem is that Guava from Orbit has another structure and includes more packages than the original.
Regarding the relatively frequent major version in Guava:
In the release notes Guava 32 it was announced that
Removed @Beta from almost all APIs. For details, see the bottom of the release notes. At this point, it's probably simpler to look at a list of APIs that still are @Beta, such as [this list for guava-jre](https://guava.dev/releases/32.0.0-jre/api/docs/com/google/common/annotations/class-use/Beta.html). Most of the remaining @Beta APIs are in graph and hash.
So from an OSGi point of view it might be reasonable to start decoupling the bundle from the package version and control the package version with corresponding annotations plus using the bnd-baseline-maven-plugin to ensure that the packages are versioned in a correct SemVer matter.
I have already thought about suggesting this, but didn't have the time for that yet.
@guw
Any updates on your attempts at workarounds?
Yes. I updated all versions to require the latest one and this forces resolution to be consistent. I also added Uses where possible. That got me past this issue.
I think we might as well close this because I think this will be fixed some time with the range [hell-freezes-over,end-of-time). 😱
After installing the latest M2E update (2.4.0) some of my plug-ins started failing. It couldn't start a bundle anymore.
Debugging the problem in the host OSGi console shows a wiring issue:
However, that wiring should be technically impossible because Equinox is supposed to discover that 1710 and 1708 and 1706 require all the same Guava version.
This is especially important because 1710 re-exports 1708. Additionally 1710 has a
Require-Bundle
on 1708. This should trigger Equniox to resolve to the same imports/version used by each bundle.