Bug 463218 - Investigate Guava Linkage errors
Summary: Investigate Guava Linkage errors
Status: NEW
Alias: None
Product: Papyrus
Classification: Modeling
Component: Core (show other bugs)
Version: 1.1.0   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 1.1.0   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-03-26 11:29 EDT by Camille Letavernier CLA
Modified: 2017-08-25 07:18 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Camille Letavernier CLA 2015-03-26 11:29:29 EDT
Although it has been worked around (and presumably fixed) several times, the Guava Linkage errors may still happen in some cases.

Investigate a long-term solution, backed with reproducible test cases, to get rid of the issue
Comment 1 Camille Letavernier CLA 2015-03-26 11:32:59 EDT
The main issue seems related to the Guava API used by oep.infra.emf.readonly which, if it breaks, has catastrophic consequences to all Papyrus (Since this is a critical component)

One possible solution for Mars would be to reexport the Guava bundle used by oep.infra.core (So it would be reexported to 95% of the Papyrus plug-ins), and use internal (non-reexported) Guava dependencies for remaining cases (Where Guava is only used internally)

For Mars +1, a more definitive solution would be to use Java 8 instead of Guava, whenever possible (And it seems that currently, it would be possible to entirely replace Guava with Java 8 equivalents, although a more exhaustive investigation is required to confirm that)
Comment 2 Christian Damus CLA 2015-03-26 13:06:52 EDT
I have reproduced the classic Guava run-time linkage error using two Guavas (Guavae?) in my PDE target.

Plug-in A: org.eclipse.papyrus.infra.core exporting an API returning Optional<T>
Plug-in B: a test plug-in that exports an API returning Optional<T>
Plug-in C: an "integrator" that uses both of the A and B APIs.

A requires Guava 15 or later (I hacked it) but doesn't re-export the requirement.
B requires Guava 12 to 13 exclusive.
C requires Guava 11 or later.

A menu action in C that invokes both of the A and B APIs fails with

!ENTRY org.eclipse.ui 4 0 2015-03-26 18:02:06.281
!MESSAGE Unhandled event loop exception
!STACK 0
java.lang.LinkageError: loader constraint violation: loader (instance of org/ecl
ipse/osgi/internal/loader/EquinoxClassLoader) previously initiated loading for a
 different type with name "com/google/common/base/Optional"
	at org.eclipse.papyrus.examples.j2ee.ConnectHandler.execute(ConnectHandler.java
:60)
...


So, I am now in a position to test the fix proposed in the Gerrit review.
Comment 3 Christian Damus CLA 2015-03-26 14:26:51 EDT
(In reply to Christian W. Damus from comment #2)
> I have reproduced the classic Guava run-time linkage error using two Guavas
> (Guavae?) in my PDE target.
> 
> Plug-in A: org.eclipse.papyrus.infra.core exporting an API returning
> Optional<T>
> Plug-in B: a test plug-in that exports an API returning Optional<T>
> Plug-in C: an "integrator" that uses both of the A and B APIs.
> 
> A requires Guava 15 or later (I hacked it) but doesn't re-export the
> requirement.
> B requires Guava 12 to 13 exclusive.
> C requires Guava 11 or later.

Actually, this is not strictly accurate.

To simulate the accidental miswiring of bundles that could be compatible, I have this dependency graph:

      +--> A <-- P
  C --+
      +--> B <-- R

Where 

  A requires Guava [11, ∞)
  B requires Guava [11, ∞)
  C requires Guava [11, ∞)
  P requires Guava [15, ∞)
  R requires Guava [12, 13)

So that we have A and B as the usual Papyrus bundles we have today that take any Guava from 11 up and don't re-export, C is the hapless integrator, and P and R are test bundles that serve to constrain the classpath of A and B externally.

> 
> A menu action in C that invokes both of the A and B APIs fails with
> 
> !ENTRY org.eclipse.ui 4 0 2015-03-26 18:02:06.281
> !MESSAGE Unhandled event loop exception
> !STACK 0
> java.lang.LinkageError: loader constraint violation: loader (instance of
> org/ecl
> ipse/osgi/internal/loader/EquinoxClassLoader) previously initiated loading
> for a
>  different type with name "com/google/common/base/Optional"
> 	at
> org.eclipse.papyrus.examples.j2ee.ConnectHandler.execute(ConnectHandler.java
> :60)
> ...
> 
> 
> So, I am now in a position to test the fix proposed in the Gerrit review.
Comment 4 Christian Damus CLA 2015-03-26 18:20:28 EDT
Sorry, wrong again.  I'll try once more.

I can reproduce the LinkageError printed previously by this scenario.

1. Launch a run-time workbench with only the Papyrus plug-ins as delivered by the
   Simultaneous Release except that it also includes Guava 12 in addition to Guava 15.
   Before launching, I clear the platform/Equinox configuration area to ensure that
   all dependency wiring is as new.  This launch configuration includes the plug-in
   org.eclipse.papyrus.infra.core (which we shall call A) that requires
   Guava [11, ∞) and publishes API methods returning Optional<T>.  A does not
   re-export Guava (per current Papyrus practice)

2. Verify basic diagram editing behaviour.  Quit the run-time workbench.

3. Add to the launch configuration two new plug-ins:
   * B requires Guava [11, 13) (thus allowing 12 but forbidding 15) and publishing
     an API method that returns Optional<T>.  This is a "third party" plug-in.
     B does re-export Guava because it's part of the API, which many third parties
     can be expected to do
   * C requires Guava [11, ∞) (aligned with common Papyrus practice, which an
     integrator might think is the correct thing to do) that uses the APIs of both
     the "third-party" plug-in B and also of the Papyrus plug-in A

     Thus, C is an "integrator" plug-in using Guava APIs published by A and B
     where neither of these re-exports their own Guava dependency.

4. Uncheck the option to clear the configuration area and launch.

5. Verify basic diagram editing behaviour.

6. Invoke an action provided by plug-in C that invokes the A and B APIs returning
   Optional<T>.  Observe the LinkageError.

Applying Camille's Gerrit patch does not, much to my chagrin, resolve the problem by causing the OSGi resolver to fail to resolve plug-in C at start-up at step 4 of the scenario (starting again from the plain but patched Papyrus configuration).  Instead, I get all the way to the LinkageError at step 6 again.
Comment 5 Benoit Maggi CLA 2017-08-25 07:18:20 EDT
Is this bug still valid with "Import-Package solution" that was provided in Oxygen.0 ?