Author: tjwatson
Date: Wed Nov 2 19:09:40 2016
New Revision: 1767765
URL: http://svn.apache.org/viewvc?rev=1767765&view=rev
Log:
[FELIX-5389] NullPointerException in Candidates#prepare() method
Modified:
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/Candidates.java
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/WrappedCapability.java
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/util/CandidateSelector.java
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/util/ShadowList.java
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/Main.java
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/ResolverTest.java
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/util/IdentityCapability.java
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/util/ResourceImpl.java
Modified:
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/Candidates.java
URL:
http://svn.apache.org/viewvc/felix/trunk/resolver/src/main/java/org/apache/felix/resolver/Candidates.java?rev=1767765&r1=1767764&r2=1767765&view=diff
==============================================================================
---
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/Candidates.java
(original)
+++
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/Candidates.java
Wed Nov 2 19:09:40 2016
@@ -939,7 +939,12 @@ class Candidates
CandidateSelector cands = m_candidateMap.get(origReq);
if (cands != null)
{
- m_candidateMap.put(r, cands.copy());
+ if (cands instanceof ShadowList)
+ {
+ m_candidateMap.put(r, ShadowList.deepCopy((ShadowList)
cands));
+ } else {
+ m_candidateMap.put(r, cands.copy());
+ }
for (Capability cand : cands.getRemainingCandidates())
{
Set<Requirement> dependents = m_dependentMap.get(cand);
Modified:
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/WrappedCapability.java
URL:
http://svn.apache.org/viewvc/felix/trunk/resolver/src/main/java/org/apache/felix/resolver/WrappedCapability.java?rev=1767765&r1=1767764&r2=1767765&view=diff
==============================================================================
---
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/WrappedCapability.java
(original)
+++
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/WrappedCapability.java
Wed Nov 2 19:09:40 2016
@@ -15,6 +15,8 @@
*/
package org.apache.felix.resolver;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
import org.osgi.framework.namespace.PackageNamespace;
import org.osgi.resource.Capability;
@@ -25,11 +27,25 @@ public class WrappedCapability implement
{
private final Resource m_host;
private final Capability m_cap;
+ private final Map<String, Object> m_augmentedAttrs;
public WrappedCapability(Resource host, Capability cap)
{
m_host = host;
m_cap = cap;
+ if ("osgi.content".equals(m_cap.getNamespace())) {
+ // Augment the attributes only for osgi.content namespace.
+ // This is done to work around issues with wrapper resources
equality tests.
+ // Note this is depends on the implementation details of the
ResolveContext to actually
+ // check the osgi.content capability.
+ Map<String, Object> augmentedDirs = new HashMap<String,
Object>(m_cap.getAttributes());
+ Object wrapperUrl = augmentedDirs.get("url");
+ wrapperUrl = "wrapper:" + wrapperUrl;
+ augmentedDirs.put("url", wrapperUrl);
+ m_augmentedAttrs = Collections.unmodifiableMap(augmentedDirs);
+ } else {
+ m_augmentedAttrs = m_cap.getAttributes();
+ }
}
@Override
@@ -86,7 +102,7 @@ public class WrappedCapability implement
public Map<String, Object> getAttributes()
{
- return m_cap.getAttributes();
+ return m_augmentedAttrs;
}
// TODO: RFC-112 - Need impl-specific type.
Modified:
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/util/CandidateSelector.java
URL:
http://svn.apache.org/viewvc/felix/trunk/resolver/src/main/java/org/apache/felix/resolver/util/CandidateSelector.java?rev=1767765&r1=1767764&r2=1767765&view=diff
==============================================================================
---
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/util/CandidateSelector.java
(original)
+++
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/util/CandidateSelector.java
Wed Nov 2 19:09:40 2016
@@ -26,7 +26,7 @@ import java.util.concurrent.atomic.Atomi
import org.osgi.resource.Capability;
public class CandidateSelector {
- private final AtomicBoolean isUnmodifiable;
+ protected final AtomicBoolean isUnmodifiable;
protected final List<Capability> unmodifiable;
private int currentIndex = 0;
Modified:
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/util/ShadowList.java
URL:
http://svn.apache.org/viewvc/felix/trunk/resolver/src/main/java/org/apache/felix/resolver/util/ShadowList.java?rev=1767765&r1=1767764&r2=1767765&view=diff
==============================================================================
---
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/util/ShadowList.java
(original)
+++
felix/trunk/resolver/src/main/java/org/apache/felix/resolver/util/ShadowList.java
Wed Nov 2 19:09:40 2016
@@ -20,7 +20,7 @@ package org.apache.felix.resolver.util;
import java.util.ArrayList;
import java.util.List;
-
+import java.util.concurrent.atomic.AtomicBoolean;
import org.osgi.resource.Capability;
import org.osgi.service.resolver.HostedCapability;
import org.osgi.service.resolver.ResolveContext;
@@ -28,9 +28,18 @@ import org.osgi.service.resolver.Resolve
public class ShadowList extends CandidateSelector
{
public static ShadowList createShadowList(CandidateSelector original) {
+ if (original instanceof ShadowList)
+ {
+ throw new IllegalArgumentException("Cannot create a ShadowList
using another ShadowList.");
+ }
return new ShadowList(original);
}
+ public static ShadowList deepCopy(ShadowList original) {
+ List<Capability> originalCopy = new
ArrayList<Capability>(original.m_original);
+ return new ShadowList(original.unmodifiable, originalCopy,
original.isUnmodifiable);
+ }
+
private final List<Capability> m_original;
private ShadowList(CandidateSelector original)
@@ -45,6 +54,11 @@ public class ShadowList extends Candidat
m_original = original;
}
+ public ShadowList(List<Capability> unmodifiable, List<Capability>
originalCopy, AtomicBoolean isUnmodifiable) {
+ super(unmodifiable, isUnmodifiable);
+ m_original = originalCopy;
+ }
+
public ShadowList copy() {
return new ShadowList(this, m_original);
}
Modified:
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/Main.java
URL:
http://svn.apache.org/viewvc/felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/Main.java?rev=1767765&r1=1767764&r2=1767765&view=diff
==============================================================================
--- felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/Main.java
(original)
+++ felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/Main.java
Wed Nov 2 19:09:40 2016
@@ -35,6 +35,7 @@ import org.apache.felix.resolver.test.ut
import org.apache.felix.resolver.test.util.PackageRequirement;
import org.apache.felix.resolver.test.util.ResolveContextImpl;
import org.apache.felix.resolver.test.util.ResourceImpl;
+import org.osgi.framework.Version;
import org.osgi.framework.namespace.BundleNamespace;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.namespace.IdentityNamespace;
@@ -430,12 +431,12 @@ public class Main
a1_hostCap.addAttribute(HostNamespace.HOST_NAMESPACE, "A");
a1.addCapability(a1_hostCap);
- ResourceImpl f1 = new ResourceImpl("F1",
IdentityNamespace.TYPE_FRAGMENT);
+ ResourceImpl f1 = new ResourceImpl("F1",
IdentityNamespace.TYPE_FRAGMENT, Version.emptyVersion);
GenericRequirement f1_hostReq = new GenericRequirement(f1,
HostNamespace.HOST_NAMESPACE);
f1_hostReq.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, "(" +
HostNamespace.HOST_NAMESPACE + "=A)");
f1.addRequirement(f1_hostReq);
- ResourceImpl f2 = new ResourceImpl("F2",
IdentityNamespace.TYPE_FRAGMENT);
+ ResourceImpl f2 = new ResourceImpl("F2",
IdentityNamespace.TYPE_FRAGMENT, Version.emptyVersion);
GenericRequirement f2_hostReq = new GenericRequirement(f2,
HostNamespace.HOST_NAMESPACE);
f2_hostReq.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, "(" +
HostNamespace.HOST_NAMESPACE + "=A)");
f2.addRequirement(f2_hostReq);
Modified:
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/ResolverTest.java
URL:
http://svn.apache.org/viewvc/felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/ResolverTest.java?rev=1767765&r1=1767764&r2=1767765&view=diff
==============================================================================
---
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/ResolverTest.java
(original)
+++
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/ResolverTest.java
Wed Nov 2 19:09:40 2016
@@ -46,6 +46,7 @@ import org.apache.felix.resolver.test.ut
import org.junit.Test;
import org.mockito.Mockito;
import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
import org.osgi.framework.namespace.BundleNamespace;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.namespace.IdentityNamespace;
@@ -445,7 +446,7 @@ public class ResolverTest
ResourceImpl a1 = new ResourceImpl("A");
Capability a1_hostCap = addCap(a1, HostNamespace.HOST_NAMESPACE, "A");
- ResourceImpl f1 = new ResourceImpl("F1",
IdentityNamespace.TYPE_FRAGMENT);
+ ResourceImpl f1 = new ResourceImpl("F1",
IdentityNamespace.TYPE_FRAGMENT, Version.emptyVersion);
Requirement f1_hostReq = addReq(f1, HostNamespace.HOST_NAMESPACE, "A");
Capability f1_pkgCap = addCap(f1, PackageNamespace.PACKAGE_NAMESPACE,
"org.foo.a");
@@ -499,7 +500,7 @@ public class ResolverTest
ResourceImpl a1 = new ResourceImpl("A");
Capability a1_hostCap = addCap(a1, HostNamespace.HOST_NAMESPACE, "A");
- ResourceImpl f1 = new ResourceImpl("F1",
IdentityNamespace.TYPE_FRAGMENT);
+ ResourceImpl f1 = new ResourceImpl("F1",
IdentityNamespace.TYPE_FRAGMENT, Version.emptyVersion);
Requirement f1_hostReq = addReq(f1, HostNamespace.HOST_NAMESPACE, "A");
Capability f1_pkgCap = addCap(f1, PackageNamespace.PACKAGE_NAMESPACE,
"org.foo.a");
@@ -603,7 +604,7 @@ public class ResolverTest
ResourceImpl a1 = new ResourceImpl("A");
Capability a1_hostCap = addCap(a1, HostNamespace.HOST_NAMESPACE, "A");
- ResourceImpl f1 = new ResourceImpl("F1",
IdentityNamespace.TYPE_FRAGMENT);
+ ResourceImpl f1 = new ResourceImpl("F1",
IdentityNamespace.TYPE_FRAGMENT, Version.emptyVersion);
Requirement f1_hostReq = addReq(f1, HostNamespace.HOST_NAMESPACE, "A");
Capability f1_pkgCap = addCap(f1, PackageNamespace.PACKAGE_NAMESPACE,
"org.foo.a");
@@ -628,6 +629,63 @@ public class ResolverTest
}
@Test
+ public void testScenario14() throws Exception
+ {
+ ResolverImpl resolver = new ResolverImpl(new Logger(Logger.LOG_DEBUG),
1);
+
+ Map<Resource, Wiring> wirings = new HashMap<Resource, Wiring>();
+ Map<Requirement, List<Capability>> candMap = new HashMap<Requirement,
List<Capability>>();
+
+ ResourceImpl a1 = new ResourceImpl("A", IdentityNamespace.TYPE_BUNDLE,
Version.parseVersion("1.0.0"));
+ Capability a1_hostCap = addCap(a1, HostNamespace.HOST_NAMESPACE, "A");
+ Capability a1_pkgCap = addCap(a1, PackageNamespace.PACKAGE_NAMESPACE,
"a");
+ Requirement a1_pkgReq = addReq(a1, PackageNamespace.PACKAGE_NAMESPACE,
"a.impl");
+
+ ResourceImpl a2 = new ResourceImpl("A", IdentityNamespace.TYPE_BUNDLE,
Version.parseVersion("2.0.0"));
+ Capability a2_hostCap = addCap(a2, HostNamespace.HOST_NAMESPACE, "A");
+ Capability a2_pkgCap = addCap(a2, PackageNamespace.PACKAGE_NAMESPACE,
"a");
+ Requirement a2_pkgReq = addReq(a2, PackageNamespace.PACKAGE_NAMESPACE,
"a.impl");
+
+ ResourceImpl a3 = new ResourceImpl("A", IdentityNamespace.TYPE_BUNDLE,
Version.parseVersion("3.0.0"));
+ Capability a3_hostCap = addCap(a3, HostNamespace.HOST_NAMESPACE, "A");
+ Capability a3_pkgCap = addCap(a3, PackageNamespace.PACKAGE_NAMESPACE,
"a");
+ Requirement a3_pkgReq = addReq(a3, PackageNamespace.PACKAGE_NAMESPACE,
"a.impl");
+
+ ResourceImpl f1 = new ResourceImpl("F1",
IdentityNamespace.TYPE_FRAGMENT, Version.emptyVersion);
+ Requirement f1_hostReq = addReq(f1, HostNamespace.HOST_NAMESPACE, "A");
+ Capability f1_pkgCap = addCap(f1, PackageNamespace.PACKAGE_NAMESPACE,
"a.impl");
+ Requirement f1_pkgReq = addReq(f1, PackageNamespace.PACKAGE_NAMESPACE,
"a");
+
+ ResourceImpl b1 = new ResourceImpl("B");
+ Requirement b_pkgReq1 = addReq(b1, PackageNamespace.PACKAGE_NAMESPACE,
"a");
+
+ candMap.put(a1_pkgReq, Collections.singletonList(f1_pkgCap));
+ candMap.put(a2_pkgReq, Collections.singletonList(f1_pkgCap));
+ candMap.put(a3_pkgReq, Collections.singletonList(f1_pkgCap));
+ candMap.put(b_pkgReq1, Arrays.asList(a3_pkgCap, a2_pkgCap, a1_pkgCap));
+ candMap.put(f1_pkgReq, Arrays.asList(a3_pkgCap, a2_pkgCap, a1_pkgCap));
+ candMap.put(f1_hostReq, Arrays.asList(a3_hostCap, a2_hostCap,
a1_hostCap));
+
+
+ ResolveContextImpl rci = new ResolveContextImpl(wirings, candMap,
Arrays.<Resource> asList(b1, a1, a2, a3), Collections.<Resource> emptyList());
+
+ Map<Resource, List<Wire>> wireMap = resolver.resolve(rci);
+
+ // all bundles should be resolved
+ assertEquals(5, wireMap.size());
+ List<Wire> wiresB = wireMap.get(b1);
+ assertNotNull(wiresB);
+ assertEquals(1, wiresB.size());
+ assertEquals(a3, wiresB.get(0).getProvider());
+ assertEquals(a3_pkgCap, wiresB.get(0).getCapability());
+
+ // There should be three hosts
+ List<Wire> wiresF1 = wireMap.get(f1);
+ assertNotNull(wiresF1);
+ assertEquals(3, wiresF1.size());
+ }
+
+ @Test
public void testPackageSources() throws Exception {
Method m = ResolverImpl.class.getDeclaredMethod("getPackageSources",
Capability.class, Map.class);
@@ -918,12 +976,12 @@ public class ResolverTest
a1_hostCap.addAttribute(HostNamespace.HOST_NAMESPACE, "A");
a1.addCapability(a1_hostCap);
- ResourceImpl f1 = new ResourceImpl("F1",
IdentityNamespace.TYPE_FRAGMENT);
+ ResourceImpl f1 = new ResourceImpl("F1",
IdentityNamespace.TYPE_FRAGMENT, Version.emptyVersion);
GenericRequirement f1_hostReq = new GenericRequirement(f1,
HostNamespace.HOST_NAMESPACE);
f1_hostReq.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, "(" +
HostNamespace.HOST_NAMESPACE + "=A)");
f1.addRequirement(f1_hostReq);
- ResourceImpl f2 = new ResourceImpl("F2",
IdentityNamespace.TYPE_FRAGMENT);
+ ResourceImpl f2 = new ResourceImpl("F2",
IdentityNamespace.TYPE_FRAGMENT, Version.emptyVersion);
GenericRequirement f2_hostReq = new GenericRequirement(f2,
HostNamespace.HOST_NAMESPACE);
f2_hostReq.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, "(" +
HostNamespace.HOST_NAMESPACE + "=A)");
f2.addRequirement(f2_hostReq);
@@ -989,7 +1047,7 @@ public class ResolverTest
ResourceImpl a1 = new ResourceImpl("A");
Capability a1_hostCap = addCap(a1, HostNamespace.HOST_NAMESPACE, "A");
- ResourceImpl f1 = new ResourceImpl("F1",
IdentityNamespace.TYPE_FRAGMENT);
+ ResourceImpl f1 = new ResourceImpl("F1",
IdentityNamespace.TYPE_FRAGMENT, Version.emptyVersion);
Requirement f1_hostReq = addReq(f1, HostNamespace.HOST_NAMESPACE, "A");
Requirement f1_pkgReq = addReq(f1, PackageNamespace.PACKAGE_NAMESPACE,
"org.foo.c");
Capability f1_pkgCap = addCap(f1, PackageNamespace.PACKAGE_NAMESPACE,
"org.foo.a", "org.foo.c");
Modified:
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/util/IdentityCapability.java
URL:
http://svn.apache.org/viewvc/felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/util/IdentityCapability.java?rev=1767765&r1=1767764&r2=1767765&view=diff
==============================================================================
---
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/util/IdentityCapability.java
(original)
+++
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/util/IdentityCapability.java
Wed Nov 2 19:09:40 2016
@@ -32,14 +32,14 @@ public class IdentityCapability implemen
private final Map<String, String> m_dirs;
private final Map<String, Object> m_attrs;
- public IdentityCapability(Resource resource, String name, String type)
+ public IdentityCapability(Resource resource, String name, String type,
Version v)
{
m_resource = resource;
m_dirs = new HashMap<String, String>();
m_attrs = new HashMap<String, Object>();
m_attrs.put(IdentityNamespace.IDENTITY_NAMESPACE, name);
m_attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, type);
- m_attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE,
Version.emptyVersion);
+ m_attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, v);
}
public String getNamespace()
Modified:
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/util/ResourceImpl.java
URL:
http://svn.apache.org/viewvc/felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/util/ResourceImpl.java?rev=1767765&r1=1767764&r2=1767765&view=diff
==============================================================================
---
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/util/ResourceImpl.java
(original)
+++
felix/trunk/resolver/src/test/java/org/apache/felix/resolver/test/util/ResourceImpl.java
Wed Nov 2 19:09:40 2016
@@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.List;
import org.apache.felix.resolver.test.util.IdentityCapability;
+import org.osgi.framework.Version;
import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
@@ -38,12 +39,12 @@ public class ResourceImpl implements Res
m_reqs = new ArrayList<Requirement>();
}
public ResourceImpl(String name) {
- this(name, IdentityNamespace.TYPE_BUNDLE);
+ this(name, IdentityNamespace.TYPE_BUNDLE, Version.emptyVersion);
}
- public ResourceImpl(String name, String type)
+ public ResourceImpl(String name, String type, Version v)
{
m_caps = new ArrayList<Capability>();
- m_caps.add(0, new IdentityCapability(this, name, type));
+ m_caps.add(0, new IdentityCapability(this, name, type, v));
m_reqs = new ArrayList<Requirement>();
}