You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2015/06/11 08:31:39 UTC
[1/2] karaf git commit: [KARAF-3764] NoClassDefFoundError when the
features-core bundle is refreshed by itself
Repository: karaf
Updated Branches:
refs/heads/master 947d2eb7c -> 8723b8fd8
[KARAF-3764] NoClassDefFoundError when the features-core bundle is refreshed by itself
Also fix problems with eventadmin and packageadmin causing refreshes of pax-logging-api and most of bundles at the start phase
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/8723b8fd
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/8723b8fd
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/8723b8fd
Branch: refs/heads/master
Commit: 8723b8fd843040e7eed3fd9f887efd53727c0c3a
Parents: 9770185
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Wed Jun 10 21:08:25 2015 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Wed Jun 10 21:13:35 2015 +0200
----------------------------------------------------------------------
assemblies/apache-karaf/pom.xml | 5 +-
.../standard/src/main/feature/feature.xml | 2 +-
config/pom.xml | 5 +-
.../karaf/config/command/MetaCommand.java | 125 ++++++++++---------
.../features/internal/service/Deployer.java | 24 ++--
.../internal/service/EventAdminListener.java | 93 ++++++++------
.../karaf/itests/ConditionalFeaturesTest.java | 3 +-
.../org/apache/karaf/itests/FeatureTest.java | 2 +-
8 files changed, 147 insertions(+), 112 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/8723b8fd/assemblies/apache-karaf/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/apache-karaf/pom.xml b/assemblies/apache-karaf/pom.xml
index f2b7e7b..ba12881 100644
--- a/assemblies/apache-karaf/pom.xml
+++ b/assemblies/apache-karaf/pom.xml
@@ -48,7 +48,6 @@
<artifactId>standard</artifactId>
<classifier>features</classifier>
<type>xml</type>
- <scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.karaf.features</groupId>
@@ -159,8 +158,10 @@
<installedFeatures>
<feature>wrapper</feature>
</installedFeatures>
- <bootFeatures>
+ <startupFeatures>
<feature>eventadmin</feature>
+ </startupFeatures>
+ <bootFeatures>
<feature>wrap</feature>
<feature>aries-blueprint</feature>
<feature>shell</feature>
http://git-wip-us.apache.org/repos/asf/karaf/blob/8723b8fd/assemblies/features/standard/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/standard/src/main/feature/feature.xml b/assemblies/features/standard/src/main/feature/feature.xml
index 7c66305..c45c828 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -499,7 +499,7 @@
org.apache.felix.eventadmin.AddTimestamp=true
org.apache.felix.eventadmin.AddSubject=true
</config>
- <bundle start-level="30">mvn:org.apache.karaf.services/org.apache.karaf.services.eventadmin/${project.version}</bundle>
+ <bundle start-level="5">mvn:org.apache.karaf.services/org.apache.karaf.services.eventadmin/${project.version}</bundle>
<conditional>
<condition>webconsole</condition>
<bundle start-level="30">mvn:org.apache.felix/org.apache.felix.webconsole.plugins.event/${felix.eventadmin.webconsole.plugin.version}</bundle>
http://git-wip-us.apache.org/repos/asf/karaf/blob/8723b8fd/config/pom.xml
----------------------------------------------------------------------
diff --git a/config/pom.xml b/config/pom.xml
index a460394..16abc8c 100644
--- a/config/pom.xml
+++ b/config/pom.xml
@@ -102,11 +102,10 @@
<Export-Package>
org.apache.karaf.config.command*,
org.apache.karaf.config.core,
- org.osgi.service.metatype
</Export-Package>
<Import-Package>
- *,
- org.osgi.service.metatype
+ org.osgi.service.metatype;resolution:=optional,
+ *
</Import-Package>
<Private-Package>
org.apache.karaf.config.core.impl,
http://git-wip-us.apache.org/repos/asf/karaf/blob/8723b8fd/config/src/main/java/org/apache/karaf/config/command/MetaCommand.java
----------------------------------------------------------------------
diff --git a/config/src/main/java/org/apache/karaf/config/command/MetaCommand.java b/config/src/main/java/org/apache/karaf/config/command/MetaCommand.java
index 83a1e7d..b7554ae 100644
--- a/config/src/main/java/org/apache/karaf/config/command/MetaCommand.java
+++ b/config/src/main/java/org/apache/karaf/config/command/MetaCommand.java
@@ -61,74 +61,87 @@ public class MetaCommand extends ConfigCommandSupport {
}
@Override
- protected Object doExecute() throws Exception {
-
- ServiceReference<MetaTypeService> ref = context.getServiceReference(MetaTypeService.class);
- if (ref == null) {
+ public Object doExecute() throws Exception {
+ try {
+ new InnerCommand().doExecute();
+ } catch (NoClassDefFoundError e) {
System.out
- .println("No MetaTypeService present. You need to install an implementation to use this command.");
- }
- MetaTypeService metaTypeService = context.getService(ref);
- ObjectClassDefinition def = getMetatype(metaTypeService, pid);
- context.ungetService(ref);
-
- if (def == null) {
- System.out.println("No meta type definition found for pid: " + pid);
- return null;
+ .println("No MetaTypeService present. You need to install an implementation to use this command.");
}
- System.out.println("Meta type informations for pid: " + pid);
- ShellTable table = new ShellTable();
- table.column("key");
- table.column("name");
- table.column("type");
- table.column("default");
- table.column("description");
- AttributeDefinition[] attrs = def.getAttributeDefinitions(ObjectClassDefinition.ALL);
- if (attrs != null) {
- for (AttributeDefinition attr : attrs) {
- table.addRow().addContent(attr.getID(), attr.getName(), getType(attr.getType()),
- getDefaultValueStr(attr.getDefaultValue()), attr.getDescription());
- }
- }
- table.print(System.out);
return null;
}
- private String getType(int type) {
- return typeMap.get(type);
- }
+ class InnerCommand {
- private String getDefaultValueStr(String[] defaultValues) {
- if (defaultValues == null) {
- return "";
- }
- StringBuilder result = new StringBuilder();
- boolean first = true;
- for (String defaultValue : defaultValues) {
- if (first) {
- first = false;
- } else {
- result.append(",");
+ protected Object doExecute() throws Exception {
+
+ ServiceReference<MetaTypeService> ref = context.getServiceReference(MetaTypeService.class);
+ if (ref == null) {
+ System.out
+ .println("No MetaTypeService present. You need to install an implementation to use this command.");
+ }
+ MetaTypeService metaTypeService = context.getService(ref);
+ ObjectClassDefinition def = getMetatype(metaTypeService, pid);
+ context.ungetService(ref);
+
+ if (def == null) {
+ System.out.println("No meta type definition found for pid: " + pid);
+ return null;
+ }
+ System.out.println("Meta type informations for pid: " + pid);
+ ShellTable table = new ShellTable();
+ table.column("key");
+ table.column("name");
+ table.column("type");
+ table.column("default");
+ table.column("description");
+ AttributeDefinition[] attrs = def.getAttributeDefinitions(ObjectClassDefinition.ALL);
+ if (attrs != null) {
+ for (AttributeDefinition attr : attrs) {
+ table.addRow().addContent(attr.getID(), attr.getName(), getType(attr.getType()),
+ getDefaultValueStr(attr.getDefaultValue()), attr.getDescription());
+ }
}
- result.append(defaultValue);
+ table.print(System.out);
+ return null;
+ }
+
+ private String getType(int type) {
+ return typeMap.get(type);
}
- return result.toString();
- }
- public ObjectClassDefinition getMetatype(MetaTypeService metaTypeService, String pid) {
- for (Bundle bundle : context.getBundles()) {
- MetaTypeInformation info = metaTypeService.getMetaTypeInformation(bundle);
- if (info == null) {
- continue;
+ private String getDefaultValueStr(String[] defaultValues) {
+ if (defaultValues == null) {
+ return "";
}
- String[] pids = info.getPids();
- for (String cPid : pids) {
- if (cPid.equals(pid)) {
- return info.getObjectClassDefinition(cPid, null);
+ StringBuilder result = new StringBuilder();
+ boolean first = true;
+ for (String defaultValue : defaultValues) {
+ if (first) {
+ first = false;
+ } else {
+ result.append(",");
}
+ result.append(defaultValue);
}
+ return result.toString();
}
- return null;
- }
+ public ObjectClassDefinition getMetatype(MetaTypeService metaTypeService, String pid) {
+ for (Bundle bundle : context.getBundles()) {
+ MetaTypeInformation info = metaTypeService.getMetaTypeInformation(bundle);
+ if (info == null) {
+ continue;
+ }
+ String[] pids = info.getPids();
+ for (String cPid : pids) {
+ if (cPid.equals(pid)) {
+ return info.getObjectClassDefinition(cPid, null);
+ }
+ }
+ }
+ return null;
+ }
+
+ }
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/8723b8fd/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
index e6bc258..f3f767b 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
@@ -775,10 +775,6 @@ public class Deployer {
}
}
- // TODO: remove this hack, but it avoids loading the class after the bundle is refreshed
- new CopyOnWriteArrayIdentityList().iterator();
- RequirementSort.sort(Collections.<Resource>emptyList());
-
if (!noRefresh) {
toStop = new HashSet<>();
toStop.addAll(toRefresh.keySet());
@@ -802,9 +798,12 @@ public class Deployer {
Bundle bundle = entry.getKey();
print(" " + bundle.getSymbolicName() + " / " + bundle.getVersion() + " (" + entry.getValue() + ")", verbose);
}
- if (!toRefresh.isEmpty()) {
- callback.refreshPackages(toRefresh.keySet());
+ // Ensure all classes are loaded in case the bundle will be refreshed
+ if (dstate.serviceBundle != null && toRefresh.containsKey(dstate.serviceBundle)) {
+ ensureAllClassesLoaded(dstate.serviceBundle);
}
+ callback.refreshPackages(toRefresh.keySet());
+
}
}
@@ -935,7 +934,7 @@ public class Deployer {
Resource resource = bndToRes.get(bundle);
// This bundle is not managed
if (resource == null) {
- continue;
+ resource = bundle.adapt(BundleRevision.class);
}
// Continue if we already know about this bundle
if (toRefresh.containsKey(bundle)) {
@@ -1370,4 +1369,15 @@ public class Deployer {
return provider.open();
}
+ public static void ensureAllClassesLoaded(Bundle bundle) throws ClassNotFoundException {
+ BundleWiring wiring = bundle.adapt(BundleWiring.class);
+ if (wiring != null) {
+ for (String path : wiring.listResources("/", "*.class", BundleWiring.LISTRESOURCES_RECURSE)) {
+ String className = path.substring(0, path.length() - ".class".length());
+ className = className.replace('/', '.');
+ bundle.loadClass(className);
+ }
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/8723b8fd/features/core/src/main/java/org/apache/karaf/features/internal/service/EventAdminListener.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/EventAdminListener.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/EventAdminListener.java
index c16613d..bd5c0d5 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/EventAdminListener.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/EventAdminListener.java
@@ -27,12 +27,15 @@ import org.osgi.framework.BundleContext;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* A listener to publish events to EventAdmin
*/
public class EventAdminListener implements FeaturesListener {
+ private static final Logger LOGGER = LoggerFactory.getLogger(EventAdminListener.class);
private final ServiceTracker<EventAdmin, EventAdmin> tracker;
public EventAdminListener(BundleContext context) {
@@ -41,51 +44,59 @@ public class EventAdminListener implements FeaturesListener {
}
public void featureEvent(FeatureEvent event) {
- EventAdmin eventAdmin = tracker.getService();
- if (eventAdmin == null) {
- return;
+ try {
+ EventAdmin eventAdmin = tracker.getService();
+ if (eventAdmin == null) {
+ return;
+ }
+ Dictionary<String, Object> props = new Hashtable<String, Object>();
+ props.put(EventConstants.TYPE, event.getType());
+ props.put(EventConstants.EVENT, event);
+ props.put(EventConstants.TIMESTAMP, System.currentTimeMillis());
+ props.put(EventConstants.FEATURE_NAME, event.getFeature().getName());
+ props.put(EventConstants.FEATURE_VERSION, event.getFeature().getVersion());
+ String topic;
+ switch (event.getType()) {
+ case FeatureInstalled:
+ topic = EventConstants.TOPIC_FEATURES_INSTALLED;
+ break;
+ case FeatureUninstalled:
+ topic = EventConstants.TOPIC_FEATURES_UNINSTALLED;
+ break;
+ default:
+ throw new IllegalStateException("Unknown features event type: " + event.getType());
+ }
+ eventAdmin.postEvent(new Event(topic, props));
+ } catch (IllegalStateException e) {
+ LOGGER.warn("Unable to post event to EventAdmin", e);
}
- Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put(EventConstants.TYPE, event.getType());
- props.put(EventConstants.EVENT, event);
- props.put(EventConstants.TIMESTAMP, System.currentTimeMillis());
- props.put(EventConstants.FEATURE_NAME, event.getFeature().getName());
- props.put(EventConstants.FEATURE_VERSION, event.getFeature().getVersion());
- String topic;
- switch (event.getType()) {
- case FeatureInstalled:
- topic = EventConstants.TOPIC_FEATURES_INSTALLED;
- break;
- case FeatureUninstalled:
- topic = EventConstants.TOPIC_FEATURES_UNINSTALLED;
- break;
- default:
- throw new IllegalStateException("Unknown features event type: " + event.getType());
- }
- eventAdmin.postEvent(new Event(topic, props));
}
public void repositoryEvent(RepositoryEvent event) {
- EventAdmin eventAdmin = tracker.getService();
- if (eventAdmin == null) {
- return;
- }
- Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put(EventConstants.TYPE, event.getType());
- props.put(EventConstants.EVENT, event);
- props.put(EventConstants.TIMESTAMP, System.currentTimeMillis());
- props.put(EventConstants.REPOSITORY_URI, event.getRepository().getURI().toString());
- String topic;
- switch (event.getType()) {
- case RepositoryAdded:
- topic = EventConstants.TOPIC_REPOSITORY_ADDED;
- break;
- case RepositoryRemoved:
- topic = EventConstants.TOPIC_REPOSITORY_REMOVED;
- break;
- default:
- throw new IllegalStateException("Unknown repository event type: " + event.getType());
+ try {
+ EventAdmin eventAdmin = tracker.getService();
+ if (eventAdmin == null) {
+ return;
+ }
+ Dictionary<String, Object> props = new Hashtable<String, Object>();
+ props.put(EventConstants.TYPE, event.getType());
+ props.put(EventConstants.EVENT, event);
+ props.put(EventConstants.TIMESTAMP, System.currentTimeMillis());
+ props.put(EventConstants.REPOSITORY_URI, event.getRepository().getURI().toString());
+ String topic;
+ switch (event.getType()) {
+ case RepositoryAdded:
+ topic = EventConstants.TOPIC_REPOSITORY_ADDED;
+ break;
+ case RepositoryRemoved:
+ topic = EventConstants.TOPIC_REPOSITORY_REMOVED;
+ break;
+ default:
+ throw new IllegalStateException("Unknown repository event type: " + event.getType());
+ }
+ eventAdmin.postEvent(new Event(topic, props));
+ } catch (IllegalStateException e) {
+ LOGGER.warn("Unable to post event to EventAdmin", e);
}
- eventAdmin.postEvent(new Event(topic, props));
}
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/8723b8fd/itests/src/test/java/org/apache/karaf/itests/ConditionalFeaturesTest.java
----------------------------------------------------------------------
diff --git a/itests/src/test/java/org/apache/karaf/itests/ConditionalFeaturesTest.java b/itests/src/test/java/org/apache/karaf/itests/ConditionalFeaturesTest.java
index f64dc02..18ef2d0 100644
--- a/itests/src/test/java/org/apache/karaf/itests/ConditionalFeaturesTest.java
+++ b/itests/src/test/java/org/apache/karaf/itests/ConditionalFeaturesTest.java
@@ -76,6 +76,7 @@ public class ConditionalFeaturesTest extends KarafTestSupport {
featureService.uninstallFeature("scr", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
} catch (Exception e) {
}
+ featureService.installFeature("eventadmin", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
featureService.installFeature("webconsole", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
assertBundleInstalled("org.apache.karaf.webconsole.features");
@@ -84,7 +85,7 @@ public class ConditionalFeaturesTest extends KarafTestSupport {
assertBundleInstalled("org.apache.karaf.webconsole.http");
assertBundleInstalled("org.apache.felix.webconsole.plugins.event");
- // remove eventadmin
+ // add eventadmin
featureService.uninstallFeature("eventadmin", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles));
assertBundleNotInstalled("org.apache.felix.webconsole.plugins.event");
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/8723b8fd/itests/src/test/java/org/apache/karaf/itests/FeatureTest.java
----------------------------------------------------------------------
diff --git a/itests/src/test/java/org/apache/karaf/itests/FeatureTest.java b/itests/src/test/java/org/apache/karaf/itests/FeatureTest.java
index 9aa4112..e87b111 100644
--- a/itests/src/test/java/org/apache/karaf/itests/FeatureTest.java
+++ b/itests/src/test/java/org/apache/karaf/itests/FeatureTest.java
@@ -34,7 +34,7 @@ public class FeatureTest extends KarafTestSupport {
@Test
public void bootFeatures() throws Exception {
- assertFeaturesInstalled("eventadmin","jaas", "ssh", "management", "bundle", "config", "deployer", "diagnostic",
+ assertFeaturesInstalled("jaas", "ssh", "management", "bundle", "config", "deployer", "diagnostic",
"instance", "kar", "log", "package", "service", "system");
}
[2/2] karaf git commit: [KARAF-3759] Provide tooling to store a
resolution attempt that failed so that it can be replayed offline for
analysis
Posted by gn...@apache.org.
[KARAF-3759] Provide tooling to store a resolution attempt that failed so that it can be replayed offline for analysis
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/9770185c
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/9770185c
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/9770185c
Branch: refs/heads/master
Commit: 9770185c85d0d38d78e3e9d0854582ef8529dd3b
Parents: 947d2eb
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Mon Jun 8 10:25:52 2015 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Wed Jun 10 21:13:35 2015 +0200
----------------------------------------------------------------------
.../features/command/InstallFeatureCommand.java | 4 +
features/core/pom.xml | 6 +
.../apache/karaf/features/FeaturesService.java | 2 +
.../internal/region/OfflineResolver.java | 167 +++++++++++++++++++
.../region/SubsystemResolveContext.java | 8 +
.../internal/region/SubsystemResolver.java | 72 +++++++-
.../internal/resolver/ResourceBuilder.java | 83 ++++++++-
.../features/internal/service/Deployer.java | 4 +-
.../internal/service/FeaturesServiceImpl.java | 25 ++-
.../features/internal/util/JsonWriter.java | 15 +-
.../features/internal/region/SubsystemTest.java | 16 +-
11 files changed, 380 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/9770185c/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
----------------------------------------------------------------------
diff --git a/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java b/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
index 600310b..571a713 100644
--- a/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
+++ b/features/command/src/main/java/org/apache/karaf/features/command/InstallFeatureCommand.java
@@ -52,6 +52,9 @@ public class InstallFeatureCommand extends FeaturesCommandSupport {
@Option(name = "-t", aliases = "--simulate", description = "Perform a simulation only", required = false, multiValued = false)
boolean simulate;
+ @Option(name = "--store", description = "Store the resolution into the given file and result for offline analysis")
+ String outputFile;
+
@Option(name = "-g", aliases = "--region", description = "Region to install to")
String region;
@@ -61,6 +64,7 @@ public class InstallFeatureCommand extends FeaturesCommandSupport {
addOption(FeaturesService.Option.NoAutoRefreshBundles, noRefresh);
addOption(FeaturesService.Option.NoAutoManageBundles, noManage);
addOption(FeaturesService.Option.Verbose, verbose);
+ admin.setResolutionOutputFile(outputFile);
admin.installFeatures(new HashSet<String>(features), region, options);
}
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/9770185c/features/core/pom.xml
----------------------------------------------------------------------
diff --git a/features/core/pom.xml b/features/core/pom.xml
index d45feb5..767fe12 100644
--- a/features/core/pom.xml
+++ b/features/core/pom.xml
@@ -52,6 +52,11 @@
<dependency>
<groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.resolver</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.utils</artifactId>
<scope>provided</scope>
</dependency>
@@ -135,6 +140,7 @@
org.eclipse.equinox.region.*
</Export-Package>
<Import-Package>
+ !org.apache.felix.resolver,
!org.eclipse.osgi.service.resolver,
*
</Import-Package>
http://git-wip-us.apache.org/repos/asf/karaf/blob/9770185c/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java b/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java
index 82d246d..57e7014 100644
--- a/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java
+++ b/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java
@@ -83,6 +83,8 @@ public interface FeaturesService {
String getRepositoryName(URI uri) throws Exception;
+ void setResolutionOutputFile(String outputFile);
+
void installFeature(String name) throws Exception;
void installFeature(String name, EnumSet<Option> options) throws Exception;
http://git-wip-us.apache.org/repos/asf/karaf/blob/9770185c/features/core/src/main/java/org/apache/karaf/features/internal/region/OfflineResolver.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/region/OfflineResolver.java b/features/core/src/main/java/org/apache/karaf/features/internal/region/OfflineResolver.java
new file mode 100644
index 0000000..1c89dc2
--- /dev/null
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/region/OfflineResolver.java
@@ -0,0 +1,167 @@
+/*
+ * 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.karaf.features.internal.region;
+
+import java.io.BufferedReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.resolver.Logger;
+import org.apache.felix.resolver.ResolverImpl;
+import org.apache.karaf.features.internal.repository.BaseRepository;
+import org.apache.karaf.features.internal.resolver.RequirementImpl;
+import org.apache.karaf.features.internal.resolver.ResourceBuilder;
+import org.apache.karaf.features.internal.resolver.ResourceImpl;
+import org.apache.karaf.features.internal.resolver.SimpleFilter;
+import org.apache.karaf.features.internal.util.JsonReader;
+import org.osgi.framework.BundleException;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wire;
+import org.osgi.resource.Wiring;
+import org.osgi.service.repository.Repository;
+import org.osgi.service.resolver.HostedCapability;
+import org.osgi.service.resolver.ResolveContext;
+import org.osgi.service.resolver.Resolver;
+
+import static org.osgi.framework.Constants.RESOLUTION_DIRECTIVE;
+import static org.osgi.framework.Constants.RESOLUTION_OPTIONAL;
+import static org.osgi.framework.namespace.IdentityNamespace.IDENTITY_NAMESPACE;
+
+public class OfflineResolver {
+
+ public static void main(String[] args) throws Exception {
+ if (args == null || args.length != 1) {
+ throw new IllegalArgumentException("File path expected");
+ }
+ resolve(args[0]);
+ }
+
+ public static void resolve(String resolutionFile) throws Exception {
+ Map<String, Object> resolution;
+ try (BufferedReader reader = Files.newBufferedReader(Paths.get(resolutionFile), StandardCharsets.UTF_8)) {
+ resolution = (Map<String, Object>) JsonReader.read(reader);
+ }
+
+ final Repository globalRepository;
+ if (resolution.containsKey("globalRepository")) {
+ globalRepository = readRepository(resolution.get("globalRepository"));
+ } else {
+ globalRepository = null;
+ }
+ final Repository repository = readRepository(resolution.get("repository"));
+
+ Resolver resolver = new ResolverImpl(new Logger(Logger.LOG_ERROR));
+ Map<Resource, List<Wire>> wiring = resolver.resolve(new ResolveContext() {
+ private final Set<Resource> mandatory = new HashSet<>();
+ private final CandidateComparator candidateComparator = new CandidateComparator(mandatory);
+
+ @Override
+ public Collection<Resource> getMandatoryResources() {
+ List<Resource> resources = new ArrayList<Resource>();
+ Requirement req = new RequirementImpl(
+ null,
+ IDENTITY_NAMESPACE,
+ Collections.<String, String>emptyMap(),
+ Collections.<String, Object>emptyMap(),
+ SimpleFilter.parse("(" + IDENTITY_NAMESPACE + "=root)"));
+ Collection<Capability> identities = repository.findProviders(Collections.singleton(req)).get(req);
+ for (Capability identity : identities) {
+ resources.add(identity.getResource());
+ }
+ return resources;
+ }
+
+ @Override
+ public List<Capability> findProviders(Requirement requirement) {
+ List<Capability> caps = new ArrayList<>();
+ Map<Requirement, Collection<Capability>> resMap =
+ repository.findProviders(Collections.singleton(requirement));
+ Collection<Capability> res = resMap != null ? resMap.get(requirement) : null;
+ if (res != null && !res.isEmpty()) {
+ caps.addAll(res);
+ } else if (globalRepository != null) {
+ // Only bring in external resources for non optional requirements
+ if (!RESOLUTION_OPTIONAL.equals(requirement.getDirectives().get(RESOLUTION_DIRECTIVE))) {
+ resMap = globalRepository.findProviders(Collections.singleton(requirement));
+ res = resMap != null ? resMap.get(requirement) : null;
+ if (res != null && !res.isEmpty()) {
+ caps.addAll(res);
+ }
+ }
+ }
+
+ // Sort caps
+ Collections.sort(caps, candidateComparator);
+ return caps;
+ }
+
+ @Override
+ public int insertHostedCapability(List<Capability> capabilities, HostedCapability hostedCapability) {
+ int idx = Collections.binarySearch(capabilities, hostedCapability, candidateComparator);
+ if (idx < 0) {
+ idx = Math.abs(idx + 1);
+ }
+ capabilities.add(idx, hostedCapability);
+ return idx;
+ }
+
+ @Override
+ public boolean isEffective(Requirement requirement) {
+ return true;
+ }
+
+ @Override
+ public Map<Resource, Wiring> getWirings() {
+ return Collections.emptyMap();
+ }
+ });
+ }
+
+ private static Repository readRepository(Object repository) throws BundleException {
+ List<Resource> resources = new ArrayList<>();
+ Collection<Map<String, List<String>>> metadatas;
+ if (repository instanceof Map) {
+ metadatas = ((Map<String, Map<String, List<String>>>) repository).values();
+ } else {
+ metadatas = (Collection<Map<String, List<String>>>) repository;
+ }
+ for (Map<String, List<String>> metadata : metadatas) {
+ ResourceImpl res = new ResourceImpl();
+ for (String cap : metadata.get("capabilities")) {
+ res.addCapabilities(ResourceBuilder.parseCapability(res, cap));
+ }
+ if (metadata.containsKey("requirements")) {
+ for (String req : metadata.get("requirements")) {
+ res.addRequirements(ResourceBuilder.parseRequirement(res, req));
+ }
+ }
+ resources.add(res);
+ }
+ return new BaseRepository(resources);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/9770185c/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java
index fdf9016..de990f4 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java
@@ -87,6 +87,14 @@ public class SubsystemResolveContext extends ResolveContext {
findMandatory(root);
}
+ public Repository getRepository() {
+ return repository;
+ }
+
+ public Repository getGlobalRepository() {
+ return globalRepository;
+ }
+
void findMandatory(Resource res) {
if (mandatory.add(res)) {
for (Requirement req : res.getRequirements(null)) {
http://git-wip-us.apache.org/repos/asf/karaf/blob/9770185c/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
index 0402c12..d3701c7 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
@@ -16,6 +16,12 @@
*/
package org.apache.karaf.features.internal.region;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -30,12 +36,16 @@ import org.apache.karaf.features.Feature;
import org.apache.karaf.features.internal.download.DownloadManager;
import org.apache.karaf.features.internal.download.Downloader;
import org.apache.karaf.features.internal.download.StreamProvider;
+import org.apache.karaf.features.internal.resolver.BaseClause;
import org.apache.karaf.features.internal.resolver.CapabilityImpl;
import org.apache.karaf.features.internal.resolver.CapabilitySet;
+import org.apache.karaf.features.internal.resolver.RequirementImpl;
import org.apache.karaf.features.internal.resolver.ResolverUtil;
import org.apache.karaf.features.internal.resolver.ResourceBuilder;
import org.apache.karaf.features.internal.resolver.ResourceImpl;
+import org.apache.karaf.features.internal.resolver.ResourceUtils;
import org.apache.karaf.features.internal.resolver.SimpleFilter;
+import org.apache.karaf.features.internal.util.JsonWriter;
import org.eclipse.equinox.internal.region.StandardRegionDigraph;
import org.eclipse.equinox.region.Region;
import org.eclipse.equinox.region.RegionDigraph;
@@ -49,6 +59,7 @@ import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
import org.osgi.resource.Resource;
import org.osgi.resource.Wire;
+import org.osgi.service.repository.Repository;
import org.osgi.service.resolver.Resolver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -168,8 +179,9 @@ public class SubsystemResolver {
public Map<Resource, List<Wire>> resolve(
Set<String> overrides,
String featureResolutionRange,
- final org.osgi.service.repository.Repository globalRepository
- ) throws Exception {
+ final Repository globalRepository,
+ String outputFile) throws Exception {
+
if (root == null) {
return Collections.emptyMap();
}
@@ -182,7 +194,30 @@ public class SubsystemResolver {
populateDigraph(digraph, root);
Downloader downloader = manager.createDownloader();
- wiring = resolver.resolve(new SubsystemResolveContext(root, digraph, globalRepository, downloader));
+ SubsystemResolveContext context = new SubsystemResolveContext(root, digraph, globalRepository, downloader);
+ if (outputFile != null) {
+ Map<String, Object> json = new HashMap<>();
+ if (globalRepository != null) {
+ json.put("globalRepository", toJson(globalRepository));
+ }
+ json.put("repository", toJson(context.getRepository()));
+ try {
+ wiring = resolver.resolve(context);
+ json.put("success", "true");
+ } catch (Exception e) {
+ json.put("exception", e.toString());
+ throw e;
+ } finally {
+ try (Writer writer = Files.newBufferedWriter(
+ Paths.get(outputFile),
+ StandardCharsets.UTF_8,
+ StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
+ JsonWriter.write(writer, json);
+ }
+ }
+ } else {
+ wiring = resolver.resolve(context);
+ }
downloader.await();
// Remove wiring to the fake environment resource
@@ -203,6 +238,37 @@ public class SubsystemResolver {
return wiring;
}
+ private Object toJson(Repository repository) {
+ Requirement req = new RequirementImpl(
+ null,
+ IDENTITY_NAMESPACE,
+ Collections.<String, String>emptyMap(),
+ Collections.<String, Object>emptyMap(),
+ new SimpleFilter(null, null, SimpleFilter.MATCH_ALL));
+ Collection<Capability> identities = repository.findProviders(Collections.singleton(req)).get(req);
+ List<Object> resources = new ArrayList<>();
+ for (Capability identity : identities) {
+ String id = BaseClause.toString(null, identity.getNamespace(), identity.getAttributes(), identity.getDirectives());
+ resources.add(toJson(identity.getResource()));
+ }
+ return resources;
+ }
+
+ private Object toJson(Resource resource) {
+ Map<String, Object> obj = new HashMap<>();
+ List<Object> caps = new ArrayList<>();
+ List<Object> reqs = new ArrayList<>();
+ for (Capability cap : resource.getCapabilities(null)) {
+ caps.add(BaseClause.toString(null, cap.getNamespace(), cap.getAttributes(), cap.getDirectives()));
+ }
+ for (Requirement req : resource.getRequirements(null)) {
+ reqs.add(BaseClause.toString(null, req.getNamespace(), req.getAttributes(), req.getDirectives()));
+ }
+ obj.put("capabilities", caps);
+ obj.put("requirements", reqs);
+ return obj;
+ }
+
public Map<String, Map<String, BundleInfo>> getBundleInfos() {
if (bundleInfos == null) {
bundleInfos = new HashMap<>();
http://git-wip-us.apache.org/repos/asf/karaf/blob/9770185c/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java
index 47a0661..0dbf4e2 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceBuilder.java
@@ -455,6 +455,87 @@ public final class ResourceBuilder {
private static List<ParsedHeaderClause> normalizeRequireCapabilityClauses(
List<ParsedHeaderClause> clauses) throws BundleException {
+ // Convert attributes into specified types.
+ for (ParsedHeaderClause clause : clauses) {
+ for (Map.Entry<String, Object> entry : clause.attrs.entrySet()) {
+ if (entry.getKey().equals("version")) {
+ clause.attrs.put(entry.getKey(), new VersionRange(entry.getValue().toString()));
+ }
+ }
+ for (Map.Entry<String, String> entry : clause.types.entrySet()) {
+ String type = entry.getValue();
+ if (!type.equals("String")) {
+ if (type.equals("Double")) {
+ clause.attrs.put(
+ entry.getKey(),
+ new Double(clause.attrs.get(entry.getKey()).toString().trim()));
+ } else if (type.equals("Version")) {
+ clause.attrs.put(
+ entry.getKey(),
+ new Version(clause.attrs.get(entry.getKey()).toString().trim()));
+ } else if (type.equals("Long")) {
+ clause.attrs.put(
+ entry.getKey(),
+ new Long(clause.attrs.get(entry.getKey()).toString().trim()));
+ } else if (type.startsWith("List")) {
+ int startIdx = type.indexOf('<');
+ int endIdx = type.indexOf('>');
+ if (((startIdx > 0) && (endIdx <= startIdx))
+ || ((startIdx < 0) && (endIdx > 0))) {
+ throw new BundleException(
+ "Invalid Provide-Capability attribute list type for '"
+ + entry.getKey()
+ + "' : "
+ + type
+ );
+ }
+
+ String listType = "String";
+ if (endIdx > startIdx) {
+ listType = type.substring(startIdx + 1, endIdx).trim();
+ }
+
+ List<String> tokens = parseDelimitedString(
+ clause.attrs.get(entry.getKey()).toString(), ",", false);
+ List<Object> values = new ArrayList<>(tokens.size());
+ for (String token : tokens) {
+ switch (listType) {
+ case "String":
+ values.add(token);
+ break;
+ case "Double":
+ values.add(new Double(token.trim()));
+ break;
+ case "Version":
+ values.add(new Version(token.trim()));
+ break;
+ case "Long":
+ values.add(new Long(token.trim()));
+ break;
+ default:
+ throw new BundleException(
+ "Unknown Provide-Capability attribute list type for '"
+ + entry.getKey()
+ + "' : "
+ + type
+ );
+ }
+ }
+ clause.attrs.put(
+ entry.getKey(),
+ values);
+ } else {
+ throw new BundleException(
+ "Unknown Provide-Capability attribute type for '"
+ + entry.getKey()
+ + "' : "
+ + type
+ );
+ }
+ }
+ }
+ }
+
return clauses;
}
@@ -550,7 +631,7 @@ public final class ResourceBuilder {
String filterStr = clause.dirs.get(Constants.FILTER_DIRECTIVE);
SimpleFilter sf = (filterStr != null)
? SimpleFilter.parse(filterStr)
- : new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
+ : SimpleFilter.convert(clause.attrs);
for (String path : clause.paths) {
// Create requirement and add to requirement list.
reqList.add(new RequirementImpl(
http://git-wip-us.apache.org/repos/asf/karaf/blob/9770185c/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
index e1d4354..e6bc258 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
@@ -163,6 +163,7 @@ public class Deployer {
public Map<String, Set<String>> requirements;
public Map<String, Map<String, FeatureState>> stateChanges;
public EnumSet<FeaturesService.Option> options;
+ public String outputFile;
}
static class Deployment {
@@ -261,7 +262,8 @@ public class Deployer {
resolver.resolve(
request.overrides,
request.featureResolutionRange,
- request.globalRepository);
+ request.globalRepository,
+ request.outputFile);
Map<String, StreamProvider> providers = resolver.getProviders();
Map<String, Set<Resource>> featuresPerRegion = resolver.getFeaturesPerRegions();
http://git-wip-us.apache.org/repos/asf/karaf/blob/9770185c/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
index b003331..4dcd267 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
@@ -160,6 +160,8 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
private final String blacklisted;
+ private final ThreadLocal<String> outputFile = new ThreadLocal<>();
+
/**
* Optional global repository
*/
@@ -799,6 +801,11 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
@Override
+ public void setResolutionOutputFile(String outputFile) {
+ this.outputFile.set(outputFile);
+ }
+
+ @Override
public void installFeatures(Set<String> features, String region, EnumSet<Option> options) throws Exception {
State state = copyState();
Map<String, Set<String>> required = copy(state.requirements);
@@ -954,10 +961,12 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
final EnumSet<Option> options) throws Exception {
ExecutorService executor = Executors.newCachedThreadPool();
try {
+ final String outputFile = this.outputFile.get();
+ this.outputFile.set(null);
executor.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
- doProvision(requirements, stateChanges, state, options);
+ doProvision(requirements, stateChanges, state, options, outputFile);
return null;
}
}).get();
@@ -1026,7 +1035,7 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
return dstate;
}
- private Deployer.DeploymentRequest getDeploymentRequest(Map<String, Set<String>> requirements, Map<String, Map<String, FeatureState>> stateChanges, EnumSet<Option> options) {
+ private Deployer.DeploymentRequest getDeploymentRequest(Map<String, Set<String>> requirements, Map<String, Map<String, FeatureState>> stateChanges, EnumSet<Option> options, String outputFile) {
Deployer.DeploymentRequest request = new Deployer.DeploymentRequest();
request.bundleUpdateRange = bundleUpdateRange;
request.featureResolutionRange = featureResolutionRange;
@@ -1036,15 +1045,17 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
request.requirements = requirements;
request.stateChanges = stateChanges;
request.options = options;
+ request.outputFile = outputFile;
return request;
}
- public void doProvision(Map<String, Set<String>> requirements, // all requirements
- Map<String, Map<String, FeatureState>> stateChanges, // features state changes
- State state, // current state
- EnumSet<Option> options // installation options
+ public void doProvision(Map<String, Set<String>> requirements, // all requirements
+ Map<String, Map<String, FeatureState>> stateChanges, // features state changes
+ State state, // current state
+ EnumSet<Option> options, // installation options
+ String outputFile // file to store the resolution or null
) throws Exception {
Dictionary<String, String> props = getMavenConfig();
@@ -1057,7 +1068,7 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
while (true) {
try {
Deployer.DeploymentState dstate = getDeploymentState(state);
- Deployer.DeploymentRequest request = getDeploymentRequest(requirements, stateChanges, options);
+ Deployer.DeploymentRequest request = getDeploymentRequest(requirements, stateChanges, options, outputFile);
new Deployer(manager, this.resolver, this).deploy(dstate, request);
break;
} catch (Deployer.PartialDeploymentException e) {
http://git-wip-us.apache.org/repos/asf/karaf/blob/9770185c/features/core/src/main/java/org/apache/karaf/features/internal/util/JsonWriter.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/util/JsonWriter.java b/features/core/src/main/java/org/apache/karaf/features/internal/util/JsonWriter.java
index d65bc35..fb27346 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/util/JsonWriter.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/util/JsonWriter.java
@@ -76,14 +76,25 @@ public final class JsonWriter {
char c = value.charAt(i);
switch (c) {
case '\"':
+ writer.append("\\\"");
+ break;
case '\\':
+ writer.append("\\\\");
+ break;
case '\b':
+ writer.append("\\b");
+ break;
case '\f':
+ writer.append("\\f");
+ break;
case '\n':
+ writer.append("\\n");
+ break;
case '\r':
+ writer.append("\\r");
+ break;
case '\t':
- writer.append('\\');
- writer.append(c);
+ writer.append("\\t");
break;
default:
if (c < ' ' || (c >= '\u0080' && c < '\u00a0') || (c >= '\u2000' && c < '\u2100')) {
http://git-wip-us.apache.org/repos/asf/karaf/blob/9770185c/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
index 965b5f6..846a2c9 100644
--- a/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
@@ -67,7 +67,7 @@ public class SubsystemTest {
Collections.<String, Set<BundleRevision>>emptyMap());
resolver.resolve(Collections.<String>emptySet(),
FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
- null);
+ null, null);
verify(resolver, expected);
}
@@ -98,7 +98,7 @@ public class SubsystemTest {
Collections.<String, Set<BundleRevision>>emptyMap());
resolver.resolve(Collections.<String>emptySet(),
FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
- null);
+ null, null);
verify(resolver, expected);
}
@@ -119,7 +119,7 @@ public class SubsystemTest {
Collections.<String, Set<BundleRevision>>emptyMap());
resolver.resolve(Collections.singleton("b"),
FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
- null);
+ null, null);
verify(resolver, expected);
}
@@ -139,7 +139,7 @@ public class SubsystemTest {
Collections.<String, Set<BundleRevision>>emptyMap());
resolver.resolve(Collections.<String>emptySet(),
FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
- null);
+ null, null);
verify(resolver, expected);
}
@@ -161,7 +161,7 @@ public class SubsystemTest {
Collections.<String, Set<BundleRevision>>emptyMap());
resolver.resolve(Collections.<String>emptySet(),
FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
- null);
+ null, null);
verify(resolver, expected);
}
@@ -183,7 +183,7 @@ public class SubsystemTest {
Collections.<String, Set<BundleRevision>>emptyMap());
resolver.resolve(Collections.<String>emptySet(),
FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
- null);
+ null, null);
verify(resolver, expected);
}
@@ -204,7 +204,7 @@ public class SubsystemTest {
Collections.<String, Set<BundleRevision>>emptyMap());
resolver.resolve(Collections.<String>emptySet(),
FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
- null);
+ null, null);
verify(resolver, expected);
}
@@ -226,7 +226,7 @@ public class SubsystemTest {
Collections.<String, Set<BundleRevision>>emptyMap());
resolver.resolve(Collections.<String>emptySet(),
FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
- null);
+ null, null);
verify(resolver, expected);
}