|Re: [cross-project-issues-dev] Still issues with multiple Guava versions ... still time to fix them|
Please excuse the lengthy reply, I'm trying to clarify many confusions.
My projects depend heavily on Xtext, so they just 'inherit' the Xtext dependency. I do not have a problem. However when I see my projects used in a larger system I see pain and consequently feel a responsibility to highlight this cross-project issue.
The symptom of the problem is a Class loading failure reporting conflicting versions of a Guava class.
This can obviously occur if :
a Class loader for component A has loaded Guava class G on behalf of itself or component A
the same class loader attempts to load a different G on behalf of component B or itself.
In dealing with this problem we seem to need to consider class loading dependencies rather than non-provate API. Thus even if a plugin keep its version of Guava 100% 'private', it nonetheless exports a Guava class loading dependency if any externally loadable class inherits from a Guava class or constructs a Guava field. Use of Guava in function argument types does not appear to cause class loading and so is not a problem.
Within OSGI each plugin has its own class loader so it is possible for well behaved components A and B to co-exist with different Guava versions, just so long as an integrating application is not able to construct anything from both A and B.
For standalone applications there is only one class loader and so any conflicts between components A and B in the same application can be killers.
These problems have not been 100% reproducible. Within Eclipse the amount of lazy functionality, such as the concurrent EMF live validation thread, means that the order of class loading is not repeatable and so the order of Guava loading can vary. I'm not entirely clear as to whether a class loader faced with an a choice makes a consistent resolution, or is perhaps influenced by previously loaded packages.
The first problem arose when Guava 12 became available with a BREE 6. Consequently the many Java 5 upwards Kepler distributions started to fail. For me the problem went away by changing my test launch configurations to BREE >= 6. Once org.eclipse.osgi.utils went to BREE 6, any pretense of Java 5 support vanished and so this is a non-issue.
[Of course if API tooling warned about a BREE outside the transitive non-optional dependence BREE we would avoid these confusions.]
The next problem arose when Xtext re-exported a narrow Guava range leaving the Eclipse class loader confused. The re-export was corrected before it made it into a milestone build
Problems for large applications such as Papyrus have come and gone and come back again. They went away as Guava dependencies were widened so that the second user tolerated whatever was first loaded. They have come back with partial migration to Guava 15 which is outside the earlier wide bounds.
The reliable solution of making Guava a singleton is unacceptable to the community as a whole.
So we must make the best of it. I think we need to try to observe
a) Guava must not be exported and so avoid OSGI class loader confusion.
- API tooling could warn if any non-singleton plugin is exported.
b) Requirements to load Guava classes must not be exported
- API tooling could warn if a class in a non-singleton plugin is externally class loadable
c) All plugins that may be used in standalone applications must have a version bound that includes the latest Guava in Orbit (and as may other versions as possible)
- SimRel tooling could at least report two lists of plugins that exclude the latest version in Orbit, one with and one without a non-optional OSGI dependency.
On 02/06/2014 06:07, David M Williams wrote:
This has been discussed before, but apparently is still causing problem. The most recent bug I've seen is
Back to the top