You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2010/01/28 23:25:37 UTC
svn commit: r904281 - in
/felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework:
Felix.java resolver/ResolverImpl.java
Author: rickhall
Date: Thu Jan 28 22:25:36 2010
New Revision: 904281
URL: http://svn.apache.org/viewvc?rev=904281&view=rev
Log:
Fix more issues with dynamic imports.
Modified:
felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/Felix.java
felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
Modified: felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/Felix.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/Felix.java?rev=904281&r1=904280&r2=904281&view=diff
==============================================================================
--- felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/Felix.java (original)
+++ felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/Felix.java Thu Jan 28 22:25:36 2010
@@ -2504,7 +2504,6 @@
"Could not remove from cache.", ex1);
}
}
-
if (ex instanceof BundleException)
{
throw (BundleException) ex;
@@ -3916,7 +3915,7 @@
// okay since the resolver will double check later after we have
// acquired the global lock below.
if (module.isResolved()
- && (ResolverImpl.findAllowedDynamicImport(m_resolverState, module, pkgName) != null))
+ && (ResolverImpl.isAllowedDynamicImport(m_resolverState, module, pkgName, new HashMap())))
{
// Acquire global lock.
boolean locked = acquireGlobalLock();
Modified: felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java?rev=904281&r1=904280&r2=904281&view=diff
==============================================================================
--- felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java (original)
+++ felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java Thu Jan 28 22:25:36 2010
@@ -87,7 +87,7 @@
{
m_candidatePermutations.clear();
-System.out.println("+++ RESOLVING " + module);
+//System.out.println("+++ RESOLVING " + module);
Map<Requirement, Set<Capability>> candidateMap =
new HashMap<Requirement, Set<Capability>>();
@@ -101,7 +101,7 @@
rethrow = null;
candidateMap = m_candidatePermutations.remove(0);
-dumpCandidateMap(state, candidateMap);
+//dumpCandidateMap(state, candidateMap);
try
{
@@ -152,18 +152,16 @@
// 5. The package in question matches a dynamic import of the bundle.
// The following call checks all of these conditions and returns
// a matching dynamic requirement if possible.
- Requirement dynReq = findAllowedDynamicImport(state, module, pkgName);
- if (dynReq != null)
+ Map<Requirement, Set<Capability>> candidateMap =
+ new HashMap<Requirement, Set<Capability>>();
+ if (isAllowedDynamicImport(state, module, pkgName, candidateMap))
{
m_candidatePermutations.clear();
Map<Module, Packages> modulePkgMap = new HashMap<Module, Packages>();
-System.out.println("+++ DYNAMICALLY RESOLVING " + module + " - " + dynReq);
- Map<Requirement, Set<Capability>> candidateMap =
- new HashMap<Requirement, Set<Capability>>();
-
- populateDynamicCandidates(state, module, dynReq, candidateMap, new HashSet<Module>());
+//System.out.println("+++ DYNAMICALLY RESOLVING " + module + " - " + pkgName);
+ populateDynamicCandidates(state, module, candidateMap, new HashSet<Module>());
m_candidatePermutations.add(candidateMap);
ResolveException rethrow = null;
@@ -172,7 +170,7 @@
rethrow = null;
candidateMap = m_candidatePermutations.remove(0);
-dumpCandidateMap(state, candidateMap);
+//dumpCandidateMap(state, candidateMap);
try
{
@@ -201,21 +199,26 @@
populateDynamicWireMap(
module, pkgName, modulePkgMap, new HashMap<Module, List<Wire>>());
+//System.out.println("+++ DYNAMIC SUCCESS: " + wireMap.get(module));
return wireMap;
}
+//System.out.println("+++ DYNAMIC FAILURE");
return null;
}
// TODO: FELIX3 - It would be nice to make this private.
- public static Requirement findAllowedDynamicImport(
- ResolverState state, Module module, String pkgName)
+ // TODO: FELIX3 - At a minimum, figure out a different way than passing in the
+ // candidate map.
+ public static boolean isAllowedDynamicImport(
+ ResolverState state, Module module, String pkgName, Map<Requirement,
+ Set<Capability>> candidateMap)
{
// Unresolved modules cannot dynamically import, nor can the default
// package be dynamically imported.
if (!module.isResolved() || pkgName.length() == 0)
{
- return null;
+ return false;
}
// If any of the module exports this package, then we cannot
@@ -226,7 +229,7 @@
if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
&& caps.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue().equals(pkgName))
{
- return null;
+ return false;
}
}
// If any of our wires have this package, then we cannot
@@ -236,7 +239,7 @@
{
if (wires.get(i).hasPackage(pkgName))
{
- return null;
+ return false;
}
}
@@ -249,20 +252,48 @@
Requirement req = new RequirementImpl(Capability.PACKAGE_NAMESPACE, dirs, attrs);
Set<Capability> candidates = state.getCandidates(module, req, false);
List<Requirement> dynamics = module.getDynamicRequirements();
+
+ // First find a dynamic requirement that matches the capabilities.
+ Requirement dynReq = null;
for (int dynIdx = 0;
- (candidates.size() > 0) && (dynIdx < dynamics.size());
+ (candidates.size() > 0) && (dynReq == null) && (dynIdx < dynamics.size());
dynIdx++)
{
- for (Capability cap : candidates)
+ for (Iterator<Capability> itCand = candidates.iterator();
+ (dynReq == null) && itCand.hasNext(); )
{
+ Capability cap = itCand.next();
if (CapabilitySet.matches(cap, dynamics.get(dynIdx).getFilter()))
{
- return dynamics.get(dynIdx);
+ dynReq = dynamics.get(dynIdx);
}
}
}
- return null;
+ // If we found a matching dynamic requirement, then filter out
+ // any candidates that do not match it.
+ if (dynReq != null)
+ {
+ for (Iterator<Capability> itCand = candidates.iterator(); itCand.hasNext(); )
+ {
+ Capability cap = itCand.next();
+ if (!CapabilitySet.matches(cap, dynReq.getFilter()))
+ {
+ itCand.remove();
+ }
+ }
+
+ if (candidates.size() > 0)
+ {
+ candidateMap.put(dynReq, candidates);
+ }
+ }
+ else
+ {
+ candidates.clear();
+ }
+
+ return !candidates.isEmpty();
}
private static void dumpCandidateMap(
@@ -390,7 +421,7 @@
}
private static void populateDynamicCandidates(
- ResolverState state, Module module, Requirement dynReq,
+ ResolverState state, Module module,
Map<Requirement, Set<Capability>> candidateMap, Set<Module> cycles)
{
if (m_isInvokeCount)
@@ -408,8 +439,12 @@
}
cycles.add(module);
- // Find candidates for all requirements for the target module.
- Set<Capability> candidates = state.getCandidates(module, dynReq, true);
+ // There should be one entry in the candidate map, which are the
+ // the candidates for the matching dynamic requirement. Get the
+ // matching candidates and populate their candidates if necessary.
+ Entry<Requirement, Set<Capability>> entry = candidateMap.entrySet().iterator().next();
+ Requirement dynReq = entry.getKey();
+ Set<Capability> candidates = entry.getValue();
for (Iterator<Capability> itCandCap = candidates.iterator(); itCandCap.hasNext(); )
{
Capability candCap = itCandCap.next();
@@ -427,18 +462,21 @@
}
}
- // Put candidates for all requirements into the global candidate map.
- if (candidates.size() > 0)
+// TODO: FELIX3 - Since we reuse the same dynamic requirement, it is possible
+// that some sort of cycle could cause us to try try to match another
+// set of candidates to the same requirement.
+ if (candidates.size() == 0)
{
- candidateMap.put(dynReq, candidates);
+ candidateMap.remove(dynReq);
+ throw new ResolveException("Dynamic import failed.", module, dynReq);
+ }
- // Add existing wires as candidates.
- for (Wire wire : module.getWires())
- {
- Set<Capability> cs = new TreeSet();
- cs.add(wire.getCapability());
- candidateMap.put(wire.getRequirement(), cs);
- }
+ // Add existing wires as candidates.
+ for (Wire wire : module.getWires())
+ {
+ Set<Capability> cs = new TreeSet();
+ cs.add(wire.getCapability());
+ candidateMap.put(wire.getRequirement(), cs);
}
}
@@ -513,7 +551,7 @@
for (Iterator<Capability> it = candCaps.iterator(); it.hasNext(); )
{
Capability candCap = it.next();
-System.out.println("+++ TRYING CAND " + candCap + " FOR " + req);
+//System.out.println("+++ TRYING CAND " + candCap + " FOR " + req);
try
{
// Try to resolve the candidate.
@@ -666,7 +704,7 @@
// then it should be listed as an export.
if (candBlame.m_cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
-System.out.println("+++ MERGING " + candBlame.m_cap + " INTO " + current);
+//System.out.println("+++ MERGING " + candBlame.m_cap + " INTO " + current);
String pkgName = (String)
candBlame.m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue();
@@ -757,7 +795,7 @@
currentPkgs.m_requiredPkgs.putAll(currentPkgsCopy.m_requiredPkgs);
currentPkgs.m_usedPkgs.putAll(currentPkgsCopy.m_usedPkgs);
}
-dumpModulePkgs(current, currentPkgs);
+//dumpModulePkgs(current, currentPkgs);
}
}
@@ -844,10 +882,10 @@
List<Blame> currentRequiredBlames = currentPkgs.m_requiredPkgs.get(usedPkgName);
Packages candSourcePkgs = modulePkgMap.get(candSourceCap.getModule());
-System.out.println("+++ candSourceCap " + candSourceCap);
-System.out.println("+++ candSourceCap.getModule() " + candSourceCap.getModule() + " (" + candSourceCap.getModule().isResolved() + ")");
-System.out.println("+++ candSourcePkgs " + candSourcePkgs);
-System.out.println("+++ candSourcePkgs.m_exportedPkgs " + candSourcePkgs.m_exportedPkgs);
+//System.out.println("+++ candSourceCap " + candSourceCap);
+//System.out.println("+++ candSourceCap.getModule() " + candSourceCap.getModule() + " (" + candSourceCap.getModule().isResolved() + ")");
+//System.out.println("+++ candSourcePkgs " + candSourcePkgs);
+//System.out.println("+++ candSourcePkgs.m_exportedPkgs " + candSourcePkgs.m_exportedPkgs);
Blame candSourceBlame = candSourcePkgs.m_exportedPkgs.get(usedPkgName);
candSourceBlame = (candSourceBlame != null)
? candSourceBlame
@@ -876,7 +914,7 @@
usedCaps = new ArrayList<Blame>();
currentPkgs.m_usedPkgs.put(usedPkgName, usedCaps);
}
-System.out.println("+++ MERGING CB " + candBlame + " SB " + candSourceBlame);
+//System.out.println("+++ MERGING CB " + candBlame + " SB " + candSourceBlame);
// usedCaps.add(new Blame(candBlame.m_reqs, sourceBlame.m_cap));
usedCaps.add(candSourceBlame);
// return;
@@ -1109,10 +1147,15 @@
&& entry.getValue().m_cap.getAttribute(
Capability.PACKAGE_ATTR).getValue().equals(pkgName))
{
+ List<Attribute> attrs = new ArrayList();
+ attrs.add(new Attribute(Capability.PACKAGE_ATTR, pkgName, false));
packageWires.add(
new WireImpl(
module,
- entry.getValue().m_reqs.get(0),
+ // We need an unique requirement here or else subsequent
+ // dynamic imports for the same dynamic requirement will
+ // conflict with previous ones.
+ new RequirementImpl(Capability.PACKAGE_NAMESPACE, new ArrayList(0), attrs),
entry.getValue().m_cap.getModule(),
entry.getValue().m_cap));
}