Try to permutate all imports associated with uses constraints that conflict
with an exported package in one pass, like with imported packages. (FELIX-2035)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@944451 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
index ac0f29f..c3fbd5a 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
@@ -998,14 +998,17 @@
for (Entry<String, Blame> entry : pkgs.m_exportedPkgs.entrySet())
{
String pkgName = entry.getKey();
+ Blame exportBlame = entry.getValue();
if (!pkgs.m_usedPkgs.containsKey(pkgName))
{
continue;
}
- for (Blame blame : pkgs.m_usedPkgs.get(pkgName))
+ for (Blame usedBlame : pkgs.m_usedPkgs.get(pkgName))
{
- if (!isCompatible(entry.getValue().m_cap, blame.m_cap, modulePkgMap))
+ if (!isCompatible(exportBlame.m_cap, usedBlame.m_cap, modulePkgMap))
{
+ // Create a candidate permutation that eliminates any candidates
+ // that conflict with existing selected candidates.
copyConflict = (copyConflict != null)
? copyConflict
: copyCandidateMap(candidateMap);
@@ -1015,30 +1018,48 @@
"Constraint violation for package '"
+ pkgName + "' when resolving module "
+ module + " between existing export "
- + entry.getValue() + " and uses constraint "
- + blame, null, null);
+ + exportBlame + " and uses constraint "
+ + usedBlame, null, null);
+
mutated = (mutated != null)
? mutated
: new HashSet();
-// TODO: FELIX3 - I think we need to walk up the uses chain too.
- Requirement req = blame.m_reqs.get(blame.m_reqs.size() - 1);
- if (!mutated.contains(req))
+
+ for (int reqIdx = usedBlame.m_reqs.size() - 1; reqIdx >= 0; reqIdx--)
{
- mutated.add(req);
- Set<Capability> caps = copyConflict.get(req);
- Iterator it = caps.iterator();
- it.next();
- it.remove();
- if (caps.size() == 0)
+ Requirement req = usedBlame.m_reqs.get(reqIdx);
+
+ // If we've already permutated this requirement in another
+ // uses constraint, don't permutate it again just continue
+ // with the next uses constraint.
+ if (mutated.contains(req))
{
- removeInvalidateCandidate(req.getModule(), capDepSet, copyConflict);
+ break;
+ }
+
+ // See if we can permutate the candidates for blamed
+ // requirement; there may be no candidates if the module
+ // associated with the requirement is already resolved.
+ Set<Capability> candidates = copyConflict.get(req);
+ if ((candidates != null) && (candidates.size() > 1))
+ {
+ mutated.add(req);
+ Iterator it = candidates.iterator();
+ it.next();
+ it.remove();
+ // Continue with the next uses constraint.
+ break;
}
}
}
}
+
if (rethrow != null)
{
- m_usesPermutations.add(copyConflict);
+ if (mutated.size() > 0)
+ {
+ m_usesPermutations.add(copyConflict);
+ }
m_logger.log(Logger.LOG_DEBUG, "Conflict between an export and import", rethrow);
throw rethrow;
}
@@ -1153,59 +1174,6 @@
}
}
- private void removeInvalidateCandidate(
- Module invalid, Map<Capability, Set<Requirement>> capDepSet,
- Map<Requirement, Set<Capability>> candidateMap)
- {
- if (m_isInvokeCount)
- {
- String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
- Long count = m_invokeCounts.get(methodName);
- count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
- m_invokeCounts.put(methodName, count);
- }
-
- Set<Module> invalidated = new HashSet();
-
- for (Requirement req : invalid.getRequirements())
- {
- candidateMap.remove(req);
- }
-
- boolean wasRequired = false;
-
- for (Capability cap : invalid.getCapabilities())
- {
- Set<Requirement> reqs = capDepSet.remove(cap);
- if (reqs == null)
- {
- continue;
- }
- wasRequired = true;
- for (Requirement req : reqs)
- {
- Set<Capability> candidates = candidateMap.get(req);
- candidates.remove(cap);
- if (candidates.size() == 0)
- {
- candidateMap.remove(req);
- invalidated.add(req.getModule());
- }
- }
- }
-
- if (!wasRequired)
- {
- throw new ResolveException(
- "Unable to resolve module", invalid, null);
- }
-
- for (Module m : invalidated)
- {
- removeInvalidateCandidate(m, capDepSet, candidateMap);
- }
- }
-
private static void calculateExportedPackages(
Module module, Map<Module, Packages> modulePkgMap)
{