Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional testcase that show some unexpected behavior of resolver #469

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

laeubi
Copy link
Member

@laeubi laeubi commented Jan 9, 2024

this is not to meant to be merged in its current form

The added testcase demonstrates some unexpected behavior of resolver we have already seen in the past eclipse simrel releases and I see regular with custom installations, also m2e suffers from long running resolve operations when starting test from the IDE.

To summarize the both things that hurt the most here are boil down to the following facts:

Undesired substitutions

  • A bundle V1.0 has a substitution package A and imports it with consumer range (e.g. [1,2)) and export it with a specific version 1.0
  • Now there is also a bundle V1.5 that exports the package A with version 1.5 exporting the package with version 1.5
  • Now there is a consumer C importing A with range [1,2)
  • Now there is a provider P importing A with range [1,1.5)

Under some circumstance now it happens that the package of bundle V1.0 get substituted with these from V1.5 resulting in P not being resolved because the import package can not be resolved anymore.

What is expected: the resolver does not substitute the package for V1.0 because that will make it impossible for P to resolve.

FYI @tjwatson in the bundle test set I can provide to you this is the org.eclipse.lsp4j.jsonrpc bundle that gets packages substituted

Undesired binding to a higher package version causing use-constraint violations

  • There is a bundle A importing a package with a consumer range (e.g. [1,2))
  • There is a bundle B importing a package with a narrow range (e.g. [1,1.5))
  • The package is available in two versions (e.g. 1.0 + 1.8)
  • Bundle B requires A.

Under some circumstances it now happens that A is bound to a higher version (1.8) and B is failed to resolve because there is a use constraint violation because B is exposed to the same package in different versions, the bundle A is actually not used by any other bundle at all.

What is expected: the resolver does not bind A to a higher version if a consumer of A restrict it to a lower version already as it makes any consumer of A exposed to use-constraint violations.

@tjwatson in the bundle test set I can provide to you this is the org.eclipse.sprotty.server bundle that gets packages com.google.gson;version="[2.8,3)" bound to a higher gson version than those bundles that require org.eclipse.sprotty.server

What we have done in the past

In simrel or similar situation we are currently forced to a very unfortunate situation that people (mostly @merks ) are forced to watch the dependencies and carefully examine the dependencies, asking projects to update their dependencies to "fix" such issues. While it is a lot of effort this has been working in the past but puts a lot of stress on the release process.

For plugin providers / product vendors this always leads to the very unfortunate situation that they are having hard times to update their products / plugins and still maintain a certain degree of backward compatibility with older eclipse releases or users that are at the bleeding edge. The main problem is that in almost all cases it is impossible to provide a "reproducing testcase" for the following reasons:

  1. The problem seem not occur in a small isolated environment
  2. the problem is hard to analyze and understand (Add a 'wires' command to allow easy investigation of bundle wires #466 might help with that in the past) so in most cases the advice was "just update to the latest and greatest)
  3. Complex setups often include vendor specific bundles that can't be shared due to different reasons (Add a command to export the module database into a file #468 might improve this in the future)

Why this is undesired behavior

The OSGi resolver is actually the entity that should solve complex dependency problems, it should not be the developer or release manager that needs to find out how to resolve the requirements best.

Even worse, in the case I have analyzed in deep here I can actually make the state resolve when I perform some manual steps, these steps are rather trivial operations (if one gets the idea) but the resolver burns a lot of CPU cycles and does not find a suitable solution and simply gave up after a timeout or even there are situations where it seem to run forever (> 30 minutes until I killed the process).

This can be especially frustrating if one looks at the "unsatisfied" requirements and see they are there, or has use-violations but can "see" the solution that must be chosen... a computer should even be better to spot such things

The "algorithm" to fix the resolve problem is implemented here:

but it has the drawback that it takes a considerable amount of time and there is no guarantee it always fixes the problem as it simply has no way to perform anything more than ask the resolver to try a little bit harder on something that seems to be part of the problem.

@tjwatson I'll contact you directly with how you can get the bundle test set in the hope that is helps, the test-case here actually resembles the problem quite good, it shows in first round a timeout after two minutes, then some bundles are selected for refresh, this again times out but with a different set of bundles, repeating this then leads with two more refreshes to a resolved state. It even seem not be much important how high the timeout is so basically a lot of time is spend here without making any progress.

Copy link

github-actions bot commented Jan 9, 2024

Test Results

   27 files  + 1     27 suites  +1   12m 28s ⏱️ +59s
2 171 tests + 1  2 125 ✅ + 1  46 💤 ±0  0 ❌ ±0 
2 229 runs  +15  2 183 ✅ +15  46 💤 ±0  0 ❌ ±0 

Results for commit b02fd1c. ± Comparison against base commit 906f6d6.

♻️ This comment has been updated with latest results.

@laeubi
Copy link
Member Author

laeubi commented Feb 22, 2024

I now was able to derive a "public" test set it shows the following:

If you run the org.eclipse.osgi.tests.container.TestModuleContainer.testManyBundles() test you will see that at first round it runs forever (you can increase the timeout if you like) it then fails like:

Resolve bundles (0)...
Time is up!
Unresolved: osgi.identity; osgi.identity="org.eclipse.linuxtools.cdt.libhover.devhelp"; type="osgi.bundle"; version:Version="1.1.0.202309052024"; singleton:="true"
Unsatisfied: osgi.wiring.bundle; filter:="(&(osgi.wiring.bundle=org.codelibs.nekohtml)(bundle-version>=2.1.2))"
bundlesToRefresh:
	- osgi.identity; osgi.identity="org.codelibs.nekohtml"; type="osgi.bundle"; version:Version="2.1.2.v20230802-0829" [id=117]

then the second round is fast and results in

Resolve bundles (1)...
Everything seems resolved now!

Plotting the calls and number of the method ResolverImpl.ResolveSession.addPermutation(PermutationType, Candidates) show for the first case the following behavior:
grafik

one can see here that substPermutations stay at relative constant level, usesPermutations grow and than are "flapping" up & down, importPermutations grow quite linear, then timeout kicks in as the line drops.

@laeubi
Copy link
Member Author

laeubi commented Feb 22, 2024

How can one make this finally resolve is to replace the file 485_org.eclipse.lsp4j_0.19.0.v20221118-0359.MF with:

Manifest-Version: 1.0
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-SymbolicName: org.eclipse.lsp4j
Import-Package: 
 com.google.common.base;version="[30.1,31)",
 com.google.gson;version="[2.9.1,2.10)",
 com.google.gson.annotations;version="[2.9.1,2.10)",
 com.google.gson.reflect;version="[2.9.1,2.10)",com.google.gson.stream;version="[2.9.1,2.10)",
 org.eclipse.lsp4j;version="[0.19,0.20)",
 org.eclipse.lsp4j.adapters;version="[0.19,0.20)",
 org.eclipse.lsp4j.services;version="[0.19,0.20)",
 org.eclipse.lsp4j.util;version="[0.19,0.20)",
 org.eclipse.lsp4j.jsonrpc;version="[0.19,0.20)",
 org.eclipse.lsp4j.jsonrpc.json;version="[0.19,0.20)",
 org.eclipse.lsp4j.jsonrpc.json.adapters;version="[0.19,0.20)",
 org.eclipse.lsp4j.jsonrpc.messages;version="[0.19,0.20)",
 org.eclipse.lsp4j.jsonrpc.services;version="[0.19,0.20)",
 org.eclipse.lsp4j.jsonrpc.validation;version="[0.19,0.20)",
 org.eclipse.xtext.xbase.lib;version="[2.28,3)",
 org.eclipse.xtext.xbase.lib.util;version="[2.28,3)"
Bundle-ManifestVersion: 2
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Export-Package: org.eclipse.lsp4j;uses:="com.google.gson.annotations,org
 .eclipse.lsp4j.adapters,org.eclipse.lsp4j.jsonrpc.messages,org.eclipse.
 lsp4j.jsonrpc.validation,org.eclipse.xtext.xbase.lib";version="0.19.0",
 org.eclipse.lsp4j.adapters;uses:="com.google.gson,com.google.gson.refle
 ct,com.google.gson.stream,org.eclipse.lsp4j,org.eclipse.lsp4j.jsonrpc.m
 essages";version="0.19.0",org.eclipse.lsp4j.launch;uses:="org.eclipse.l
 sp4j.jsonrpc,org.eclipse.lsp4j.services";version="0.19.0",org.eclipse.l
 sp4j.services;uses:="org.eclipse.lsp4j,org.eclipse.lsp4j.adapters,org.e
 clipse.lsp4j.jsonrpc.json,org.eclipse.lsp4j.jsonrpc.messages,org.eclips
 e.lsp4j.jsonrpc.services";version="0.19.0",org.eclipse.lsp4j.util;uses:
 ="org.eclipse.lsp4j";version="0.19.0"
Bundle-Version: 0.19.0.v20221118-0359

then it still takes some times but resolve in the first round (but still feels too slow) and now the chart looks like this:

grafik

@laeubi
Copy link
Member Author

laeubi commented Feb 23, 2024

I now have created a different test set where one can see complexity explosion:

  1. rename folder many_bundles to many_bundles_tmp
  2. rename folder many_bundles_reduced to many_bundles

Test finishes for me in 0.087 seconds with 15 iterations and 51 unprocessed permutations
grafik

  1. now move 483_org.eclipse.lsp4e_0.17.1.202308231210.MF from folder bad into many_bundles

please note that this bundle is rather only a consumer of things not really used by anyone, so it should be easy to resolve, but test now takes 2.8 seconds (32 times longer) and finishes with 3500 unprocessed permutations and 2000 iterations (133 times more iterations)

grafik

@laeubi
Copy link
Member Author

laeubi commented Feb 24, 2024

I have now made some experiments and came up with the ProblemReduction class that performs some steps to eliminate invalid providers. In The case here I'm filtering all substitute packages that would lead to a state where some resource is guaranteed to not resolve (because one other resource requires the package exported).

This itself does not solve the problem and is maybe not complete but I still think its worth to share it here as something to discuss, this currently strikes out for example some of the org.eclipse.lsp4j.jsonrpc.messages alternatives as well as for com.google.gson, what needs to be also considered here is that a uses clause then will allow to strike more (e.g. for gson) if one of the substitutions was discarded, I'll probably try that out as well.

@laeubi laeubi force-pushed the complex_test_case branch 2 times, most recently from e161e88 to 3f7f9d4 Compare February 24, 2024 08:37
@laeubi
Copy link
Member Author

laeubi commented Feb 24, 2024

what needs to be also considered here is that a uses clause then will allow to strike more (e.g. for gson) if one of the substitutions was discarded, I'll probably try that out as well.

I did this now and it strikes out one more candidate of a substitution package (com.google.gson), in total this strikes out 12 possible alternatives as invalid but still to much freedom as it seems as the number of use constraint violations is still (too) high to find a solution in short time.

@laeubi
Copy link
Member Author

laeubi commented Feb 24, 2024

Next problem is now this kind of violations:

Uses constraint violation. Unable to resolve resource org.eclipse.lsp4j [osgi.identity; osgi.identity="org.eclipse.lsp4j"; type="osgi.bundle"; version:Version="0.21.1.v20230829-0012"] because it is exposed to package 'org.eclipse.lsp4j.adapters' from resources org.eclipse.lsp4j [osgi.identity; osgi.identity="org.eclipse.lsp4j"; type="osgi.bundle"; version:Version="0.21.1.v20230829-0012"] and org.eclipse.lsp4j [osgi.identity; osgi.identity="org.eclipse.lsp4j"; type="osgi.bundle"; version:Version="0.19.0.v20221118-0359"] via two dependency chains.

Chain 1:
  org.eclipse.lsp4j [osgi.identity; osgi.identity="org.eclipse.lsp4j"; type="osgi.bundle"; version:Version="0.21.1.v20230829-0012"]
    import: (osgi.wiring.package=org.eclipse.lsp4j.adapters)
     |
    export: osgi.wiring.package: org.eclipse.lsp4j.adapters
  org.eclipse.lsp4j [osgi.identity; osgi.identity="org.eclipse.lsp4j"; type="osgi.bundle"; version:Version="0.21.1.v20230829-0012"]

Chain 2:
  org.eclipse.lsp4j [osgi.identity; osgi.identity="org.eclipse.lsp4j"; type="osgi.bundle"; version:Version="0.21.1.v20230829-0012"]
    import: (osgi.wiring.package=org.eclipse.lsp4j)
     |
    export: osgi.wiring.package=org.eclipse.lsp4j; uses:=org.eclipse.lsp4j.adapters
  org.eclipse.lsp4j [osgi.identity; osgi.identity="org.eclipse.lsp4j"; type="osgi.bundle"; version:Version="0.19.0.v20221118-0359"]
    import: (osgi.wiring.package=org.eclipse.lsp4j.adapters)
     |
    export: osgi.wiring.package: org.eclipse.lsp4j.adapters
  org.eclipse.lsp4j [osgi.identity; osgi.identity="org.eclipse.lsp4j"; type="osgi.bundle"; version:Version="0.19.0.v20221118-0359"]

as one can see it looks like in the substitution step only one of the packages are substituted in a permutation but the uses is not taken into account.

@laeubi
Copy link
Member Author

laeubi commented Feb 24, 2024

I now added a new step that when a permutation is computed it checks if the removed capability has any uses if these are found all packages need to be removed from the provider as well because they will create a use-constraint violation when selected. This still results in unwanted use-constraint violations for substituted packages, but again a few less.

What next needs to be checked that after this first filter steps there can be any providers for an import left that now conflicts with the available choices for their use clauses.

An example is this what lists all requirements that currently has more than one choice for the bundle:
grafik

as one can see com.google.gson.internal.reflect uses com.google.gson, as for this package their is currently no choice, it must use the same provider as the one used for com.google.gson currently so one of the choices have to be removed here.

@laeubi
Copy link
Member Author

laeubi commented Feb 24, 2024

After striking substitution packages out now still a lot of use constraint violations happen making the resolving explode:

Uses constraint violation. Unable to resolve resource org.eclipse.elk.alg.layered [osgi.identity; osgi.identity="org.eclipse.elk.alg.layered"; type="osgi.bundle"; version:Version="0.8.0"; singleton:="true"] because it is exposed to package 'com.google.common.util.concurrent.internal' from resources com.google.guava [osgi.identity; osgi.identity="com.google.guava"; type="osgi.bundle"; version:Version="30.1.0.v20221112-0806"] and com.google.guava.failureaccess [osgi.identity; osgi.identity="com.google.guava.failureaccess"; type="osgi.bundle"; version:Version="1.0.1"] via two dependency chains.

Chain 1:
  org.eclipse.elk.alg.layered [osgi.identity; osgi.identity="org.eclipse.elk.alg.layered"; type="osgi.bundle"; version:Version="0.8.0"; singleton:="true"]
    require: (&(osgi.wiring.bundle=org.eclipse.xtext.xbase.lib)(bundle-version>=2.10.0))
     |
    provide: osgi.wiring.bundle: org.eclipse.xtext.xbase.lib
  com.google.guava [osgi.identity; osgi.identity="com.google.guava"; type="osgi.bundle"; version:Version="30.1.0.v20221112-0806"]

Chain 2:
  org.eclipse.elk.alg.layered [osgi.identity; osgi.identity="org.eclipse.elk.alg.layered"; type="osgi.bundle"; version:Version="0.8.0"; singleton:="true"]
    require: (osgi.wiring.bundle=com.google.guava)
     |
    provide: osgi.wiring.bundle; bundle-version:Version="32.1.2.jre"; osgi.wiring.bundle="com.google.guava"
  com.google.guava [osgi.identity; osgi.identity="com.google.guava"; type="osgi.bundle"; version:Version="32.1.2.jre"]
    import: (&(osgi.wiring.package=com.google.common.util.concurrent.internal)(&(version>=1.0.0)(!(version>=2.0.0))))
     |
    export: osgi.wiring.package: com.google.common.util.concurrent.internal
  com.google.guava.failureaccess [osgi.identity; osgi.identity="com.google.guava.failureaccess"; type="osgi.bundle"; version:Version="1.0.1"]

the elk layered starts with this alternatives:

  [?]org.eclipse.elk.alg.layered 0.8.0 (UNRESOLVED)
    [?]Require-Bundle: com.google.guava: 
        Bundle-SymbolicName: com.google.guava; bundle-version="32.1.2.jre"
        Bundle-SymbolicName: com.google.guava; bundle-version="30.1.0.v20221112-0806"
        Bundle-SymbolicName: com.google.guava; bundle-version="27.1.0.v20221112-0806"
    [!]Require-Bundle: org.eclipse.xtext.xbase.lib; bundle-version="2.10.0": 
        Bundle-SymbolicName: org.eclipse.xtext.xbase.lib; bundle-version="2.29.0.v20221121-0915"
    [!]Require-Bundle: org.eclipse.elk.graph: 
        Bundle-SymbolicName: org.eclipse.elk.graph; bundle-version="0.8.0"; singleton:="true"
    [!]Require-Bundle: org.eclipse.elk.core: 
        Bundle-SymbolicName: org.eclipse.elk.core; bundle-version="0.8.0"; singleton:="true"
    [!]Require-Bundle: org.eclipse.elk.alg.common: 
        Bundle-SymbolicName: org.eclipse.elk.alg.common; bundle-version="0.8.0"; singleton:="true"
    [!]Require-Capability: osgi.ee; filter:="(&(osgi.ee=JavaSE)(version=1.8))": 
        Provide-Capability: osgi.ee; osgi.ee="JavaSE"; version:List<Version>="1.0.0,1.1.0,1.2.0,1.3.0,1.4.0,1.5.0,1.6.0,1.7.0,1.8.0,9.0.0,10.0.0,11.0.0,12.0.0,13.0.0,14.0.0,15.0.0,16.0.0,17.0.0"

while xbase.lib has no alternatives at all but using a reexport of guava:

  [!]org.eclipse.xtext.xbase.lib 2.29.0.v20221121-0915 (UNRESOLVED)
    [!]Require-Bundle: com.google.guava; bundle-version="[30.1.0,31.0.0)"; visibility:="reexport": 
        Bundle-SymbolicName: com.google.guava; bundle-version="30.1.0.v20221112-0806"
    [!]Require-Capability: osgi.ee; filter:="(&(osgi.ee=JavaSE)(version=11))": 
        Provide-Capability: osgi.ee; osgi.ee="JavaSE"; version:List<Version>="1.0.0,1.1.0,1.2.0,1.3.0,1.4.0,1.5.0,1.6.0,1.7.0,1.8.0,9.0.0,10.0.0,11.0.0,12.0.0,13.0.0,14.0.0,15.0.0,16.0.0,17.0.0"

looking at this one can see that any bundle that requires org.eclipse.xtext.xbase.lib can never use a different version than com.google.guava; bundle-version="30.1.0.v20221112-0806" as an alternative.

Currently candidates of a substitution package might be permuted even
though they are mandatory for others (e.g. they import a package that
can only be fulfilled by this one capability).

This now adds a ProblemReduction class that tries to figure out some
conflicting options and remove them from the set of items to consider.
@laeubi
Copy link
Member Author

laeubi commented Feb 25, 2024

After filtering the reexport inconsistency now we have this use constraint violation:

Uses constraint violation. Unable to resolve resource org.eclipse.linuxtools.cdt.libhover.devhelp [osgi.identity; osgi.identity="org.eclipse.linuxtools.cdt.libhover.devhelp"; type="osgi.bundle"; version:Version="1.1.0.202309052024"; singleton:="true"] because it is exposed to package 'org.w3c.dom.events' from resources org.eclipse.osgi [osgi.identity; osgi.identity="org.eclipse.osgi"; type="osgi.bundle"; version:Version="3.18.500.v20230801-1826"; singleton:="true"] and org.w3c.dom.events [osgi.identity; osgi.identity="org.w3c.dom.events"; type="osgi.bundle"; version:Version="3.0.0.draft20060413_v201105210656"] via two dependency chains.

Chain 1:
  org.eclipse.linuxtools.cdt.libhover.devhelp [osgi.identity; osgi.identity="org.eclipse.linuxtools.cdt.libhover.devhelp"; type="osgi.bundle"; version:Version="1.1.0.202309052024"; singleton:="true"]
    require: (osgi.wiring.bundle=org.eclipse.core.runtime)
     |
    provide: osgi.wiring.bundle: org.eclipse.core.runtime
  org.eclipse.osgi [osgi.identity; osgi.identity="org.eclipse.osgi"; type="osgi.bundle"; version:Version="3.18.500.v20230801-1826"; singleton:="true"]

Chain 2:
  org.eclipse.linuxtools.cdt.libhover.devhelp [osgi.identity; osgi.identity="org.eclipse.linuxtools.cdt.libhover.devhelp"; type="osgi.bundle"; version:Version="1.1.0.202309052024"; singleton:="true"]
    require: (&(osgi.wiring.bundle=org.codelibs.nekohtml)(bundle-version>=2.1.2))
     |
    provide: osgi.wiring.bundle; bundle-version:Version="2.1.2.v20230802-0829"; osgi.wiring.bundle="org.codelibs.nekohtml"
  org.codelibs.nekohtml [osgi.identity; osgi.identity="org.codelibs.nekohtml"; type="osgi.bundle"; version:Version="2.1.2.v20230802-0829"]
    import: (osgi.wiring.package=org.w3c.dom.events)
     |
    export: osgi.wiring.package: org.w3c.dom.events
  org.w3c.dom.events [osgi.identity; osgi.identity="org.w3c.dom.events"; type="osgi.bundle"; version:Version="3.0.0.draft20060413_v201105210656"]

Looking at the initial state the devhelp itself has no alternatives:

  [!]org.eclipse.linuxtools.cdt.libhover.devhelp 1.1.0.202309052024 (UNRESOLVED)
    [!]Require-Bundle: org.eclipse.ui: 
        Bundle-SymbolicName: org.eclipse.ui; bundle-version="3.204.0.v20230821-1342"; singleton:="true"
    [!]Require-Bundle: org.eclipse.core.runtime: 
        Bundle-SymbolicName: org.eclipse.core.runtime; bundle-version="3.29.0.v20230726-0617"; singleton:="true"
    [!]Require-Bundle: org.eclipse.help; bundle-version="3.5.0": 
        Bundle-SymbolicName: org.eclipse.help; bundle-version="3.10.100.v20230726-0617"; singleton:="true"
    [!]Require-Bundle: org.eclipse.linuxtools.cdt.libhover; bundle-version="1.1.0": 
        Bundle-SymbolicName: org.eclipse.linuxtools.cdt.libhover; bundle-version="1.2.0.202309052024"; singleton:="true"
    [!]Require-Bundle: org.eclipse.linuxtools.cdt.libhover.library.docs; bundle-version="1.0.1": 
        Bundle-SymbolicName: org.eclipse.linuxtools.cdt.libhover.library.docs; bundle-version="1.0.2.202309052024"; singleton:="true"
    [!]Require-Bundle: org.codelibs.nekohtml; bundle-version="2.1.2": 
        Bundle-SymbolicName: org.codelibs.nekohtml; bundle-version="2.1.2.v20230802-0829"
    [!]Require-Capability: osgi.ee; filter:="(&(osgi.ee=JavaSE)(version=17))": 
        Provide-Capability: osgi.ee; osgi.ee="JavaSE"; version:List<Version>="1.0.0,1.1.0,1.2.0,1.3.0,1.4.0,1.5.0,1.6.0,1.7.0,1.8.0,9.0.0,10.0.0,11.0.0,12.0.0,13.0.0,14.0.0,15.0.0,16.0.0,17.0.0"

eclipse.core runtime on the other hand requires eclipse.osg (the system bundle) with visibility reexport:

  [!]org.eclipse.core.runtime 3.29.0.v20230726-0617 (UNRESOLVED)
    [!]Require-Bundle: org.eclipse.osgi; bundle-version="[3.17.0,4.0.0)"; visibility:="reexport": 
        Bundle-SymbolicName: org.eclipse.osgi; bundle-version="3.18.500.v20230801-1826"; singleton:="true"

org.codelibs.nekohtml has the following alternatives:

   [?]org.codelibs.nekohtml 2.1.2.v20230802-0829 (UNRESOLVED)
    [?]Import-Package: org.w3c.dom: 
        Export-Package: org.w3c.dom; bundle-symbolic-name="javax.xml"; bundle-version="1.3.4.v201005080400"; version="3.0.0"
        Export-Package: org.w3c.dom; bundle-symbolic-name="org.eclipse.osgi"; bundle-version="3.18.500.v20230801-1826"; version="0.0.0"
    [?]Import-Package: org.w3c.dom.events: 
        Export-Package: org.w3c.dom.events; bundle-symbolic-name="org.w3c.dom.events"; bundle-version="3.0.0.draft20060413_v201105210656"; version="3.0.0"; draft="20060413"
        Export-Package: org.w3c.dom.events; bundle-symbolic-name="javax.xml"; bundle-version="1.3.4.v201005080400"; version="2.0.0"
        Export-Package: org.w3c.dom.events; bundle-symbolic-name="org.eclipse.osgi"; bundle-version="3.18.500.v20230801-1826"; version="0.0.0"
    [?]Import-Package: org.w3c.dom.html: 
        Export-Package: org.w3c.dom.html; bundle-symbolic-name="org.apache.xerces"; bundle-version="2.12.2.v20220131-0835"; version="2.12.2"; uses:="org.w3c.dom"
        Export-Package: org.w3c.dom.html; bundle-symbolic-name="javax.xml"; bundle-version="1.3.4.v201005080400"; version="2.0.0"
        Export-Package: org.w3c.dom.html; bundle-symbolic-name="org.eclipse.osgi"; bundle-version="3.18.500.v20230801-1826"; version="0.0.0"
    [?]Import-Package: org.w3c.dom.ls: 
        Export-Package: org.w3c.dom.ls; bundle-symbolic-name="javax.xml"; bundle-version="1.3.4.v201005080400"; version="2.0.0"
        Export-Package: org.w3c.dom.ls; bundle-symbolic-name="org.eclipse.osgi"; bundle-version="3.18.500.v20230801-1826"; version="0.0.0"
    [?]Import-Package: org.w3c.dom.ranges: 
        Export-Package: org.w3c.dom.ranges; bundle-symbolic-name="javax.xml"; bundle-version="1.3.4.v201005080400"; version="2.0.0"
        Export-Package: org.w3c.dom.ranges; bundle-symbolic-name="org.eclipse.osgi"; bundle-version="3.18.500.v20230801-1826"; version="0.0.0"
    [?]Import-Package: org.w3c.dom.traversal: 
        Export-Package: org.w3c.dom.traversal; bundle-symbolic-name="javax.xml"; bundle-version="1.3.4.v201005080400"; version="2.0.0"
        Export-Package: org.w3c.dom.traversal; bundle-symbolic-name="org.eclipse.osgi"; bundle-version="3.18.500.v20230801-1826"; version="0.0.0"
    [?]Import-Package: org.w3c.dom.views: 
        Export-Package: org.w3c.dom.views; bundle-symbolic-name="javax.xml"; bundle-version="1.3.4.v201005080400"; version="2.0.0"
        Export-Package: org.w3c.dom.views; bundle-symbolic-name="org.eclipse.osgi"; bundle-version="3.18.500.v20230801-1826"; version="0.0.0"

So in this case org.codelibs.nekohtml is constrained by any user of it that has no alternatives to choose, in this case it is especially bad that we effectively reexport the system packages, that have no versions and no uses constraints and are most likely never used by eclipse.core runtime.

This will probably be challenging to solve but we finally now reached the point to the root error that is reported in this test-case (org.eclipse.linuxtools.cdt.libhover.devhelp cannot be resolved) where things go bad, and why we probably see a dramatic increase of import permutations, this is from this code path here:

// If the lower level check didn't create any permutations,
// then we should create an import permutation for the
// requirement with the dependency on the failing resource
// to backtrack on our current candidate selection.
if (permCount == session.getPermutationCount())
{
session.addPermutation(PermutationType.IMPORT, allCandidates.permutate(req));
}
return rethrow;

because the resolver can not really "blame" the system bundle (org.eclipse.osgi) for the package error it adds a new package permutation for every requirement, but permutation of one will result in even more use errors adding more and more, as at the same time there are other use-contraint violations that are explored first it never comes to the point where it would actually explore this path here until it times out.

Here is a chart of the current state and as one can see at laest the usesPermutations have already dropped below the initial threshold of about 1000 to 500 now:

grafik

@laeubi
Copy link
Member Author

laeubi commented Feb 25, 2024

Just for testing I added a preliminary check that if the "system bundle" is a provider for a package strike out all other providers as an alternative for that, then the mentioned line is never hit and the resolver completes after 13 seconds with 272 iterations successfully with this search graph:

grafik

as one can see uses permutations drop below 100 now (import permutations still growing)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant