From 5baf8192d2025dff792b71a9f02ba419d910f6bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Mon, 26 Feb 2024 17:30:21 +0100 Subject: [PATCH] Expose the permutation data through the felix resolver logger Currently it is not really possible to write a test that asserts something about the complexity of a problem that the resolver has performed. This has the risk of undetected performance regressions but also means performance improvements can not be easily investigated. Also in general code (like for example console commands) it could be useful to gather some statistics. This now adds two new methods to the logger, one that is performing a log each time when a permutation is added or processed to either log this by the caller or perform any statistics on them. --- .../tests/container/TestModuleContainer.java | 32 +++++++++++--- .../org.eclipse.osgi/.settings/.api_filters | 11 +++++ bundles/org.eclipse.osgi/META-INF/MANIFEST.MF | 4 +- .../osgi/container/ModuleContainer.java | 10 ++--- .../container/ModuleResolutionReport.java | 29 ++++++++++-- .../osgi/container/ModuleResolver.java | 34 +++++++++++++- .../org/apache/felix/resolver/Candidates.java | 1 - .../src/org/apache/felix/resolver/Logger.java | 26 +++++++++++ .../felix/resolver/PermutationType.java | 24 ++++++++++ .../apache/felix/resolver/ResolverImpl.java | 44 +++++++++++++------ bundles/org.eclipse.osgi/pom.xml | 3 +- .../supplement/META-INF/MANIFEST.MF | 2 +- .../report/resolution/ResolutionReport.java | 24 ++++++++++ 13 files changed, 209 insertions(+), 35 deletions(-) create mode 100644 bundles/org.eclipse.osgi/.settings/.api_filters create mode 100644 bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/PermutationType.java diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java index 02add784310..cba65a01b79 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java @@ -78,6 +78,7 @@ import org.eclipse.osgi.internal.debug.Debug; import org.eclipse.osgi.internal.framework.EquinoxConfiguration; import org.eclipse.osgi.report.resolution.ResolutionReport; +import org.eclipse.osgi.report.resolution.ResolutionReport.ResolutionStatistics; import org.eclipse.osgi.tests.container.dummys.DummyCollisionHook; import org.eclipse.osgi.tests.container.dummys.DummyContainerAdaptor; import org.eclipse.osgi.tests.container.dummys.DummyDebugOptions; @@ -1981,20 +1982,20 @@ public void testUses4() throws BundleException, IOException { */ @Test public void testUses5Importer() throws BundleException, IOException { - doTestUses5("uses.k.importer.MF"); + doTestUses5("uses.k.importer.MF", 3); } @Test public void testUses5ReqCap() throws BundleException, IOException { - doTestUses5("uses.k.reqCap.MF"); + doTestUses5("uses.k.reqCap.MF", 3); } @Test public void testUses5Requirer() throws BundleException, IOException { - doTestUses5("uses.k.requirer.MF"); + doTestUses5("uses.k.requirer.MF", 3); } - public void doTestUses5(String kManifest) throws BundleException, IOException { + public void doTestUses5(String kManifest, int max) throws BundleException, IOException { DummyContainerAdaptor adaptor = createDummyAdaptor(); ModuleContainer container = adaptor.getContainer(); @@ -2006,12 +2007,13 @@ public void doTestUses5(String kManifest) throws BundleException, IOException { Module uses_m_conflict1 = installDummyModule("uses.m.conflict1.MF", "m.conflict1", container); Module uses_m_conflict2 = installDummyModule("uses.m.conflict2.MF", "m.conflict2", container); - container.resolve(null, false); + ResolutionReport report = container.resolve(null, false); assertEquals("k should resolve.", State.RESOLVED, uses_k.getState()); assertEquals("l should resolve.", State.RESOLVED, uses_l.getState()); assertEquals("m.conflict1 should resolve.", State.RESOLVED, uses_m_conflict1.getState()); assertEquals("m.conflict2 should resolve.", State.RESOLVED, uses_m_conflict2.getState()); + assertNotMoreThanPermutationCreated(report, max); } @Test @@ -3929,14 +3931,32 @@ public void testSubstitutionWithMoreThan2Providers() throws BundleException, IOE "osgi.ee; osgi.ee=JavaSE; version:List=\"1.3, 1.4, 1.5, 1.6, 1.7\"", // container); ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true); - assertNull("Failed to resolve test.", report.getResolutionException()); + assertSucessfulWith(report, 1); List modules = new ArrayList<>(); for (String manifest : HTTPCOMPS_AND_EATHER) { modules.add(installDummyModule(manifest, manifest, container)); } report = container.resolve(modules, true); + assertSucessfulWith(report, 115); + } + + protected void assertSucessfulWith(ResolutionReport report, int maxTotalPermutations) { assertNull("Failed to resolve test.", report.getResolutionException()); + assertNotMoreThanPermutationCreated(report, maxTotalPermutations); + } + + protected void assertNotMoreThanPermutationCreated(ResolutionReport report, int maxTotal) { + if (report instanceof ResolutionStatistics) { + ResolutionStatistics statistics = (ResolutionStatistics) report; + int totalPermutations = statistics.getTotalPermutations(); + if (totalPermutations > maxTotal) { + fail("Maximum of " + maxTotal + " permutations expected but was " + totalPermutations + " (" + + statistics.getProcessedPermutations() + " processed)."); + } + return; + } + fail("Report does not provide performance statistics!"); } @Test diff --git a/bundles/org.eclipse.osgi/.settings/.api_filters b/bundles/org.eclipse.osgi/.settings/.api_filters new file mode 100644 index 00000000000..047d8370886 --- /dev/null +++ b/bundles/org.eclipse.osgi/.settings/.api_filters @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF index f78b0b106f8..5c4ecd9f507 100644 --- a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF @@ -36,7 +36,7 @@ Export-Package: org.eclipse.core.runtime.adaptor;x-friends:="org.eclipse.core.ru org.eclipse.osgi.internal.signedcontent;x-internal:=true, org.eclipse.osgi.internal.url;x-internal:=true, org.eclipse.osgi.launch;version="1.1";uses:="org.osgi.framework,org.osgi.framework.launch,org.osgi.framework.connect", - org.eclipse.osgi.report.resolution;version="1.0";uses:="org.osgi.service.resolver,org.osgi.resource", + org.eclipse.osgi.report.resolution;version="1.1.0";uses:="org.osgi.service.resolver,org.osgi.resource", org.eclipse.osgi.service.datalocation;version="1.4.0", org.eclipse.osgi.service.debug;version="1.2", org.eclipse.osgi.service.environment;version="1.4", @@ -107,7 +107,7 @@ Bundle-Activator: org.eclipse.osgi.internal.framework.SystemBundleActivator Bundle-Description: %systemBundle Bundle-Copyright: %copyright Bundle-Vendor: %eclipse.org -Bundle-Version: 3.19.100.qualifier +Bundle-Version: 3.20.0.qualifier Bundle-Localization: systembundle Bundle-DocUrl: http://www.eclipse.org Eclipse-ExtensibleAPI: true diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java index 4f260770dec..15d12c0eea2 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java @@ -38,7 +38,6 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; - import org.eclipse.osgi.container.Module.StartOptions; import org.eclipse.osgi.container.Module.State; import org.eclipse.osgi.container.Module.StopOptions; @@ -651,7 +650,7 @@ public ResolutionReport resolve(Collection triggers, boolean triggersMan private ResolutionReport resolve(Collection triggers, boolean triggersMandatory, boolean restartTriggers) { if (isRefreshingSystemModule()) { return new ModuleResolutionReport(null, Collections.emptyMap(), - new ResolutionException("Unable to resolve while shutting down the framework.")); //$NON-NLS-1$ + new ResolutionException("Unable to resolve while shutting down the framework."), -1, -1, -1); //$NON-NLS-1$ } ResolutionReport report = null; try (ResolutionLock.Permits resolutionPermits = _resolutionLock.acquire(1)) { @@ -664,7 +663,7 @@ private ResolutionReport resolve(Collection triggers, boolean triggersMa if (be.getType() == BundleException.REJECTED_BY_HOOK || be.getType() == BundleException.STATECHANGE_ERROR) { return new ModuleResolutionReport(null, Collections.emptyMap(), - new ResolutionException(be)); + new ResolutionException(be), -1, -1, -1); } } throw e; @@ -672,7 +671,8 @@ private ResolutionReport resolve(Collection triggers, boolean triggersMa } while (report == null); } catch (ResolutionLockException e) { return new ModuleResolutionReport(null, Collections.emptyMap(), - new ResolutionException("Timeout acquiring lock for resolution", e, Collections.emptyList())); //$NON-NLS-1$ + new ResolutionException("Timeout acquiring lock for resolution", e, Collections.emptyList()), -1, //$NON-NLS-1$ + -1, -1); } return report; } @@ -1341,7 +1341,7 @@ public ResolutionReport refresh(Collection initial) { if (!isRefreshingSystemModule()) { return resolve(refreshTriggers, false, true); } - return new ModuleResolutionReport(null, null, null); + return new ModuleResolutionReport(null, null, null, -1, -1, -1); } /** diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolutionReport.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolutionReport.java index a55766421b9..368e0020077 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolutionReport.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolutionReport.java @@ -49,8 +49,10 @@ public void addEntry(Resource resource, Entry.Type type, Object data) { entries.add(new EntryImpl(type, data)); } - public ModuleResolutionReport build(Map> resolutionResult, ResolutionException cause) { - return new ModuleResolutionReport(resolutionResult, resourceToEntries, cause); + public ModuleResolutionReport build(Map> resolutionResult, ResolutionException cause, + int totalPerm, int processedPerm, int usesPerm) { + return new ModuleResolutionReport(resolutionResult, resourceToEntries, cause, totalPerm, processedPerm, + usesPerm); } } @@ -77,9 +79,15 @@ public Type getType() { private final Map> entries; private final ResolutionException resolutionException; private final Map> resolutionResult; + private int totalPerm; + private int processedPerm; + private int usesPerm; ModuleResolutionReport(Map> resolutionResult, Map> entries, - ResolutionException cause) { + ResolutionException cause, int totalPerm, int processedPerm, int usesPerm) { + this.totalPerm = totalPerm; + this.processedPerm = processedPerm; + this.usesPerm = usesPerm; this.entries = entries == null ? Collections.emptyMap() : Collections.unmodifiableMap(new HashMap<>(entries)); this.resolutionResult = resolutionResult == null ? Collections.emptyMap() : Collections.unmodifiableMap(resolutionResult); @@ -176,4 +184,19 @@ private static void printResolutionEntry(StringBuilder result, String prepend, R public String getResolutionReportMessage(Resource resource) { return getResolutionReport0(null, (ModuleRevision) resource, getEntries(), null); } + + @Override + public int getTotalPermutations() { + return totalPerm; + } + + @Override + public int getProcessedPermutations() { + return processedPerm; + } + + @Override + public int getUsesPermutations() { + return usesPerm; + } } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java index 64f918e9833..dae98ddc348 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java @@ -37,7 +37,10 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.ToIntFunction; +import java.util.stream.Collectors; import org.apache.felix.resolver.Logger; +import org.apache.felix.resolver.PermutationType; import org.apache.felix.resolver.ResolutionError; import org.apache.felix.resolver.ResolverImpl; import org.eclipse.osgi.container.ModuleRequirement.DynamicModuleRequirement; @@ -89,11 +92,13 @@ final class ModuleResolver { private static final String OPTION_USES = OPTION_RESOLVER + "/uses"; //$NON-NLS-1$ private static final String OPTION_WIRING = OPTION_RESOLVER + "/wiring"; //$NON-NLS-1$ private static final String OPTION_REPORT = OPTION_RESOLVER + "/report"; //$NON-NLS-1$ + private static final String OPTION_PERMUTATION = OPTION_RESOLVER + "/permutation"; //$NON-NLS-1$ boolean DEBUG_ROOTS = false; boolean DEBUG_PROVIDERS = false; boolean DEBUG_HOOKS = false; boolean DEBUG_USES = false; + boolean DEBUG_PERMUTATIONS = false; boolean DEBUG_WIRING = false; boolean DEBUG_REPORT = false; @@ -115,6 +120,7 @@ void setDebugOptions() { DEBUG_USES = debugAll || options.getBooleanOption(OPTION_USES, false); DEBUG_WIRING = debugAll || options.getBooleanOption(OPTION_WIRING, false); DEBUG_REPORT = debugAll || options.getBooleanOption(OPTION_REPORT, false); + DEBUG_PERMUTATIONS = debugAll || options.getBooleanOption(OPTION_PERMUTATION, false); } static final Collection NON_PAYLOAD_CAPABILITIES = Arrays.asList(IdentityNamespace.IDENTITY_NAMESPACE); @@ -470,6 +476,9 @@ class ResolveProcess extends ResolveContext implements Comparator, E class ResolveLogger extends Logger { private Map errors = null; + public int totalPerm; + public int processedPerm; + public int usesPerm; public ResolveLogger() { super(DEBUG_USES ? Logger.LOG_DEBUG : 0); @@ -510,6 +519,27 @@ protected void doLog(int level, String msg, Throwable throwable) { + (throwable != null ? (TAB + TAB + throwable.getMessage()) : "")); //$NON-NLS-1$ } + @Override + public void logPermutationAdded(PermutationType type, ToIntFunction remaining) { + totalPerm++; + if (type == PermutationType.USES) { + usesPerm++; + } + } + + PermutationType[] permutationTypes = PermutationType.values(); + + @Override + public void logProcessPermutation(PermutationType type, ToIntFunction remaining) { + processedPerm++; + if (DEBUG_PERMUTATIONS) { + Debug.println( + "RESOLVER: Process " + type + " permutation remaining: " + SEPARATOR + TAB //$NON-NLS-1$ //$NON-NLS-2$ + + Arrays.stream(permutationTypes).map(t -> t + ": " + remaining.applyAsInt(t)) //$NON-NLS-1$ + .collect(Collectors.joining(SEPARATOR + TAB))); + } + } + } private final ModuleResolutionReport.Builder reportBuilder = new ModuleResolutionReport.Builder(); @@ -918,7 +948,7 @@ ModuleResolutionReport resolve() { BundleException be = (BundleException) e.getCause(); if (be.getType() == BundleException.REJECTED_BY_HOOK) { return new ModuleResolutionReport(null, Collections.emptyMap(), - new ResolutionException(be)); + new ResolutionException(be), -1, -1, -1); } } throw e; @@ -962,7 +992,7 @@ ModuleResolutionReport resolve() { if (DEBUG_WIRING) { printWirings(result); } - report = reportBuilder.build(result, re); + report = reportBuilder.build(result, re, logger.totalPerm, logger.processedPerm, logger.usesPerm); if (DEBUG_REPORT) { if (report.getResolutionException() != null) { Debug.printStackTrace(report.getResolutionException()); diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Candidates.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Candidates.java index 8750706f0a8..0b59f6dac0b 100644 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Candidates.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Candidates.java @@ -22,7 +22,6 @@ import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.felix.resolver.ResolverImpl.PermutationType; import org.apache.felix.resolver.ResolverImpl.ResolveSession; import org.apache.felix.resolver.reason.ReasonException; import org.apache.felix.resolver.util.*; diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Logger.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Logger.java index 7789ffba10a..47b93932577 100644 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Logger.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Logger.java @@ -18,6 +18,7 @@ */ package org.apache.felix.resolver; +import java.util.function.ToIntFunction; import org.osgi.resource.Resource; /** @@ -131,4 +132,29 @@ public void logUsesConstraintViolation(Resource resource, ResolutionError error) { // do nothing by default } + + /** + * Called whenever a new permutation is added by the resolver. + * + * @param type the type of the permutation + * @param remaining a function that can be used to query the now current number + * of permutation types + */ + public void logPermutationAdded(PermutationType type, ToIntFunction remaining) + { + // do nothing by default + } + + /** + * Called whenever a permutation is removed and about to be processed by the + * resolver. + * + * @param type the type of permutation that will be processed + * @param remaining a function that can be used to query the now current number + * of permutation types + */ + public void logProcessPermutation(PermutationType type, ToIntFunction remaining) + { + // do nothing by default + } } diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/PermutationType.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/PermutationType.java new file mode 100644 index 00000000000..43d583ba75b --- /dev/null +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/PermutationType.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.felix.resolver; +public enum PermutationType { + USES, + IMPORT, + SUBSTITUTE +} \ No newline at end of file diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java index 6c9b278db3c..9a98877547c 100644 --- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java +++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java @@ -23,7 +23,7 @@ import java.util.Map.Entry; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; - +import java.util.function.ToIntFunction; import org.apache.felix.resolver.reason.ReasonException; import org.apache.felix.resolver.util.ArrayMap; import org.apache.felix.resolver.util.CandidateSelector; @@ -45,12 +45,6 @@ public class ResolverImpl implements Resolver private final Executor m_executor; - enum PermutationType { - USES, - IMPORT, - SUBSTITUTE - } - // Note this class is not thread safe. // Only use in the context of a single thread. static class ResolveSession implements Runnable @@ -91,10 +85,24 @@ static class ResolveSession implements Runnable private final ConcurrentMap> m_usesCache = new ConcurrentHashMap>(); private ResolutionError m_currentError; volatile private CancellationException m_isCancelled = null; + private Logger logger; + private ToIntFunction remaining = type -> { + switch (type) { + case USES: + return m_usesPermutations.size(); + case IMPORT: + return m_importPermutations.size(); + case SUBSTITUTE: + return m_substPermutations.size(); + } + return 0; + }; - static ResolveSession createSession(ResolveContext resolveContext, Executor executor, Resource dynamicHost, Requirement dynamicReq, List dynamicCandidates) + static ResolveSession createSession(ResolveContext resolveContext, Executor executor, Resource dynamicHost, + Requirement dynamicReq, List dynamicCandidates, Logger logger) { - ResolveSession session = new ResolveSession(resolveContext, executor, dynamicHost, dynamicReq, dynamicCandidates); + ResolveSession session = new ResolveSession(resolveContext, executor, dynamicHost, dynamicReq, + dynamicCandidates, logger); // call onCancel first session.getContext().onCancel(session); // now gather the mandatory and optional resources @@ -102,13 +110,15 @@ static ResolveSession createSession(ResolveContext resolveContext, Executor exec return session; } - private ResolveSession(ResolveContext resolveContext, Executor executor, Resource dynamicHost, Requirement dynamicReq, List dynamicCandidates) + private ResolveSession(ResolveContext resolveContext, Executor executor, Resource dynamicHost, + Requirement dynamicReq, List dynamicCandidates, Logger logger) { m_resolveContext = resolveContext; m_executor = executor; m_dynamicHost = dynamicHost; m_dynamicReq = dynamicReq; m_dynamicCandidates = dynamicCandidates; + this.logger = logger; if (m_dynamicHost != null) { m_mandatoryResources = Collections.singletonList(dynamicHost); m_optionalResources = Collections.emptyList(); @@ -186,29 +196,34 @@ void addPermutation(PermutationType type, Candidates permutation) { m_substPermutations.add(m_substituteIndex++, permutation); break; default : - throw new IllegalArgumentException("Unknown permitation type: " + type); + throw new IllegalArgumentException("Unknown permutation type: " + type); } } catch (IndexOutOfBoundsException e) { // just a safeguard, this really should never happen typeToAddTo.add(permutation); } + logger.logPermutationAdded(type, remaining); } } Candidates getNextPermutation() { Candidates next = null; + PermutationType type; do { if (!m_usesPermutations.isEmpty()) { next = m_usesPermutations.remove(0); + type = PermutationType.USES; } else if (!m_importPermutations.isEmpty()) { next = m_importPermutations.remove(0); + type = PermutationType.IMPORT; } else if (!m_substPermutations.isEmpty()) { next = m_substPermutations.remove(0); + type = PermutationType.SUBSTITUTE; } else { return null; @@ -222,6 +237,8 @@ else if (!m_substPermutations.isEmpty()) // clear mutateIndexes also so we insert new permutations // based of this permutation as a higher priority clearMutateIndexes(); + + logger.logProcessPermutation(type, remaining); return next; } @@ -416,7 +433,7 @@ public Void run() { public Map> resolve(ResolveContext rc, Executor executor) throws ResolutionException { - ResolveSession session = ResolveSession.createSession(rc, executor, null, null, null); + ResolveSession session = ResolveSession.createSession(rc, executor, null, null, null, m_logger); return doResolve(session); } @@ -667,7 +684,8 @@ public Map> resolveDynamic(ResolveContext context, "Matching candidate does not provide a package name."); } } - ResolveSession session = ResolveSession.createSession(context, new DumbExecutor(), host, dynamicRequirement, matches); + ResolveSession session = ResolveSession.createSession(context, new DumbExecutor(), host, dynamicRequirement, + matches, m_logger); return doResolve(session); } diff --git a/bundles/org.eclipse.osgi/pom.xml b/bundles/org.eclipse.osgi/pom.xml index 2da1930a94b..30dfff9fc0f 100644 --- a/bundles/org.eclipse.osgi/pom.xml +++ b/bundles/org.eclipse.osgi/pom.xml @@ -19,7 +19,7 @@ org.eclipse.osgi org.eclipse.osgi - 3.19.100-SNAPSHOT + 3.20.0-SNAPSHOT eclipse-plugin @@ -31,7 +31,6 @@ org.eclipse.tycho tycho-compiler-plugin - ${tycho.version} -nowarn:[${project.basedir}/osgi/src${path.separator}${project.basedir}/felix/src] diff --git a/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF index 129f85cb422..0a60e767518 100644 --- a/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.osgi/supplement/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.equinox.supplement -Bundle-Version: 1.10.800.qualifier +Bundle-Version: 1.10.900.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: org.eclipse.equinox.log;version="1.1", diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/report/resolution/ResolutionReport.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/report/resolution/ResolutionReport.java index fdf783c6383..05317fc0b5a 100644 --- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/report/resolution/ResolutionReport.java +++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/report/resolution/ResolutionReport.java @@ -15,6 +15,8 @@ import java.util.List; import java.util.Map; +import org.eclipse.pde.api.tools.annotations.NoImplement; +import org.osgi.annotation.versioning.ProviderType; import org.osgi.framework.hooks.resolver.ResolverHook; import org.osgi.resource.Resource; import org.osgi.service.resolver.ResolutionException; @@ -96,6 +98,8 @@ * * @since 3.10 */ +@ProviderType +@NoImplement public interface ResolutionReport { public interface Entry { enum Type { @@ -193,4 +197,24 @@ public interface Listener { * @return a resolution report message. */ String getResolutionReportMessage(Resource resource); + + /** + * @return the number of permutations created to solve the problem or -1 if + * unknown + * @since 3.20 + */ + int getTotalPermutations(); + + /** + * @return the number of processed permutations -1 if unknown + * @since 3.20 + */ + int getProcessedPermutations(); + + /** + * @return the number of permutations cause by a use-constraint violation -1 if + * unknown + * @since 3.20 + */ + int getUsesPermutations(); }