When populating candidates, we need to check for a failed result
after recursing since cycles may cause the resolving revision to
fail in a deeper recursion. We weren't checking this previously,
which caused us to ignore failures in some cases. (FELIX-3178)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1203866 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
index a411bcb..d244685 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
@@ -257,7 +257,7 @@
}
// If we have requirements remaining, then find candidates for them.
- while (remainingReqs.size() > 0)
+ while (!remainingReqs.isEmpty())
{
BundleRequirement req = remainingReqs.remove(0);
@@ -276,10 +276,16 @@
state.getCandidates((BundleRequirementImpl) req, true);
ResolveException rethrow = processCandidates(state, revision, candidates);
- // If there are no candidates for the current requirement
- // and it is not optional, then create, cache, and throw
- // a resolve exception.
- if (candidates.isEmpty() && !((BundleRequirementImpl) req).isOptional())
+ // First, due to cycles, makes sure we haven't already failed in
+ // a deeper recursion.
+ Object result = m_populateResultCache.get(revision);
+ if (result instanceof ResolveException)
+ {
+ throw (ResolveException) result;
+ }
+ // Next, if are no candidates remaining and the requirement is not
+ // not optional, then record and throw a resolve exception.
+ else if (candidates.isEmpty() && !((BundleRequirementImpl) req).isOptional())
{
String msg = "Unable to resolve " + revision
+ ": missing requirement " + req;
@@ -291,7 +297,7 @@
m_populateResultCache.put(revision, rethrow);
throw rethrow;
}
- // If we actually have candidates for the requirement, then
+ // Otherwise, if we actually have candidates for the requirement, then
// add them to the local candidate map.
else if (candidates.size() > 0)
{
@@ -455,9 +461,8 @@
// since we effectively chain exception messages for each level
// of recursion; thus, any avoided recursion results in fewer
// exceptions to chain when an error does occur.
- if (isFragment
- || ((candCap.getRevision().getWiring() == null)
- && !candCap.getRevision().equals(revision)))
+ if ((isFragment || (candCap.getRevision().getWiring() == null))
+ && !candCap.getRevision().equals(revision))
{
try
{
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
index 6b2772e..20c31ff 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
@@ -229,11 +229,11 @@
// Combine all requirements.
m_requirements = new ArrayList(
- importReqs.size() + rbReqs.size() + hostReqs.size()
+ hostReqs.size() + importReqs.size() + rbReqs.size()
+ requireReqs.size() + dynamicReqs.size());
+ m_requirements.addAll(hostReqs);
m_requirements.addAll(importReqs);
m_requirements.addAll(rbReqs);
- m_requirements.addAll(hostReqs);
m_requirements.addAll(requireReqs);
m_requirements.addAll(dynamicReqs);